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