tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / dhcp / common / conflex.c
blobbaa01e3471bef19a09991fad742524c65954d36b
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 #if 0
36 static char copyright[] =
37 "$Id$ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
38 #endif
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;
164 #ifdef OLD_LEXER
165 int u;
166 #endif
168 do {
169 l = cfile -> line;
170 p = cfile -> lpos;
171 #ifdef OLD_LEXER
172 u = cfile -> ugflag;
173 #endif
175 c = get_char (cfile);
176 #ifdef OLD_LEXER
177 if (c == '\n' && p == 1 && !u
178 && cfile -> comment_index < sizeof cfile -> comments)
179 cfile -> comments [cfile -> comment_index++] = '\n';
180 #endif
182 if (!(c == '\n' && cfile -> eol_token)
183 && isascii (c) && isspace (c))
184 continue;
185 if (c == '#') {
186 #ifdef OLD_LEXER
187 if (cfile -> comment_index < sizeof cfile -> comments)
188 cfile -> comments [cfile -> comment_index++] = '#';
189 #endif
190 skip_to_eol (cfile);
191 continue;
193 if (c == '"') {
194 cfile -> lexline = l;
195 cfile -> lexchar = p;
196 ttok = read_string (cfile);
197 break;
199 if ((isascii (c) && isdigit (c)) || c == '-') {
200 cfile -> lexline = l;
201 cfile -> lexchar = p;
202 ttok = read_number (c, cfile);
203 break;
204 } else if (isascii (c) && isalpha (c)) {
205 cfile -> lexline = l;
206 cfile -> lexchar = p;
207 ttok = read_num_or_name (c, cfile);
208 break;
209 } else if (c == EOF) {
210 ttok = END_OF_FILE;
211 cfile -> tlen = 0;
212 break;
213 } else {
214 cfile -> lexline = l;
215 cfile -> lexchar = p;
216 tb [0] = c;
217 tb [1] = 0;
218 cfile -> tval = tb;
219 cfile -> tlen = 1;
220 ttok = c;
221 break;
223 } while (1);
224 return ttok;
227 enum dhcp_token next_token (rval, rlen, cfile)
228 const char **rval;
229 unsigned *rlen;
230 struct parse *cfile;
232 int rv;
234 if (cfile -> token) {
235 if (cfile -> lexline != cfile -> tline)
236 cfile -> token_line = cfile -> cur_line;
237 cfile -> lexchar = cfile -> tlpos;
238 cfile -> lexline = cfile -> tline;
239 rv = cfile -> token;
240 cfile -> token = 0;
241 } else {
242 rv = get_token (cfile);
243 cfile -> token_line = cfile -> cur_line;
245 if (rval)
246 *rval = cfile -> tval;
247 if (rlen)
248 *rlen = cfile -> tlen;
249 #ifdef DEBUG_TOKENS
250 fprintf (stderr, "%s:%d ", cfile -> tval, rv);
251 #endif
252 return rv;
255 enum dhcp_token peek_token (rval, rlen, cfile)
256 const char **rval;
257 unsigned int *rlen;
258 struct parse *cfile;
260 int x;
262 if (!cfile -> token) {
263 cfile -> tlpos = cfile -> lexchar;
264 cfile -> tline = cfile -> lexline;
265 cfile -> token = get_token (cfile);
266 if (cfile -> lexline != cfile -> tline)
267 cfile -> token_line = cfile -> prev_line;
269 x = cfile -> lexchar;
270 cfile -> lexchar = cfile -> tlpos;
271 cfile -> tlpos = x;
273 x = cfile -> lexline;
274 cfile -> lexline = cfile -> tline;
275 cfile -> tline = x;
277 if (rval)
278 *rval = cfile -> tval;
279 if (rlen)
280 *rlen = cfile -> tlen;
281 #ifdef DEBUG_TOKENS
282 fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
283 #endif
284 return cfile -> token;
287 static void skip_to_eol (cfile)
288 struct parse *cfile;
290 int c;
291 do {
292 c = get_char (cfile);
293 if (c == EOF)
294 return;
295 #ifdef OLD_LEXER
296 if (cfile -> comment_index < sizeof (cfile -> comments))
297 comments [cfile -> comment_index++] = c;
298 #endif
299 if (c == EOL) {
300 return;
302 } while (1);
305 static enum dhcp_token read_string (cfile)
306 struct parse *cfile;
308 int i;
309 int bs = 0;
310 int c;
311 int value = 0;
312 int hex = 0;
314 for (i = 0; i < sizeof cfile -> tokbuf; i++) {
315 again:
316 c = get_char (cfile);
317 if (c == EOF) {
318 parse_warn (cfile, "eof in string constant");
319 break;
321 if (bs == 1) {
322 switch (c) {
323 case 't':
324 cfile -> tokbuf [i] = '\t';
325 break;
326 case 'r':
327 cfile -> tokbuf [i] = '\r';
328 break;
329 case 'n':
330 cfile -> tokbuf [i] = '\n';
331 break;
332 case 'b':
333 cfile -> tokbuf [i] = '\b';
334 break;
335 case '0':
336 case '1':
337 case '2':
338 case '3':
339 hex = 0;
340 value = c - '0';
341 ++bs;
342 goto again;
343 case 'x':
344 hex = 1;
345 value = 0;
346 ++bs;
347 goto again;
348 default:
349 cfile -> tokbuf [i] = c;
350 bs = 0;
351 break;
353 bs = 0;
354 } else if (bs > 1) {
355 if (hex) {
356 if (c >= '0' && c <= '9') {
357 value = value * 16 + (c - '0');
358 } else if (c >= 'a' && c <= 'f') {
359 value = value * 16 + (c - 'a' + 10);
360 } else if (c >= 'A' && c <= 'F') {
361 value = value * 16 + (c - 'A' + 10);
362 } else {
363 parse_warn (cfile,
364 "invalid hex digit: %x",
366 bs = 0;
367 continue;
369 if (++bs == 4) {
370 cfile -> tokbuf [i] = value;
371 bs = 0;
372 } else
373 goto again;
374 } else {
375 if (c >= '0' && c <= '9') {
376 value = value * 8 + (c - '0');
377 } else {
378 if (value != 0) {
379 parse_warn (cfile,
380 "invalid octal digit %x",
382 continue;
383 } else
384 cfile -> tokbuf [i] = 0;
385 bs = 0;
387 if (++bs == 4) {
388 cfile -> tokbuf [i] = value;
389 bs = 0;
390 } else
391 goto again;
393 } else if (c == '\\') {
394 bs = 1;
395 goto again;
396 } else if (c == '"')
397 break;
398 else
399 cfile -> tokbuf [i] = c;
401 /* Normally, I'd feel guilty about this, but we're talking about
402 strings that'll fit in a DHCP packet here... */
403 if (i == sizeof cfile -> tokbuf) {
404 parse_warn (cfile,
405 "string constant larger than internal buffer");
406 --i;
408 cfile -> tokbuf [i] = 0;
409 cfile -> tlen = i;
410 cfile -> tval = cfile -> tokbuf;
411 return STRING;
414 static enum dhcp_token read_number (c, cfile)
415 int c;
416 struct parse *cfile;
418 #ifdef OLD_LEXER
419 int seenx = 0;
420 #endif
421 int i = 0;
422 int token = NUMBER;
424 cfile -> tokbuf [i++] = c;
425 for (; i < sizeof cfile -> tokbuf; i++) {
426 c = get_char (cfile);
428 #ifndef OLD_LEXER
429 /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
430 * Except in the case of '0x' syntax hex, which gets called
431 * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
432 * verified to be at least 0xf or less.
434 switch(isascii(c) ? token : BREAK) {
435 case NUMBER:
436 if(isdigit(c))
437 break;
438 /* FALLTHROUGH */
439 case NUMBER_OR_NAME:
440 if(isxdigit(c)) {
441 token = NUMBER_OR_NAME;
442 break;
444 /* FALLTHROUGH */
445 case NAME:
446 if((i == 2) && isxdigit(c) &&
447 (cfile->tokbuf[0] == '0') &&
448 ((cfile->tokbuf[1] == 'x') ||
449 (cfile->tokbuf[1] == 'X'))) {
450 token = NUMBER_OR_NAME;
451 break;
452 } else if(((c == '-') || (c == '_') || isalnum(c))) {
453 token = NAME;
454 break;
456 /* FALLTHROUGH */
457 case BREAK:
458 /* At this point c is either EOF or part of the next
459 * token. If not EOF, rewind the file one byte so
460 * the next token is read from there.
462 if(c != EOF) {
463 cfile->bufix--;
464 cfile->ugflag = 1;
466 goto end_read;
468 default:
469 log_fatal("read_number():%s:%d: impossible case", MDL);
471 #else /* OLD_LEXER */
472 if (!seenx && (c == 'x') {
473 seenx = 1;
474 } else if (!isascii (c) || !isxdigit (c)) {
475 if (c != EOF) {
476 cfile -> bufix--;
477 cfile -> ugflag = 1;
479 break;
481 #endif /* OLD_LEXER */
483 cfile -> tokbuf [i] = c;
486 if (i == sizeof cfile -> tokbuf) {
487 parse_warn (cfile,
488 "numeric token larger than internal buffer");
489 --i;
492 end_read:
493 cfile -> tokbuf [i] = 0;
494 cfile -> tlen = i;
495 cfile -> tval = cfile -> tokbuf;
497 return token;
500 static enum dhcp_token read_num_or_name (c, cfile)
501 int c;
502 struct parse *cfile;
504 int i = 0;
505 enum dhcp_token rv = NUMBER_OR_NAME;
506 cfile -> tokbuf [i++] = c;
507 for (; i < sizeof cfile -> tokbuf; i++) {
508 c = get_char (cfile);
509 if (!isascii (c) ||
510 (c != '-' && c != '_' && !isalnum (c))) {
511 if (c != EOF) {
512 cfile -> bufix--;
513 cfile -> ugflag = 1;
515 break;
517 if (!isxdigit (c))
518 rv = NAME;
519 cfile -> tokbuf [i] = c;
521 if (i == sizeof cfile -> tokbuf) {
522 parse_warn (cfile, "token larger than internal buffer");
523 --i;
525 cfile -> tokbuf [i] = 0;
526 cfile -> tlen = i;
527 cfile -> tval = cfile -> tokbuf;
528 return intern (cfile -> tval, rv);
531 static enum dhcp_token intern (atom, dfv)
532 char *atom;
533 enum dhcp_token dfv;
535 if (!isascii (atom [0]))
536 return dfv;
538 switch (tolower (atom [0])) {
539 case '-':
540 if (atom [1] == 0)
541 return MINUS;
542 break;
544 case 'a':
545 if (!strncasecmp (atom + 1, "uth", 3)) {
546 if (!strncasecmp (atom + 3, "uthenticat", 10)) {
547 if (!strcasecmp (atom + 13, "ed"))
548 return AUTHENTICATED;
549 if (!strcasecmp (atom + 13, "ion"))
550 return AUTHENTICATION;
551 break;
553 if (!strcasecmp (atom + 1, "uthoritative"))
554 return AUTHORITATIVE;
555 break;
557 if (!strcasecmp (atom + 1, "nd"))
558 return AND;
559 if (!strcasecmp (atom + 1, "ppend"))
560 return APPEND;
561 if (!strcasecmp (atom + 1, "llow"))
562 return ALLOW;
563 if (!strcasecmp (atom + 1, "lias"))
564 return ALIAS;
565 if (!strcasecmp (atom + 1, "lgorithm"))
566 return ALGORITHM;
567 if (!strcasecmp (atom + 1, "bandoned"))
568 return TOKEN_ABANDONED;
569 if (!strcasecmp (atom + 1, "dd"))
570 return TOKEN_ADD;
571 if (!strcasecmp (atom + 1, "ll"))
572 return ALL;
573 if (!strcasecmp (atom + 1, "t"))
574 return AT;
575 if (!strcasecmp (atom + 1, "rray"))
576 return ARRAY;
577 if (!strcasecmp (atom + 1, "ddress"))
578 return ADDRESS;
579 if (!strcasecmp (atom + 1, "ctive"))
580 return TOKEN_ACTIVE;
581 break;
582 case 'b':
583 if (!strcasecmp (atom + 1, "ackup"))
584 return TOKEN_BACKUP;
585 if (!strcasecmp (atom + 1, "ootp"))
586 return TOKEN_BOOTP;
587 if (!strcasecmp (atom + 1, "inding"))
588 return BINDING;
589 if (!strcasecmp (atom + 1, "inary-to-ascii"))
590 return BINARY_TO_ASCII;
591 if (!strcasecmp (atom + 1, "ackoff-cutoff"))
592 return BACKOFF_CUTOFF;
593 if (!strcasecmp (atom + 1, "ooting"))
594 return BOOTING;
595 if (!strcasecmp (atom + 1, "oot-unknown-clients"))
596 return BOOT_UNKNOWN_CLIENTS;
597 if (!strcasecmp (atom + 1, "reak"))
598 return BREAK;
599 if (!strcasecmp (atom + 1, "illing"))
600 return BILLING;
601 if (!strcasecmp (atom + 1, "oolean"))
602 return BOOLEAN;
603 if (!strcasecmp (atom + 1, "alance"))
604 return BALANCE;
605 if (!strcasecmp (atom + 1, "ound"))
606 return BOUND;
607 break;
608 case 'c':
609 if (!strcasecmp (atom + 1, "ase"))
610 return CASE;
611 if (!strcasecmp (atom + 1, "ommit"))
612 return COMMIT;
613 if (!strcasecmp (atom + 1, "ode"))
614 return CODE;
615 if (!strcasecmp (atom + 1, "onfig-option"))
616 return CONFIG_OPTION;
617 if (!strcasecmp (atom + 1, "heck"))
618 return CHECK;
619 if (!strcasecmp (atom + 1, "lass"))
620 return CLASS;
621 if (!strcasecmp (atom + 1, "lose"))
622 return TOKEN_CLOSE;
623 if (!strcasecmp (atom + 1, "reate"))
624 return TOKEN_CREATE;
625 if (!strcasecmp (atom + 1, "iaddr"))
626 return CIADDR;
627 if (!strncasecmp (atom + 1, "lient", 5)) {
628 if (!strcasecmp (atom + 6, "-identifier"))
629 return CLIENT_IDENTIFIER;
630 if (!strcasecmp (atom + 6, "-hostname"))
631 return CLIENT_HOSTNAME;
632 if (!strcasecmp (atom + 6, "-state"))
633 return CLIENT_STATE;
634 if (!strcasecmp (atom + 6, "-updates"))
635 return CLIENT_UPDATES;
636 if (!strcasecmp (atom + 6, "s"))
637 return CLIENTS;
639 if (!strcasecmp (atom + 1, "oncat"))
640 return CONCAT;
641 if (!strcasecmp (atom + 1, "onnect"))
642 return CONNECT;
643 if (!strcasecmp (atom + 1, "ommunications-interrupted"))
644 return COMMUNICATIONS_INTERRUPTED;
645 if (!strcasecmp (atom + 1, "ltt"))
646 return CLTT;
647 break;
648 case 'd':
649 if (!strcasecmp (atom + 1, "ns-update"))
650 return DNS_UPDATE;
651 if (!strcasecmp (atom + 1, "ns-delete"))
652 return DNS_DELETE;
653 if (!strcasecmp (atom + 1, "omain"))
654 return DOMAIN;
655 if (!strcasecmp (atom + 1, "omain-name"))
656 return DOMAIN_NAME;
657 if (!strcasecmp (atom + 1, "o-forward-update"))
658 return DO_FORWARD_UPDATE;
659 if (!strcasecmp (atom + 1, "ebug"))
660 return TOKEN_DEBUG;
661 if (!strcasecmp (atom + 1, "eny"))
662 return DENY;
663 if (!strcasecmp (atom + 1, "eleted"))
664 return TOKEN_DELETED;
665 if (!strcasecmp (atom + 1, "elete"))
666 return TOKEN_DELETE;
667 if (!strncasecmp (atom + 1, "efault", 6)) {
668 if (!atom [7])
669 return DEFAULT;
670 if (!strcasecmp (atom + 7, "-lease-time"))
671 return DEFAULT_LEASE_TIME;
672 break;
674 if (!strncasecmp (atom + 1, "ynamic", 6)) {
675 if (!atom [7])
676 return DYNAMIC;
677 if (!strncasecmp (atom + 7, "-bootp", 6)) {
678 if (!atom [13])
679 return DYNAMIC_BOOTP;
680 if (!strcasecmp (atom + 13, "-lease-cutoff"))
681 return DYNAMIC_BOOTP_LEASE_CUTOFF;
682 if (!strcasecmp (atom + 13, "-lease-length"))
683 return DYNAMIC_BOOTP_LEASE_LENGTH;
684 break;
687 if (!strcasecmp (atom + 1, "uplicates"))
688 return DUPLICATES;
689 if (!strcasecmp (atom + 1, "eclines"))
690 return DECLINES;
691 if (!strncasecmp (atom + 1, "efine", 5)) {
692 if (!strcasecmp (atom + 6, "d"))
693 return DEFINED;
694 if (!atom [6])
695 return DEFINE;
697 break;
698 case 'e':
699 if (isascii (atom [1]) && tolower (atom [1]) == 'x') {
700 if (!strcasecmp (atom + 2, "tract-int"))
701 return EXTRACT_INT;
702 if (!strcasecmp (atom + 2, "ists"))
703 return EXISTS;
704 if (!strcasecmp (atom + 2, "piry"))
705 return EXPIRY;
706 if (!strcasecmp (atom + 2, "pire"))
707 return EXPIRE;
708 if (!strcasecmp (atom + 2, "pired"))
709 return TOKEN_EXPIRED;
711 if (!strcasecmp (atom + 1, "ncode-int"))
712 return ENCODE_INT;
713 if (!strcasecmp (atom + 1, "thernet"))
714 return ETHERNET;
715 if (!strcasecmp (atom + 1, "nds"))
716 return ENDS;
717 if (!strncasecmp (atom + 1, "ls", 2)) {
718 if (!strcasecmp (atom + 3, "e"))
719 return ELSE;
720 if (!strcasecmp (atom + 3, "if"))
721 return ELSIF;
722 break;
724 if (!strcasecmp (atom + 1, "rror"))
725 return ERROR;
726 if (!strcasecmp (atom + 1, "val"))
727 return EVAL;
728 if (!strcasecmp (atom + 1, "ncapsulate"))
729 return ENCAPSULATE;
730 break;
731 case 'f':
732 if (!strcasecmp (atom + 1, "atal"))
733 return FATAL;
734 if (!strcasecmp (atom + 1, "ilename"))
735 return FILENAME;
736 if (!strcasecmp (atom + 1, "ixed-address"))
737 return FIXED_ADDR;
738 if (!strcasecmp (atom + 1, "ddi"))
739 return FDDI;
740 if (!strcasecmp (atom + 1, "ormerr"))
741 return NS_FORMERR;
742 if (!strcasecmp (atom + 1, "unction"))
743 return FUNCTION;
744 if (!strcasecmp (atom + 1, "ailover"))
745 return FAILOVER;
746 if (!strcasecmp (atom + 1, "ree"))
747 return TOKEN_FREE;
748 break;
749 case 'g':
750 if (!strcasecmp (atom + 1, "iaddr"))
751 return GIADDR;
752 if (!strcasecmp (atom + 1, "roup"))
753 return GROUP;
754 if (!strcasecmp (atom + 1, "et-lease-hostnames"))
755 return GET_LEASE_HOSTNAMES;
756 break;
757 case 'h':
758 if (!strcasecmp (atom + 1, "ba"))
759 return HBA;
760 if (!strcasecmp (atom + 1, "ost"))
761 return HOST;
762 if (!strcasecmp (atom + 1, "ost-decl-name"))
763 return HOST_DECL_NAME;
764 if (!strcasecmp (atom + 1, "ardware"))
765 return HARDWARE;
766 if (!strcasecmp (atom + 1, "ostname"))
767 return HOSTNAME;
768 if (!strcasecmp (atom + 1, "elp"))
769 return TOKEN_HELP;
770 break;
771 case 'i':
772 if (!strcasecmp (atom + 1, "nclude"))
773 return INCLUDE;
774 if (!strcasecmp (atom + 1, "nteger"))
775 return INTEGER;
776 if (!strcasecmp (atom + 1, "nfinite"))
777 return INFINITE;
778 if (!strcasecmp (atom + 1, "nfo"))
779 return INFO;
780 if (!strcasecmp (atom + 1, "p-address"))
781 return IP_ADDRESS;
782 if (!strcasecmp (atom + 1, "nitial-interval"))
783 return INITIAL_INTERVAL;
784 if (!strcasecmp (atom + 1, "nterface"))
785 return INTERFACE;
786 if (!strcasecmp (atom + 1, "dentifier"))
787 return IDENTIFIER;
788 if (!strcasecmp (atom + 1, "f"))
789 return IF;
790 if (!strcasecmp (atom + 1, "s"))
791 return IS;
792 if (!strcasecmp (atom + 1, "gnore"))
793 return IGNORE;
794 break;
795 case 'k':
796 if (!strncasecmp (atom + 1, "nown", 4)) {
797 if (!strcasecmp (atom + 5, "-clients"))
798 return KNOWN_CLIENTS;
799 if (!atom[5])
800 return KNOWN;
801 break;
803 if (!strcasecmp (atom + 1, "ey"))
804 return KEY;
805 break;
806 case 'l':
807 if (!strcasecmp (atom + 1, "ease"))
808 return LEASE;
809 if (!strcasecmp (atom + 1, "eased-address"))
810 return LEASED_ADDRESS;
811 if (!strcasecmp (atom + 1, "ease-time"))
812 return LEASE_TIME;
813 if (!strcasecmp (atom + 1, "imit"))
814 return LIMIT;
815 if (!strcasecmp (atom + 1, "et"))
816 return LET;
817 if (!strcasecmp (atom + 1, "oad"))
818 return LOAD;
819 if (!strcasecmp (atom + 1, "og"))
820 return LOG;
821 break;
822 case 'm':
823 if (!strncasecmp (atom + 1, "ax", 2)) {
824 if (!atom [3])
825 return TOKEN_MAX;
826 if (!strcasecmp (atom + 3, "-lease-time"))
827 return MAX_LEASE_TIME;
828 if (!strcasecmp (atom + 3, "-transmit-idle"))
829 return MAX_TRANSMIT_IDLE;
830 if (!strcasecmp (atom + 3, "-response-delay"))
831 return MAX_RESPONSE_DELAY;
832 if (!strcasecmp (atom + 3, "-unacked-updates"))
833 return MAX_UNACKED_UPDATES;
835 if (!strncasecmp (atom + 1, "in-", 3)) {
836 if (!strcasecmp (atom + 4, "lease-time"))
837 return MIN_LEASE_TIME;
838 if (!strcasecmp (atom + 4, "secs"))
839 return MIN_SECS;
840 break;
842 if (!strncasecmp (atom + 1, "edi", 3)) {
843 if (!strcasecmp (atom + 4, "a"))
844 return MEDIA;
845 if (!strcasecmp (atom + 4, "um"))
846 return MEDIUM;
847 break;
849 if (!strcasecmp (atom + 1, "atch"))
850 return MATCH;
851 if (!strcasecmp (atom + 1, "embers"))
852 return MEMBERS;
853 if (!strcasecmp (atom + 1, "y"))
854 return MY;
855 if (!strcasecmp (atom + 1, "clt"))
856 return MCLT;
857 break;
858 case 'n':
859 if (!strcasecmp (atom + 1, "ormal"))
860 return NORMAL;
861 if (!strcasecmp (atom + 1, "ameserver"))
862 return NAMESERVER;
863 if (!strcasecmp (atom + 1, "etmask"))
864 return NETMASK;
865 if (!strcasecmp (atom + 1, "ever"))
866 return NEVER;
867 if (!strcasecmp (atom + 1, "ext-server"))
868 return NEXT_SERVER;
869 if (!strcasecmp (atom + 1, "ot"))
870 return TOKEN_NOT;
871 if (!strcasecmp (atom + 1, "o"))
872 return NO;
873 if (!strcasecmp (atom + 1, "s-update"))
874 return NS_UPDATE;
875 if (!strcasecmp (atom + 1, "oerror"))
876 return NS_NOERROR;
877 if (!strcasecmp (atom + 1, "otauth"))
878 return NS_NOTAUTH;
879 if (!strcasecmp (atom + 1, "otimp"))
880 return NS_NOTIMP;
881 if (!strcasecmp (atom + 1, "otzone"))
882 return NS_NOTZONE;
883 if (!strcasecmp (atom + 1, "xdomain"))
884 return NS_NXDOMAIN;
885 if (!strcasecmp (atom + 1, "xrrset"))
886 return NS_NXRRSET;
887 if (!strcasecmp (atom + 1, "ull"))
888 return TOKEN_NULL;
889 if (!strcasecmp (atom + 1, "ext"))
890 return TOKEN_NEXT;
891 if (!strcasecmp (atom + 1, "ew"))
892 return TOKEN_NEW;
893 break;
894 case 'o':
895 if (!strcasecmp (atom + 1, "mapi"))
896 return OMAPI;
897 if (!strcasecmp (atom + 1, "r"))
898 return OR;
899 if (!strcasecmp (atom + 1, "n"))
900 return ON;
901 if (!strcasecmp (atom + 1, "pen"))
902 return TOKEN_OPEN;
903 if (!strcasecmp (atom + 1, "ption"))
904 return OPTION;
905 if (!strcasecmp (atom + 1, "ne-lease-per-client"))
906 return ONE_LEASE_PER_CLIENT;
907 if (!strcasecmp (atom + 1, "f"))
908 return OF;
909 if (!strcasecmp (atom + 1, "wner"))
910 return OWNER;
911 break;
912 case 'p':
913 if (!strcasecmp (atom + 1, "repend"))
914 return PREPEND;
915 if (!strcasecmp (atom + 1, "acket"))
916 return PACKET;
917 if (!strcasecmp (atom + 1, "ool"))
918 return POOL;
919 if (!strcasecmp (atom + 1, "seudo"))
920 return PSEUDO;
921 if (!strcasecmp (atom + 1, "eer"))
922 return PEER;
923 if (!strcasecmp (atom + 1, "rimary"))
924 return PRIMARY;
925 if (!strncasecmp (atom + 1, "artner", 6)) {
926 if (!atom [7])
927 return PARTNER;
928 if (!strcasecmp (atom + 7, "-down"))
929 return PARTNER_DOWN;
931 if (!strcasecmp (atom + 1, "ort"))
932 return PORT;
933 if (!strcasecmp (atom + 1, "otential-conflict"))
934 return POTENTIAL_CONFLICT;
935 if (!strcasecmp (atom + 1, "ick-first-value") ||
936 !strcasecmp (atom + 1, "ick"))
937 return PICK;
938 if (!strcasecmp (atom + 1, "aused"))
939 return PAUSED;
940 break;
941 case 'r':
942 if (!strcasecmp (atom + 1, "esolution-interrupted"))
943 return RESOLUTION_INTERRUPTED;
944 if (!strcasecmp (atom + 1, "ange"))
945 return RANGE;
946 if (!strcasecmp (atom + 1, "ecover"))
947 return RECOVER;
948 if (!strcasecmp (atom + 1, "ecover-done"))
949 return RECOVER_DONE;
950 if (!strcasecmp (atom + 1, "ecover-wait"))
951 return RECOVER_WAIT;
952 if (!strcasecmp (atom + 1, "econtact-interval"))
953 return RECONTACT_INTERVAL;
954 if (!strcasecmp (atom + 1, "equest"))
955 return REQUEST;
956 if (!strcasecmp (atom + 1, "equire"))
957 return REQUIRE;
958 if (!strcasecmp (atom + 1, "equire"))
959 return REQUIRE;
960 if (!strcasecmp (atom + 1, "etry"))
961 return RETRY;
962 if (!strcasecmp (atom + 1, "eturn"))
963 return RETURN;
964 if (!strcasecmp (atom + 1, "enew"))
965 return RENEW;
966 if (!strcasecmp (atom + 1, "ebind"))
967 return REBIND;
968 if (!strcasecmp (atom + 1, "eboot"))
969 return REBOOT;
970 if (!strcasecmp (atom + 1, "eject"))
971 return REJECT;
972 if (!strcasecmp (atom + 1, "everse"))
973 return REVERSE;
974 if (!strcasecmp (atom + 1, "elease"))
975 return RELEASE;
976 if (!strcasecmp (atom + 1, "efused"))
977 return NS_REFUSED;
978 if (!strcasecmp (atom + 1, "eleased"))
979 return TOKEN_RELEASED;
980 if (!strcasecmp (atom + 1, "eset"))
981 return TOKEN_RESET;
982 if (!strcasecmp (atom + 1, "eserved"))
983 return TOKEN_RESERVED;
984 if (!strcasecmp (atom + 1, "emove"))
985 return REMOVE;
986 if (!strcasecmp (atom + 1, "efresh"))
987 return REFRESH;
988 break;
989 case 's':
990 if (!strcasecmp (atom + 1, "tate"))
991 return STATE;
992 if (!strcasecmp (atom + 1, "ecret"))
993 return SECRET;
994 if (!strcasecmp (atom + 1, "ervfail"))
995 return NS_SERVFAIL;
996 if (!strcasecmp (atom + 1, "witch"))
997 return SWITCH;
998 if (!strcasecmp (atom + 1, "igned"))
999 return SIGNED;
1000 if (!strcasecmp (atom + 1, "tring"))
1001 return STRING_TOKEN;
1002 if (!strcasecmp (atom + 1, "uffix"))
1003 return SUFFIX;
1004 if (!strcasecmp (atom + 1, "earch"))
1005 return SEARCH;
1006 if (!strcasecmp (atom + 1, "tarts"))
1007 return STARTS;
1008 if (!strcasecmp (atom + 1, "iaddr"))
1009 return SIADDR;
1010 if (!strcasecmp (atom + 1, "hared-network"))
1011 return SHARED_NETWORK;
1012 if (!strcasecmp (atom + 1, "econdary"))
1013 return SECONDARY;
1014 if (!strcasecmp (atom + 1, "erver-name"))
1015 return SERVER_NAME;
1016 if (!strcasecmp (atom + 1, "erver-identifier"))
1017 return SERVER_IDENTIFIER;
1018 if (!strcasecmp (atom + 1, "erver"))
1019 return SERVER;
1020 if (!strcasecmp (atom + 1, "elect-timeout"))
1021 return SELECT_TIMEOUT;
1022 if (!strcasecmp (atom + 1, "elect"))
1023 return SELECT;
1024 if (!strcasecmp (atom + 1, "end"))
1025 return SEND;
1026 if (!strcasecmp (atom + 1, "cript"))
1027 return SCRIPT;
1028 if (!strcasecmp (atom + 1, "upersede"))
1029 return SUPERSEDE;
1030 if (!strncasecmp (atom + 1, "ub", 2)) {
1031 if (!strcasecmp (atom + 3, "string"))
1032 return SUBSTRING;
1033 if (!strcasecmp (atom + 3, "net"))
1034 return SUBNET;
1035 if (!strcasecmp (atom + 3, "class"))
1036 return SUBCLASS;
1037 break;
1039 if (!strcasecmp (atom + 1, "pawn"))
1040 return SPAWN;
1041 if (!strcasecmp (atom + 1, "pace"))
1042 return SPACE;
1043 if (!strcasecmp (atom + 1, "tatic"))
1044 return _STATIC;
1045 if (!strcasecmp (atom + 1, "plit"))
1046 return SPLIT;
1047 if (!strcasecmp (atom + 1, "et"))
1048 return TOKEN_SET;
1049 if (!strcasecmp (atom + 1, "econds"))
1050 return SECONDS;
1051 if (!strcasecmp (atom + 1, "hutdown"))
1052 return SHUTDOWN;
1053 if (!strcasecmp (atom + 1, "tartup"))
1054 return STARTUP;
1055 break;
1056 case 't':
1057 if (!strcasecmp (atom + 1, "imestamp"))
1058 return TIMESTAMP;
1059 if (!strcasecmp (atom + 1, "imeout"))
1060 return TIMEOUT;
1061 if (!strcasecmp (atom + 1, "oken-ring"))
1062 return TOKEN_RING;
1063 if (!strcasecmp (atom + 1, "ext"))
1064 return _TEXT;
1065 if (!strcasecmp (atom + 1, "stp"))
1066 return TSTP;
1067 if (!strcasecmp (atom + 1, "sfp"))
1068 return TSFP;
1069 if (!strcasecmp (atom + 1, "ransmission"))
1070 return TRANSMISSION;
1071 break;
1072 case 'u':
1073 if (!strcasecmp (atom + 1, "nset"))
1074 return UNSET;
1075 if (!strcasecmp (atom + 1, "nsigned"))
1076 return UNSIGNED;
1077 if (!strcasecmp (atom + 1, "id"))
1078 return UID;
1079 if (!strncasecmp (atom + 1, "se", 2)) {
1080 if (!strcasecmp (atom + 3, "r-class"))
1081 return USER_CLASS;
1082 if (!strcasecmp (atom + 3, "-host-decl-names"))
1083 return USE_HOST_DECL_NAMES;
1084 if (!strcasecmp (atom + 3,
1085 "-lease-addr-for-default-route"))
1086 return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1087 break;
1089 if (!strncasecmp (atom + 1, "nknown", 6)) {
1090 if (!strcasecmp (atom + 7, "-clients"))
1091 return UNKNOWN_CLIENTS;
1092 if (!strcasecmp (atom + 7, "-state"))
1093 return UNKNOWN_STATE;
1094 if (!atom [7])
1095 return UNKNOWN;
1096 break;
1098 if (!strcasecmp (atom + 1, "nauthenticated"))
1099 return AUTHENTICATED;
1100 if (!strcasecmp (atom + 1, "pdated-dns-rr"))
1101 return UPDATED_DNS_RR;
1102 if (!strcasecmp (atom + 1, "pdate"))
1103 return UPDATE;
1104 break;
1105 case 'v':
1106 if (!strcasecmp (atom + 1, "endor-class"))
1107 return VENDOR_CLASS;
1108 if (!strcasecmp (atom + 1, "endor"))
1109 return VENDOR;
1110 break;
1111 case 'w':
1112 if (!strcasecmp (atom + 1, "ith"))
1113 return WITH;
1114 break;
1115 case 'y':
1116 if (!strcasecmp (atom + 1, "iaddr"))
1117 return YIADDR;
1118 if (!strcasecmp (atom + 1, "xdomain"))
1119 return NS_YXDOMAIN;
1120 if (!strcasecmp (atom + 1, "xrrset"))
1121 return NS_YXRRSET;
1122 break;
1123 case 'z':
1124 if (!strcasecmp (atom + 1, "one"))
1125 return ZONE;
1126 break;
1128 return dfv;