common/conflex.c

Go to the documentation of this file.
00001 /* conflex.c
00002 
00003    Lexical scanner for dhcpd config file... */
00004 
00005 /*
00006  * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 1995-2003 by Internet Software Consortium
00008  *
00009  * Permission to use, copy, modify, and distribute this software for any
00010  * purpose with or without fee is hereby granted, provided that the above
00011  * copyright notice and this permission notice appear in all copies.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00014  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00015  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00016  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00017  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00018  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00019  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00020  *
00021  *   Internet Systems Consortium, Inc.
00022  *   950 Charter Street
00023  *   Redwood City, CA 94063
00024  *   <info@isc.org>
00025  *   https://www.isc.org/
00026  *
00027  */
00028 
00029 #include "dhcpd.h"
00030 #include <ctype.h>
00031 
00032 static int get_char (struct parse *);
00033 static void unget_char(struct parse *, int);
00034 static void skip_to_eol (struct parse *);
00035 static enum dhcp_token read_whitespace(int c, struct parse *cfile);
00036 static enum dhcp_token read_string (struct parse *);
00037 static enum dhcp_token read_number (int, struct parse *);
00038 static enum dhcp_token read_num_or_name (int, struct parse *);
00039 static enum dhcp_token intern (char *, enum dhcp_token);
00040 
00041 isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
00042         struct parse **cfile;
00043         int file;
00044         char *inbuf;
00045         unsigned buflen;
00046         const char *name;
00047         int eolp;
00048 {
00049         isc_result_t status = ISC_R_SUCCESS;
00050         struct parse *tmp;
00051 
00052         tmp = dmalloc(sizeof(struct parse), MDL);
00053         if (tmp == NULL) {
00054                 return (ISC_R_NOMEMORY);
00055         }
00056 
00057         /*
00058          * We don't need to initialize things to zero here, since 
00059          * dmalloc() returns memory that is set to zero.
00060          */
00061         tmp->tlname = name;
00062         tmp->lpos = tmp -> line = 1;
00063         tmp->cur_line = tmp->line1;
00064         tmp->prev_line = tmp->line2;
00065         tmp->token_line = tmp->cur_line;
00066         tmp->cur_line[0] = tmp->prev_line[0] = 0;
00067         tmp->file = file;
00068         tmp->eol_token = eolp;
00069 
00070         if (inbuf != NULL) {
00071                 tmp->inbuf = inbuf;
00072                 tmp->buflen = buflen;
00073                 tmp->bufsiz = 0;
00074         } else {
00075                 struct stat sb;
00076 
00077                 if (fstat(file, &sb) < 0) {
00078                         status = ISC_R_IOERROR;
00079                         goto cleanup;
00080                 }
00081 
00082                 if (sb.st_size == 0)
00083                         goto cleanup;
00084 
00085                 tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
00086                 tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
00087                                   file, 0);
00088 
00089                 if (tmp->inbuf == MAP_FAILED) {
00090                         status = ISC_R_IOERROR;
00091                         goto cleanup;
00092                 }
00093         }
00094 
00095         *cfile = tmp;
00096         return (ISC_R_SUCCESS);
00097 
00098 cleanup:
00099         dfree(tmp, MDL);
00100         return (status);
00101 }
00102 
00103 isc_result_t end_parse (cfile)
00104         struct parse **cfile;
00105 {
00106         /* "Memory" config files have no file. */
00107         if ((*cfile)->file != -1) {
00108                 munmap((*cfile)->inbuf, (*cfile)->bufsiz);
00109                 close((*cfile)->file);
00110         }
00111 
00112         if ((*cfile)->saved_state != NULL) {
00113                 dfree((*cfile)->saved_state, MDL);
00114         }
00115                 
00116         dfree(*cfile, MDL);
00117         *cfile = NULL;
00118         return ISC_R_SUCCESS;
00119 }
00120 
00121 /*
00122  * Save the current state of the parser.
00123  *
00124  * Only one state may be saved. Any previous saved state is
00125  * lost.
00126  */
00127 isc_result_t
00128 save_parse_state(struct parse *cfile) {
00129         /*
00130          * Free any previous saved state.
00131          */
00132         if (cfile->saved_state != NULL) {
00133                 dfree(cfile->saved_state, MDL);
00134         }
00135 
00136         /*
00137          * Save our current state.
00138          */
00139         cfile->saved_state = dmalloc(sizeof(struct parse), MDL);
00140         if (cfile->saved_state == NULL) {
00141                 return ISC_R_NOMEMORY;
00142         }
00143         memcpy(cfile->saved_state, cfile, sizeof(*cfile));
00144         return ISC_R_SUCCESS;
00145 }
00146 
00147 /*
00148  * Return the parser to the previous saved state.
00149  *
00150  * You must call save_parse_state() before calling 
00151  * restore_parse_state(), but you can call restore_parse_state() any
00152  * number of times after that.
00153  */
00154 isc_result_t
00155 restore_parse_state(struct parse *cfile) {
00156         struct parse *saved_state;
00157 
00158         if (cfile->saved_state == NULL) {
00159                 return DHCP_R_NOTYET;
00160         }
00161 
00162         saved_state = cfile->saved_state;
00163         memcpy(cfile, saved_state, sizeof(*cfile));
00164         cfile->saved_state = saved_state;
00165         return ISC_R_SUCCESS;
00166 }
00167 
00168 static int get_char (cfile)
00169         struct parse *cfile;
00170 {
00171         /* My kingdom for WITH... */
00172         int c;
00173 
00174         if (cfile->bufix == cfile->buflen) {
00175 #if !defined(LDAP_CONFIGURATION)
00176                 c = EOF;
00177 #else /* defined(LDAP_CONFIGURATION) */
00178                 if (cfile->read_function != NULL)
00179                         c = cfile->read_function(cfile);
00180                 else
00181                         c = EOF;
00182 #endif
00183         } else {
00184                 c = cfile->inbuf [cfile->bufix];
00185                 cfile->bufix++;
00186         }
00187 
00188         if (!cfile->ugflag) {
00189                 if (c == EOL) {
00190                         if (cfile->cur_line == cfile->line1) {  
00191                                 cfile->cur_line = cfile->line2;
00192                                 cfile->prev_line = cfile->line1;
00193                         } else {
00194                                 cfile->cur_line = cfile->line1;
00195                                 cfile->prev_line = cfile->line2;
00196                         }
00197                         cfile->line++;
00198                         cfile->lpos = 1;
00199                         cfile->cur_line [0] = 0;
00200                 } else if (c != EOF) {
00201                         if (cfile->lpos <= 80) {
00202                                 cfile->cur_line [cfile->lpos - 1] = c;
00203                                 cfile->cur_line [cfile->lpos] = 0;
00204                         }
00205                         cfile->lpos++;
00206                 }
00207         } else
00208                 cfile->ugflag = 0;
00209         return c;               
00210 }
00211 
00212 /*
00213  * Return a character to our input buffer.
00214  */
00215 static void
00216 unget_char(struct parse *cfile, int c) {
00217         if (c != EOF) {
00218                 cfile->bufix--;
00219                 cfile->ugflag = 1;      /* do not put characters into
00220                                            our error buffer on the next
00221                                            call to get_char() */
00222         }
00223 }
00224 
00225 /*
00226  * GENERAL NOTE ABOUT TOKENS
00227  *
00228  * We normally only want non-whitespace tokens. There are some 
00229  * circumstances where we *do* want to see whitespace (for example
00230  * when parsing IPv6 addresses).
00231  *
00232  * Generally we use the next_token() function to read tokens. This 
00233  * in turn calls get_next_token, which does *not* return tokens for
00234  * whitespace. Rather, it skips these.
00235  *
00236  * When we need to see whitespace, we us next_raw_token(), which also
00237  * returns the WHITESPACE token.
00238  *
00239  * The peek_token() and peek_raw_token() functions work as expected.
00240  *
00241  * Warning: if you invoke peek_token(), then if there is a whitespace
00242  * token, it will be lost, and subsequent use of next_raw_token() or
00243  * peek_raw_token() will NOT see it.
00244  */
00245 
00246 static enum dhcp_token
00247 get_raw_token(struct parse *cfile) {
00248         int c;
00249         enum dhcp_token ttok;
00250         static char tb [2];
00251         int l, p;
00252 
00253         do {
00254                 l = cfile -> line;
00255                 p = cfile -> lpos;
00256 
00257                 c = get_char (cfile);
00258                 if (!((c == '\n') && cfile->eol_token) && 
00259                     isascii(c) && isspace(c)) {
00260                         ttok = read_whitespace(c, cfile);
00261                         break;
00262                 }
00263                 if (c == '#') {
00264                         skip_to_eol (cfile);
00265                         continue;
00266                 }
00267                 if (c == '"') {
00268                         cfile -> lexline = l;
00269                         cfile -> lexchar = p;
00270                         ttok = read_string (cfile);
00271                         break;
00272                 }
00273                 if ((isascii (c) && isdigit (c)) || c == '-') {
00274                         cfile -> lexline = l;
00275                         cfile -> lexchar = p;
00276                         ttok = read_number (c, cfile);
00277                         break;
00278                 } else if (isascii (c) && isalpha (c)) {
00279                         cfile -> lexline = l;
00280                         cfile -> lexchar = p;
00281                         ttok = read_num_or_name (c, cfile);
00282                         break;
00283                 } else if (c == EOF) {
00284                         ttok = END_OF_FILE;
00285                         cfile -> tlen = 0;
00286                         break;
00287                 } else {
00288                         cfile -> lexline = l;
00289                         cfile -> lexchar = p;
00290                         tb [0] = c;
00291                         tb [1] = 0;
00292                         cfile -> tval = tb;
00293                         cfile -> tlen = 1;
00294                         ttok = c;
00295                         break;
00296                 }
00297         } while (1);
00298         return ttok;
00299 }
00300 
00301 /*
00302  * The get_next_token() function consumes the next token and
00303  * returns it to the caller.
00304  *
00305  * Since the code is almost the same for "normal" and "raw" 
00306  * input, we pass a flag to alter the way it works.
00307  */
00308 
00309 static enum dhcp_token 
00310 get_next_token(const char **rval, unsigned *rlen, 
00311                struct parse *cfile, isc_boolean_t raw) {
00312         int rv;
00313 
00314         if (cfile -> token) {
00315                 if (cfile -> lexline != cfile -> tline)
00316                         cfile -> token_line = cfile -> cur_line;
00317                 cfile -> lexchar = cfile -> tlpos;
00318                 cfile -> lexline = cfile -> tline;
00319                 rv = cfile -> token;
00320                 cfile -> token = 0;
00321         } else {
00322                 rv = get_raw_token(cfile);
00323                 cfile -> token_line = cfile -> cur_line;
00324         }
00325 
00326         if (!raw) {
00327                 while (rv == WHITESPACE) {
00328                         rv = get_raw_token(cfile);
00329                         cfile->token_line = cfile->cur_line;
00330                 }
00331         }
00332         
00333         if (rval)
00334                 *rval = cfile -> tval;
00335         if (rlen)
00336                 *rlen = cfile -> tlen;
00337 #ifdef DEBUG_TOKENS
00338         fprintf (stderr, "%s:%d ", cfile -> tval, rv);
00339 #endif
00340         return rv;
00341 }
00342 
00343 
00344 /*
00345  * Get the next token from cfile and return it.
00346  *
00347  * If rval is non-NULL, set the pointer it contains to 
00348  * the contents of the token.
00349  *
00350  * If rlen is non-NULL, set the integer it contains to 
00351  * the length of the token.
00352  */
00353 
00354 enum dhcp_token
00355 next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
00356         return get_next_token(rval, rlen, cfile, ISC_FALSE);
00357 }
00358 
00359 
00360 /*
00361  * The same as the next_token() function above, but will return space
00362  * as the WHITESPACE token.
00363  */
00364 
00365 enum dhcp_token
00366 next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
00367         return get_next_token(rval, rlen, cfile, ISC_TRUE);
00368 }
00369 
00370 
00371 /*
00372  * The do_peek_token() function checks the next token without
00373  * consuming it, and returns it to the caller.
00374  *
00375  * Since the code is almost the same for "normal" and "raw" 
00376  * input, we pass a flag to alter the way it works. (See the 
00377  * warning in the GENERAL NOTES ABOUT TOKENS above though.)
00378  */
00379 
00380 enum dhcp_token
00381 do_peek_token(const char **rval, unsigned int *rlen,
00382               struct parse *cfile, isc_boolean_t raw) {
00383         int x;
00384 
00385         if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
00386                 cfile -> tlpos = cfile -> lexchar;
00387                 cfile -> tline = cfile -> lexline;
00388 
00389                 do {
00390                         cfile->token = get_raw_token(cfile);
00391                 } while (!raw && (cfile->token == WHITESPACE));
00392 
00393                 if (cfile -> lexline != cfile -> tline)
00394                         cfile -> token_line = cfile -> prev_line;
00395 
00396                 x = cfile -> lexchar;
00397                 cfile -> lexchar = cfile -> tlpos;
00398                 cfile -> tlpos = x;
00399 
00400                 x = cfile -> lexline;
00401                 cfile -> lexline = cfile -> tline;
00402                 cfile -> tline = x;
00403         }
00404         if (rval)
00405                 *rval = cfile -> tval;
00406         if (rlen)
00407                 *rlen = cfile -> tlen;
00408 #ifdef DEBUG_TOKENS
00409         fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
00410 #endif
00411         return cfile -> token;
00412 }
00413 
00414 
00415 /*
00416  * Get the next token from cfile and return it, leaving it for a 
00417  * subsequent call to next_token().
00418  *
00419  * Note that it WILL consume whitespace tokens.
00420  *
00421  * If rval is non-NULL, set the pointer it contains to 
00422  * the contents of the token.
00423  *
00424  * If rlen is non-NULL, set the integer it contains to 
00425  * the length of the token.
00426  */
00427 
00428 enum dhcp_token
00429 peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
00430         return do_peek_token(rval, rlen, cfile, ISC_FALSE);
00431 }
00432 
00433 
00434 /*
00435  * The same as the peek_token() function above, but will return space
00436  * as the WHITESPACE token.
00437  */
00438 
00439 enum dhcp_token
00440 peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
00441         return do_peek_token(rval, rlen, cfile, ISC_TRUE);
00442 }
00443 
00444 static void skip_to_eol (cfile)
00445         struct parse *cfile;
00446 {
00447         int c;
00448         do {
00449                 c = get_char (cfile);
00450                 if (c == EOF)
00451                         return;
00452                 if (c == EOL) {
00453                         return;
00454                 }
00455         } while (1);
00456 }
00457 
00458 static enum dhcp_token
00459 read_whitespace(int c, struct parse *cfile) {
00460         int ofs;
00461 
00462         /*
00463          * Read as much whitespace as we have available.
00464          */
00465         ofs = 0;
00466         do {
00467                 if (ofs >= sizeof(cfile->tokbuf)) {
00468                         /*
00469                          * As the file includes a huge amount of whitespace,
00470                          * it's probably broken.
00471                          * Print out a warning and bail out.
00472                          */
00473                         parse_warn(cfile,
00474                                    "whitespace too long, buffer overflow.");
00475                         log_fatal("Exiting");
00476                 }
00477                 cfile->tokbuf[ofs++] = c;
00478                 c = get_char(cfile);
00479         } while (!((c == '\n') && cfile->eol_token) && 
00480                  isascii(c) && isspace(c));
00481 
00482         /*
00483          * Put the last (non-whitespace) character back.
00484          */
00485         unget_char(cfile, c);
00486 
00487         /*
00488          * Return our token.
00489          */
00490         cfile->tokbuf[ofs] = '\0';
00491         cfile->tlen = ofs;
00492         cfile->tval = cfile->tokbuf;
00493         return WHITESPACE;
00494 }
00495 
00496 static enum dhcp_token read_string (cfile)
00497         struct parse *cfile;
00498 {
00499         int i;
00500         int bs = 0;
00501         int c;
00502         int value = 0;
00503         int hex = 0;
00504 
00505         for (i = 0; i < sizeof cfile -> tokbuf; i++) {
00506               again:
00507                 c = get_char (cfile);
00508                 if (c == EOF) {
00509                         parse_warn (cfile, "eof in string constant");
00510                         break;
00511                 }
00512                 if (bs == 1) {
00513                         switch (c) {
00514                               case 't':
00515                                 cfile -> tokbuf [i] = '\t';
00516                                 break;
00517                               case 'r':
00518                                 cfile -> tokbuf [i] = '\r';
00519                                 break;
00520                               case 'n':
00521                                 cfile -> tokbuf [i] = '\n';
00522                                 break;
00523                               case 'b':
00524                                 cfile -> tokbuf [i] = '\b';
00525                                 break;
00526                               case '0':
00527                               case '1':
00528                               case '2':
00529                               case '3':
00530                                 hex = 0;
00531                                 value = c - '0';
00532                                 ++bs;
00533                                 goto again;
00534                               case 'x':
00535                                 hex = 1;
00536                                 value = 0;
00537                                 ++bs;
00538                                 goto again;
00539                               default:
00540                                 cfile -> tokbuf [i] = c;
00541                                 break;
00542                         }
00543                         bs = 0;
00544                 } else if (bs > 1) {
00545                         if (hex) {
00546                                 if (c >= '0' && c <= '9') {
00547                                         value = value * 16 + (c - '0');
00548                                 } else if (c >= 'a' && c <= 'f') {
00549                                         value = value * 16 + (c - 'a' + 10);
00550                                 } else if (c >= 'A' && c <= 'F') {
00551                                         value = value * 16 + (c - 'A' + 10);
00552                                 } else {
00553                                         parse_warn (cfile,
00554                                                     "invalid hex digit: %x",
00555                                                     c);
00556                                         bs = 0;
00557                                         continue;
00558                                 }
00559                                 if (++bs == 4) {
00560                                         cfile -> tokbuf [i] = value;
00561                                         bs = 0;
00562                                 } else
00563                                         goto again;
00564                         } else {
00565                                 if (c >= '0' && c <= '7') {
00566                                         value = value * 8 + (c - '0');
00567                                 } else {
00568                                     if (value != 0) {
00569                                         parse_warn (cfile,
00570                                                     "invalid octal digit %x",
00571                                                     c);
00572                                         continue;
00573                                     } else
00574                                         cfile -> tokbuf [i] = 0;
00575                                     bs = 0;
00576                                 }
00577                                 if (++bs == 4) {
00578                                         cfile -> tokbuf [i] = value;
00579                                         bs = 0;
00580                                 } else
00581                                         goto again;
00582                         }
00583                 } else if (c == '\\') {
00584                         bs = 1;
00585                         goto again;
00586                 } else if (c == '"')
00587                         break;
00588                 else
00589                         cfile -> tokbuf [i] = c;
00590         }
00591         /* Normally, I'd feel guilty about this, but we're talking about
00592            strings that'll fit in a DHCP packet here... */
00593         if (i == sizeof cfile -> tokbuf) {
00594                 parse_warn (cfile,
00595                             "string constant larger than internal buffer");
00596                 --i;
00597         }
00598         cfile -> tokbuf [i] = 0;
00599         cfile -> tlen = i;
00600         cfile -> tval = cfile -> tokbuf;
00601         return STRING;
00602 }
00603 
00604 static enum dhcp_token read_number (c, cfile)
00605         int c;
00606         struct parse *cfile;
00607 {
00608         int i = 0;
00609         int token = NUMBER;
00610 
00611         cfile -> tokbuf [i++] = c;
00612         for (; i < sizeof cfile -> tokbuf; i++) {
00613                 c = get_char (cfile);
00614 
00615                 /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
00616                  * Except in the case of '0x' syntax hex, which gets called
00617                  * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
00618                  * verified to be at least 0xf or less.
00619                  */
00620                 switch(isascii(c) ? token : BREAK) {
00621                     case NUMBER:
00622                         if(isdigit(c))
00623                                 break;
00624                         /* FALLTHROUGH */
00625                     case NUMBER_OR_NAME:
00626                         if(isxdigit(c)) {
00627                                 token = NUMBER_OR_NAME;
00628                                 break;
00629                         }
00630                         /* FALLTHROUGH */
00631                     case NAME:
00632                         if((i == 2) && isxdigit(c) &&
00633                                 (cfile->tokbuf[0] == '0') &&
00634                                 ((cfile->tokbuf[1] == 'x') ||
00635                                  (cfile->tokbuf[1] == 'X'))) {
00636                                 token = NUMBER_OR_NAME;
00637                                 break;
00638                         } else if(((c == '-') || (c == '_') || isalnum(c))) {
00639                                 token = NAME;
00640                                 break;
00641                         }
00642                         /* FALLTHROUGH */
00643                     case BREAK:
00644                         /* At this point c is either EOF or part of the next
00645                          * token.  If not EOF, rewind the file one byte so
00646                          * the next token is read from there.
00647                          */
00648                         unget_char(cfile, c);
00649                         goto end_read;
00650 
00651                     default:
00652                         log_fatal("read_number():%s:%d: impossible case", MDL);
00653                 }
00654 
00655                 cfile -> tokbuf [i] = c;
00656         }
00657 
00658         if (i == sizeof cfile -> tokbuf) {
00659                 parse_warn (cfile,
00660                             "numeric token larger than internal buffer");
00661                 --i;
00662         }
00663 
00664   end_read:
00665         cfile -> tokbuf [i] = 0;
00666         cfile -> tlen = i;
00667         cfile -> tval = cfile -> tokbuf;
00668 
00669         /*
00670          * If this entire token from start to finish was "-", such as
00671          * the middle parameter in "42 - 7", return just the MINUS token.
00672          */
00673         if ((i == 1) && (cfile->tokbuf[i] == '-'))
00674                 return MINUS;
00675         else
00676                 return token;
00677 }
00678 
00679 static enum dhcp_token read_num_or_name (c, cfile)
00680         int c;
00681         struct parse *cfile;
00682 {
00683         int i = 0;
00684         enum dhcp_token rv = NUMBER_OR_NAME;
00685         cfile -> tokbuf [i++] = c;
00686         for (; i < sizeof cfile -> tokbuf; i++) {
00687                 c = get_char (cfile);
00688                 if (!isascii (c) ||
00689                     (c != '-' && c != '_' && !isalnum (c))) {
00690                         unget_char(cfile, c);
00691                         break;
00692                 }
00693                 if (!isxdigit (c))
00694                         rv = NAME;
00695                 cfile -> tokbuf [i] = c;
00696         }
00697         if (i == sizeof cfile -> tokbuf) {
00698                 parse_warn (cfile, "token larger than internal buffer");
00699                 --i;
00700         }
00701         cfile -> tokbuf [i] = 0;
00702         cfile -> tlen = i;
00703         cfile -> tval = cfile -> tokbuf;
00704         return intern(cfile->tval, rv);
00705 }
00706 
00707 static enum dhcp_token
00708 intern(char *atom, enum dhcp_token dfv) {
00709         if (!isascii(atom[0]))
00710                 return dfv;
00711 
00712         switch (tolower((unsigned char)atom[0])) {
00713               case '-':
00714                 if (atom [1] == 0)
00715                         return MINUS;
00716                 break;
00717 
00718               case 'a':
00719                 if (!strcasecmp(atom + 1, "bandoned"))
00720                         return TOKEN_ABANDONED;
00721                 if (!strcasecmp(atom + 1, "ctive"))
00722                         return TOKEN_ACTIVE;
00723                 if (!strncasecmp(atom + 1, "dd", 2)) {
00724                         if (atom[3] == '\0')
00725                                 return TOKEN_ADD;
00726                         else if (!strcasecmp(atom + 3, "ress"))
00727                                 return ADDRESS;
00728                         break;
00729                 }
00730                 if (!strcasecmp(atom + 1, "fter"))
00731                         return AFTER;
00732                 if (isascii(atom[1]) &&
00733                     (tolower((unsigned char)atom[1]) == 'l')) {
00734                         if (!strcasecmp(atom + 2, "gorithm"))
00735                                 return ALGORITHM;
00736                         if (!strcasecmp(atom + 2, "ias"))
00737                                 return ALIAS;
00738                         if (isascii(atom[2]) &&
00739                             (tolower((unsigned char)atom[2]) == 'l')) {
00740                                 if (atom[3] == '\0')
00741                                         return ALL;
00742                                 else if (!strcasecmp(atom + 3, "ow"))
00743                                         return ALLOW;
00744                                 break;
00745                         }
00746                         if (!strcasecmp(atom + 2, "so"))
00747                                 return TOKEN_ALSO;
00748                         break;
00749                 }
00750                 if (isascii(atom[1]) &&
00751                     (tolower((unsigned char)atom[1]) == 'n')) {
00752                         if (!strcasecmp(atom + 2, "d"))
00753                                 return AND;
00754                         if (!strcasecmp(atom + 2, "ycast-mac"))
00755                                 return ANYCAST_MAC;
00756                         break;
00757                 }
00758                 if (!strcasecmp(atom + 1, "ppend"))
00759                         return APPEND;
00760                 if (!strcasecmp(atom + 1, "rray"))
00761                         return ARRAY;
00762                 if (isascii(atom[1]) &&
00763                     (tolower((unsigned char)atom[1]) == 't')) {
00764                         if (atom[2] == '\0')
00765                                 return AT;
00766                         if (!strcasecmp(atom + 2, "sfp"))
00767                                 return ATSFP;
00768                         break;
00769                 }
00770                 if (!strncasecmp(atom + 1, "ut", 2)) {
00771                         if (isascii(atom[3]) &&
00772                             (tolower((unsigned char)atom[3]) == 'h')) {
00773                                 if (!strncasecmp(atom + 4, "enticat", 7)) {
00774                                         if (!strcasecmp(atom + 11, "ed"))
00775                                                 return AUTHENTICATED;
00776                                         if (!strcasecmp(atom + 11, "ion"))
00777                                                 return AUTHENTICATION;
00778                                         break;
00779                                 }
00780                                 if (!strcasecmp(atom + 4, "oritative"))
00781                                         return AUTHORITATIVE;
00782                                 break;
00783                         }
00784                         if (!strcasecmp(atom + 3, "o-partner-down"))
00785                                 return AUTO_PARTNER_DOWN;
00786                         break;
00787                 }
00788                 break;
00789               case 'b':
00790                 if (!strcasecmp (atom + 1, "ackup"))
00791                         return TOKEN_BACKUP;
00792                 if (!strcasecmp (atom + 1, "ootp"))
00793                         return TOKEN_BOOTP;
00794                 if (!strcasecmp (atom + 1, "inding"))
00795                         return BINDING;
00796                 if (!strcasecmp (atom + 1, "inary-to-ascii"))
00797                         return BINARY_TO_ASCII;
00798                 if (!strcasecmp (atom + 1, "ackoff-cutoff"))
00799                         return BACKOFF_CUTOFF;
00800                 if (!strcasecmp (atom + 1, "ooting"))
00801                         return BOOTING;
00802                 if (!strcasecmp (atom + 1, "oot-unknown-clients"))
00803                         return BOOT_UNKNOWN_CLIENTS;
00804                 if (!strcasecmp (atom + 1, "reak"))
00805                         return BREAK;
00806                 if (!strcasecmp (atom + 1, "illing"))
00807                         return BILLING;
00808                 if (!strcasecmp (atom + 1, "oolean"))
00809                         return BOOLEAN;
00810                 if (!strcasecmp (atom + 1, "alance"))
00811                         return BALANCE;
00812                 if (!strcasecmp (atom + 1, "ound"))
00813                         return BOUND;
00814                 if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
00815                         return BOOTP_BROADCAST_ALWAYS;
00816                 break;
00817               case 'c':
00818                 if (!strcasecmp(atom + 1, "ase"))
00819                         return CASE;
00820                 if (!strcasecmp(atom + 1, "heck"))
00821                         return CHECK;
00822                 if (!strcasecmp(atom + 1, "iaddr"))
00823                         return CIADDR;
00824                 if (isascii(atom[1]) &&
00825                     tolower((unsigned char)atom[1]) == 'l') {
00826                         if (!strcasecmp(atom + 2, "ass"))
00827                                 return CLASS;
00828                         if (!strncasecmp(atom + 2, "ient", 4)) {
00829                                 if (!strcasecmp(atom + 6, "s"))
00830                                         return CLIENTS;
00831                                 if (atom[6] == '-') {
00832                                         if (!strcasecmp(atom + 7, "hostname"))
00833                                                 return CLIENT_HOSTNAME;
00834                                         if (!strcasecmp(atom + 7, "identifier"))
00835                                                 return CLIENT_IDENTIFIER;
00836                                         if (!strcasecmp(atom + 7, "state"))
00837                                                 return CLIENT_STATE;
00838                                         if (!strcasecmp(atom + 7, "updates"))
00839                                                 return CLIENT_UPDATES;
00840                                         break;
00841                                 }
00842                                 break;
00843                         }
00844                         if (!strcasecmp(atom + 2, "ose"))
00845                                 return TOKEN_CLOSE;
00846                         if (!strcasecmp(atom + 2, "tt"))
00847                                 return CLTT;
00848                         break;
00849                 }
00850                 if (isascii(atom[1]) &&
00851                     tolower((unsigned char)atom[1]) == 'o') {
00852                         if (!strcasecmp(atom + 2, "de"))
00853                                 return CODE;
00854                         if (isascii(atom[2]) &&
00855                             tolower((unsigned char)atom[2]) == 'm') {
00856                                 if (!strcasecmp(atom + 3, "mit"))
00857                                         return COMMIT;
00858                                 if (!strcasecmp(atom + 3,
00859                                                 "munications-interrupted"))
00860                                         return COMMUNICATIONS_INTERRUPTED;
00861                                 if (!strcasecmp(atom + 3, "pressed"))
00862                                         return COMPRESSED;
00863                                 break;
00864                         }
00865                         if (isascii(atom[2]) &&
00866                             tolower((unsigned char)atom[2]) == 'n') {
00867                                 if (!strcasecmp(atom + 3, "cat"))
00868                                         return CONCAT;
00869                                 if (!strcasecmp(atom + 3, "fig-option"))
00870                                         return CONFIG_OPTION;
00871                                 if (!strcasecmp(atom + 3, "flict-done"))
00872                                         return CONFLICT_DONE;
00873                                 if (!strcasecmp(atom + 3, "nect"))
00874                                         return CONNECT;
00875                                 break;
00876                         }
00877                         break;
00878                 }
00879                 if (!strcasecmp(atom + 1, "reate"))
00880                         return TOKEN_CREATE;
00881                 break;
00882               case 'd':
00883                 if (!strcasecmp(atom + 1, "b-time-format"))
00884                         return DB_TIME_FORMAT;
00885                 if (!strcasecmp (atom + 1, "omain"))
00886                         return DOMAIN;
00887                 if (!strncasecmp (atom + 1, "omain-", 6)) {
00888                         if (!strcasecmp(atom + 7, "name"))
00889                                 return DOMAIN_NAME;
00890                         if (!strcasecmp(atom + 7, "list"))
00891                                 return DOMAIN_LIST;
00892                 }
00893                 if (!strcasecmp (atom + 1, "o-forward-updates"))
00894                         return DO_FORWARD_UPDATE;
00895                 if (!strcasecmp (atom + 1, "ebug"))
00896                         return TOKEN_DEBUG;
00897                 if (!strcasecmp (atom + 1, "eny"))
00898                         return DENY;
00899                 if (!strcasecmp (atom + 1, "eleted"))
00900                         return TOKEN_DELETED;
00901                 if (!strcasecmp (atom + 1, "elete"))
00902                         return TOKEN_DELETE;
00903                 if (!strncasecmp (atom + 1, "efault", 6)) {
00904                         if (!atom [7])
00905                                 return DEFAULT;
00906                         if (!strcasecmp(atom + 7, "-duid"))
00907                                 return DEFAULT_DUID;
00908                         if (!strcasecmp (atom + 7, "-lease-time"))
00909                                 return DEFAULT_LEASE_TIME;
00910                         break;
00911                 }
00912                 if (!strncasecmp (atom + 1, "ynamic", 6)) {
00913                         if (!atom [7])
00914                                 return DYNAMIC;
00915                         if (!strncasecmp (atom + 7, "-bootp", 6)) {
00916                                 if (!atom [13])
00917                                         return DYNAMIC_BOOTP;
00918                                 if (!strcasecmp (atom + 13, "-lease-cutoff"))
00919                                         return DYNAMIC_BOOTP_LEASE_CUTOFF;
00920                                 if (!strcasecmp (atom + 13, "-lease-length"))
00921                                         return DYNAMIC_BOOTP_LEASE_LENGTH;
00922                                 break;
00923                         }
00924                 }
00925                 if (!strcasecmp (atom + 1, "uplicates"))
00926                         return DUPLICATES;
00927                 if (!strcasecmp (atom + 1, "eclines"))
00928                         return DECLINES;
00929                 if (!strncasecmp (atom + 1, "efine", 5)) {
00930                         if (!strcasecmp (atom + 6, "d"))
00931                                 return DEFINED;
00932                         if (!atom [6])
00933                                 return DEFINE;
00934                 }
00935                 break;
00936               case 'e':
00937                 if (isascii (atom [1]) && 
00938                     tolower((unsigned char)atom[1]) == 'x') {
00939                         if (!strcasecmp (atom + 2, "tract-int"))
00940                                 return EXTRACT_INT;
00941                         if (!strcasecmp (atom + 2, "ists"))
00942                                 return EXISTS;
00943                         if (!strcasecmp (atom + 2, "piry"))
00944                                 return EXPIRY;
00945                         if (!strcasecmp (atom + 2, "pire"))
00946                                 return EXPIRE;
00947                         if (!strcasecmp (atom + 2, "pired"))
00948                                 return TOKEN_EXPIRED;
00949                 }
00950                 if (!strcasecmp (atom + 1, "ncode-int"))
00951                         return ENCODE_INT;
00952                 if (!strcasecmp(atom + 1, "poch"))
00953                         return EPOCH;
00954                 if (!strcasecmp (atom + 1, "thernet"))
00955                         return ETHERNET;
00956                 if (!strcasecmp (atom + 1, "nds"))
00957                         return ENDS;
00958                 if (!strncasecmp (atom + 1, "ls", 2)) {
00959                         if (!strcasecmp (atom + 3, "e"))
00960                                 return ELSE;
00961                         if (!strcasecmp (atom + 3, "if"))
00962                                 return ELSIF;
00963                         break;
00964                 }
00965                 if (!strcasecmp (atom + 1, "rror"))
00966                         return ERROR;
00967                 if (!strcasecmp (atom + 1, "val"))
00968                         return EVAL;
00969                 if (!strcasecmp (atom + 1, "ncapsulate"))
00970                         return ENCAPSULATE;
00971                 if (!strcasecmp(atom + 1, "xecute"))
00972                         return EXECUTE;
00973                 if (!strcasecmp(atom+1, "n")) {
00974                         return EN;
00975                 }
00976                 break;
00977               case 'f':
00978                 if (!strcasecmp (atom + 1, "atal"))
00979                         return FATAL;
00980                 if (!strcasecmp (atom + 1, "ilename"))
00981                         return FILENAME;
00982                 if (!strcasecmp (atom + 1, "ixed-address"))
00983                         return FIXED_ADDR;
00984                 if (!strcasecmp (atom + 1, "ixed-address6"))
00985                         return FIXED_ADDR6;
00986                 if (!strcasecmp (atom + 1, "ixed-prefix6"))
00987                         return FIXED_PREFIX6;
00988                 if (!strcasecmp (atom + 1, "ddi"))
00989                         return TOKEN_FDDI;
00990                 if (!strcasecmp (atom + 1, "ormerr"))
00991                         return NS_FORMERR;
00992                 if (!strcasecmp (atom + 1, "unction"))
00993                         return FUNCTION;
00994                 if (!strcasecmp (atom + 1, "ailover"))
00995                         return FAILOVER;
00996                 if (!strcasecmp (atom + 1, "ree"))
00997                         return TOKEN_FREE;
00998                 break;
00999               case 'g':
01000                 if (!strncasecmp(atom + 1, "et", 2)) {
01001                         if (!strcasecmp(atom + 3, "-lease-hostnames"))
01002                                 return GET_LEASE_HOSTNAMES;
01003                         if (!strcasecmp(atom + 3, "hostbyname"))
01004                                 return GETHOSTBYNAME;
01005                         if (!strcasecmp(atom + 3, "hostname"))
01006                                 return GETHOSTNAME;
01007                         break;
01008                 }
01009                 if (!strcasecmp (atom + 1, "iaddr"))
01010                         return GIADDR;
01011                 if (!strcasecmp (atom + 1, "roup"))
01012                         return GROUP;
01013                 break;
01014               case 'h':
01015                 if (!strcasecmp(atom + 1, "ash"))
01016                         return HASH;
01017                 if (!strcasecmp (atom + 1, "ba"))
01018                         return HBA;
01019                 if (!strcasecmp (atom + 1, "ost"))
01020                         return HOST;
01021                 if (!strcasecmp (atom + 1, "ost-decl-name"))
01022                         return HOST_DECL_NAME;
01023                 if (!strcasecmp(atom + 1, "ost-identifier"))
01024                         return HOST_IDENTIFIER;
01025                 if (!strcasecmp (atom + 1, "ardware"))
01026                         return HARDWARE;
01027                 if (!strcasecmp (atom + 1, "ostname"))
01028                         return HOSTNAME;
01029                 if (!strcasecmp (atom + 1, "elp"))
01030                         return TOKEN_HELP;
01031                 break;
01032               case 'i':
01033                 if (!strcasecmp(atom+1, "a-na")) 
01034                         return IA_NA;
01035                 if (!strcasecmp(atom+1, "a-ta")) 
01036                         return IA_TA;
01037                 if (!strcasecmp(atom+1, "a-pd")) 
01038                         return IA_PD;
01039                 if (!strcasecmp(atom+1, "aaddr")) 
01040                         return IAADDR;
01041                 if (!strcasecmp(atom+1, "aprefix")) 
01042                         return IAPREFIX;
01043                 if (!strcasecmp (atom + 1, "nclude"))
01044                         return INCLUDE;
01045                 if (!strcasecmp (atom + 1, "nteger"))
01046                         return INTEGER;
01047                 if (!strcasecmp (atom  + 1, "nfiniband"))
01048                         return TOKEN_INFINIBAND;
01049                 if (!strcasecmp (atom + 1, "nfinite"))
01050                         return INFINITE;
01051                 if (!strcasecmp (atom + 1, "nfo"))
01052                         return INFO;
01053                 if (!strcasecmp (atom + 1, "p-address"))
01054                         return IP_ADDRESS;
01055                 if (!strcasecmp (atom + 1, "p6-address"))
01056                         return IP6_ADDRESS;
01057                 if (!strcasecmp (atom + 1, "nitial-interval"))
01058                         return INITIAL_INTERVAL;
01059                 if (!strcasecmp (atom + 1, "nitial-delay"))
01060                         return INITIAL_DELAY;
01061                 if (!strcasecmp (atom + 1, "nterface"))
01062                         return INTERFACE;
01063                 if (!strcasecmp (atom + 1, "dentifier"))
01064                         return IDENTIFIER;
01065                 if (!strcasecmp (atom + 1, "f"))
01066                         return IF;
01067                 if (!strcasecmp (atom + 1, "s"))
01068                         return IS;
01069                 if (!strcasecmp (atom + 1, "gnore"))
01070                         return IGNORE;
01071                 break;
01072               case 'k':
01073                 if (!strncasecmp (atom + 1, "nown", 4)) {
01074                         if (!strcasecmp (atom + 5, "-clients"))
01075                                 return KNOWN_CLIENTS;
01076                         if (!atom[5])
01077                                 return KNOWN;
01078                         break;
01079                 }
01080                 if (!strcasecmp (atom + 1, "ey"))
01081                         return KEY;
01082                 break;
01083               case 'l':
01084                 if (!strcasecmp (atom + 1, "case"))
01085                         return LCASE;
01086                 if (!strcasecmp (atom + 1, "ease"))
01087                         return LEASE;
01088                 if (!strcasecmp(atom + 1, "ease6"))
01089                         return LEASE6;
01090                 if (!strcasecmp (atom + 1, "eased-address"))
01091                         return LEASED_ADDRESS;
01092                 if (!strcasecmp (atom + 1, "ease-time"))
01093                         return LEASE_TIME;
01094                 if (!strcasecmp(atom + 1, "easequery"))
01095                         return LEASEQUERY;
01096                 if (!strcasecmp(atom + 1, "ength"))
01097                         return LENGTH;
01098                 if (!strcasecmp (atom + 1, "imit"))
01099                         return LIMIT;
01100                 if (!strcasecmp (atom + 1, "et"))
01101                         return LET;
01102                 if (!strcasecmp (atom + 1, "oad"))
01103                         return LOAD;
01104                 if (!strcasecmp(atom + 1, "ocal"))
01105                         return LOCAL;
01106                 if (!strcasecmp (atom + 1, "og"))
01107                         return LOG;
01108                 if (!strcasecmp(atom+1, "lt")) {
01109                         return LLT;
01110                 }
01111                 if (!strcasecmp(atom+1, "l")) {
01112                         return LL;
01113                 }
01114                 break;
01115               case 'm':
01116                 if (!strncasecmp (atom + 1, "ax", 2)) {
01117                         if (!atom [3])
01118                                 return TOKEN_MAX;
01119                         if (!strcasecmp (atom + 3, "-balance"))
01120                                 return MAX_BALANCE;
01121                         if (!strncasecmp (atom + 3, "-lease-", 7)) {
01122                                 if (!strcasecmp(atom + 10, "misbalance"))
01123                                         return MAX_LEASE_MISBALANCE;
01124                                 if (!strcasecmp(atom + 10, "ownership"))
01125                                         return MAX_LEASE_OWNERSHIP;
01126                                 if (!strcasecmp(atom + 10, "time"))
01127                                         return MAX_LEASE_TIME;
01128                         }
01129                         if (!strcasecmp(atom + 3, "-life"))
01130                                 return MAX_LIFE;
01131                         if (!strcasecmp (atom + 3, "-transmit-idle"))
01132                                 return MAX_TRANSMIT_IDLE;
01133                         if (!strcasecmp (atom + 3, "-response-delay"))
01134                                 return MAX_RESPONSE_DELAY;
01135                         if (!strcasecmp (atom + 3, "-unacked-updates"))
01136                                 return MAX_UNACKED_UPDATES;
01137                 }
01138                 if (!strncasecmp (atom + 1, "in-", 3)) {
01139                         if (!strcasecmp (atom + 4, "balance"))
01140                                 return MIN_BALANCE;
01141                         if (!strcasecmp (atom + 4, "lease-time"))
01142                                 return MIN_LEASE_TIME;
01143                         if (!strcasecmp (atom + 4, "secs"))
01144                                 return MIN_SECS;
01145                         break;
01146                 }
01147                 if (!strncasecmp (atom + 1, "edi", 3)) {
01148                         if (!strcasecmp (atom + 4, "a"))
01149                                 return MEDIA;
01150                         if (!strcasecmp (atom + 4, "um"))
01151                                 return MEDIUM;
01152                         break;
01153                 }
01154                 if (!strcasecmp (atom + 1, "atch"))
01155                         return MATCH;
01156                 if (!strcasecmp (atom + 1, "embers"))
01157                         return MEMBERS;
01158                 if (!strcasecmp (atom + 1, "y"))
01159                         return MY;
01160                 if (!strcasecmp (atom + 1, "clt"))
01161                         return MCLT;
01162                 break;
01163               case 'n':
01164                 if (!strcasecmp (atom + 1, "ormal"))
01165                         return NORMAL;
01166                 if (!strcasecmp (atom + 1, "ameserver"))
01167                         return NAMESERVER;
01168                 if (!strcasecmp (atom + 1, "etmask"))
01169                         return NETMASK;
01170                 if (!strcasecmp (atom + 1, "ever"))
01171                         return NEVER;
01172                 if (!strcasecmp (atom + 1, "ext-server"))
01173                         return NEXT_SERVER;
01174                 if (!strcasecmp (atom + 1, "ot"))
01175                         return TOKEN_NOT;
01176                 if (!strcasecmp (atom + 1, "o"))
01177                         return TOKEN_NO;
01178                 if (!strcasecmp (atom + 1, "oerror"))
01179                         return NS_NOERROR;
01180                 if (!strcasecmp (atom + 1, "otauth"))
01181                         return NS_NOTAUTH;
01182                 if (!strcasecmp (atom + 1, "otimp"))
01183                         return NS_NOTIMP;
01184                 if (!strcasecmp (atom + 1, "otzone"))
01185                         return NS_NOTZONE;
01186                 if (!strcasecmp (atom + 1, "xdomain"))
01187                         return NS_NXDOMAIN;
01188                 if (!strcasecmp (atom + 1, "xrrset"))
01189                         return NS_NXRRSET;
01190                 if (!strcasecmp (atom + 1, "ull"))
01191                         return TOKEN_NULL;
01192                 if (!strcasecmp (atom + 1, "ext"))
01193                         return TOKEN_NEXT;
01194                 if (!strcasecmp (atom + 1, "ew"))
01195                         return TOKEN_NEW;
01196                 break;
01197               case 'o':
01198                 if (!strcasecmp (atom + 1, "mapi"))
01199                         return OMAPI;
01200                 if (!strcasecmp (atom + 1, "r"))
01201                         return OR;
01202                 if (!strcasecmp (atom + 1, "n"))
01203                         return ON;
01204                 if (!strcasecmp (atom + 1, "pen"))
01205                         return TOKEN_OPEN;
01206                 if (!strcasecmp (atom + 1, "ption"))
01207                         return OPTION;
01208                 if (!strcasecmp (atom + 1, "ne-lease-per-client"))
01209                         return ONE_LEASE_PER_CLIENT;
01210                 if (!strcasecmp (atom + 1, "f"))
01211                         return OF;
01212                 if (!strcasecmp (atom + 1, "wner"))
01213                         return OWNER;
01214                 break;
01215               case 'p':
01216                 if (!strcasecmp (atom + 1, "repend"))
01217                         return PREPEND;
01218                 if (!strcasecmp(atom + 1, "referred-life"))
01219                         return PREFERRED_LIFE;
01220                 if (!strcasecmp (atom + 1, "acket"))
01221                         return PACKET;
01222                 if (!strcasecmp (atom + 1, "ool"))
01223                         return POOL;
01224                 if (!strcasecmp (atom + 1, "ool6"))
01225                         return POOL6;
01226                 if (!strcasecmp (atom + 1, "refix6"))
01227                         return PREFIX6;
01228                 if (!strcasecmp (atom + 1, "seudo"))
01229                         return PSEUDO;
01230                 if (!strcasecmp (atom + 1, "eer"))
01231                         return PEER;
01232                 if (!strcasecmp (atom + 1, "rimary"))
01233                         return PRIMARY;
01234                 if (!strcasecmp (atom + 1, "rimary6"))
01235                         return PRIMARY6;
01236                 if (!strncasecmp (atom + 1, "artner", 6)) {
01237                         if (!atom [7])
01238                                 return PARTNER;
01239                         if (!strcasecmp (atom + 7, "-down"))
01240                                 return PARTNER_DOWN;
01241                 }
01242                 if (!strcasecmp (atom + 1, "ort"))
01243                         return PORT;
01244                 if (!strcasecmp (atom + 1, "otential-conflict"))
01245                         return POTENTIAL_CONFLICT;
01246                 if (!strcasecmp (atom + 1, "ick-first-value") ||
01247                     !strcasecmp (atom + 1, "ick"))
01248                         return PICK;
01249                 if (!strcasecmp (atom + 1, "aused"))
01250                         return PAUSED;
01251                 break;
01252               case 'r':
01253                 if (!strcasecmp(atom + 1, "ange"))
01254                         return RANGE;
01255                 if (!strcasecmp(atom + 1, "ange6"))
01256                         return RANGE6;
01257                 if (isascii(atom[1]) &&
01258                     (tolower((unsigned char)atom[1]) == 'e')) {
01259                         if (!strcasecmp(atom + 2, "bind"))
01260                                 return REBIND;
01261                         if (!strcasecmp(atom + 2, "boot"))
01262                                 return REBOOT;
01263                         if (!strcasecmp(atom + 2, "contact-interval"))
01264                                 return RECONTACT_INTERVAL;
01265                         if (!strncasecmp(atom + 2, "cover", 5)) {
01266                                 if (atom[7] == '\0')
01267                                         return RECOVER;
01268                                 if (!strcasecmp(atom + 7, "-done"))
01269                                         return RECOVER_DONE;
01270                                 if (!strcasecmp(atom + 7, "-wait"))
01271                                         return RECOVER_WAIT;
01272                                 break;
01273                         }
01274                         if (!strcasecmp(atom + 2, "fresh"))
01275                                 return REFRESH;
01276                         if (!strcasecmp(atom + 2, "fused"))
01277                                 return NS_REFUSED;
01278                         if (!strcasecmp(atom + 2, "ject"))
01279                                 return REJECT;
01280                         if (!strcasecmp(atom + 2, "lease"))
01281                                 return RELEASE;
01282                         if (!strcasecmp(atom + 2, "leased"))
01283                                 return TOKEN_RELEASED;
01284                         if (!strcasecmp(atom + 2, "move"))
01285                                 return REMOVE;
01286                         if (!strcasecmp(atom + 2, "new"))
01287                                 return RENEW;
01288                         if (!strcasecmp(atom + 2, "quest"))
01289                                 return REQUEST;
01290                         if (!strcasecmp(atom + 2, "quire"))
01291                                 return REQUIRE;
01292                         if (isascii(atom[2]) &&
01293                             (tolower((unsigned char)atom[2]) == 's')) {
01294                                 if (!strcasecmp(atom + 3, "erved"))
01295                                         return TOKEN_RESERVED;
01296                                 if (!strcasecmp(atom + 3, "et"))
01297                                         return TOKEN_RESET;
01298                                 if (!strcasecmp(atom + 3,
01299                                                 "olution-interrupted"))
01300                                         return RESOLUTION_INTERRUPTED;
01301                                 break;
01302                         }
01303                         if (!strcasecmp(atom + 2, "try"))
01304                                 return RETRY;
01305                         if (!strcasecmp(atom + 2, "turn"))
01306                                 return RETURN;
01307                         if (!strcasecmp(atom + 2, "verse"))
01308                                 return REVERSE;
01309                         if (!strcasecmp(atom + 2, "wind"))
01310                                 return REWIND;
01311                         break;
01312                 }
01313                 break;
01314               case 's':
01315                 if (!strcasecmp(atom + 1, "cript"))
01316                         return SCRIPT;
01317                 if (isascii(atom[1]) && 
01318                     tolower((unsigned char)atom[1]) == 'e') {
01319                         if (!strcasecmp(atom + 2, "arch"))
01320                                 return SEARCH;
01321                         if (isascii(atom[2]) && 
01322                             tolower((unsigned char)atom[2]) == 'c') {
01323                                 if (!strncasecmp(atom + 3, "ond", 3)) {
01324                                         if (!strcasecmp(atom + 6, "ary"))
01325                                                 return SECONDARY;
01326                                         if (!strcasecmp(atom + 6, "ary6"))
01327                                                 return SECONDARY6;
01328                                         if (!strcasecmp(atom + 6, "s"))
01329                                                 return SECONDS;
01330                                         break;
01331                                 }
01332                                 if (!strcasecmp(atom + 3, "ret"))
01333                                         return SECRET;
01334                                 break;
01335                         }
01336                         if (!strncasecmp(atom + 2, "lect", 4)) {
01337                                 if (atom[6] == '\0')
01338                                         return SELECT;
01339                                 if (!strcasecmp(atom + 6, "-timeout"))
01340                                         return SELECT_TIMEOUT;
01341                                 break;
01342                         }
01343                         if (!strcasecmp(atom + 2, "nd"))
01344                                 return SEND;
01345                         if (!strncasecmp(atom + 2, "rv", 2)) {
01346                                 if (!strncasecmp(atom + 4, "er", 2)) {
01347                                         if (atom[6] == '\0')
01348                                                 return TOKEN_SERVER;
01349                                         if (atom[6] == '-') {
01350                                                 if (!strcasecmp(atom + 7,
01351                                                                 "duid")) 
01352                                                         return SERVER_DUID;
01353                                                 if (!strcasecmp(atom + 7,
01354                                                                 "name"))
01355                                                         return SERVER_NAME;
01356                                                 if (!strcasecmp(atom + 7,
01357                                                                 "identifier"))
01358                                                       return SERVER_IDENTIFIER;
01359                                                 break;
01360                                         }
01361                                         break;
01362                                 }
01363                                 if (!strcasecmp(atom + 4, "fail"))
01364                                         return NS_SERVFAIL;
01365                                 break;
01366                         }
01367                         if (!strcasecmp(atom + 2, "t"))
01368                                 return TOKEN_SET;
01369                         break;
01370                 }
01371                 if (isascii(atom[1]) && 
01372                     tolower((unsigned char)atom[1]) == 'h') {
01373                         if (!strcasecmp(atom + 2, "ared-network"))
01374                                 return SHARED_NETWORK;
01375                         if (!strcasecmp(atom + 2, "utdown"))
01376                                 return SHUTDOWN;
01377                         break;
01378                 }
01379                 if (isascii(atom[1]) && 
01380                     tolower((unsigned char)atom[1]) == 'i') {
01381                         if (!strcasecmp(atom + 2, "addr"))
01382                                 return SIADDR;
01383                         if (!strcasecmp(atom + 2, "gned"))
01384                                 return SIGNED;
01385                         if (!strcasecmp(atom + 2, "ze"))
01386                                 return SIZE;
01387                         break;
01388                 }
01389                 if (isascii(atom[1]) && 
01390                     tolower((unsigned char)atom[1]) == 'p') {
01391                         if (isascii(atom[2]) && 
01392                             tolower((unsigned char)atom[2]) == 'a') {
01393                                 if (!strcasecmp(atom + 3, "ce"))
01394                                         return SPACE;
01395                                 if (!strcasecmp(atom + 3, "wn"))
01396                                         return SPAWN;
01397                                 break;
01398                         }
01399                         if (!strcasecmp(atom + 2, "lit"))
01400                                 return SPLIT;
01401                         break;
01402                 }
01403                 if (isascii(atom[1]) && 
01404                     tolower((unsigned char)atom[1]) == 't') {
01405                         if (isascii(atom[2]) && 
01406                             tolower((unsigned char)atom[2]) == 'a') {
01407                                 if(!strncasecmp(atom + 3, "rt", 2)) {
01408                                          if (!strcasecmp(atom + 5, "s"))
01409                                                  return STARTS;
01410                                          if (!strcasecmp(atom + 5, "up"))
01411                                                  return STARTUP;
01412                                         break;
01413                                 }
01414                                 if (isascii(atom[3]) &&
01415                                     tolower((unsigned char)atom[3]) == 't') {
01416                                         if (!strcasecmp(atom + 4, "e"))
01417                                                 return STATE;
01418                                         if (!strcasecmp(atom + 4, "ic"))
01419                                                 return STATIC;
01420                                         break;
01421                                 }
01422                         }
01423                         if (!strcasecmp(atom + 2, "ring"))
01424                                 return STRING_TOKEN;
01425                         break;
01426                 }
01427                 if (!strncasecmp(atom + 1, "ub", 2)) {
01428                         if (!strcasecmp(atom + 3, "class"))
01429                                 return SUBCLASS;
01430                         if (!strcasecmp(atom + 3, "net"))
01431                                 return SUBNET;
01432                         if (!strcasecmp(atom + 3, "net6"))
01433                                 return SUBNET6;
01434                         if (!strcasecmp(atom + 3, "string"))
01435                                 return SUBSTRING;
01436                         break;
01437                 }
01438                 if (isascii(atom[1]) && 
01439                     tolower((unsigned char)atom[1]) == 'u') {
01440                         if (!strcasecmp(atom + 2, "ffix"))
01441                                 return SUFFIX;
01442                         if (!strcasecmp(atom + 2, "persede"))
01443                                 return SUPERSEDE;
01444                 }
01445                 if (!strcasecmp(atom + 1, "witch"))
01446                         return SWITCH;
01447                 break;
01448               case 't':
01449                 if (!strcasecmp (atom + 1, "imestamp"))
01450                         return TIMESTAMP;
01451                 if (!strcasecmp (atom + 1, "imeout"))
01452                         return TIMEOUT;
01453                 if (!strcasecmp (atom + 1, "oken-ring"))
01454                         return TOKEN_RING;
01455                 if (!strcasecmp (atom + 1, "ext"))
01456                         return TEXT;
01457                 if (!strcasecmp (atom + 1, "stp"))
01458                         return TSTP;
01459                 if (!strcasecmp (atom + 1, "sfp"))
01460                         return TSFP;
01461                 if (!strcasecmp (atom + 1, "ransmission"))
01462                         return TRANSMISSION;
01463                 if (!strcasecmp(atom + 1, "emporary"))
01464                         return TEMPORARY;
01465                 break;
01466               case 'u':
01467                 if (!strcasecmp (atom + 1, "case"))
01468                         return UCASE;
01469                 if (!strcasecmp (atom + 1, "nset"))
01470                         return UNSET;
01471                 if (!strcasecmp (atom + 1, "nsigned"))
01472                         return UNSIGNED;
01473                 if (!strcasecmp (atom + 1, "id"))
01474                         return UID;
01475                 if (!strncasecmp (atom + 1, "se", 2)) {
01476                         if (!strcasecmp (atom + 3, "r-class"))
01477                                 return USER_CLASS;
01478                         if (!strcasecmp (atom + 3, "-host-decl-names"))
01479                                 return USE_HOST_DECL_NAMES;
01480                         if (!strcasecmp (atom + 3,
01481                                          "-lease-addr-for-default-route"))
01482                                 return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
01483                         break;
01484                 }
01485                 if (!strncasecmp (atom + 1, "nknown", 6)) {
01486                         if (!strcasecmp (atom + 7, "-clients"))
01487                                 return UNKNOWN_CLIENTS;
01488                         if (!strcasecmp (atom + 7, "-state"))
01489                                 return UNKNOWN_STATE;
01490                         if (!atom [7])
01491                                 return UNKNOWN;
01492                         break;
01493                 }
01494                 if (!strcasecmp (atom + 1, "nauthenticated"))
01495                         return UNAUTHENTICATED;
01496                 if (!strcasecmp (atom + 1, "pdate"))
01497                         return UPDATE;
01498                 break;
01499               case 'v':
01500                 if (!strcasecmp (atom + 1, "6relay"))
01501                         return V6RELAY;
01502                 if (!strcasecmp (atom + 1, "6relopt"))
01503                         return V6RELOPT;
01504                 if (!strcasecmp (atom + 1, "endor-class"))
01505                         return VENDOR_CLASS;
01506                 if (!strcasecmp (atom + 1, "endor"))
01507                         return VENDOR;
01508                 break;
01509               case 'w':
01510                 if (!strcasecmp (atom + 1, "ith"))
01511                         return WITH;
01512                 if (!strcasecmp(atom + 1, "idth"))
01513                         return WIDTH;
01514                 break;
01515               case 'y':
01516                 if (!strcasecmp (atom + 1, "iaddr"))
01517                         return YIADDR;
01518                 if (!strcasecmp (atom + 1, "xdomain"))
01519                         return NS_YXDOMAIN;
01520                 if (!strcasecmp (atom + 1, "xrrset"))
01521                         return NS_YXRRSET;
01522                 break;
01523               case 'z':
01524                 if (!strcasecmp (atom + 1, "erolen"))
01525                         return ZEROLEN;
01526                 if (!strcasecmp (atom + 1, "one"))
01527                         return ZONE;
01528                 break;
01529         }
01530         return dfv;
01531 }
01532 

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1