Remove building with NOCRYPTO option
[minix.git] / external / bsd / dhcp / dist / common / conflex.c
bloba159a6a8f1cbac802e31badc7773163232e7399e
1 /* $NetBSD: conflex.c,v 1.4 2014/07/12 12:09:37 spz Exp $ */
2 /* conflex.c
4 Lexical scanner for dhcpd config file... */
6 /*
7 * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1995-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
26 * https://www.isc.org/
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: conflex.c,v 1.4 2014/07/12 12:09:37 spz Exp $");
33 #include "dhcpd.h"
34 #include <ctype.h>
36 static int get_char (struct parse *);
37 static void unget_char(struct parse *, int);
38 static void skip_to_eol (struct parse *);
39 static enum dhcp_token read_whitespace(int c, struct parse *cfile);
40 static enum dhcp_token read_string (struct parse *);
41 static enum dhcp_token read_number (int, struct parse *);
42 static enum dhcp_token read_num_or_name (int, struct parse *);
43 static enum dhcp_token intern (char *, enum dhcp_token);
45 isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
46 struct parse **cfile;
47 int file;
48 char *inbuf;
49 unsigned buflen;
50 const char *name;
51 int eolp;
53 isc_result_t status = ISC_R_SUCCESS;
54 struct parse *tmp;
56 tmp = dmalloc(sizeof(struct parse), MDL);
57 if (tmp == NULL) {
58 return (ISC_R_NOMEMORY);
62 * We don't need to initialize things to zero here, since
63 * dmalloc() returns memory that is set to zero.
65 tmp->tlname = name;
66 tmp->lpos = tmp -> line = 1;
67 tmp->cur_line = tmp->line1;
68 tmp->prev_line = tmp->line2;
69 tmp->token_line = tmp->cur_line;
70 tmp->cur_line[0] = tmp->prev_line[0] = 0;
71 tmp->file = file;
72 tmp->eol_token = eolp;
74 if (inbuf != NULL) {
75 tmp->inbuf = inbuf;
76 tmp->buflen = buflen;
77 tmp->bufsiz = 0;
78 } else {
79 struct stat sb;
81 if (fstat(file, &sb) < 0) {
82 status = ISC_R_IOERROR;
83 goto cleanup;
86 if (sb.st_size == 0)
87 goto cleanup;
89 tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
90 tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
91 file, 0);
93 if (tmp->inbuf == MAP_FAILED) {
94 status = ISC_R_IOERROR;
95 goto cleanup;
99 *cfile = tmp;
100 return (ISC_R_SUCCESS);
102 cleanup:
103 dfree(tmp, MDL);
104 return (status);
107 isc_result_t end_parse (cfile)
108 struct parse **cfile;
110 /* "Memory" config files have no file. */
111 if ((*cfile)->file != -1) {
112 munmap((*cfile)->inbuf, (*cfile)->bufsiz);
113 close((*cfile)->file);
116 if ((*cfile)->saved_state != NULL) {
117 dfree((*cfile)->saved_state, MDL);
120 dfree(*cfile, MDL);
121 *cfile = NULL;
122 return ISC_R_SUCCESS;
126 * Save the current state of the parser.
128 * Only one state may be saved. Any previous saved state is
129 * lost.
131 isc_result_t
132 save_parse_state(struct parse *cfile) {
134 * Free any previous saved state.
136 if (cfile->saved_state != NULL) {
137 dfree(cfile->saved_state, MDL);
141 * Save our current state.
143 cfile->saved_state = dmalloc(sizeof(struct parse), MDL);
144 if (cfile->saved_state == NULL) {
145 return ISC_R_NOMEMORY;
147 memcpy(cfile->saved_state, cfile, sizeof(*cfile));
148 return ISC_R_SUCCESS;
152 * Return the parser to the previous saved state.
154 * You must call save_parse_state() before calling
155 * restore_parse_state(), but you can call restore_parse_state() any
156 * number of times after that.
158 isc_result_t
159 restore_parse_state(struct parse *cfile) {
160 struct parse *saved_state;
162 if (cfile->saved_state == NULL) {
163 return DHCP_R_NOTYET;
166 saved_state = cfile->saved_state;
167 memcpy(cfile, saved_state, sizeof(*cfile));
168 cfile->saved_state = saved_state;
169 return ISC_R_SUCCESS;
172 static int get_char (cfile)
173 struct parse *cfile;
175 /* My kingdom for WITH... */
176 int c;
178 if (cfile->bufix == cfile->buflen) {
179 #if !defined(LDAP_CONFIGURATION)
180 c = EOF;
181 #else /* defined(LDAP_CONFIGURATION) */
182 if (cfile->read_function != NULL)
183 c = cfile->read_function(cfile);
184 else
185 c = EOF;
186 #endif
187 } else {
188 c = cfile->inbuf [cfile->bufix];
189 cfile->bufix++;
192 if (!cfile->ugflag) {
193 if (c == EOL) {
194 if (cfile->cur_line == cfile->line1) {
195 cfile->cur_line = cfile->line2;
196 cfile->prev_line = cfile->line1;
197 } else {
198 cfile->cur_line = cfile->line1;
199 cfile->prev_line = cfile->line2;
201 cfile->line++;
202 cfile->lpos = 1;
203 cfile->cur_line [0] = 0;
204 } else if (c != EOF) {
205 if (cfile->lpos <= 80) {
206 cfile->cur_line [cfile->lpos - 1] = c;
207 cfile->cur_line [cfile->lpos] = 0;
209 cfile->lpos++;
211 } else
212 cfile->ugflag = 0;
213 return c;
217 * Return a character to our input buffer.
219 static void
220 unget_char(struct parse *cfile, int c) {
221 if (c != EOF) {
222 cfile->bufix--;
223 cfile->ugflag = 1; /* do not put characters into
224 our error buffer on the next
225 call to get_char() */
230 * GENERAL NOTE ABOUT TOKENS
232 * We normally only want non-whitespace tokens. There are some
233 * circumstances where we *do* want to see whitespace (for example
234 * when parsing IPv6 addresses).
236 * Generally we use the next_token() function to read tokens. This
237 * in turn calls get_next_token, which does *not* return tokens for
238 * whitespace. Rather, it skips these.
240 * When we need to see whitespace, we us next_raw_token(), which also
241 * returns the WHITESPACE token.
243 * The peek_token() and peek_raw_token() functions work as expected.
245 * Warning: if you invoke peek_token(), then if there is a whitespace
246 * token, it will be lost, and subsequent use of next_raw_token() or
247 * peek_raw_token() will NOT see it.
250 static enum dhcp_token
251 get_raw_token(struct parse *cfile) {
252 int c;
253 enum dhcp_token ttok;
254 static char tb [2];
255 int l, p;
257 do {
258 l = cfile -> line;
259 p = cfile -> lpos;
261 c = get_char (cfile);
262 if (!((c == '\n') && cfile->eol_token) &&
263 isascii(c) && isspace(c)) {
264 ttok = read_whitespace(c, cfile);
265 break;
267 if (c == '#') {
268 skip_to_eol (cfile);
269 continue;
271 if (c == '"') {
272 cfile -> lexline = l;
273 cfile -> lexchar = p;
274 ttok = read_string (cfile);
275 break;
277 if ((isascii (c) && isdigit (c)) || c == '-') {
278 cfile -> lexline = l;
279 cfile -> lexchar = p;
280 ttok = read_number (c, cfile);
281 break;
282 } else if (isascii (c) && isalpha (c)) {
283 cfile -> lexline = l;
284 cfile -> lexchar = p;
285 ttok = read_num_or_name (c, cfile);
286 break;
287 } else if (c == EOF) {
288 ttok = END_OF_FILE;
289 cfile -> tlen = 0;
290 break;
291 } else {
292 cfile -> lexline = l;
293 cfile -> lexchar = p;
294 tb [0] = c;
295 tb [1] = 0;
296 cfile -> tval = tb;
297 cfile -> tlen = 1;
298 ttok = c;
299 break;
301 } while (1);
302 return ttok;
306 * The get_next_token() function consumes the next token and
307 * returns it to the caller.
309 * Since the code is almost the same for "normal" and "raw"
310 * input, we pass a flag to alter the way it works.
313 static enum dhcp_token
314 get_next_token(const char **rval, unsigned *rlen,
315 struct parse *cfile, isc_boolean_t raw) {
316 int rv;
318 if (cfile -> token) {
319 if (cfile -> lexline != cfile -> tline)
320 cfile -> token_line = cfile -> cur_line;
321 cfile -> lexchar = cfile -> tlpos;
322 cfile -> lexline = cfile -> tline;
323 rv = cfile -> token;
324 cfile -> token = 0;
325 } else {
326 rv = get_raw_token(cfile);
327 cfile -> token_line = cfile -> cur_line;
330 if (!raw) {
331 while (rv == WHITESPACE) {
332 rv = get_raw_token(cfile);
333 cfile->token_line = cfile->cur_line;
337 if (rval)
338 *rval = cfile -> tval;
339 if (rlen)
340 *rlen = cfile -> tlen;
341 #ifdef DEBUG_TOKENS
342 fprintf (stderr, "%s:%d ", cfile -> tval, rv);
343 #endif
344 return rv;
349 * Get the next token from cfile and return it.
351 * If rval is non-NULL, set the pointer it contains to
352 * the contents of the token.
354 * If rlen is non-NULL, set the integer it contains to
355 * the length of the token.
358 enum dhcp_token
359 next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
360 return get_next_token(rval, rlen, cfile, ISC_FALSE);
365 * The same as the next_token() function above, but will return space
366 * as the WHITESPACE token.
369 enum dhcp_token
370 next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
371 return get_next_token(rval, rlen, cfile, ISC_TRUE);
376 * The do_peek_token() function checks the next token without
377 * consuming it, and returns it to the caller.
379 * Since the code is almost the same for "normal" and "raw"
380 * input, we pass a flag to alter the way it works. (See the
381 * warning in the GENERAL NOTES ABOUT TOKENS above though.)
384 static enum dhcp_token
385 do_peek_token(const char **rval, unsigned int *rlen,
386 struct parse *cfile, isc_boolean_t raw) {
387 int x;
389 if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
390 cfile -> tlpos = cfile -> lexchar;
391 cfile -> tline = cfile -> lexline;
393 do {
394 cfile->token = get_raw_token(cfile);
395 } while (!raw && (cfile->token == WHITESPACE));
397 if (cfile -> lexline != cfile -> tline)
398 cfile -> token_line = cfile -> prev_line;
400 x = cfile -> lexchar;
401 cfile -> lexchar = cfile -> tlpos;
402 cfile -> tlpos = x;
404 x = cfile -> lexline;
405 cfile -> lexline = cfile -> tline;
406 cfile -> tline = x;
408 if (rval)
409 *rval = cfile -> tval;
410 if (rlen)
411 *rlen = cfile -> tlen;
412 #ifdef DEBUG_TOKENS
413 fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
414 #endif
415 return cfile -> token;
420 * Get the next token from cfile and return it, leaving it for a
421 * subsequent call to next_token().
423 * Note that it WILL consume whitespace tokens.
425 * If rval is non-NULL, set the pointer it contains to
426 * the contents of the token.
428 * If rlen is non-NULL, set the integer it contains to
429 * the length of the token.
432 enum dhcp_token
433 peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
434 return do_peek_token(rval, rlen, cfile, ISC_FALSE);
439 * The same as the peek_token() function above, but will return space
440 * as the WHITESPACE token.
443 enum dhcp_token
444 peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
445 return do_peek_token(rval, rlen, cfile, ISC_TRUE);
448 static void skip_to_eol (cfile)
449 struct parse *cfile;
451 int c;
452 do {
453 c = get_char (cfile);
454 if (c == EOF)
455 return;
456 if (c == EOL) {
457 return;
459 } while (1);
462 static enum dhcp_token
463 read_whitespace(int c, struct parse *cfile) {
464 int ofs;
467 * Read as much whitespace as we have available.
469 ofs = 0;
470 do {
471 if (ofs >= sizeof(cfile->tokbuf)) {
473 * As the file includes a huge amount of whitespace,
474 * it's probably broken.
475 * Print out a warning and bail out.
477 parse_warn(cfile,
478 "whitespace too long, buffer overflow.");
479 log_fatal("Exiting");
481 cfile->tokbuf[ofs++] = c;
482 c = get_char(cfile);
483 } while (!((c == '\n') && cfile->eol_token) &&
484 isascii(c) && isspace(c));
487 * Put the last (non-whitespace) character back.
489 unget_char(cfile, c);
492 * Return our token.
494 cfile->tokbuf[ofs] = '\0';
495 cfile->tlen = ofs;
496 cfile->tval = cfile->tokbuf;
497 return WHITESPACE;
500 static enum dhcp_token read_string (cfile)
501 struct parse *cfile;
503 int i;
504 int bs = 0;
505 int c;
506 int value = 0;
507 int hex = 0;
509 for (i = 0; i < sizeof cfile -> tokbuf; i++) {
510 again:
511 c = get_char (cfile);
512 if (c == EOF) {
513 parse_warn (cfile, "eof in string constant");
514 break;
516 if (bs == 1) {
517 switch (c) {
518 case 't':
519 cfile -> tokbuf [i] = '\t';
520 break;
521 case 'r':
522 cfile -> tokbuf [i] = '\r';
523 break;
524 case 'n':
525 cfile -> tokbuf [i] = '\n';
526 break;
527 case 'b':
528 cfile -> tokbuf [i] = '\b';
529 break;
530 case '0':
531 case '1':
532 case '2':
533 case '3':
534 hex = 0;
535 value = c - '0';
536 ++bs;
537 goto again;
538 case 'x':
539 hex = 1;
540 value = 0;
541 ++bs;
542 goto again;
543 default:
544 cfile -> tokbuf [i] = c;
545 break;
547 bs = 0;
548 } else if (bs > 1) {
549 if (hex) {
550 if (c >= '0' && c <= '9') {
551 value = value * 16 + (c - '0');
552 } else if (c >= 'a' && c <= 'f') {
553 value = value * 16 + (c - 'a' + 10);
554 } else if (c >= 'A' && c <= 'F') {
555 value = value * 16 + (c - 'A' + 10);
556 } else {
557 parse_warn (cfile,
558 "invalid hex digit: %x",
560 bs = 0;
561 continue;
563 if (++bs == 4) {
564 cfile -> tokbuf [i] = value;
565 bs = 0;
566 } else
567 goto again;
568 } else {
569 if (c >= '0' && c <= '7') {
570 value = value * 8 + (c - '0');
571 } else {
572 if (value != 0) {
573 parse_warn (cfile,
574 "invalid octal digit %x",
576 continue;
577 } else
578 cfile -> tokbuf [i] = 0;
579 bs = 0;
581 if (++bs == 4) {
582 cfile -> tokbuf [i] = value;
583 bs = 0;
584 } else
585 goto again;
587 } else if (c == '\\') {
588 bs = 1;
589 goto again;
590 } else if (c == '"')
591 break;
592 else
593 cfile -> tokbuf [i] = c;
595 /* Normally, I'd feel guilty about this, but we're talking about
596 strings that'll fit in a DHCP packet here... */
597 if (i == sizeof cfile -> tokbuf) {
598 parse_warn (cfile,
599 "string constant larger than internal buffer");
600 --i;
602 cfile -> tokbuf [i] = 0;
603 cfile -> tlen = i;
604 cfile -> tval = cfile -> tokbuf;
605 return STRING;
608 static enum dhcp_token read_number (c, cfile)
609 int c;
610 struct parse *cfile;
612 int i = 0;
613 int token = NUMBER;
615 cfile -> tokbuf [i++] = c;
616 for (; i < sizeof cfile -> tokbuf; i++) {
617 c = get_char (cfile);
619 /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
620 * Except in the case of '0x' syntax hex, which gets called
621 * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
622 * verified to be at least 0xf or less.
624 switch(isascii(c) ? token : BREAK) {
625 case NUMBER:
626 if(isdigit(c))
627 break;
628 /* FALLTHROUGH */
629 case NUMBER_OR_NAME:
630 if(isxdigit(c)) {
631 token = NUMBER_OR_NAME;
632 break;
634 /* FALLTHROUGH */
635 case NAME:
636 if((i == 2) && isxdigit(c) &&
637 (cfile->tokbuf[0] == '0') &&
638 ((cfile->tokbuf[1] == 'x') ||
639 (cfile->tokbuf[1] == 'X'))) {
640 token = NUMBER_OR_NAME;
641 break;
642 } else if(((c == '-') || (c == '_') || isalnum(c))) {
643 token = NAME;
644 break;
646 /* FALLTHROUGH */
647 case BREAK:
648 /* At this point c is either EOF or part of the next
649 * token. If not EOF, rewind the file one byte so
650 * the next token is read from there.
652 unget_char(cfile, c);
653 goto end_read;
655 default:
656 log_fatal("read_number():%s:%d: impossible case", MDL);
659 cfile -> tokbuf [i] = c;
662 if (i == sizeof cfile -> tokbuf) {
663 parse_warn (cfile,
664 "numeric token larger than internal buffer");
665 --i;
668 end_read:
669 cfile -> tokbuf [i] = 0;
670 cfile -> tlen = i;
671 cfile -> tval = cfile -> tokbuf;
674 * If this entire token from start to finish was "-", such as
675 * the middle parameter in "42 - 7", return just the MINUS token.
677 if ((i == 1) && (cfile->tokbuf[i] == '-'))
678 return MINUS;
679 else
680 return token;
683 static enum dhcp_token read_num_or_name (c, cfile)
684 int c;
685 struct parse *cfile;
687 int i = 0;
688 enum dhcp_token rv = NUMBER_OR_NAME;
689 cfile -> tokbuf [i++] = c;
690 for (; i < sizeof cfile -> tokbuf; i++) {
691 c = get_char (cfile);
692 if (!isascii (c) ||
693 (c != '-' && c != '_' && !isalnum (c))) {
694 unget_char(cfile, c);
695 break;
697 if (!isxdigit (c))
698 rv = NAME;
699 cfile -> tokbuf [i] = c;
701 if (i == sizeof cfile -> tokbuf) {
702 parse_warn (cfile, "token larger than internal buffer");
703 --i;
705 cfile -> tokbuf [i] = 0;
706 cfile -> tlen = i;
707 cfile -> tval = cfile -> tokbuf;
708 return intern(cfile->tval, rv);
711 static enum dhcp_token
712 intern(char *atom, enum dhcp_token dfv) {
713 if (!isascii(atom[0]))
714 return dfv;
716 switch (tolower((unsigned char)atom[0])) {
717 case '-':
718 if (atom [1] == 0)
719 return MINUS;
720 break;
722 case 'a':
723 if (!strcasecmp(atom + 1, "bandoned"))
724 return TOKEN_ABANDONED;
725 if (!strcasecmp(atom + 1, "ctive"))
726 return TOKEN_ACTIVE;
727 if (!strncasecmp(atom + 1, "dd", 2)) {
728 if (atom[3] == '\0')
729 return TOKEN_ADD;
730 else if (!strcasecmp(atom + 3, "ress"))
731 return ADDRESS;
732 break;
734 if (!strcasecmp(atom + 1, "fter"))
735 return AFTER;
736 if (isascii(atom[1]) &&
737 (tolower((unsigned char)atom[1]) == 'l')) {
738 if (!strcasecmp(atom + 2, "gorithm"))
739 return ALGORITHM;
740 if (!strcasecmp(atom + 2, "ias"))
741 return ALIAS;
742 if (isascii(atom[2]) &&
743 (tolower((unsigned char)atom[2]) == 'l')) {
744 if (atom[3] == '\0')
745 return ALL;
746 else if (!strcasecmp(atom + 3, "ow"))
747 return ALLOW;
748 break;
750 if (!strcasecmp(atom + 2, "so"))
751 return TOKEN_ALSO;
752 break;
754 if (isascii(atom[1]) &&
755 (tolower((unsigned char)atom[1]) == 'n')) {
756 if (!strcasecmp(atom + 2, "d"))
757 return AND;
758 if (!strcasecmp(atom + 2, "ycast-mac"))
759 return ANYCAST_MAC;
760 break;
762 if (!strcasecmp(atom + 1, "ppend"))
763 return APPEND;
764 if (!strcasecmp(atom + 1, "rray"))
765 return ARRAY;
766 if (isascii(atom[1]) &&
767 (tolower((unsigned char)atom[1]) == 't')) {
768 if (atom[2] == '\0')
769 return AT;
770 if (!strcasecmp(atom + 2, "sfp"))
771 return ATSFP;
772 break;
774 if (!strncasecmp(atom + 1, "ut", 2)) {
775 if (isascii(atom[3]) &&
776 (tolower((unsigned char)atom[3]) == 'h')) {
777 if (!strncasecmp(atom + 4, "enticat", 7)) {
778 if (!strcasecmp(atom + 11, "ed"))
779 return AUTHENTICATED;
780 if (!strcasecmp(atom + 11, "ion"))
781 return AUTHENTICATION;
782 break;
784 if (!strcasecmp(atom + 4, "oritative"))
785 return AUTHORITATIVE;
786 break;
788 if (!strcasecmp(atom + 3, "o-partner-down"))
789 return AUTO_PARTNER_DOWN;
790 break;
792 break;
793 case 'b':
794 if (!strcasecmp (atom + 1, "ackup"))
795 return TOKEN_BACKUP;
796 if (!strcasecmp (atom + 1, "ootp"))
797 return TOKEN_BOOTP;
798 if (!strcasecmp (atom + 1, "inding"))
799 return BINDING;
800 if (!strcasecmp (atom + 1, "inary-to-ascii"))
801 return BINARY_TO_ASCII;
802 if (!strcasecmp (atom + 1, "ackoff-cutoff"))
803 return BACKOFF_CUTOFF;
804 if (!strcasecmp (atom + 1, "ooting"))
805 return BOOTING;
806 if (!strcasecmp (atom + 1, "oot-unknown-clients"))
807 return BOOT_UNKNOWN_CLIENTS;
808 if (!strcasecmp (atom + 1, "reak"))
809 return BREAK;
810 if (!strcasecmp (atom + 1, "illing"))
811 return BILLING;
812 if (!strcasecmp (atom + 1, "oolean"))
813 return BOOLEAN;
814 if (!strcasecmp (atom + 1, "alance"))
815 return BALANCE;
816 if (!strcasecmp (atom + 1, "ound"))
817 return BOUND;
818 break;
819 case 'c':
820 if (!strcasecmp(atom + 1, "ase"))
821 return CASE;
822 if (!strcasecmp(atom + 1, "heck"))
823 return CHECK;
824 if (!strcasecmp(atom + 1, "iaddr"))
825 return CIADDR;
826 if (isascii(atom[1]) &&
827 tolower((unsigned char)atom[1]) == 'l') {
828 if (!strcasecmp(atom + 2, "ass"))
829 return CLASS;
830 if (!strncasecmp(atom + 2, "ient", 4)) {
831 if (!strcasecmp(atom + 6, "s"))
832 return CLIENTS;
833 if (atom[6] == '-') {
834 if (!strcasecmp(atom + 7, "hostname"))
835 return CLIENT_HOSTNAME;
836 if (!strcasecmp(atom + 7, "identifier"))
837 return CLIENT_IDENTIFIER;
838 if (!strcasecmp(atom + 7, "state"))
839 return CLIENT_STATE;
840 if (!strcasecmp(atom + 7, "updates"))
841 return CLIENT_UPDATES;
842 break;
844 break;
846 if (!strcasecmp(atom + 2, "ose"))
847 return TOKEN_CLOSE;
848 if (!strcasecmp(atom + 2, "tt"))
849 return CLTT;
850 break;
852 if (isascii(atom[1]) &&
853 tolower((unsigned char)atom[1]) == 'o') {
854 if (!strcasecmp(atom + 2, "de"))
855 return CODE;
856 if (isascii(atom[2]) &&
857 tolower((unsigned char)atom[2]) == 'm') {
858 if (!strcasecmp(atom + 3, "mit"))
859 return COMMIT;
860 if (!strcasecmp(atom + 3,
861 "munications-interrupted"))
862 return COMMUNICATIONS_INTERRUPTED;
863 if (!strcasecmp(atom + 3, "pressed"))
864 return COMPRESSED;
865 break;
867 if (isascii(atom[2]) &&
868 tolower((unsigned char)atom[2]) == 'n') {
869 if (!strcasecmp(atom + 3, "cat"))
870 return CONCAT;
871 if (!strcasecmp(atom + 3, "fig-option"))
872 return CONFIG_OPTION;
873 if (!strcasecmp(atom + 3, "flict-done"))
874 return CONFLICT_DONE;
875 if (!strcasecmp(atom + 3, "nect"))
876 return CONNECT;
877 break;
879 break;
881 if (!strcasecmp(atom + 1, "reate"))
882 return TOKEN_CREATE;
883 break;
884 case 'd':
885 if (!strcasecmp(atom + 1, "b-time-format"))
886 return DB_TIME_FORMAT;
887 if (!strcasecmp (atom + 1, "omain"))
888 return DOMAIN;
889 if (!strncasecmp (atom + 1, "omain-", 6)) {
890 if (!strcasecmp(atom + 7, "name"))
891 return DOMAIN_NAME;
892 if (!strcasecmp(atom + 7, "list"))
893 return DOMAIN_LIST;
895 if (!strcasecmp (atom + 1, "o-forward-update"))
896 return DO_FORWARD_UPDATE;
897 if (!strcasecmp (atom + 1, "ebug"))
898 return TOKEN_DEBUG;
899 if (!strcasecmp (atom + 1, "eny"))
900 return DENY;
901 if (!strcasecmp (atom + 1, "eleted"))
902 return TOKEN_DELETED;
903 if (!strcasecmp (atom + 1, "elete"))
904 return TOKEN_DELETE;
905 if (!strncasecmp (atom + 1, "efault", 6)) {
906 if (!atom [7])
907 return DEFAULT;
908 if (!strcasecmp(atom + 7, "-duid"))
909 return DEFAULT_DUID;
910 if (!strcasecmp (atom + 7, "-lease-time"))
911 return DEFAULT_LEASE_TIME;
912 break;
914 if (!strncasecmp (atom + 1, "ynamic", 6)) {
915 if (!atom [7])
916 return DYNAMIC;
917 if (!strncasecmp (atom + 7, "-bootp", 6)) {
918 if (!atom [13])
919 return DYNAMIC_BOOTP;
920 if (!strcasecmp (atom + 13, "-lease-cutoff"))
921 return DYNAMIC_BOOTP_LEASE_CUTOFF;
922 if (!strcasecmp (atom + 13, "-lease-length"))
923 return DYNAMIC_BOOTP_LEASE_LENGTH;
924 break;
927 if (!strcasecmp (atom + 1, "uplicates"))
928 return DUPLICATES;
929 if (!strcasecmp (atom + 1, "eclines"))
930 return DECLINES;
931 if (!strncasecmp (atom + 1, "efine", 5)) {
932 if (!strcasecmp (atom + 6, "d"))
933 return DEFINED;
934 if (!atom [6])
935 return DEFINE;
937 break;
938 case 'e':
939 if (isascii (atom [1]) &&
940 tolower((unsigned char)atom[1]) == 'x') {
941 if (!strcasecmp (atom + 2, "tract-int"))
942 return EXTRACT_INT;
943 if (!strcasecmp (atom + 2, "ists"))
944 return EXISTS;
945 if (!strcasecmp (atom + 2, "piry"))
946 return EXPIRY;
947 if (!strcasecmp (atom + 2, "pire"))
948 return EXPIRE;
949 if (!strcasecmp (atom + 2, "pired"))
950 return TOKEN_EXPIRED;
952 if (!strcasecmp (atom + 1, "ncode-int"))
953 return ENCODE_INT;
954 if (!strcasecmp(atom + 1, "poch"))
955 return EPOCH;
956 if (!strcasecmp (atom + 1, "thernet"))
957 return ETHERNET;
958 if (!strcasecmp (atom + 1, "nds"))
959 return ENDS;
960 if (!strncasecmp (atom + 1, "ls", 2)) {
961 if (!strcasecmp (atom + 3, "e"))
962 return ELSE;
963 if (!strcasecmp (atom + 3, "if"))
964 return ELSIF;
965 break;
967 if (!strcasecmp (atom + 1, "rror"))
968 return ERROR;
969 if (!strcasecmp (atom + 1, "val"))
970 return EVAL;
971 if (!strcasecmp (atom + 1, "ncapsulate"))
972 return ENCAPSULATE;
973 if (!strcasecmp(atom + 1, "xecute"))
974 return EXECUTE;
975 if (!strcasecmp(atom+1, "n")) {
976 return EN;
978 break;
979 case 'f':
980 if (!strcasecmp (atom + 1, "atal"))
981 return FATAL;
982 if (!strcasecmp (atom + 1, "ilename"))
983 return FILENAME;
984 if (!strcasecmp (atom + 1, "ixed-address"))
985 return FIXED_ADDR;
986 if (!strcasecmp (atom + 1, "ixed-address6"))
987 return FIXED_ADDR6;
988 if (!strcasecmp (atom + 1, "ixed-prefix6"))
989 return FIXED_PREFIX6;
990 if (!strcasecmp (atom + 1, "ddi"))
991 return TOKEN_FDDI;
992 if (!strcasecmp (atom + 1, "ormerr"))
993 return NS_FORMERR;
994 if (!strcasecmp (atom + 1, "unction"))
995 return FUNCTION;
996 if (!strcasecmp (atom + 1, "ailover"))
997 return FAILOVER;
998 if (!strcasecmp (atom + 1, "ree"))
999 return TOKEN_FREE;
1000 break;
1001 case 'g':
1002 if (!strncasecmp(atom + 1, "et", 2)) {
1003 if (!strcasecmp(atom + 3, "-lease-hostnames"))
1004 return GET_LEASE_HOSTNAMES;
1005 if (!strcasecmp(atom + 3, "hostbyname"))
1006 return GETHOSTBYNAME;
1007 if (!strcasecmp(atom + 3, "hostname"))
1008 return GETHOSTNAME;
1009 break;
1011 if (!strcasecmp (atom + 1, "iaddr"))
1012 return GIADDR;
1013 if (!strcasecmp (atom + 1, "roup"))
1014 return GROUP;
1015 break;
1016 case 'h':
1017 if (!strcasecmp(atom + 1, "ash"))
1018 return HASH;
1019 if (!strcasecmp (atom + 1, "ba"))
1020 return HBA;
1021 if (!strcasecmp (atom + 1, "ost"))
1022 return HOST;
1023 if (!strcasecmp (atom + 1, "ost-decl-name"))
1024 return HOST_DECL_NAME;
1025 if (!strcasecmp(atom + 1, "ost-identifier"))
1026 return HOST_IDENTIFIER;
1027 if (!strcasecmp (atom + 1, "ardware"))
1028 return HARDWARE;
1029 if (!strcasecmp (atom + 1, "ostname"))
1030 return HOSTNAME;
1031 if (!strcasecmp (atom + 1, "elp"))
1032 return TOKEN_HELP;
1033 break;
1034 case 'i':
1035 if (!strcasecmp(atom+1, "a-na"))
1036 return IA_NA;
1037 if (!strcasecmp(atom+1, "a-ta"))
1038 return IA_TA;
1039 if (!strcasecmp(atom+1, "a-pd"))
1040 return IA_PD;
1041 if (!strcasecmp(atom+1, "aaddr"))
1042 return IAADDR;
1043 if (!strcasecmp(atom+1, "aprefix"))
1044 return IAPREFIX;
1045 if (!strcasecmp (atom + 1, "nclude"))
1046 return INCLUDE;
1047 if (!strcasecmp (atom + 1, "nteger"))
1048 return INTEGER;
1049 if (!strcasecmp (atom + 1, "nfiniband"))
1050 return TOKEN_INFINIBAND;
1051 if (!strcasecmp (atom + 1, "nfinite"))
1052 return INFINITE;
1053 if (!strcasecmp (atom + 1, "nfo"))
1054 return INFO;
1055 if (!strcasecmp (atom + 1, "p-address"))
1056 return IP_ADDRESS;
1057 if (!strcasecmp (atom + 1, "p6-address"))
1058 return IP6_ADDRESS;
1059 if (!strcasecmp (atom + 1, "nitial-interval"))
1060 return INITIAL_INTERVAL;
1061 if (!strcasecmp (atom + 1, "nitial-delay"))
1062 return INITIAL_DELAY;
1063 if (!strcasecmp (atom + 1, "nterface"))
1064 return INTERFACE;
1065 if (!strcasecmp (atom + 1, "dentifier"))
1066 return IDENTIFIER;
1067 if (!strcasecmp (atom + 1, "f"))
1068 return IF;
1069 if (!strcasecmp (atom + 1, "s"))
1070 return IS;
1071 if (!strcasecmp (atom + 1, "gnore"))
1072 return IGNORE;
1073 break;
1074 case 'k':
1075 if (!strncasecmp (atom + 1, "nown", 4)) {
1076 if (!strcasecmp (atom + 5, "-clients"))
1077 return KNOWN_CLIENTS;
1078 if (!atom[5])
1079 return KNOWN;
1080 break;
1082 if (!strcasecmp (atom + 1, "ey"))
1083 return KEY;
1084 break;
1085 case 'l':
1086 if (!strcasecmp (atom + 1, "case"))
1087 return LCASE;
1088 if (!strcasecmp (atom + 1, "ease"))
1089 return LEASE;
1090 if (!strcasecmp(atom + 1, "ease6"))
1091 return LEASE6;
1092 if (!strcasecmp (atom + 1, "eased-address"))
1093 return LEASED_ADDRESS;
1094 if (!strcasecmp (atom + 1, "ease-time"))
1095 return LEASE_TIME;
1096 if (!strcasecmp(atom + 1, "easequery"))
1097 return LEASEQUERY;
1098 if (!strcasecmp(atom + 1, "ength"))
1099 return LENGTH;
1100 if (!strcasecmp (atom + 1, "imit"))
1101 return LIMIT;
1102 if (!strcasecmp (atom + 1, "et"))
1103 return LET;
1104 if (!strcasecmp (atom + 1, "oad"))
1105 return LOAD;
1106 if (!strcasecmp(atom + 1, "ocal"))
1107 return LOCAL;
1108 if (!strcasecmp (atom + 1, "og"))
1109 return LOG;
1110 if (!strcasecmp(atom+1, "lt")) {
1111 return LLT;
1113 if (!strcasecmp(atom+1, "l")) {
1114 return LL;
1116 break;
1117 case 'm':
1118 if (!strncasecmp (atom + 1, "ax", 2)) {
1119 if (!atom [3])
1120 return TOKEN_MAX;
1121 if (!strcasecmp (atom + 3, "-balance"))
1122 return MAX_BALANCE;
1123 if (!strncasecmp (atom + 3, "-lease-", 7)) {
1124 if (!strcasecmp(atom + 10, "misbalance"))
1125 return MAX_LEASE_MISBALANCE;
1126 if (!strcasecmp(atom + 10, "ownership"))
1127 return MAX_LEASE_OWNERSHIP;
1128 if (!strcasecmp(atom + 10, "time"))
1129 return MAX_LEASE_TIME;
1131 if (!strcasecmp(atom + 3, "-life"))
1132 return MAX_LIFE;
1133 if (!strcasecmp (atom + 3, "-transmit-idle"))
1134 return MAX_TRANSMIT_IDLE;
1135 if (!strcasecmp (atom + 3, "-response-delay"))
1136 return MAX_RESPONSE_DELAY;
1137 if (!strcasecmp (atom + 3, "-unacked-updates"))
1138 return MAX_UNACKED_UPDATES;
1140 if (!strncasecmp (atom + 1, "in-", 3)) {
1141 if (!strcasecmp (atom + 4, "balance"))
1142 return MIN_BALANCE;
1143 if (!strcasecmp (atom + 4, "lease-time"))
1144 return MIN_LEASE_TIME;
1145 if (!strcasecmp (atom + 4, "secs"))
1146 return MIN_SECS;
1147 break;
1149 if (!strncasecmp (atom + 1, "edi", 3)) {
1150 if (!strcasecmp (atom + 4, "a"))
1151 return MEDIA;
1152 if (!strcasecmp (atom + 4, "um"))
1153 return MEDIUM;
1154 break;
1156 if (!strcasecmp (atom + 1, "atch"))
1157 return MATCH;
1158 if (!strcasecmp (atom + 1, "embers"))
1159 return MEMBERS;
1160 if (!strcasecmp (atom + 1, "y"))
1161 return MY;
1162 if (!strcasecmp (atom + 1, "clt"))
1163 return MCLT;
1164 break;
1165 case 'n':
1166 if (!strcasecmp (atom + 1, "ormal"))
1167 return NORMAL;
1168 if (!strcasecmp (atom + 1, "ameserver"))
1169 return NAMESERVER;
1170 if (!strcasecmp (atom + 1, "etmask"))
1171 return NETMASK;
1172 if (!strcasecmp (atom + 1, "ever"))
1173 return NEVER;
1174 if (!strcasecmp (atom + 1, "ext-server"))
1175 return NEXT_SERVER;
1176 if (!strcasecmp (atom + 1, "ot"))
1177 return TOKEN_NOT;
1178 if (!strcasecmp (atom + 1, "o"))
1179 return TOKEN_NO;
1180 if (!strcasecmp (atom + 1, "oerror"))
1181 return NS_NOERROR;
1182 if (!strcasecmp (atom + 1, "otauth"))
1183 return NS_NOTAUTH;
1184 if (!strcasecmp (atom + 1, "otimp"))
1185 return NS_NOTIMP;
1186 if (!strcasecmp (atom + 1, "otzone"))
1187 return NS_NOTZONE;
1188 if (!strcasecmp (atom + 1, "xdomain"))
1189 return NS_NXDOMAIN;
1190 if (!strcasecmp (atom + 1, "xrrset"))
1191 return NS_NXRRSET;
1192 if (!strcasecmp (atom + 1, "ull"))
1193 return TOKEN_NULL;
1194 if (!strcasecmp (atom + 1, "ext"))
1195 return TOKEN_NEXT;
1196 if (!strcasecmp (atom + 1, "ew"))
1197 return TOKEN_NEW;
1198 break;
1199 case 'o':
1200 if (!strcasecmp (atom + 1, "mapi"))
1201 return OMAPI;
1202 if (!strcasecmp (atom + 1, "r"))
1203 return OR;
1204 if (!strcasecmp (atom + 1, "n"))
1205 return ON;
1206 if (!strcasecmp (atom + 1, "pen"))
1207 return TOKEN_OPEN;
1208 if (!strcasecmp (atom + 1, "ption"))
1209 return OPTION;
1210 if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1211 return ONE_LEASE_PER_CLIENT;
1212 if (!strcasecmp (atom + 1, "f"))
1213 return OF;
1214 if (!strcasecmp (atom + 1, "wner"))
1215 return OWNER;
1216 break;
1217 case 'p':
1218 if (!strcasecmp (atom + 1, "repend"))
1219 return PREPEND;
1220 if (!strcasecmp(atom + 1, "referred-life"))
1221 return PREFERRED_LIFE;
1222 if (!strcasecmp (atom + 1, "acket"))
1223 return PACKET;
1224 if (!strcasecmp (atom + 1, "ool"))
1225 return POOL;
1226 if (!strcasecmp (atom + 1, "ool6"))
1227 return POOL6;
1228 if (!strcasecmp (atom + 1, "refix6"))
1229 return PREFIX6;
1230 if (!strcasecmp (atom + 1, "seudo"))
1231 return PSEUDO;
1232 if (!strcasecmp (atom + 1, "eer"))
1233 return PEER;
1234 if (!strcasecmp (atom + 1, "rimary"))
1235 return PRIMARY;
1236 if (!strcasecmp (atom + 1, "rimary6"))
1237 return PRIMARY6;
1238 if (!strncasecmp (atom + 1, "artner", 6)) {
1239 if (!atom [7])
1240 return PARTNER;
1241 if (!strcasecmp (atom + 7, "-down"))
1242 return PARTNER_DOWN;
1244 if (!strcasecmp (atom + 1, "ort"))
1245 return PORT;
1246 if (!strcasecmp (atom + 1, "otential-conflict"))
1247 return POTENTIAL_CONFLICT;
1248 if (!strcasecmp (atom + 1, "ick-first-value") ||
1249 !strcasecmp (atom + 1, "ick"))
1250 return PICK;
1251 if (!strcasecmp (atom + 1, "aused"))
1252 return PAUSED;
1253 break;
1254 case 'r':
1255 if (!strcasecmp(atom + 1, "ange"))
1256 return RANGE;
1257 if (!strcasecmp(atom + 1, "ange6"))
1258 return RANGE6;
1259 if (isascii(atom[1]) &&
1260 (tolower((unsigned char)atom[1]) == 'e')) {
1261 if (!strcasecmp(atom + 2, "bind"))
1262 return REBIND;
1263 if (!strcasecmp(atom + 2, "boot"))
1264 return REBOOT;
1265 if (!strcasecmp(atom + 2, "contact-interval"))
1266 return RECONTACT_INTERVAL;
1267 if (!strncasecmp(atom + 2, "cover", 5)) {
1268 if (atom[7] == '\0')
1269 return RECOVER;
1270 if (!strcasecmp(atom + 7, "-done"))
1271 return RECOVER_DONE;
1272 if (!strcasecmp(atom + 7, "-wait"))
1273 return RECOVER_WAIT;
1274 break;
1276 if (!strcasecmp(atom + 2, "fresh"))
1277 return REFRESH;
1278 if (!strcasecmp(atom + 2, "fused"))
1279 return NS_REFUSED;
1280 if (!strcasecmp(atom + 2, "ject"))
1281 return REJECT;
1282 if (!strcasecmp(atom + 2, "lease"))
1283 return RELEASE;
1284 if (!strcasecmp(atom + 2, "leased"))
1285 return TOKEN_RELEASED;
1286 if (!strcasecmp(atom + 2, "move"))
1287 return REMOVE;
1288 if (!strcasecmp(atom + 2, "new"))
1289 return RENEW;
1290 if (!strcasecmp(atom + 2, "quest"))
1291 return REQUEST;
1292 if (!strcasecmp(atom + 2, "quire"))
1293 return REQUIRE;
1294 if (isascii(atom[2]) &&
1295 (tolower((unsigned char)atom[2]) == 's')) {
1296 if (!strcasecmp(atom + 3, "erved"))
1297 return TOKEN_RESERVED;
1298 if (!strcasecmp(atom + 3, "et"))
1299 return TOKEN_RESET;
1300 if (!strcasecmp(atom + 3,
1301 "olution-interrupted"))
1302 return RESOLUTION_INTERRUPTED;
1303 break;
1305 if (!strcasecmp(atom + 2, "try"))
1306 return RETRY;
1307 if (!strcasecmp(atom + 2, "turn"))
1308 return RETURN;
1309 if (!strcasecmp(atom + 2, "verse"))
1310 return REVERSE;
1311 if (!strcasecmp(atom + 2, "wind"))
1312 return REWIND;
1313 break;
1315 break;
1316 case 's':
1317 if (!strcasecmp(atom + 1, "cript"))
1318 return SCRIPT;
1319 if (isascii(atom[1]) &&
1320 tolower((unsigned char)atom[1]) == 'e') {
1321 if (!strcasecmp(atom + 2, "arch"))
1322 return SEARCH;
1323 if (isascii(atom[2]) &&
1324 tolower((unsigned char)atom[2]) == 'c') {
1325 if (!strncasecmp(atom + 3, "ond", 3)) {
1326 if (!strcasecmp(atom + 6, "ary"))
1327 return SECONDARY;
1328 if (!strcasecmp(atom + 6, "ary6"))
1329 return SECONDARY6;
1330 if (!strcasecmp(atom + 6, "s"))
1331 return SECONDS;
1332 break;
1334 if (!strcasecmp(atom + 3, "ret"))
1335 return SECRET;
1336 break;
1338 if (!strncasecmp(atom + 2, "lect", 4)) {
1339 if (atom[6] == '\0')
1340 return SELECT;
1341 if (!strcasecmp(atom + 6, "-timeout"))
1342 return SELECT_TIMEOUT;
1343 break;
1345 if (!strcasecmp(atom + 2, "nd"))
1346 return SEND;
1347 if (!strncasecmp(atom + 2, "rv", 2)) {
1348 if (!strncasecmp(atom + 4, "er", 2)) {
1349 if (atom[6] == '\0')
1350 return TOKEN_SERVER;
1351 if (atom[6] == '-') {
1352 if (!strcasecmp(atom + 7,
1353 "duid"))
1354 return SERVER_DUID;
1355 if (!strcasecmp(atom + 7,
1356 "name"))
1357 return SERVER_NAME;
1358 if (!strcasecmp(atom + 7,
1359 "identifier"))
1360 return SERVER_IDENTIFIER;
1361 break;
1363 break;
1365 if (!strcasecmp(atom + 4, "fail"))
1366 return NS_SERVFAIL;
1367 break;
1369 if (!strcasecmp(atom + 2, "t"))
1370 return TOKEN_SET;
1371 break;
1373 if (isascii(atom[1]) &&
1374 tolower((unsigned char)atom[1]) == 'h') {
1375 if (!strcasecmp(atom + 2, "ared-network"))
1376 return SHARED_NETWORK;
1377 if (!strcasecmp(atom + 2, "utdown"))
1378 return SHUTDOWN;
1379 break;
1381 if (isascii(atom[1]) &&
1382 tolower((unsigned char)atom[1]) == 'i') {
1383 if (!strcasecmp(atom + 2, "addr"))
1384 return SIADDR;
1385 if (!strcasecmp(atom + 2, "gned"))
1386 return SIGNED;
1387 if (!strcasecmp(atom + 2, "ze"))
1388 return SIZE;
1389 break;
1391 if (isascii(atom[1]) &&
1392 tolower((unsigned char)atom[1]) == 'p') {
1393 if (isascii(atom[2]) &&
1394 tolower((unsigned char)atom[2]) == 'a') {
1395 if (!strcasecmp(atom + 3, "ce"))
1396 return SPACE;
1397 if (!strcasecmp(atom + 3, "wn"))
1398 return SPAWN;
1399 break;
1401 if (!strcasecmp(atom + 2, "lit"))
1402 return SPLIT;
1403 break;
1405 if (isascii(atom[1]) &&
1406 tolower((unsigned char)atom[1]) == 't') {
1407 if (isascii(atom[2]) &&
1408 tolower((unsigned char)atom[2]) == 'a') {
1409 if(!strncasecmp(atom + 3, "rt", 2)) {
1410 if (!strcasecmp(atom + 5, "s"))
1411 return STARTS;
1412 if (!strcasecmp(atom + 5, "up"))
1413 return STARTUP;
1414 break;
1416 if (isascii(atom[3]) &&
1417 tolower((unsigned char)atom[3]) == 't') {
1418 if (!strcasecmp(atom + 4, "e"))
1419 return STATE;
1420 if (!strcasecmp(atom + 4, "ic"))
1421 return STATIC;
1422 break;
1425 if (!strcasecmp(atom + 2, "ring"))
1426 return STRING_TOKEN;
1427 break;
1429 if (!strncasecmp(atom + 1, "ub", 2)) {
1430 if (!strcasecmp(atom + 3, "class"))
1431 return SUBCLASS;
1432 if (!strcasecmp(atom + 3, "net"))
1433 return SUBNET;
1434 if (!strcasecmp(atom + 3, "net6"))
1435 return SUBNET6;
1436 if (!strcasecmp(atom + 3, "string"))
1437 return SUBSTRING;
1438 break;
1440 if (isascii(atom[1]) &&
1441 tolower((unsigned char)atom[1]) == 'u') {
1442 if (!strcasecmp(atom + 2, "ffix"))
1443 return SUFFIX;
1444 if (!strcasecmp(atom + 2, "persede"))
1445 return SUPERSEDE;
1447 if (!strcasecmp(atom + 1, "witch"))
1448 return SWITCH;
1449 break;
1450 case 't':
1451 if (!strcasecmp (atom + 1, "imestamp"))
1452 return TIMESTAMP;
1453 if (!strcasecmp (atom + 1, "imeout"))
1454 return TIMEOUT;
1455 if (!strcasecmp (atom + 1, "oken-ring"))
1456 return TOKEN_RING;
1457 if (!strcasecmp (atom + 1, "ext"))
1458 return TEXT;
1459 if (!strcasecmp (atom + 1, "stp"))
1460 return TSTP;
1461 if (!strcasecmp (atom + 1, "sfp"))
1462 return TSFP;
1463 if (!strcasecmp (atom + 1, "ransmission"))
1464 return TRANSMISSION;
1465 if (!strcasecmp(atom + 1, "emporary"))
1466 return TEMPORARY;
1467 break;
1468 case 'u':
1469 if (!strcasecmp (atom + 1, "case"))
1470 return UCASE;
1471 if (!strcasecmp (atom + 1, "nset"))
1472 return UNSET;
1473 if (!strcasecmp (atom + 1, "nsigned"))
1474 return UNSIGNED;
1475 if (!strcasecmp (atom + 1, "id"))
1476 return UID;
1477 if (!strncasecmp (atom + 1, "se", 2)) {
1478 if (!strcasecmp (atom + 3, "r-class"))
1479 return USER_CLASS;
1480 if (!strcasecmp (atom + 3, "-host-decl-names"))
1481 return USE_HOST_DECL_NAMES;
1482 if (!strcasecmp (atom + 3,
1483 "-lease-addr-for-default-route"))
1484 return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1485 break;
1487 if (!strncasecmp (atom + 1, "nknown", 6)) {
1488 if (!strcasecmp (atom + 7, "-clients"))
1489 return UNKNOWN_CLIENTS;
1490 if (!strcasecmp (atom + 7, "-state"))
1491 return UNKNOWN_STATE;
1492 if (!atom [7])
1493 return UNKNOWN;
1494 break;
1496 if (!strcasecmp (atom + 1, "nauthenticated"))
1497 return UNAUTHENTICATED;
1498 if (!strcasecmp (atom + 1, "pdate"))
1499 return UPDATE;
1500 break;
1501 case 'v':
1502 if (!strcasecmp (atom + 1, "6relay"))
1503 return V6RELAY;
1504 if (!strcasecmp (atom + 1, "6relopt"))
1505 return V6RELOPT;
1506 if (!strcasecmp (atom + 1, "endor-class"))
1507 return VENDOR_CLASS;
1508 if (!strcasecmp (atom + 1, "endor"))
1509 return VENDOR;
1510 break;
1511 case 'w':
1512 if (!strcasecmp (atom + 1, "ith"))
1513 return WITH;
1514 if (!strcasecmp(atom + 1, "idth"))
1515 return WIDTH;
1516 break;
1517 case 'y':
1518 if (!strcasecmp (atom + 1, "iaddr"))
1519 return YIADDR;
1520 if (!strcasecmp (atom + 1, "xdomain"))
1521 return NS_YXDOMAIN;
1522 if (!strcasecmp (atom + 1, "xrrset"))
1523 return NS_YXRRSET;
1524 break;
1525 case 'z':
1526 if (!strcasecmp (atom + 1, "erolen"))
1527 return ZEROLEN;
1528 if (!strcasecmp (atom + 1, "one"))
1529 return ZONE;
1530 break;
1532 return dfv;