3
Lexical scanner for dhcpd config file... */
6
* Copyright (c) 2004-2008 by Internet Systems Consortium, Inc. ("ISC")
7
* Copyright (c) 1995-2003 by Internet Software Consortium
9
* Permission to use, copy, modify, and distribute this software for any
10
* purpose with or without fee is hereby granted, provided that the above
11
* copyright notice and this permission notice appear in all copies.
13
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
* Internet Systems Consortium, Inc.
23
* Redwood City, CA 94063
27
* This software has been written for Internet Systems Consortium
28
* by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29
* To learn more about Internet Systems Consortium, see
30
* ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31
* see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32
* ``http://www.nominum.com''.
38
static int get_char PROTO ((struct parse *));
39
static void unget_char(struct parse *, int);
40
static void skip_to_eol PROTO ((struct parse *));
41
static enum dhcp_token read_whitespace(int c, struct parse *cfile);
42
static enum dhcp_token read_string PROTO ((struct parse *));
43
static enum dhcp_token read_number PROTO ((int, struct parse *));
44
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
45
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
47
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
55
isc_result_t status = ISC_R_SUCCESS;
58
tmp = dmalloc(sizeof(struct parse), MDL);
60
return (ISC_R_NOMEMORY);
64
* We don't need to initialize things to zero here, since
65
* dmalloc() returns memory that is set to zero.
68
tmp->lpos = tmp -> line = 1;
69
tmp->cur_line = tmp->line1;
70
tmp->prev_line = tmp->line2;
71
tmp->token_line = tmp->cur_line;
72
tmp->cur_line[0] = tmp->prev_line[0] = 0;
74
tmp->eol_token = eolp;
83
if (fstat(file, &sb) < 0) {
84
status = ISC_R_IOERROR;
91
tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
92
tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
95
if (tmp->inbuf == MAP_FAILED) {
96
status = ISC_R_IOERROR;
102
return (ISC_R_SUCCESS);
109
isc_result_t end_parse (cfile)
110
struct parse **cfile;
112
/* "Memory" config files have no file. */
113
if ((*cfile)->file != -1) {
114
munmap((*cfile)->inbuf, (*cfile)->bufsiz);
115
close((*cfile)->file);
118
if ((*cfile)->saved_state != NULL) {
119
dfree((*cfile)->saved_state, MDL);
124
return ISC_R_SUCCESS;
128
* Save the current state of the parser.
130
* Only one state may be saved. Any previous saved state is
134
save_parse_state(struct parse *cfile) {
136
* Free any previous saved state.
138
if (cfile->saved_state != NULL) {
139
dfree(cfile->saved_state, MDL);
143
* Save our current state.
145
cfile->saved_state = dmalloc(sizeof(struct parse), MDL);
146
if (cfile->saved_state == NULL) {
147
return ISC_R_NOMEMORY;
149
memcpy(cfile->saved_state, cfile, sizeof(*cfile));
150
return ISC_R_SUCCESS;
154
* Return the parser to the previous saved state.
156
* You must call save_parse_state() before calling
157
* restore_parse_state(), but you can call restore_parse_state() any
158
* number of times after that.
161
restore_parse_state(struct parse *cfile) {
162
struct parse *saved_state;
164
if (cfile->saved_state == NULL) {
168
saved_state = cfile->saved_state;
169
memcpy(cfile, saved_state, sizeof(*cfile));
170
cfile->saved_state = saved_state;
171
return ISC_R_SUCCESS;
174
static int get_char (cfile)
177
/* My kingdom for WITH... */
180
if (cfile->bufix == cfile->buflen)
183
c = cfile->inbuf [cfile->bufix];
187
if (!cfile->ugflag) {
189
if (cfile->cur_line == cfile->line1) {
190
cfile->cur_line = cfile->line2;
191
cfile->prev_line = cfile->line1;
193
cfile->cur_line = cfile->line1;
194
cfile->prev_line = cfile->line2;
198
cfile->cur_line [0] = 0;
199
} else if (c != EOF) {
200
if (cfile->lpos <= 80) {
201
cfile->cur_line [cfile->lpos - 1] = c;
202
cfile->cur_line [cfile->lpos] = 0;
212
* Return a character to our input buffer.
215
unget_char(struct parse *cfile, int c) {
218
cfile->ugflag = 1; /* do not put characters into
219
our error buffer on the next
220
call to get_char() */
225
* GENERAL NOTE ABOUT TOKENS
227
* We normally only want non-whitespace tokens. There are some
228
* circumstances where we *do* want to see whitespace (for example
229
* when parsing IPv6 addresses).
231
* Generally we use the next_token() function to read tokens. This
232
* in turn calls get_next_token, which does *not* return tokens for
233
* whitespace. Rather, it skips these.
235
* When we need to see whitespace, we us next_raw_token(), which also
236
* returns the WHITESPACE token.
238
* The peek_token() and peek_raw_token() functions work as expected.
240
* Warning: if you invoke peek_token(), then if there is a whitespace
241
* token, it will be lost, and subsequent use of next_raw_token() or
242
* peek_raw_token() will NOT see it.
245
static enum dhcp_token
246
get_raw_token(struct parse *cfile) {
248
enum dhcp_token ttok;
256
c = get_char (cfile);
257
if (!((c == '\n') && cfile->eol_token) &&
258
isascii(c) && isspace(c)) {
259
ttok = read_whitespace(c, cfile);
267
cfile -> lexline = l;
268
cfile -> lexchar = p;
269
ttok = read_string (cfile);
272
if ((isascii (c) && isdigit (c)) || c == '-') {
273
cfile -> lexline = l;
274
cfile -> lexchar = p;
275
ttok = read_number (c, cfile);
277
} else if (isascii (c) && isalpha (c)) {
278
cfile -> lexline = l;
279
cfile -> lexchar = p;
280
ttok = read_num_or_name (c, cfile);
282
} else if (c == EOF) {
287
cfile -> lexline = l;
288
cfile -> lexchar = p;
301
* The get_next_token() function consumes the next token and
302
* returns it to the caller.
304
* Since the code is almost the same for "normal" and "raw"
305
* input, we pass a flag to alter the way it works.
308
static enum dhcp_token
309
get_next_token(const char **rval, unsigned *rlen,
310
struct parse *cfile, isc_boolean_t raw) {
313
if (cfile -> token) {
314
if (cfile -> lexline != cfile -> tline)
315
cfile -> token_line = cfile -> cur_line;
316
cfile -> lexchar = cfile -> tlpos;
317
cfile -> lexline = cfile -> tline;
321
rv = get_raw_token(cfile);
322
cfile -> token_line = cfile -> cur_line;
326
while (rv == WHITESPACE) {
327
rv = get_raw_token(cfile);
328
cfile->token_line = cfile->cur_line;
333
*rval = cfile -> tval;
335
*rlen = cfile -> tlen;
337
fprintf (stderr, "%s:%d ", cfile -> tval, rv);
344
* Get the next token from cfile and return it.
346
* If rval is non-NULL, set the pointer it contains to
347
* the contents of the token.
349
* If rlen is non-NULL, set the integer it contains to
350
* the length of the token.
354
next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
355
return get_next_token(rval, rlen, cfile, ISC_FALSE);
360
* The same as the next_token() function above, but will return space
361
* as the WHITESPACE token.
365
next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
366
return get_next_token(rval, rlen, cfile, ISC_TRUE);
371
* The do_peek_token() function checks the next token without
372
* consuming it, and returns it to the caller.
374
* Since the code is almost the same for "normal" and "raw"
375
* input, we pass a flag to alter the way it works. (See the
376
* warning in the GENERAL NOTES ABOUT TOKENS above though.)
380
do_peek_token(const char **rval, unsigned int *rlen,
381
struct parse *cfile, isc_boolean_t raw) {
384
if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
385
cfile -> tlpos = cfile -> lexchar;
386
cfile -> tline = cfile -> lexline;
389
cfile->token = get_raw_token(cfile);
390
} while (!raw && (cfile->token == WHITESPACE));
392
if (cfile -> lexline != cfile -> tline)
393
cfile -> token_line = cfile -> prev_line;
395
x = cfile -> lexchar;
396
cfile -> lexchar = cfile -> tlpos;
399
x = cfile -> lexline;
400
cfile -> lexline = cfile -> tline;
404
*rval = cfile -> tval;
406
*rlen = cfile -> tlen;
408
fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
410
return cfile -> token;
415
* Get the next token from cfile and return it, leaving it for a
416
* subsequent call to next_token().
418
* Note that it WILL consume whitespace tokens.
420
* If rval is non-NULL, set the pointer it contains to
421
* the contents of the token.
423
* If rlen is non-NULL, set the integer it contains to
424
* the length of the token.
428
peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
429
return do_peek_token(rval, rlen, cfile, ISC_FALSE);
434
* The same as the peek_token() function above, but will return space
435
* as the WHITESPACE token.
439
peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
440
return do_peek_token(rval, rlen, cfile, ISC_TRUE);
443
static void skip_to_eol (cfile)
448
c = get_char (cfile);
457
static enum dhcp_token
458
read_whitespace(int c, struct parse *cfile) {
462
* Read as much whitespace as we have available.
466
cfile->tokbuf[ofs++] = c;
468
} while (!((c == '\n') && cfile->eol_token) &&
469
isascii(c) && isspace(c));
472
* Put the last (non-whitespace) character back.
474
unget_char(cfile, c);
479
cfile->tokbuf[ofs] = '\0';
481
cfile->tval = cfile->tokbuf;
485
static enum dhcp_token read_string (cfile)
494
for (i = 0; i < sizeof cfile -> tokbuf; i++) {
496
c = get_char (cfile);
498
parse_warn (cfile, "eof in string constant");
504
cfile -> tokbuf [i] = '\t';
507
cfile -> tokbuf [i] = '\r';
510
cfile -> tokbuf [i] = '\n';
513
cfile -> tokbuf [i] = '\b';
529
cfile -> tokbuf [i] = c;
536
if (c >= '0' && c <= '9') {
537
value = value * 16 + (c - '0');
538
} else if (c >= 'a' && c <= 'f') {
539
value = value * 16 + (c - 'a' + 10);
540
} else if (c >= 'A' && c <= 'F') {
541
value = value * 16 + (c - 'A' + 10);
544
"invalid hex digit: %x",
550
cfile -> tokbuf [i] = value;
555
if (c >= '0' && c <= '7') {
556
value = value * 8 + (c - '0');
560
"invalid octal digit %x",
564
cfile -> tokbuf [i] = 0;
568
cfile -> tokbuf [i] = value;
573
} else if (c == '\\') {
579
cfile -> tokbuf [i] = c;
581
/* Normally, I'd feel guilty about this, but we're talking about
582
strings that'll fit in a DHCP packet here... */
583
if (i == sizeof cfile -> tokbuf) {
585
"string constant larger than internal buffer");
588
cfile -> tokbuf [i] = 0;
590
cfile -> tval = cfile -> tokbuf;
594
static enum dhcp_token read_number (c, cfile)
601
cfile -> tokbuf [i++] = c;
602
for (; i < sizeof cfile -> tokbuf; i++) {
603
c = get_char (cfile);
605
/* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
606
* Except in the case of '0x' syntax hex, which gets called
607
* a NAME at '0x', and returned to NUMBER_OR_NAME once it's
608
* verified to be at least 0xf or less.
610
switch(isascii(c) ? token : BREAK) {
617
token = NUMBER_OR_NAME;
622
if((i == 2) && isxdigit(c) &&
623
(cfile->tokbuf[0] == '0') &&
624
((cfile->tokbuf[1] == 'x') ||
625
(cfile->tokbuf[1] == 'X'))) {
626
token = NUMBER_OR_NAME;
628
} else if(((c == '-') || (c == '_') || isalnum(c))) {
634
/* At this point c is either EOF or part of the next
635
* token. If not EOF, rewind the file one byte so
636
* the next token is read from there.
638
unget_char(cfile, c);
642
log_fatal("read_number():%s:%d: impossible case", MDL);
645
cfile -> tokbuf [i] = c;
648
if (i == sizeof cfile -> tokbuf) {
650
"numeric token larger than internal buffer");
655
cfile -> tokbuf [i] = 0;
657
cfile -> tval = cfile -> tokbuf;
660
* If this entire token from start to finish was "-", such as
661
* the middle parameter in "42 - 7", return just the MINUS token.
663
if ((i == 1) && (cfile->tokbuf[i] == '-'))
669
static enum dhcp_token read_num_or_name (c, cfile)
674
enum dhcp_token rv = NUMBER_OR_NAME;
675
cfile -> tokbuf [i++] = c;
676
for (; i < sizeof cfile -> tokbuf; i++) {
677
c = get_char (cfile);
679
(c != '-' && c != '_' && !isalnum (c))) {
680
unget_char(cfile, c);
685
cfile -> tokbuf [i] = c;
687
if (i == sizeof cfile -> tokbuf) {
688
parse_warn (cfile, "token larger than internal buffer");
691
cfile -> tokbuf [i] = 0;
693
cfile -> tval = cfile -> tokbuf;
694
return intern(cfile->tval, rv);
697
static enum dhcp_token
698
intern(char *atom, enum dhcp_token dfv) {
699
if (!isascii(atom[0]))
702
switch (tolower((unsigned char)atom[0])) {
709
if (!strncasecmp (atom + 1, "uth", 3)) {
710
if (!strncasecmp (atom + 3, "uthenticat", 10)) {
711
if (!strcasecmp (atom + 13, "ed"))
712
return AUTHENTICATED;
713
if (!strcasecmp (atom + 13, "ion"))
714
return AUTHENTICATION;
717
if (!strcasecmp (atom + 1, "uthoritative"))
718
return AUTHORITATIVE;
721
if (!strcasecmp (atom + 1, "nd"))
723
if (!strcasecmp (atom + 1, "ppend"))
725
if (!strcasecmp (atom + 1, "llow"))
727
if (!strcasecmp (atom + 1, "lias"))
729
if (!strcasecmp (atom + 1, "lgorithm"))
731
if (!strcasecmp (atom + 1, "lso"))
733
if (!strcasecmp (atom + 1, "bandoned"))
734
return TOKEN_ABANDONED;
735
if (!strcasecmp (atom + 1, "dd"))
737
if (!strcasecmp (atom + 1, "ll"))
739
if (!strcasecmp (atom + 1, "t"))
741
if (!strcasecmp (atom + 1, "rray"))
743
if (!strcasecmp (atom + 1, "ddress"))
745
if (!strcasecmp (atom + 1, "ctive"))
747
if (!strcasecmp (atom + 1, "tsfp"))
749
if (!strcasecmp (atom + 1, "fter"))
753
if (!strcasecmp (atom + 1, "ackup"))
755
if (!strcasecmp (atom + 1, "ootp"))
757
if (!strcasecmp (atom + 1, "inding"))
759
if (!strcasecmp (atom + 1, "inary-to-ascii"))
760
return BINARY_TO_ASCII;
761
if (!strcasecmp (atom + 1, "ackoff-cutoff"))
762
return BACKOFF_CUTOFF;
763
if (!strcasecmp (atom + 1, "ooting"))
765
if (!strcasecmp (atom + 1, "oot-unknown-clients"))
766
return BOOT_UNKNOWN_CLIENTS;
767
if (!strcasecmp (atom + 1, "reak"))
769
if (!strcasecmp (atom + 1, "illing"))
771
if (!strcasecmp (atom + 1, "oolean"))
773
if (!strcasecmp (atom + 1, "alance"))
775
if (!strcasecmp (atom + 1, "ound"))
779
if (!strcasecmp (atom + 1, "ase"))
781
if (!strcasecmp (atom + 1, "ommit"))
783
if (!strcasecmp (atom + 1, "ode"))
785
if (!strcasecmp (atom + 1, "onfig-option"))
786
return CONFIG_OPTION;
787
if (!strcasecmp (atom + 1, "heck"))
789
if (!strcasecmp (atom + 1, "lass"))
791
if (!strcasecmp (atom + 1, "lose"))
793
if (!strcasecmp(atom + 1, "ompressed"))
795
if (!strcasecmp (atom + 1, "reate"))
797
if (!strcasecmp (atom + 1, "iaddr"))
799
if (!strncasecmp (atom + 1, "lient", 5)) {
800
if (!strcasecmp (atom + 6, "-identifier"))
801
return CLIENT_IDENTIFIER;
802
if (!strcasecmp (atom + 6, "-hostname"))
803
return CLIENT_HOSTNAME;
804
if (!strcasecmp (atom + 6, "-state"))
806
if (!strcasecmp (atom + 6, "-updates"))
807
return CLIENT_UPDATES;
808
if (!strcasecmp (atom + 6, "s"))
811
if (!strcasecmp (atom + 1, "oncat"))
813
if (!strcasecmp (atom + 1, "onnect"))
815
if (!strcasecmp (atom + 1, "ommunications-interrupted"))
816
return COMMUNICATIONS_INTERRUPTED;
817
if (!strcasecmp (atom + 1, "ltt"))
821
if (!strcasecmp(atom + 1, "b-time-format"))
822
return DB_TIME_FORMAT;
823
if (!strcasecmp (atom + 1, "ns-update"))
825
if (!strcasecmp (atom + 1, "ns-delete"))
827
if (!strcasecmp (atom + 1, "omain"))
829
if (!strncasecmp (atom + 1, "omain-", 6)) {
830
if (!strcasecmp(atom + 7, "name"))
832
if (!strcasecmp(atom + 7, "list"))
835
if (!strcasecmp (atom + 1, "o-forward-update"))
836
return DO_FORWARD_UPDATE;
837
if (!strcasecmp (atom + 1, "ebug"))
839
if (!strcasecmp (atom + 1, "eny"))
841
if (!strcasecmp (atom + 1, "eleted"))
842
return TOKEN_DELETED;
843
if (!strcasecmp (atom + 1, "elete"))
845
if (!strncasecmp (atom + 1, "efault", 6)) {
848
if (!strcasecmp(atom + 7, "-duid"))
850
if (!strcasecmp (atom + 7, "-lease-time"))
851
return DEFAULT_LEASE_TIME;
854
if (!strncasecmp (atom + 1, "ynamic", 6)) {
857
if (!strncasecmp (atom + 7, "-bootp", 6)) {
859
return DYNAMIC_BOOTP;
860
if (!strcasecmp (atom + 13, "-lease-cutoff"))
861
return DYNAMIC_BOOTP_LEASE_CUTOFF;
862
if (!strcasecmp (atom + 13, "-lease-length"))
863
return DYNAMIC_BOOTP_LEASE_LENGTH;
867
if (!strcasecmp (atom + 1, "uplicates"))
869
if (!strcasecmp (atom + 1, "eclines"))
871
if (!strncasecmp (atom + 1, "efine", 5)) {
872
if (!strcasecmp (atom + 6, "d"))
879
if (isascii (atom [1]) &&
880
tolower((unsigned char)atom[1]) == 'x') {
881
if (!strcasecmp (atom + 2, "tract-int"))
883
if (!strcasecmp (atom + 2, "ists"))
885
if (!strcasecmp (atom + 2, "piry"))
887
if (!strcasecmp (atom + 2, "pire"))
889
if (!strcasecmp (atom + 2, "pired"))
890
return TOKEN_EXPIRED;
892
if (!strcasecmp (atom + 1, "ncode-int"))
894
if (!strcasecmp(atom + 1, "poch"))
896
if (!strcasecmp (atom + 1, "thernet"))
898
if (!strcasecmp (atom + 1, "nds"))
900
if (!strncasecmp (atom + 1, "ls", 2)) {
901
if (!strcasecmp (atom + 3, "e"))
903
if (!strcasecmp (atom + 3, "if"))
907
if (!strcasecmp (atom + 1, "rror"))
909
if (!strcasecmp (atom + 1, "val"))
911
if (!strcasecmp (atom + 1, "ncapsulate"))
913
if (!strcasecmp(atom + 1, "xecute"))
915
if (!strcasecmp(atom+1, "n")) {
920
if (!strcasecmp (atom + 1, "atal"))
922
if (!strcasecmp (atom + 1, "ilename"))
924
if (!strcasecmp (atom + 1, "ixed-address"))
926
if (!strcasecmp (atom + 1, "ixed-address6"))
928
if (!strcasecmp (atom + 1, "ixed-prefix6"))
929
return FIXED_PREFIX6;
930
if (!strcasecmp (atom + 1, "ddi"))
932
if (!strcasecmp (atom + 1, "ormerr"))
934
if (!strcasecmp (atom + 1, "unction"))
936
if (!strcasecmp (atom + 1, "ailover"))
938
if (!strcasecmp (atom + 1, "ree"))
942
if (!strcasecmp (atom + 1, "iaddr"))
944
if (!strcasecmp (atom + 1, "roup"))
946
if (!strcasecmp (atom + 1, "et-lease-hostnames"))
947
return GET_LEASE_HOSTNAMES;
950
if (!strcasecmp(atom + 1, "ash"))
952
if (!strcasecmp (atom + 1, "ba"))
954
if (!strcasecmp (atom + 1, "ost"))
956
if (!strcasecmp (atom + 1, "ost-decl-name"))
957
return HOST_DECL_NAME;
958
if (!strcasecmp(atom + 1, "ost-identifier"))
959
return HOST_IDENTIFIER;
960
if (!strcasecmp (atom + 1, "ardware"))
962
if (!strcasecmp (atom + 1, "ostname"))
964
if (!strcasecmp (atom + 1, "elp"))
968
if (!strcasecmp(atom+1, "a-na"))
970
if (!strcasecmp(atom+1, "a-ta"))
972
if (!strcasecmp(atom+1, "a-pd"))
974
if (!strcasecmp(atom+1, "aaddr"))
976
if (!strcasecmp(atom+1, "aprefix"))
978
if (!strcasecmp (atom + 1, "nclude"))
980
if (!strcasecmp (atom + 1, "nteger"))
982
if (!strcasecmp (atom + 1, "nfinite"))
984
if (!strcasecmp (atom + 1, "nfo"))
986
if (!strcasecmp (atom + 1, "p-address"))
988
if (!strcasecmp (atom + 1, "p6-address"))
990
if (!strcasecmp (atom + 1, "nitial-interval"))
991
return INITIAL_INTERVAL;
992
if (!strcasecmp (atom + 1, "nterface"))
994
if (!strcasecmp (atom + 1, "dentifier"))
996
if (!strcasecmp (atom + 1, "f"))
998
if (!strcasecmp (atom + 1, "s"))
1000
if (!strcasecmp (atom + 1, "gnore"))
1004
if (!strncasecmp (atom + 1, "nown", 4)) {
1005
if (!strcasecmp (atom + 5, "-clients"))
1006
return KNOWN_CLIENTS;
1011
if (!strcasecmp (atom + 1, "ey"))
1015
if (!strcasecmp (atom + 1, "case"))
1017
if (!strcasecmp (atom + 1, "ease"))
1019
if (!strcasecmp(atom + 1, "ease6"))
1021
if (!strcasecmp (atom + 1, "eased-address"))
1022
return LEASED_ADDRESS;
1023
if (!strcasecmp (atom + 1, "ease-time"))
1025
if (!strcasecmp(atom + 1, "easequery"))
1027
if (!strcasecmp(atom + 1, "ength"))
1029
if (!strcasecmp (atom + 1, "imit"))
1031
if (!strcasecmp (atom + 1, "et"))
1033
if (!strcasecmp (atom + 1, "oad"))
1035
if (!strcasecmp(atom + 1, "ocal"))
1037
if (!strcasecmp (atom + 1, "og"))
1039
if (!strcasecmp(atom+1, "lt")) {
1042
if (!strcasecmp(atom+1, "l")) {
1047
if (!strncasecmp (atom + 1, "ax", 2)) {
1050
if (!strcasecmp (atom + 3, "-balance"))
1052
if (!strncasecmp (atom + 3, "-lease-", 7)) {
1053
if (!strcasecmp(atom + 10, "misbalance"))
1054
return MAX_LEASE_MISBALANCE;
1055
if (!strcasecmp(atom + 10, "ownership"))
1056
return MAX_LEASE_OWNERSHIP;
1057
if (!strcasecmp(atom + 10, "time"))
1058
return MAX_LEASE_TIME;
1060
if (!strcasecmp(atom + 3, "-life"))
1062
if (!strcasecmp (atom + 3, "-transmit-idle"))
1063
return MAX_TRANSMIT_IDLE;
1064
if (!strcasecmp (atom + 3, "-response-delay"))
1065
return MAX_RESPONSE_DELAY;
1066
if (!strcasecmp (atom + 3, "-unacked-updates"))
1067
return MAX_UNACKED_UPDATES;
1069
if (!strncasecmp (atom + 1, "in-", 3)) {
1070
if (!strcasecmp (atom + 4, "balance"))
1072
if (!strcasecmp (atom + 4, "lease-time"))
1073
return MIN_LEASE_TIME;
1074
if (!strcasecmp (atom + 4, "secs"))
1078
if (!strncasecmp (atom + 1, "edi", 3)) {
1079
if (!strcasecmp (atom + 4, "a"))
1081
if (!strcasecmp (atom + 4, "um"))
1085
if (!strcasecmp (atom + 1, "atch"))
1087
if (!strcasecmp (atom + 1, "embers"))
1089
if (!strcasecmp (atom + 1, "y"))
1091
if (!strcasecmp (atom + 1, "clt"))
1095
if (!strcasecmp (atom + 1, "ormal"))
1097
if (!strcasecmp (atom + 1, "ameserver"))
1099
if (!strcasecmp (atom + 1, "etmask"))
1101
if (!strcasecmp (atom + 1, "ever"))
1103
if (!strcasecmp (atom + 1, "ext-server"))
1105
if (!strcasecmp (atom + 1, "ot"))
1107
if (!strcasecmp (atom + 1, "o"))
1109
if (!strcasecmp (atom + 1, "s-update"))
1111
if (!strcasecmp (atom + 1, "oerror"))
1113
if (!strcasecmp (atom + 1, "otauth"))
1115
if (!strcasecmp (atom + 1, "otimp"))
1117
if (!strcasecmp (atom + 1, "otzone"))
1119
if (!strcasecmp (atom + 1, "xdomain"))
1121
if (!strcasecmp (atom + 1, "xrrset"))
1123
if (!strcasecmp (atom + 1, "ull"))
1125
if (!strcasecmp (atom + 1, "ext"))
1127
if (!strcasecmp (atom + 1, "ew"))
1131
if (!strcasecmp (atom + 1, "mapi"))
1133
if (!strcasecmp (atom + 1, "r"))
1135
if (!strcasecmp (atom + 1, "n"))
1137
if (!strcasecmp (atom + 1, "pen"))
1139
if (!strcasecmp (atom + 1, "ption"))
1141
if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1142
return ONE_LEASE_PER_CLIENT;
1143
if (!strcasecmp (atom + 1, "f"))
1145
if (!strcasecmp (atom + 1, "wner"))
1149
if (!strcasecmp (atom + 1, "repend"))
1151
if (!strcasecmp(atom + 1, "referred-life"))
1152
return PREFERRED_LIFE;
1153
if (!strcasecmp (atom + 1, "acket"))
1155
if (!strcasecmp (atom + 1, "ool"))
1157
if (!strcasecmp (atom + 1, "refix6"))
1159
if (!strcasecmp (atom + 1, "seudo"))
1161
if (!strcasecmp (atom + 1, "eer"))
1163
if (!strcasecmp (atom + 1, "rimary"))
1165
if (!strncasecmp (atom + 1, "artner", 6)) {
1168
if (!strcasecmp (atom + 7, "-down"))
1169
return PARTNER_DOWN;
1171
if (!strcasecmp (atom + 1, "ort"))
1173
if (!strcasecmp (atom + 1, "otential-conflict"))
1174
return POTENTIAL_CONFLICT;
1175
if (!strcasecmp (atom + 1, "ick-first-value") ||
1176
!strcasecmp (atom + 1, "ick"))
1178
if (!strcasecmp (atom + 1, "aused"))
1182
if (!strcasecmp (atom + 1, "esolution-interrupted"))
1183
return RESOLUTION_INTERRUPTED;
1184
if (!strcasecmp (atom + 1, "ange"))
1186
if (!strcasecmp(atom + 1, "ange6")) {
1189
if (!strcasecmp (atom + 1, "ecover"))
1191
if (!strcasecmp (atom + 1, "ecover-done"))
1192
return RECOVER_DONE;
1193
if (!strcasecmp (atom + 1, "ecover-wait"))
1194
return RECOVER_WAIT;
1195
if (!strcasecmp (atom + 1, "econtact-interval"))
1196
return RECONTACT_INTERVAL;
1197
if (!strcasecmp (atom + 1, "equest"))
1199
if (!strcasecmp (atom + 1, "equire"))
1201
if (!strcasecmp (atom + 1, "equire"))
1203
if (!strcasecmp (atom + 1, "etry"))
1205
if (!strcasecmp (atom + 1, "eturn"))
1207
if (!strcasecmp (atom + 1, "enew"))
1209
if (!strcasecmp (atom + 1, "ebind"))
1211
if (!strcasecmp (atom + 1, "eboot"))
1213
if (!strcasecmp (atom + 1, "eject"))
1215
if (!strcasecmp (atom + 1, "everse"))
1217
if (!strcasecmp (atom + 1, "elease"))
1219
if (!strcasecmp (atom + 1, "efused"))
1221
if (!strcasecmp (atom + 1, "eleased"))
1222
return TOKEN_RELEASED;
1223
if (!strcasecmp (atom + 1, "eset"))
1225
if (!strcasecmp (atom + 1, "eserved"))
1226
return TOKEN_RESERVED;
1227
if (!strcasecmp (atom + 1, "emove"))
1229
if (!strcasecmp (atom + 1, "efresh"))
1233
if (!strcasecmp(atom + 1, "cript"))
1235
if (isascii(atom[1]) &&
1236
tolower((unsigned char)atom[1]) == 'e') {
1237
if (!strcasecmp(atom + 2, "arch"))
1239
if (isascii(atom[2]) &&
1240
tolower((unsigned char)atom[2]) == 'c') {
1241
if (!strncasecmp(atom + 3, "ond", 3)) {
1242
if (!strcasecmp(atom + 6, "ary"))
1244
if (!strcasecmp(atom + 6, "s"))
1248
if (!strcasecmp(atom + 3, "ret"))
1252
if (!strncasecmp(atom + 2, "lect", 4)) {
1253
if (atom[6] == '\0')
1255
if (!strcasecmp(atom + 6, "-timeout"))
1256
return SELECT_TIMEOUT;
1259
if (!strcasecmp(atom + 2, "nd"))
1261
if (!strncasecmp(atom + 2, "rv", 2)) {
1262
if (!strncasecmp(atom + 4, "er", 2)) {
1263
if (atom[6] == '\0')
1264
return TOKEN_SERVER;
1265
if (atom[6] == '-') {
1266
if (!strcasecmp(atom + 7,
1269
if (!strcasecmp(atom + 7,
1272
if (!strcasecmp(atom + 7,
1274
return SERVER_IDENTIFIER;
1279
if (!strcasecmp(atom + 4, "fail"))
1283
if (!strcasecmp(atom + 2, "t"))
1287
if (isascii(atom[1]) &&
1288
tolower((unsigned char)atom[1]) == 'h') {
1289
if (!strcasecmp(atom + 2, "ared-network"))
1290
return SHARED_NETWORK;
1291
if (!strcasecmp(atom + 2, "utdown"))
1295
if (isascii(atom[1]) &&
1296
tolower((unsigned char)atom[1]) == 'i') {
1297
if (!strcasecmp(atom + 2, "addr"))
1299
if (!strcasecmp(atom + 2, "gned"))
1301
if (!strcasecmp(atom + 2, "ze"))
1305
if (isascii(atom[1]) &&
1306
tolower((unsigned char)atom[1]) == 'p') {
1307
if (isascii(atom[2]) &&
1308
tolower((unsigned char)atom[2]) == 'a') {
1309
if (!strcasecmp(atom + 3, "ce"))
1311
if (!strcasecmp(atom + 3, "wn"))
1315
if (!strcasecmp(atom + 2, "lit"))
1319
if (isascii(atom[1]) &&
1320
tolower((unsigned char)atom[1]) == 't') {
1321
if (isascii(atom[2]) &&
1322
tolower((unsigned char)atom[2]) == 'a') {
1323
if(!strncasecmp(atom + 3, "rt", 2)) {
1324
if (!strcasecmp(atom + 5, "s"))
1326
if (!strcasecmp(atom + 5, "up"))
1330
if (isascii(atom[3]) &&
1331
tolower((unsigned char)atom[3]) == 't') {
1332
if (!strcasecmp(atom + 4, "e"))
1334
if (!strcasecmp(atom + 4, "ic"))
1339
if (!strcasecmp(atom + 2, "ring"))
1340
return STRING_TOKEN;
1343
if (!strncasecmp(atom + 1, "ub", 2)) {
1344
if (!strcasecmp(atom + 3, "class"))
1346
if (!strcasecmp(atom + 3, "net"))
1348
if (!strcasecmp(atom + 3, "net6"))
1350
if (!strcasecmp(atom + 3, "string"))
1354
if (isascii(atom[1]) &&
1355
tolower((unsigned char)atom[1]) == 'u') {
1356
if (!strcasecmp(atom + 2, "ffix"))
1358
if (!strcasecmp(atom + 2, "persede"))
1361
if (!strcasecmp(atom + 1, "witch"))
1365
if (!strcasecmp (atom + 1, "imestamp"))
1367
if (!strcasecmp (atom + 1, "imeout"))
1369
if (!strcasecmp (atom + 1, "oken-ring"))
1371
if (!strcasecmp (atom + 1, "ext"))
1373
if (!strcasecmp (atom + 1, "stp"))
1375
if (!strcasecmp (atom + 1, "sfp"))
1377
if (!strcasecmp (atom + 1, "ransmission"))
1378
return TRANSMISSION;
1379
if (!strcasecmp(atom + 1, "emporary"))
1383
if (!strcasecmp (atom + 1, "case"))
1385
if (!strcasecmp (atom + 1, "nset"))
1387
if (!strcasecmp (atom + 1, "nsigned"))
1389
if (!strcasecmp (atom + 1, "id"))
1391
if (!strncasecmp (atom + 1, "se", 2)) {
1392
if (!strcasecmp (atom + 3, "r-class"))
1394
if (!strcasecmp (atom + 3, "-host-decl-names"))
1395
return USE_HOST_DECL_NAMES;
1396
if (!strcasecmp (atom + 3,
1397
"-lease-addr-for-default-route"))
1398
return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1401
if (!strncasecmp (atom + 1, "nknown", 6)) {
1402
if (!strcasecmp (atom + 7, "-clients"))
1403
return UNKNOWN_CLIENTS;
1404
if (!strcasecmp (atom + 7, "-state"))
1405
return UNKNOWN_STATE;
1410
if (!strcasecmp (atom + 1, "nauthenticated"))
1411
return UNAUTHENTICATED;
1412
if (!strcasecmp (atom + 1, "pdated-dns-rr"))
1413
return UPDATED_DNS_RR;
1414
if (!strcasecmp (atom + 1, "pdate"))
1418
if (!strcasecmp (atom + 1, "endor-class"))
1419
return VENDOR_CLASS;
1420
if (!strcasecmp (atom + 1, "endor"))
1424
if (!strcasecmp (atom + 1, "ith"))
1426
if (!strcasecmp(atom + 1, "idth"))
1430
if (!strcasecmp (atom + 1, "iaddr"))
1432
if (!strcasecmp (atom + 1, "xdomain"))
1434
if (!strcasecmp (atom + 1, "xrrset"))
1438
if (!strcasecmp (atom + 1, "erolen"))
1440
if (!strcasecmp (atom + 1, "one"))