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