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