Make setthetime() static per the prototype.
[dragonfly.git] / contrib / isc-dhcp / common / conflex.c
1 /* conflex.c
2
3    Lexical scanner for dhcpd config file... */
4
5 /*
6  * Copyright (c) 1995-2002 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.92.2.6 2002/11/17 02:26:56 dhankins Exp $ Copyright (c) 1995-2002 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                         if (c != EOF) {
440                                 cfile -> bufix--;
441                                 cfile -> ugflag = 1;
442                         }
443                         break;
444                 }
445                 cfile -> tokbuf [i] = c;
446         }
447         if (i == sizeof cfile -> tokbuf) {
448                 parse_warn (cfile,
449                             "numeric token larger than internal buffer");
450                 --i;
451         }
452         cfile -> tokbuf [i] = 0;
453         cfile -> tlen = i;
454         cfile -> tval = cfile -> tokbuf;
455         return token;
456 }
457
458 static enum dhcp_token read_num_or_name (c, cfile)
459         int c;
460         struct parse *cfile;
461 {
462         int i = 0;
463         enum dhcp_token rv = NUMBER_OR_NAME;
464         cfile -> tokbuf [i++] = c;
465         for (; i < sizeof cfile -> tokbuf; i++) {
466                 c = get_char (cfile);
467                 if (!isascii (c) ||
468                     (c != '-' && c != '_' && !isalnum (c))) {
469                         if (c != EOF) {
470                                 cfile -> bufix--;
471                                 cfile -> ugflag = 1;
472                         }
473                         break;
474                 }
475                 if (!isxdigit (c))
476                         rv = NAME;
477                 cfile -> tokbuf [i] = c;
478         }
479         if (i == sizeof cfile -> tokbuf) {
480                 parse_warn (cfile, "token larger than internal buffer");
481                 --i;
482         }
483         cfile -> tokbuf [i] = 0;
484         cfile -> tlen = i;
485         cfile -> tval = cfile -> tokbuf;
486         return intern (cfile -> tval, rv);
487 }
488
489 static enum dhcp_token intern (atom, dfv)
490         char *atom;
491         enum dhcp_token dfv;
492 {
493         if (!isascii (atom [0]))
494                 return dfv;
495
496         switch (tolower (atom [0])) {
497               case '-':
498                 if (atom [1] == 0)
499                         return MINUS;
500                 break;
501
502               case 'a':
503                 if (!strncasecmp (atom + 1, "uth", 3)) {
504                         if (!strncasecmp (atom + 3, "uthenticat", 10)) {
505                                 if (!strcasecmp (atom + 13, "ed"))
506                                         return AUTHENTICATED;
507                                 if (!strcasecmp (atom + 13, "ion"))
508                                         return AUTHENTICATION;
509                                 break;
510                         }
511                         if (!strcasecmp (atom + 1, "uthoritative"))
512                                 return AUTHORITATIVE;
513                         break;
514                 }
515                 if (!strcasecmp (atom + 1, "nd"))
516                         return AND;
517                 if (!strcasecmp (atom + 1, "ppend"))
518                         return APPEND;
519                 if (!strcasecmp (atom + 1, "llow"))
520                         return ALLOW;
521                 if (!strcasecmp (atom + 1, "lias"))
522                         return ALIAS;
523                 if (!strcasecmp (atom + 1, "lgorithm"))
524                         return ALGORITHM;
525                 if (!strcasecmp (atom + 1, "bandoned"))
526                         return TOKEN_ABANDONED;
527                 if (!strcasecmp (atom + 1, "dd"))
528                         return TOKEN_ADD;
529                 if (!strcasecmp (atom + 1, "ll"))
530                         return ALL;
531                 if (!strcasecmp (atom + 1, "t"))
532                         return AT;
533                 if (!strcasecmp (atom + 1, "rray"))
534                         return ARRAY;
535                 if (!strcasecmp (atom + 1, "ddress"))
536                         return ADDRESS;
537                 if (!strcasecmp (atom + 1, "ctive"))
538                         return TOKEN_ACTIVE;
539                 break;
540               case 'b':
541                 if (!strcasecmp (atom + 1, "ackup"))
542                         return TOKEN_BACKUP;
543                 if (!strcasecmp (atom + 1, "ootp"))
544                         return TOKEN_BOOTP;
545                 if (!strcasecmp (atom + 1, "inding"))
546                         return BINDING;
547                 if (!strcasecmp (atom + 1, "inary-to-ascii"))
548                         return BINARY_TO_ASCII;
549                 if (!strcasecmp (atom + 1, "ackoff-cutoff"))
550                         return BACKOFF_CUTOFF;
551                 if (!strcasecmp (atom + 1, "ooting"))
552                         return BOOTING;
553                 if (!strcasecmp (atom + 1, "oot-unknown-clients"))
554                         return BOOT_UNKNOWN_CLIENTS;
555                 if (!strcasecmp (atom + 1, "reak"))
556                         return BREAK;
557                 if (!strcasecmp (atom + 1, "illing"))
558                         return BILLING;
559                 if (!strcasecmp (atom + 1, "oolean"))
560                         return BOOLEAN;
561                 if (!strcasecmp (atom + 1, "alance"))
562                         return BALANCE;
563                 if (!strcasecmp (atom + 1, "ound"))
564                         return BOUND;
565                 break;
566               case 'c':
567                 if (!strcasecmp (atom + 1, "ase"))
568                         return CASE;
569                 if (!strcasecmp (atom + 1, "ommit"))
570                         return COMMIT;
571                 if (!strcasecmp (atom + 1, "ode"))
572                         return CODE;
573                 if (!strcasecmp (atom + 1, "onfig-option"))
574                         return CONFIG_OPTION;
575                 if (!strcasecmp (atom + 1, "heck"))
576                         return CHECK;
577                 if (!strcasecmp (atom + 1, "lass"))
578                         return CLASS;
579                 if (!strcasecmp (atom + 1, "lose"))
580                         return TOKEN_CLOSE;
581                 if (!strcasecmp (atom + 1, "reate"))
582                         return TOKEN_CREATE;
583                 if (!strcasecmp (atom + 1, "iaddr"))
584                         return CIADDR;
585                 if (!strncasecmp (atom + 1, "lient", 5)) {
586                         if (!strcasecmp (atom + 6, "-identifier"))
587                                 return CLIENT_IDENTIFIER;
588                         if (!strcasecmp (atom + 6, "-hostname"))
589                                 return CLIENT_HOSTNAME;
590                         if (!strcasecmp (atom + 6, "-state"))
591                                 return CLIENT_STATE;
592                         if (!strcasecmp (atom + 6, "-updates"))
593                                 return CLIENT_UPDATES;
594                         if (!strcasecmp (atom + 6, "s"))
595                                 return CLIENTS;
596                 }
597                 if (!strcasecmp (atom + 1, "oncat"))
598                         return CONCAT;
599                 if (!strcasecmp (atom + 1, "onnect"))
600                         return CONNECT;
601                 if (!strcasecmp (atom + 1, "ommunications-interrupted"))
602                         return COMMUNICATIONS_INTERRUPTED;
603                 if (!strcasecmp (atom + 1, "ltt"))
604                         return CLTT;
605                 break;
606               case 'd':
607                 if (!strcasecmp (atom + 1, "ns-update"))
608                         return DNS_UPDATE;
609                 if (!strcasecmp (atom + 1, "ns-delete"))
610                         return DNS_DELETE;
611                 if (!strcasecmp (atom + 1, "omain"))
612                         return DOMAIN;
613                 if (!strcasecmp (atom + 1, "omain-name"))
614                         return DOMAIN_NAME;
615                 if (!strcasecmp (atom + 1, "o-forward-update"))
616                         return DO_FORWARD_UPDATE;
617                 if (!strcasecmp (atom + 1, "ebug"))
618                         return TOKEN_DEBUG;
619                 if (!strcasecmp (atom + 1, "eny"))
620                         return DENY;
621                 if (!strcasecmp (atom + 1, "eleted"))
622                         return TOKEN_DELETED;
623                 if (!strcasecmp (atom + 1, "elete"))
624                         return TOKEN_DELETE;
625                 if (!strncasecmp (atom + 1, "efault", 6)) {
626                         if (!atom [7])
627                                 return DEFAULT;
628                         if (!strcasecmp (atom + 7, "-lease-time"))
629                                 return DEFAULT_LEASE_TIME;
630                         break;
631                 }
632                 if (!strncasecmp (atom + 1, "ynamic", 6)) {
633                         if (!atom [7])
634                                 return DYNAMIC;
635                         if (!strncasecmp (atom + 7, "-bootp", 6)) {
636                                 if (!atom [13])
637                                         return DYNAMIC_BOOTP;
638                                 if (!strcasecmp (atom + 13, "-lease-cutoff"))
639                                         return DYNAMIC_BOOTP_LEASE_CUTOFF;
640                                 if (!strcasecmp (atom + 13, "-lease-length"))
641                                         return DYNAMIC_BOOTP_LEASE_LENGTH;
642                                 break;
643                         }
644                 }
645                 if (!strcasecmp (atom + 1, "uplicates"))
646                         return DUPLICATES;
647                 if (!strcasecmp (atom + 1, "eclines"))
648                         return DECLINES;
649                 if (!strncasecmp (atom + 1, "efine", 5)) {
650                         if (!strcasecmp (atom + 6, "d"))
651                                 return DEFINED;
652                         if (!atom [6])
653                                 return DEFINE;
654                 }
655                 break;
656               case 'e':
657                 if (isascii (atom [1]) && tolower (atom [1]) == 'x') {
658                         if (!strcasecmp (atom + 2, "tract-int"))
659                                 return EXTRACT_INT;
660                         if (!strcasecmp (atom + 2, "ists"))
661                                 return EXISTS;
662                         if (!strcasecmp (atom + 2, "piry"))
663                                 return EXPIRY;
664                         if (!strcasecmp (atom + 2, "pire"))
665                                 return EXPIRE;
666                         if (!strcasecmp (atom + 2, "pired"))
667                                 return TOKEN_EXPIRED;
668                 }
669                 if (!strcasecmp (atom + 1, "ncode-int"))
670                         return ENCODE_INT;
671                 if (!strcasecmp (atom + 1, "thernet"))
672                         return ETHERNET;
673                 if (!strcasecmp (atom + 1, "nds"))
674                         return ENDS;
675                 if (!strncasecmp (atom + 1, "ls", 2)) {
676                         if (!strcasecmp (atom + 3, "e"))
677                                 return ELSE;
678                         if (!strcasecmp (atom + 3, "if"))
679                                 return ELSIF;
680                         break;
681                 }
682                 if (!strcasecmp (atom + 1, "rror"))
683                         return ERROR;
684                 if (!strcasecmp (atom + 1, "val"))
685                         return EVAL;
686                 if (!strcasecmp (atom + 1, "ncapsulate"))
687                         return ENCAPSULATE;
688                 break;
689               case 'f':
690                 if (!strcasecmp (atom + 1, "atal"))
691                         return FATAL;
692                 if (!strcasecmp (atom + 1, "ilename"))
693                         return FILENAME;
694                 if (!strcasecmp (atom + 1, "ixed-address"))
695                         return FIXED_ADDR;
696                 if (!strcasecmp (atom + 1, "ddi"))
697                         return FDDI;
698                 if (!strcasecmp (atom + 1, "ormerr"))
699                         return NS_FORMERR;
700                 if (!strcasecmp (atom + 1, "unction"))
701                         return FUNCTION;
702                 if (!strcasecmp (atom + 1, "ailover"))
703                         return FAILOVER;
704                 if (!strcasecmp (atom + 1, "ree"))
705                         return TOKEN_FREE;
706                 break;
707               case 'g':
708                 if (!strcasecmp (atom + 1, "iaddr"))
709                         return GIADDR;
710                 if (!strcasecmp (atom + 1, "roup"))
711                         return GROUP;
712                 if (!strcasecmp (atom + 1, "et-lease-hostnames"))
713                         return GET_LEASE_HOSTNAMES;
714                 break;
715               case 'h':
716                 if (!strcasecmp (atom + 1, "ba"))
717                         return HBA;
718                 if (!strcasecmp (atom + 1, "ost"))
719                         return HOST;
720                 if (!strcasecmp (atom + 1, "ost-decl-name"))
721                         return HOST_DECL_NAME;
722                 if (!strcasecmp (atom + 1, "ardware"))
723                         return HARDWARE;
724                 if (!strcasecmp (atom + 1, "ostname"))
725                         return HOSTNAME;
726                 if (!strcasecmp (atom + 1, "elp"))
727                         return TOKEN_HELP;
728                 break;
729               case 'i':
730                 if (!strcasecmp (atom + 1, "nclude"))
731                         return INCLUDE;
732                 if (!strcasecmp (atom + 1, "nteger"))
733                         return INTEGER;
734                 if (!strcasecmp (atom + 1, "nfinite"))
735                         return INFINITE;
736                 if (!strcasecmp (atom + 1, "nfo"))
737                         return INFO;
738                 if (!strcasecmp (atom + 1, "p-address"))
739                         return IP_ADDRESS;
740                 if (!strcasecmp (atom + 1, "nitial-interval"))
741                         return INITIAL_INTERVAL;
742                 if (!strcasecmp (atom + 1, "nterface"))
743                         return INTERFACE;
744                 if (!strcasecmp (atom + 1, "dentifier"))
745                         return IDENTIFIER;
746                 if (!strcasecmp (atom + 1, "f"))
747                         return IF;
748                 if (!strcasecmp (atom + 1, "s"))
749                         return IS;
750                 if (!strcasecmp (atom + 1, "gnore"))
751                         return IGNORE;
752                 break;
753               case 'k':
754                 if (!strcasecmp (atom + 1, "nown"))
755                         return KNOWN;
756                 if (!strcasecmp (atom + 1, "ey"))
757                         return KEY;
758                 break;
759               case 'l':
760                 if (!strcasecmp (atom + 1, "ease"))
761                         return LEASE;
762                 if (!strcasecmp (atom + 1, "eased-address"))
763                         return LEASED_ADDRESS;
764                 if (!strcasecmp (atom + 1, "ease-time"))
765                         return LEASE_TIME;
766                 if (!strcasecmp (atom + 1, "imit"))
767                         return LIMIT;
768                 if (!strcasecmp (atom + 1, "et"))
769                         return LET;
770                 if (!strcasecmp (atom + 1, "oad"))
771                         return LOAD;
772                 if (!strcasecmp (atom + 1, "og"))
773                         return LOG;
774                 break;
775               case 'm':
776                 if (!strncasecmp (atom + 1, "ax", 2)) {
777                         if (!atom [3])
778                                 return TOKEN_MAX;
779                         if (!strcasecmp (atom + 3, "-lease-time"))
780                                 return MAX_LEASE_TIME;
781                         if (!strcasecmp (atom + 3, "-transmit-idle"))
782                                 return MAX_TRANSMIT_IDLE;
783                         if (!strcasecmp (atom + 3, "-response-delay"))
784                                 return MAX_RESPONSE_DELAY;
785                         if (!strcasecmp (atom + 3, "-unacked-updates"))
786                                 return MAX_UNACKED_UPDATES;
787                 }
788                 if (!strncasecmp (atom + 1, "in-", 3)) {
789                         if (!strcasecmp (atom + 4, "lease-time"))
790                                 return MIN_LEASE_TIME;
791                         if (!strcasecmp (atom + 4, "secs"))
792                                 return MIN_SECS;
793                         break;
794                 }
795                 if (!strncasecmp (atom + 1, "edi", 3)) {
796                         if (!strcasecmp (atom + 4, "a"))
797                                 return MEDIA;
798                         if (!strcasecmp (atom + 4, "um"))
799                                 return MEDIUM;
800                         break;
801                 }
802                 if (!strcasecmp (atom + 1, "atch"))
803                         return MATCH;
804                 if (!strcasecmp (atom + 1, "embers"))
805                         return MEMBERS;
806                 if (!strcasecmp (atom + 1, "y"))
807                         return MY;
808                 if (!strcasecmp (atom + 1, "clt"))
809                         return MCLT;
810                 break;
811               case 'n':
812                 if (!strcasecmp (atom + 1, "ormal"))
813                         return NORMAL;
814                 if (!strcasecmp (atom + 1, "ameserver"))
815                         return NAMESERVER;
816                 if (!strcasecmp (atom + 1, "etmask"))
817                         return NETMASK;
818                 if (!strcasecmp (atom + 1, "ever"))
819                         return NEVER;
820                 if (!strcasecmp (atom + 1, "ext-server"))
821                         return NEXT_SERVER;
822                 if (!strcasecmp (atom + 1, "ot"))
823                         return TOKEN_NOT;
824                 if (!strcasecmp (atom + 1, "o"))
825                         return NO;
826                 if (!strcasecmp (atom + 1, "s-update"))
827                         return NS_UPDATE;
828                 if (!strcasecmp (atom + 1, "oerror"))
829                         return NS_NOERROR;
830                 if (!strcasecmp (atom + 1, "otauth"))
831                         return NS_NOTAUTH;
832                 if (!strcasecmp (atom + 1, "otimp"))
833                         return NS_NOTIMP;
834                 if (!strcasecmp (atom + 1, "otzone"))
835                         return NS_NOTZONE;
836                 if (!strcasecmp (atom + 1, "xdomain"))
837                         return NS_NXDOMAIN;
838                 if (!strcasecmp (atom + 1, "xrrset"))
839                         return NS_NXRRSET;
840                 if (!strcasecmp (atom + 1, "ull"))
841                         return TOKEN_NULL;
842                 if (!strcasecmp (atom + 1, "ext"))
843                         return TOKEN_NEXT;
844                 if (!strcasecmp (atom + 1, "ew"))
845                         return TOKEN_NEW;
846                 break;
847               case 'o':
848                 if (!strcasecmp (atom + 1, "mapi"))
849                         return OMAPI;
850                 if (!strcasecmp (atom + 1, "r"))
851                         return OR;
852                 if (!strcasecmp (atom + 1, "n"))
853                         return ON;
854                 if (!strcasecmp (atom + 1, "pen"))
855                         return TOKEN_OPEN;
856                 if (!strcasecmp (atom + 1, "ption"))
857                         return OPTION;
858                 if (!strcasecmp (atom + 1, "ne-lease-per-client"))
859                         return ONE_LEASE_PER_CLIENT;
860                 if (!strcasecmp (atom + 1, "f"))
861                         return OF;
862                 if (!strcasecmp (atom + 1, "wner"))
863                         return OWNER;
864                 break;
865               case 'p':
866                 if (!strcasecmp (atom + 1, "repend"))
867                         return PREPEND;
868                 if (!strcasecmp (atom + 1, "acket"))
869                         return PACKET;
870                 if (!strcasecmp (atom + 1, "ool"))
871                         return POOL;
872                 if (!strcasecmp (atom + 1, "seudo"))
873                         return PSEUDO;
874                 if (!strcasecmp (atom + 1, "eer"))
875                         return PEER;
876                 if (!strcasecmp (atom + 1, "rimary"))
877                         return PRIMARY;
878                 if (!strncasecmp (atom + 1, "artner", 6)) {
879                         if (!atom [7])
880                                 return PARTNER;
881                         if (!strcasecmp (atom + 7, "-down"))
882                                 return PARTNER_DOWN;
883                 }
884                 if (!strcasecmp (atom + 1, "ort"))
885                         return PORT;
886                 if (!strcasecmp (atom + 1, "otential-conflict"))
887                         return POTENTIAL_CONFLICT;
888                 if (!strcasecmp (atom + 1, "ick-first-value") ||
889                     !strcasecmp (atom + 1, "ick"))
890                         return PICK;
891                 if (!strcasecmp (atom + 1, "aused"))
892                         return PAUSED;
893                 break;
894               case 'r':
895                 if (!strcasecmp (atom + 1, "esolution-interrupted"))
896                         return RESOLUTION_INTERRUPTED;
897                 if (!strcasecmp (atom + 1, "ange"))
898                         return RANGE;
899                 if (!strcasecmp (atom + 1, "ecover"))
900                         return RECOVER;
901                 if (!strcasecmp (atom + 1, "ecover-done"))
902                         return RECOVER_DONE;
903                 if (!strcasecmp (atom + 1, "ecover-wait"))
904                         return RECOVER_WAIT;
905                 if (!strcasecmp (atom + 1, "econtact-interval"))
906                         return RECONTACT_INTERVAL;
907                 if (!strcasecmp (atom + 1, "equest"))
908                         return REQUEST;
909                 if (!strcasecmp (atom + 1, "equire"))
910                         return REQUIRE;
911                 if (!strcasecmp (atom + 1, "equire"))
912                         return REQUIRE;
913                 if (!strcasecmp (atom + 1, "etry"))
914                         return RETRY;
915                 if (!strcasecmp (atom + 1, "eturn"))
916                         return RETURN;
917                 if (!strcasecmp (atom + 1, "enew"))
918                         return RENEW;
919                 if (!strcasecmp (atom + 1, "ebind"))
920                         return REBIND;
921                 if (!strcasecmp (atom + 1, "eboot"))
922                         return REBOOT;
923                 if (!strcasecmp (atom + 1, "eject"))
924                         return REJECT;
925                 if (!strcasecmp (atom + 1, "everse"))
926                         return REVERSE;
927                 if (!strcasecmp (atom + 1, "elease"))
928                         return RELEASE;
929                 if (!strcasecmp (atom + 1, "efused"))
930                         return NS_REFUSED;
931                 if (!strcasecmp (atom + 1, "eleased"))
932                         return TOKEN_RELEASED;
933                 if (!strcasecmp (atom + 1, "eset"))
934                         return TOKEN_RESET;
935                 if (!strcasecmp (atom + 1, "eserved"))
936                         return TOKEN_RESERVED;
937                 if (!strcasecmp (atom + 1, "emove"))
938                         return REMOVE;
939                 if (!strcasecmp (atom + 1, "efresh"))
940                         return REFRESH;
941                 break;
942               case 's':
943                 if (!strcasecmp (atom + 1, "tate"))
944                         return STATE;
945                 if (!strcasecmp (atom + 1, "ecret"))
946                         return SECRET;
947                 if (!strcasecmp (atom + 1, "ervfail"))
948                         return NS_SERVFAIL;
949                 if (!strcasecmp (atom + 1, "witch"))
950                         return SWITCH;
951                 if (!strcasecmp (atom + 1, "igned"))
952                         return SIGNED;
953                 if (!strcasecmp (atom + 1, "tring"))
954                         return STRING_TOKEN;
955                 if (!strcasecmp (atom + 1, "uffix"))
956                         return SUFFIX;
957                 if (!strcasecmp (atom + 1, "earch"))
958                         return SEARCH;
959                 if (!strcasecmp (atom + 1, "tarts"))
960                         return STARTS;
961                 if (!strcasecmp (atom + 1, "iaddr"))
962                         return SIADDR;
963                 if (!strcasecmp (atom + 1, "hared-network"))
964                         return SHARED_NETWORK;
965                 if (!strcasecmp (atom + 1, "econdary"))
966                         return SECONDARY;
967                 if (!strcasecmp (atom + 1, "erver-name"))
968                         return SERVER_NAME;
969                 if (!strcasecmp (atom + 1, "erver-identifier"))
970                         return SERVER_IDENTIFIER;
971                 if (!strcasecmp (atom + 1, "erver"))
972                         return SERVER;
973                 if (!strcasecmp (atom + 1, "elect-timeout"))
974                         return SELECT_TIMEOUT;
975                 if (!strcasecmp (atom + 1, "elect"))
976                         return SELECT;
977                 if (!strcasecmp (atom + 1, "end"))
978                         return SEND;
979                 if (!strcasecmp (atom + 1, "cript"))
980                         return SCRIPT;
981                 if (!strcasecmp (atom + 1, "upersede"))
982                         return SUPERSEDE;
983                 if (!strncasecmp (atom + 1, "ub", 2)) {
984                         if (!strcasecmp (atom + 3, "string"))
985                                 return SUBSTRING;
986                         if (!strcasecmp (atom + 3, "net"))
987                                 return SUBNET;
988                         if (!strcasecmp (atom + 3, "class"))
989                                 return SUBCLASS;
990                         break;
991                 }
992                 if (!strcasecmp (atom + 1, "pawn"))
993                         return SPAWN;
994                 if (!strcasecmp (atom + 1, "pace"))
995                         return SPACE;
996                 if (!strcasecmp (atom + 1, "tatic"))
997                         return STATIC;
998                 if (!strcasecmp (atom + 1, "plit"))
999                         return SPLIT;
1000                 if (!strcasecmp (atom + 1, "et"))
1001                         return TOKEN_SET;
1002                 if (!strcasecmp (atom + 1, "econds"))
1003                         return SECONDS;
1004                 if (!strcasecmp (atom + 1, "hutdown"))
1005                         return SHUTDOWN;
1006                 if (!strcasecmp (atom + 1, "tartup"))
1007                         return STARTUP;
1008                 break;
1009               case 't':
1010                 if (!strcasecmp (atom + 1, "imestamp"))
1011                         return TIMESTAMP;
1012                 if (!strcasecmp (atom + 1, "imeout"))
1013                         return TIMEOUT;
1014                 if (!strcasecmp (atom + 1, "oken-ring"))
1015                         return TOKEN_RING;
1016                 if (!strcasecmp (atom + 1, "ext"))
1017                         return TEXT;
1018                 if (!strcasecmp (atom + 1, "stp"))
1019                         return TSTP;
1020                 if (!strcasecmp (atom + 1, "sfp"))
1021                         return TSFP;
1022                 if (!strcasecmp (atom + 1, "ransmission"))
1023                         return TRANSMISSION;
1024                 break;
1025               case 'u':
1026                 if (!strcasecmp (atom + 1, "nset"))
1027                         return UNSET;
1028                 if (!strcasecmp (atom + 1, "nsigned"))
1029                         return UNSIGNED;
1030                 if (!strcasecmp (atom + 1, "id"))
1031                         return UID;
1032                 if (!strncasecmp (atom + 1, "se", 2)) {
1033                         if (!strcasecmp (atom + 3, "r-class"))
1034                                 return USER_CLASS;
1035                         if (!strcasecmp (atom + 3, "-host-decl-names"))
1036                                 return USE_HOST_DECL_NAMES;
1037                         if (!strcasecmp (atom + 3,
1038                                          "-lease-addr-for-default-route"))
1039                                 return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1040                         break;
1041                 }
1042                 if (!strncasecmp (atom + 1, "nknown", 6)) {
1043                         if (!strcasecmp (atom + 7, "-clients"))
1044                                 return UNKNOWN_CLIENTS;
1045                         if (!strcasecmp (atom + 7, "-state"))
1046                                 return UNKNOWN_STATE;
1047                         if (!atom [7])
1048                                 return UNKNOWN;
1049                         break;
1050                 }
1051                 if (!strcasecmp (atom + 1, "nauthenticated"))
1052                         return AUTHENTICATED;
1053                 if (!strcasecmp (atom + 1, "pdated-dns-rr"))
1054                         return UPDATED_DNS_RR;
1055                 if (!strcasecmp (atom + 1, "pdate"))
1056                         return UPDATE;
1057                 break;
1058               case 'v':
1059                 if (!strcasecmp (atom + 1, "endor-class"))
1060                         return VENDOR_CLASS;
1061                 if (!strcasecmp (atom + 1, "endor"))
1062                         return VENDOR;
1063                 break;
1064               case 'w':
1065                 if (!strcasecmp (atom + 1, "ith"))
1066                         return WITH;
1067                 break;
1068               case 'y':
1069                 if (!strcasecmp (atom + 1, "iaddr"))
1070                         return YIADDR;
1071                 if (!strcasecmp (atom + 1, "xdomain"))
1072                         return NS_YXDOMAIN;
1073                 if (!strcasecmp (atom + 1, "xrrset"))
1074                         return NS_YXRRSET;
1075                 break;
1076               case 'z':
1077                 if (!strcasecmp (atom + 1, "one"))
1078                         return ZONE;
1079                 break;
1080         }
1081         return dfv;
1082 }