Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / dhcp / common / conflex.c
blobd1f7c83e101e49b00a05015ae4e4e4ef071ca66c
1 /* conflex.c
3 Lexical scanner for dhcpd config file... */
5 /*
6 * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 #ifndef lint
36 static char copyright[] =
37 "$Id: conflex.c,v 1.5 2005/08/11 17:13:21 drochner Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
38 #endif /* not lint */
40 #include "dhcpd.h"
41 #include <ctype.h>
43 static int get_char PROTO ((struct parse *));
44 static enum dhcp_token get_token PROTO ((struct parse *));
45 static void skip_to_eol PROTO ((struct parse *));
46 static enum dhcp_token read_string PROTO ((struct parse *));
47 static enum dhcp_token read_number PROTO ((int, struct parse *));
48 static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
49 static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
51 isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
52 struct parse **cfile;
53 int file;
54 char *inbuf;
55 unsigned buflen;
56 const char *name;
57 int eolp;
59 struct parse *tmp;
61 tmp = dmalloc (sizeof (struct parse), MDL);
62 if (!tmp)
63 return ISC_R_NOMEMORY;
64 memset (tmp, 0, sizeof *tmp);
66 tmp -> token = 0;
67 tmp -> tlname = name;
68 tmp -> lpos = tmp -> line = 1;
69 tmp -> cur_line = tmp -> line1;
70 tmp -> prev_line = tmp -> line2;
71 tmp -> token_line = tmp -> cur_line;
72 tmp -> cur_line [0] = tmp -> prev_line [0] = 0;
73 tmp -> warnings_occurred = 0;
74 tmp -> file = file;
75 tmp -> eol_token = eolp;
77 tmp -> bufix = 0;
78 tmp -> buflen = buflen;
79 if (inbuf) {
80 tmp -> bufsiz = 0;
81 tmp -> inbuf = inbuf;
82 } else {
83 tmp -> inbuf = dmalloc (8192, MDL);
84 if (!tmp -> inbuf) {
85 dfree (tmp, MDL);
86 return ISC_R_NOMEMORY;
88 tmp -> bufsiz = 8192;
91 *cfile = tmp;
92 return ISC_R_SUCCESS;
95 isc_result_t end_parse (cfile)
96 struct parse **cfile;
98 if ((*cfile) -> bufsiz)
99 dfree ((*cfile) -> inbuf, MDL);
100 dfree (*cfile, MDL);
101 *cfile = (struct parse *)0;
102 return ISC_R_SUCCESS;
105 static int get_char (cfile)
106 struct parse *cfile;
108 /* My kingdom for WITH... */
109 int c;
111 if (cfile -> bufix == cfile -> buflen) {
112 if (cfile -> file != -1) {
113 cfile -> buflen =
114 read (cfile -> file,
115 cfile -> inbuf, cfile -> bufsiz);
116 if (cfile -> buflen == 0) {
117 c = EOF;
118 cfile -> bufix = 0;
119 } else if (cfile -> buflen < 0) {
120 c = EOF;
121 cfile -> bufix = cfile -> buflen = 0;
122 } else {
123 c = cfile -> inbuf [0];
124 cfile -> bufix = 1;
126 } else
127 c = EOF;
128 } else {
129 c = cfile -> inbuf [cfile -> bufix];
130 cfile -> bufix++;
133 if (!cfile -> ugflag) {
134 if (c == EOL) {
135 if (cfile -> cur_line == cfile -> line1) {
136 cfile -> cur_line = cfile -> line2;
137 cfile -> prev_line = cfile -> line1;
138 } else {
139 cfile -> cur_line = cfile -> line1;
140 cfile -> prev_line = cfile -> line2;
142 cfile -> line++;
143 cfile -> lpos = 1;
144 cfile -> cur_line [0] = 0;
145 } else if (c != EOF) {
146 if (cfile -> lpos <= 80) {
147 cfile -> cur_line [cfile -> lpos - 1] = c;
148 cfile -> cur_line [cfile -> lpos] = 0;
150 cfile -> lpos++;
152 } else
153 cfile -> ugflag = 0;
154 return c;
157 static enum dhcp_token get_token (cfile)
158 struct parse *cfile;
160 int c;
161 enum dhcp_token ttok;
162 static char tb [2];
163 int l, p, u;
165 do {
166 l = cfile -> line;
167 p = cfile -> lpos;
168 u = cfile -> ugflag;
170 c = get_char (cfile);
171 #ifdef OLD_LEXER
172 if (c == '\n' && p == 1 && !u
173 && cfile -> comment_index < sizeof cfile -> comments)
174 cfile -> comments [cfile -> comment_index++] = '\n';
175 #endif
177 if (!(c == '\n' && cfile -> eol_token)
178 && isascii (c) && isspace (c))
179 continue;
180 if (c == '#') {
181 #ifdef OLD_LEXER
182 if (cfile -> comment_index < sizeof cfile -> comments)
183 cfile -> comments [cfile -> comment_index++] = '#';
184 #endif
185 skip_to_eol (cfile);
186 continue;
188 if (c == '"') {
189 cfile -> lexline = l;
190 cfile -> lexchar = p;
191 ttok = read_string (cfile);
192 break;
194 if ((isascii (c) && isdigit (c)) || c == '-') {
195 cfile -> lexline = l;
196 cfile -> lexchar = p;
197 ttok = read_number (c, cfile);
198 break;
199 } else if (isascii (c) && isalpha (c)) {
200 cfile -> lexline = l;
201 cfile -> lexchar = p;
202 ttok = read_num_or_name (c, cfile);
203 break;
204 } else if (c == EOF) {
205 ttok = END_OF_FILE;
206 cfile -> tlen = 0;
207 break;
208 } else {
209 cfile -> lexline = l;
210 cfile -> lexchar = p;
211 tb [0] = c;
212 tb [1] = 0;
213 cfile -> tval = tb;
214 cfile -> tlen = 1;
215 ttok = c;
216 break;
218 } while (1);
219 return ttok;
222 enum dhcp_token next_token (rval, rlen, cfile)
223 const char **rval;
224 unsigned *rlen;
225 struct parse *cfile;
227 int rv;
229 if (cfile -> token) {
230 if (cfile -> lexline != cfile -> tline)
231 cfile -> token_line = cfile -> cur_line;
232 cfile -> lexchar = cfile -> tlpos;
233 cfile -> lexline = cfile -> tline;
234 rv = cfile -> token;
235 cfile -> token = 0;
236 } else {
237 rv = get_token (cfile);
238 cfile -> token_line = cfile -> cur_line;
240 if (rval)
241 *rval = cfile -> tval;
242 if (rlen)
243 *rlen = cfile -> tlen;
244 #ifdef DEBUG_TOKENS
245 fprintf (stderr, "%s:%d ", cfile -> tval, rv);
246 #endif
247 return rv;
250 enum dhcp_token peek_token (rval, rlen, cfile)
251 const char **rval;
252 unsigned int *rlen;
253 struct parse *cfile;
255 int x;
257 if (!cfile -> token) {
258 cfile -> tlpos = cfile -> lexchar;
259 cfile -> tline = cfile -> lexline;
260 cfile -> token = get_token (cfile);
261 if (cfile -> lexline != cfile -> tline)
262 cfile -> token_line = cfile -> prev_line;
264 x = cfile -> lexchar;
265 cfile -> lexchar = cfile -> tlpos;
266 cfile -> tlpos = x;
268 x = cfile -> lexline;
269 cfile -> lexline = cfile -> tline;
270 cfile -> tline = x;
272 if (rval)
273 *rval = cfile -> tval;
274 if (rlen)
275 *rlen = cfile -> tlen;
276 #ifdef DEBUG_TOKENS
277 fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
278 #endif
279 return cfile -> token;
282 static void skip_to_eol (cfile)
283 struct parse *cfile;
285 int c;
286 do {
287 c = get_char (cfile);
288 if (c == EOF)
289 return;
290 #ifdef OLD_LEXER
291 if (cfile -> comment_index < sizeof (cfile -> comments))
292 comments [cfile -> comment_index++] = c;
293 #endif
294 if (c == EOL) {
295 return;
297 } while (1);
300 static enum dhcp_token read_string (cfile)
301 struct parse *cfile;
303 int i;
304 int bs = 0;
305 int c;
306 int value = 0;
307 int hex = 0;
309 value = 0; /* XXXGCC -Wuninitialized */
310 hex = 0; /* XXXGCC -Wuninitialized */
312 for (i = 0; i < sizeof cfile -> tokbuf; i++) {
313 again:
314 c = get_char (cfile);
315 if (c == EOF) {
316 parse_warn (cfile, "eof in string constant");
317 break;
319 if (bs == 1) {
320 switch (c) {
321 case 't':
322 cfile -> tokbuf [i] = '\t';
323 break;
324 case 'r':
325 cfile -> tokbuf [i] = '\r';
326 break;
327 case 'n':
328 cfile -> tokbuf [i] = '\n';
329 break;
330 case 'b':
331 cfile -> tokbuf [i] = '\b';
332 break;
333 case '0':
334 case '1':
335 case '2':
336 case '3':
337 hex = 0;
338 value = c - '0';
339 ++bs;
340 goto again;
341 case 'x':
342 hex = 1;
343 value = 0;
344 ++bs;
345 goto again;
346 default:
347 cfile -> tokbuf [i] = c;
348 bs = 0;
349 break;
351 bs = 0;
352 } else if (bs > 1) {
353 if (hex) {
354 if (c >= '0' && c <= '9') {
355 value = value * 16 + (c - '0');
356 } else if (c >= 'a' && c <= 'f') {
357 value = value * 16 + (c - 'a' + 10);
358 } else if (c >= 'A' && c <= 'F') {
359 value = value * 16 + (c - 'A' + 10);
360 } else {
361 parse_warn (cfile,
362 "invalid hex digit: %x",
364 bs = 0;
365 continue;
367 if (++bs == 4) {
368 cfile -> tokbuf [i] = value;
369 bs = 0;
370 } else
371 goto again;
372 } else {
373 if (c >= '0' && c <= '9') {
374 value = value * 8 + (c - '0');
375 } else {
376 if (value != 0) {
377 parse_warn (cfile,
378 "invalid octal digit %x",
380 continue;
381 } else
382 cfile -> tokbuf [i] = 0;
383 bs = 0;
385 if (++bs == 4) {
386 cfile -> tokbuf [i] = value;
387 bs = 0;
388 } else
389 goto again;
391 } else if (c == '\\') {
392 bs = 1;
393 goto again;
394 } else if (c == '"')
395 break;
396 else
397 cfile -> tokbuf [i] = c;
399 /* Normally, I'd feel guilty about this, but we're talking about
400 strings that'll fit in a DHCP packet here... */
401 if (i == sizeof cfile -> tokbuf) {
402 parse_warn (cfile,
403 "string constant larger than internal buffer");
404 --i;
406 cfile -> tokbuf [i] = 0;
407 cfile -> tlen = i;
408 cfile -> tval = cfile -> tokbuf;
409 return STRING;
412 static enum dhcp_token read_number (c, cfile)
413 int c;
414 struct parse *cfile;
416 #ifdef OLD_LEXER
417 int seenx = 0;
418 #endif
419 int i = 0;
420 int token = NUMBER;
422 cfile -> tokbuf [i++] = c;
423 for (; i < sizeof cfile -> tokbuf; i++) {
424 c = get_char (cfile);
426 #ifndef OLD_LEXER
427 /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
428 * Except in the case of '0x' syntax hex, which gets called
429 * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
430 * verified to be at least 0xf or less.
432 switch(isascii(c) ? token : BREAK) {
433 case NUMBER:
434 if(isdigit(c))
435 break;
436 /* FALLTHROUGH */
437 case NUMBER_OR_NAME:
438 if(isxdigit(c)) {
439 token = NUMBER_OR_NAME;
440 break;
442 /* FALLTHROUGH */
443 case NAME:
444 if((i == 2) && isxdigit(c) &&
445 (cfile->tokbuf[0] == '0') &&
446 ((cfile->tokbuf[1] == 'x') ||
447 (cfile->tokbuf[1] == 'X'))) {
448 token = NUMBER_OR_NAME;
449 break;
450 } else if(((c == '-') || (c == '_') || isalnum(c))) {
451 token = NAME;
452 break;
454 /* FALLTHROUGH */
455 case BREAK:
456 /* At this point c is either EOF or part of the next
457 * token. If not EOF, rewind the file one byte so
458 * the next token is read from there.
460 if(c != EOF) {
461 cfile->bufix--;
462 cfile->ugflag = 1;
464 goto end_read;
466 default:
467 log_fatal("read_number():%s:%d: impossible case", MDL);
469 #else /* OLD_LEXER */
470 if (!seenx && (c == 'x') {
471 seenx = 1;
472 } else if (!isascii (c) || !isxdigit (c)) {
473 if (c != EOF) {
474 cfile -> bufix--;
475 cfile -> ugflag = 1;
477 break;
479 #endif /* OLD_LEXER */
481 cfile -> tokbuf [i] = c;
484 if (i == sizeof cfile -> tokbuf) {
485 parse_warn (cfile,
486 "numeric token larger than internal buffer");
487 --i;
490 end_read:
491 cfile -> tokbuf [i] = 0;
492 cfile -> tlen = i;
493 cfile -> tval = cfile -> tokbuf;
495 return token;
498 static enum dhcp_token read_num_or_name (c, cfile)
499 int c;
500 struct parse *cfile;
502 int i = 0;
503 enum dhcp_token rv = NUMBER_OR_NAME;
504 cfile -> tokbuf [i++] = c;
505 for (; i < sizeof cfile -> tokbuf; i++) {
506 c = get_char (cfile);
507 if (!isascii (c) ||
508 (c != '-' && c != '_' && !isalnum (c))) {
509 if (c != EOF) {
510 cfile -> bufix--;
511 cfile -> ugflag = 1;
513 break;
515 if (!isxdigit (c))
516 rv = NAME;
517 cfile -> tokbuf [i] = c;
519 if (i == sizeof cfile -> tokbuf) {
520 parse_warn (cfile, "token larger than internal buffer");
521 --i;
523 cfile -> tokbuf [i] = 0;
524 cfile -> tlen = i;
525 cfile -> tval = cfile -> tokbuf;
526 return intern (cfile -> tval, rv);
529 static enum dhcp_token intern (atom, dfv)
530 char *atom;
531 enum dhcp_token dfv;
533 if (!isascii (atom [0]))
534 return dfv;
536 switch (tolower ((unsigned char)atom [0])) {
537 case '-':
538 if (atom [1] == 0)
539 return MINUS;
540 break;
542 case 'a':
543 if (!strncasecmp (atom + 1, "uth", 3)) {
544 if (!strncasecmp (atom + 3, "uthenticat", 10)) {
545 if (!strcasecmp (atom + 13, "ed"))
546 return AUTHENTICATED;
547 if (!strcasecmp (atom + 13, "ion"))
548 return AUTHENTICATION;
549 break;
551 if (!strcasecmp (atom + 1, "uthoritative"))
552 return AUTHORITATIVE;
553 break;
555 if (!strcasecmp (atom + 1, "nd"))
556 return AND;
557 if (!strcasecmp (atom + 1, "ppend"))
558 return APPEND;
559 if (!strcasecmp (atom + 1, "llow"))
560 return ALLOW;
561 if (!strcasecmp (atom + 1, "lias"))
562 return ALIAS;
563 if (!strcasecmp (atom + 1, "lgorithm"))
564 return ALGORITHM;
565 if (!strcasecmp (atom + 1, "bandoned"))
566 return TOKEN_ABANDONED;
567 if (!strcasecmp (atom + 1, "dd"))
568 return TOKEN_ADD;
569 if (!strcasecmp (atom + 1, "ll"))
570 return ALL;
571 if (!strcasecmp (atom + 1, "t"))
572 return AT;
573 if (!strcasecmp (atom + 1, "rray"))
574 return ARRAY;
575 if (!strcasecmp (atom + 1, "ddress"))
576 return ADDRESS;
577 if (!strcasecmp (atom + 1, "ctive"))
578 return TOKEN_ACTIVE;
579 break;
580 case 'b':
581 if (!strcasecmp (atom + 1, "ackup"))
582 return TOKEN_BACKUP;
583 if (!strcasecmp (atom + 1, "ootp"))
584 return TOKEN_BOOTP;
585 if (!strcasecmp (atom + 1, "inding"))
586 return BINDING;
587 if (!strcasecmp (atom + 1, "inary-to-ascii"))
588 return BINARY_TO_ASCII;
589 if (!strcasecmp (atom + 1, "ackoff-cutoff"))
590 return BACKOFF_CUTOFF;
591 if (!strcasecmp (atom + 1, "ooting"))
592 return BOOTING;
593 if (!strcasecmp (atom + 1, "oot-unknown-clients"))
594 return BOOT_UNKNOWN_CLIENTS;
595 if (!strcasecmp (atom + 1, "reak"))
596 return BREAK;
597 if (!strcasecmp (atom + 1, "illing"))
598 return BILLING;
599 if (!strcasecmp (atom + 1, "oolean"))
600 return BOOLEAN;
601 if (!strcasecmp (atom + 1, "alance"))
602 return BALANCE;
603 if (!strcasecmp (atom + 1, "ound"))
604 return BOUND;
605 break;
606 case 'c':
607 if (!strcasecmp (atom + 1, "ase"))
608 return CASE;
609 if (!strcasecmp (atom + 1, "ommit"))
610 return COMMIT;
611 if (!strcasecmp (atom + 1, "ode"))
612 return CODE;
613 if (!strcasecmp (atom + 1, "onfig-option"))
614 return CONFIG_OPTION;
615 if (!strcasecmp (atom + 1, "heck"))
616 return CHECK;
617 if (!strcasecmp (atom + 1, "lass"))
618 return CLASS;
619 if (!strcasecmp (atom + 1, "lose"))
620 return TOKEN_CLOSE;
621 if (!strcasecmp (atom + 1, "reate"))
622 return TOKEN_CREATE;
623 if (!strcasecmp (atom + 1, "iaddr"))
624 return CIADDR;
625 if (!strncasecmp (atom + 1, "lient", 5)) {
626 if (!strcasecmp (atom + 6, "-identifier"))
627 return CLIENT_IDENTIFIER;
628 if (!strcasecmp (atom + 6, "-hostname"))
629 return CLIENT_HOSTNAME;
630 if (!strcasecmp (atom + 6, "-state"))
631 return CLIENT_STATE;
632 if (!strcasecmp (atom + 6, "-updates"))
633 return CLIENT_UPDATES;
634 if (!strcasecmp (atom + 6, "s"))
635 return CLIENTS;
637 if (!strcasecmp (atom + 1, "oncat"))
638 return CONCAT;
639 if (!strcasecmp (atom + 1, "onnect"))
640 return CONNECT;
641 if (!strcasecmp (atom + 1, "ommunications-interrupted"))
642 return COMMUNICATIONS_INTERRUPTED;
643 if (!strcasecmp (atom + 1, "ltt"))
644 return CLTT;
645 break;
646 case 'd':
647 if (!strcasecmp (atom + 1, "ns-update"))
648 return DNS_UPDATE;
649 if (!strcasecmp (atom + 1, "ns-delete"))
650 return DNS_DELETE;
651 if (!strcasecmp (atom + 1, "omain"))
652 return DOMAIN;
653 if (!strcasecmp (atom + 1, "omain-name"))
654 return DOMAIN_NAME;
655 if (!strcasecmp (atom + 1, "o-forward-update"))
656 return DO_FORWARD_UPDATE;
657 if (!strcasecmp (atom + 1, "ebug"))
658 return TOKEN_DEBUG;
659 if (!strcasecmp (atom + 1, "eny"))
660 return DENY;
661 if (!strcasecmp (atom + 1, "eleted"))
662 return TOKEN_DELETED;
663 if (!strcasecmp (atom + 1, "elete"))
664 return TOKEN_DELETE;
665 if (!strncasecmp (atom + 1, "efault", 6)) {
666 if (!atom [7])
667 return DEFAULT;
668 if (!strcasecmp (atom + 7, "-lease-time"))
669 return DEFAULT_LEASE_TIME;
670 break;
672 if (!strncasecmp (atom + 1, "ynamic", 6)) {
673 if (!atom [7])
674 return DYNAMIC;
675 if (!strncasecmp (atom + 7, "-bootp", 6)) {
676 if (!atom [13])
677 return DYNAMIC_BOOTP;
678 if (!strcasecmp (atom + 13, "-lease-cutoff"))
679 return DYNAMIC_BOOTP_LEASE_CUTOFF;
680 if (!strcasecmp (atom + 13, "-lease-length"))
681 return DYNAMIC_BOOTP_LEASE_LENGTH;
682 break;
685 if (!strcasecmp (atom + 1, "uplicates"))
686 return DUPLICATES;
687 if (!strcasecmp (atom + 1, "eclines"))
688 return DECLINES;
689 if (!strncasecmp (atom + 1, "efine", 5)) {
690 if (!strcasecmp (atom + 6, "d"))
691 return DEFINED;
692 if (!atom [6])
693 return DEFINE;
695 break;
696 case 'e':
697 if (tolower ((unsigned char)atom [1]) == 'x') {
698 if (!strcasecmp (atom + 2, "tract-int"))
699 return EXTRACT_INT;
700 if (!strcasecmp (atom + 2, "ists"))
701 return EXISTS;
702 if (!strcasecmp (atom + 2, "piry"))
703 return EXPIRY;
704 if (!strcasecmp (atom + 2, "pire"))
705 return EXPIRE;
706 if (!strcasecmp (atom + 2, "pired"))
707 return TOKEN_EXPIRED;
709 if (!strcasecmp (atom + 1, "ncode-int"))
710 return ENCODE_INT;
711 if (!strcasecmp (atom + 1, "thernet"))
712 return ETHERNET;
713 if (!strcasecmp (atom + 1, "nds"))
714 return ENDS;
715 if (!strncasecmp (atom + 1, "ls", 2)) {
716 if (!strcasecmp (atom + 3, "e"))
717 return ELSE;
718 if (!strcasecmp (atom + 3, "if"))
719 return ELSIF;
720 break;
722 if (!strcasecmp (atom + 1, "rror"))
723 return ERROR;
724 if (!strcasecmp (atom + 1, "val"))
725 return EVAL;
726 if (!strcasecmp (atom + 1, "ncapsulate"))
727 return ENCAPSULATE;
728 break;
729 case 'f':
730 if (!strcasecmp (atom + 1, "atal"))
731 return FATAL;
732 if (!strcasecmp (atom + 1, "ilename"))
733 return FILENAME;
734 if (!strcasecmp (atom + 1, "ixed-address"))
735 return FIXED_ADDR;
736 if (!strcasecmp (atom + 1, "ddi"))
737 return FDDI;
738 if (!strcasecmp (atom + 1, "ormerr"))
739 return NS_FORMERR;
740 if (!strcasecmp (atom + 1, "unction"))
741 return FUNCTION;
742 if (!strcasecmp (atom + 1, "ailover"))
743 return FAILOVER;
744 if (!strcasecmp (atom + 1, "ree"))
745 return TOKEN_FREE;
746 break;
747 case 'g':
748 if (!strcasecmp (atom + 1, "iaddr"))
749 return GIADDR;
750 if (!strcasecmp (atom + 1, "roup"))
751 return GROUP;
752 if (!strcasecmp (atom + 1, "et-lease-hostnames"))
753 return GET_LEASE_HOSTNAMES;
754 break;
755 case 'h':
756 if (!strcasecmp (atom + 1, "ba"))
757 return HBA;
758 if (!strcasecmp (atom + 1, "ost"))
759 return HOST;
760 if (!strcasecmp (atom + 1, "ost-decl-name"))
761 return HOST_DECL_NAME;
762 if (!strcasecmp (atom + 1, "ardware"))
763 return HARDWARE;
764 if (!strcasecmp (atom + 1, "ostname"))
765 return HOSTNAME;
766 if (!strcasecmp (atom + 1, "elp"))
767 return TOKEN_HELP;
768 break;
769 case 'i':
770 if (!strcasecmp (atom + 1, "nclude"))
771 return INCLUDE;
772 if (!strcasecmp (atom + 1, "nteger"))
773 return INTEGER;
774 if (!strcasecmp (atom + 1, "nfinite"))
775 return INFINITE;
776 if (!strcasecmp (atom + 1, "nfo"))
777 return INFO;
778 if (!strcasecmp (atom + 1, "p-address"))
779 return IP_ADDRESS;
780 if (!strcasecmp (atom + 1, "nitial-interval"))
781 return INITIAL_INTERVAL;
782 if (!strcasecmp (atom + 1, "nterface"))
783 return INTERFACE;
784 if (!strcasecmp (atom + 1, "dentifier"))
785 return IDENTIFIER;
786 if (!strcasecmp (atom + 1, "f"))
787 return IF;
788 if (!strcasecmp (atom + 1, "s"))
789 return IS;
790 if (!strcasecmp (atom + 1, "gnore"))
791 return IGNORE;
792 break;
793 case 'k':
794 if (!strncasecmp (atom + 1, "nown", 4)) {
795 if (!strcasecmp (atom + 5, "-clients"))
796 return KNOWN_CLIENTS;
797 if (!atom[5])
798 return KNOWN;
799 break;
801 if (!strcasecmp (atom + 1, "ey"))
802 return KEY;
803 break;
804 case 'l':
805 if (!strcasecmp (atom + 1, "ease"))
806 return LEASE;
807 if (!strcasecmp (atom + 1, "eased-address"))
808 return LEASED_ADDRESS;
809 if (!strcasecmp (atom + 1, "ease-time"))
810 return LEASE_TIME;
811 if (!strcasecmp (atom + 1, "imit"))
812 return LIMIT;
813 if (!strcasecmp (atom + 1, "et"))
814 return LET;
815 if (!strcasecmp (atom + 1, "oad"))
816 return LOAD;
817 if (!strcasecmp (atom + 1, "og"))
818 return LOG;
819 break;
820 case 'm':
821 if (!strncasecmp (atom + 1, "ax", 2)) {
822 if (!atom [3])
823 return TOKEN_MAX;
824 if (!strcasecmp (atom + 3, "-lease-time"))
825 return MAX_LEASE_TIME;
826 if (!strcasecmp (atom + 3, "-transmit-idle"))
827 return MAX_TRANSMIT_IDLE;
828 if (!strcasecmp (atom + 3, "-response-delay"))
829 return MAX_RESPONSE_DELAY;
830 if (!strcasecmp (atom + 3, "-unacked-updates"))
831 return MAX_UNACKED_UPDATES;
833 if (!strncasecmp (atom + 1, "in-", 3)) {
834 if (!strcasecmp (atom + 4, "lease-time"))
835 return MIN_LEASE_TIME;
836 if (!strcasecmp (atom + 4, "secs"))
837 return MIN_SECS;
838 break;
840 if (!strncasecmp (atom + 1, "edi", 3)) {
841 if (!strcasecmp (atom + 4, "a"))
842 return MEDIA;
843 if (!strcasecmp (atom + 4, "um"))
844 return MEDIUM;
845 break;
847 if (!strcasecmp (atom + 1, "atch"))
848 return MATCH;
849 if (!strcasecmp (atom + 1, "embers"))
850 return MEMBERS;
851 if (!strcasecmp (atom + 1, "y"))
852 return MY;
853 if (!strcasecmp (atom + 1, "clt"))
854 return MCLT;
855 break;
856 case 'n':
857 if (!strcasecmp (atom + 1, "ormal"))
858 return NORMAL;
859 if (!strcasecmp (atom + 1, "ameserver"))
860 return NAMESERVER;
861 if (!strcasecmp (atom + 1, "etmask"))
862 return NETMASK;
863 if (!strcasecmp (atom + 1, "ever"))
864 return NEVER;
865 if (!strcasecmp (atom + 1, "ext-server"))
866 return NEXT_SERVER;
867 if (!strcasecmp (atom + 1, "ot"))
868 return TOKEN_NOT;
869 if (!strcasecmp (atom + 1, "o"))
870 return NO;
871 if (!strcasecmp (atom + 1, "s-update"))
872 return NS_UPDATE;
873 if (!strcasecmp (atom + 1, "oerror"))
874 return NS_NOERROR;
875 if (!strcasecmp (atom + 1, "otauth"))
876 return NS_NOTAUTH;
877 if (!strcasecmp (atom + 1, "otimp"))
878 return NS_NOTIMP;
879 if (!strcasecmp (atom + 1, "otzone"))
880 return NS_NOTZONE;
881 if (!strcasecmp (atom + 1, "xdomain"))
882 return NS_NXDOMAIN;
883 if (!strcasecmp (atom + 1, "xrrset"))
884 return NS_NXRRSET;
885 if (!strcasecmp (atom + 1, "ull"))
886 return TOKEN_NULL;
887 if (!strcasecmp (atom + 1, "ext"))
888 return TOKEN_NEXT;
889 if (!strcasecmp (atom + 1, "ew"))
890 return TOKEN_NEW;
891 break;
892 case 'o':
893 if (!strcasecmp (atom + 1, "mapi"))
894 return OMAPI;
895 if (!strcasecmp (atom + 1, "r"))
896 return OR;
897 if (!strcasecmp (atom + 1, "n"))
898 return ON;
899 if (!strcasecmp (atom + 1, "pen"))
900 return TOKEN_OPEN;
901 if (!strcasecmp (atom + 1, "ption"))
902 return OPTION;
903 if (!strcasecmp (atom + 1, "ne-lease-per-client"))
904 return ONE_LEASE_PER_CLIENT;
905 if (!strcasecmp (atom + 1, "f"))
906 return OF;
907 if (!strcasecmp (atom + 1, "wner"))
908 return OWNER;
909 break;
910 case 'p':
911 if (!strcasecmp (atom + 1, "repend"))
912 return PREPEND;
913 if (!strcasecmp (atom + 1, "acket"))
914 return PACKET;
915 if (!strcasecmp (atom + 1, "ool"))
916 return POOL;
917 if (!strcasecmp (atom + 1, "seudo"))
918 return PSEUDO;
919 if (!strcasecmp (atom + 1, "eer"))
920 return PEER;
921 if (!strcasecmp (atom + 1, "rimary"))
922 return PRIMARY;
923 if (!strncasecmp (atom + 1, "artner", 6)) {
924 if (!atom [7])
925 return PARTNER;
926 if (!strcasecmp (atom + 7, "-down"))
927 return PARTNER_DOWN;
929 if (!strcasecmp (atom + 1, "ort"))
930 return PORT;
931 if (!strcasecmp (atom + 1, "otential-conflict"))
932 return POTENTIAL_CONFLICT;
933 if (!strcasecmp (atom + 1, "ick-first-value") ||
934 !strcasecmp (atom + 1, "ick"))
935 return PICK;
936 if (!strcasecmp (atom + 1, "aused"))
937 return PAUSED;
938 break;
939 case 'r':
940 if (!strcasecmp (atom + 1, "esolution-interrupted"))
941 return RESOLUTION_INTERRUPTED;
942 if (!strcasecmp (atom + 1, "ange"))
943 return RANGE;
944 if (!strcasecmp (atom + 1, "ecover"))
945 return RECOVER;
946 if (!strcasecmp (atom + 1, "ecover-done"))
947 return RECOVER_DONE;
948 if (!strcasecmp (atom + 1, "ecover-wait"))
949 return RECOVER_WAIT;
950 if (!strcasecmp (atom + 1, "econtact-interval"))
951 return RECONTACT_INTERVAL;
952 if (!strcasecmp (atom + 1, "equest"))
953 return REQUEST;
954 if (!strcasecmp (atom + 1, "equire"))
955 return REQUIRE;
956 if (!strcasecmp (atom + 1, "equire"))
957 return REQUIRE;
958 if (!strcasecmp (atom + 1, "etry"))
959 return RETRY;
960 if (!strcasecmp (atom + 1, "eturn"))
961 return RETURN;
962 if (!strcasecmp (atom + 1, "enew"))
963 return RENEW;
964 if (!strcasecmp (atom + 1, "ebind"))
965 return REBIND;
966 if (!strcasecmp (atom + 1, "eboot"))
967 return REBOOT;
968 if (!strcasecmp (atom + 1, "eject"))
969 return REJECT;
970 if (!strcasecmp (atom + 1, "everse"))
971 return REVERSE;
972 if (!strcasecmp (atom + 1, "elease"))
973 return RELEASE;
974 if (!strcasecmp (atom + 1, "efused"))
975 return NS_REFUSED;
976 if (!strcasecmp (atom + 1, "eleased"))
977 return TOKEN_RELEASED;
978 if (!strcasecmp (atom + 1, "eset"))
979 return TOKEN_RESET;
980 if (!strcasecmp (atom + 1, "eserved"))
981 return TOKEN_RESERVED;
982 if (!strcasecmp (atom + 1, "emove"))
983 return REMOVE;
984 if (!strcasecmp (atom + 1, "efresh"))
985 return REFRESH;
986 break;
987 case 's':
988 if (!strcasecmp (atom + 1, "tate"))
989 return STATE;
990 if (!strcasecmp (atom + 1, "ecret"))
991 return SECRET;
992 if (!strcasecmp (atom + 1, "ervfail"))
993 return NS_SERVFAIL;
994 if (!strcasecmp (atom + 1, "witch"))
995 return SWITCH;
996 if (!strcasecmp (atom + 1, "igned"))
997 return SIGNED;
998 if (!strcasecmp (atom + 1, "tring"))
999 return STRING_TOKEN;
1000 if (!strcasecmp (atom + 1, "uffix"))
1001 return SUFFIX;
1002 if (!strcasecmp (atom + 1, "earch"))
1003 return SEARCH;
1004 if (!strcasecmp (atom + 1, "tarts"))
1005 return STARTS;
1006 if (!strcasecmp (atom + 1, "iaddr"))
1007 return SIADDR;
1008 if (!strcasecmp (atom + 1, "hared-network"))
1009 return SHARED_NETWORK;
1010 if (!strcasecmp (atom + 1, "econdary"))
1011 return SECONDARY;
1012 if (!strcasecmp (atom + 1, "erver-name"))
1013 return SERVER_NAME;
1014 if (!strcasecmp (atom + 1, "erver-identifier"))
1015 return SERVER_IDENTIFIER;
1016 if (!strcasecmp (atom + 1, "erver"))
1017 return SERVER;
1018 if (!strcasecmp (atom + 1, "elect-timeout"))
1019 return SELECT_TIMEOUT;
1020 if (!strcasecmp (atom + 1, "elect"))
1021 return SELECT;
1022 if (!strcasecmp (atom + 1, "end"))
1023 return SEND;
1024 if (!strcasecmp (atom + 1, "cript"))
1025 return SCRIPT;
1026 if (!strcasecmp (atom + 1, "upersede"))
1027 return SUPERSEDE;
1028 if (!strncasecmp (atom + 1, "ub", 2)) {
1029 if (!strcasecmp (atom + 3, "string"))
1030 return SUBSTRING;
1031 if (!strcasecmp (atom + 3, "net"))
1032 return SUBNET;
1033 if (!strcasecmp (atom + 3, "class"))
1034 return SUBCLASS;
1035 break;
1037 if (!strcasecmp (atom + 1, "pawn"))
1038 return SPAWN;
1039 if (!strcasecmp (atom + 1, "pace"))
1040 return SPACE;
1041 if (!strcasecmp (atom + 1, "tatic"))
1042 return STATIC;
1043 if (!strcasecmp (atom + 1, "plit"))
1044 return SPLIT;
1045 if (!strcasecmp (atom + 1, "et"))
1046 return TOKEN_SET;
1047 if (!strcasecmp (atom + 1, "econds"))
1048 return SECONDS;
1049 if (!strcasecmp (atom + 1, "hutdown"))
1050 return SHUTDOWN;
1051 if (!strcasecmp (atom + 1, "tartup"))
1052 return STARTUP;
1053 break;
1054 case 't':
1055 if (!strcasecmp (atom + 1, "imestamp"))
1056 return TIMESTAMP;
1057 if (!strcasecmp (atom + 1, "imeout"))
1058 return TIMEOUT;
1059 if (!strcasecmp (atom + 1, "oken-ring"))
1060 return TOKEN_RING;
1061 if (!strcasecmp (atom + 1, "ext"))
1062 return TEXT;
1063 if (!strcasecmp (atom + 1, "stp"))
1064 return TSTP;
1065 if (!strcasecmp (atom + 1, "sfp"))
1066 return TSFP;
1067 if (!strcasecmp (atom + 1, "ransmission"))
1068 return TRANSMISSION;
1069 break;
1070 case 'u':
1071 if (!strcasecmp (atom + 1, "nset"))
1072 return UNSET;
1073 if (!strcasecmp (atom + 1, "nsigned"))
1074 return UNSIGNED;
1075 if (!strcasecmp (atom + 1, "id"))
1076 return UID;
1077 if (!strncasecmp (atom + 1, "se", 2)) {
1078 if (!strcasecmp (atom + 3, "r-class"))
1079 return USER_CLASS;
1080 if (!strcasecmp (atom + 3, "-host-decl-names"))
1081 return USE_HOST_DECL_NAMES;
1082 if (!strcasecmp (atom + 3,
1083 "-lease-addr-for-default-route"))
1084 return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1085 break;
1087 if (!strncasecmp (atom + 1, "nknown", 6)) {
1088 if (!strcasecmp (atom + 7, "-clients"))
1089 return UNKNOWN_CLIENTS;
1090 if (!strcasecmp (atom + 7, "-state"))
1091 return UNKNOWN_STATE;
1092 if (!atom [7])
1093 return UNKNOWN;
1094 break;
1096 if (!strcasecmp (atom + 1, "nauthenticated"))
1097 return AUTHENTICATED;
1098 if (!strcasecmp (atom + 1, "pdated-dns-rr"))
1099 return UPDATED_DNS_RR;
1100 if (!strcasecmp (atom + 1, "pdate"))
1101 return UPDATE;
1102 break;
1103 case 'v':
1104 if (!strcasecmp (atom + 1, "endor-class"))
1105 return VENDOR_CLASS;
1106 if (!strcasecmp (atom + 1, "endor"))
1107 return VENDOR;
1108 break;
1109 case 'w':
1110 if (!strcasecmp (atom + 1, "ith"))
1111 return WITH;
1112 break;
1113 case 'y':
1114 if (!strcasecmp (atom + 1, "iaddr"))
1115 return YIADDR;
1116 if (!strcasecmp (atom + 1, "xdomain"))
1117 return NS_YXDOMAIN;
1118 if (!strcasecmp (atom + 1, "xrrset"))
1119 return NS_YXRRSET;
1120 break;
1121 case 'z':
1122 if (!strcasecmp (atom + 1, "one"))
1123 return ZONE;
1124 break;
1126 return dfv;