2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00
isc-dhcp/common/conflex.c

1415 lines
37 KiB
C
Raw Normal View History

1995-11-29 07:40:04 +00:00
/* conflex.c
Lexical scanner for dhcpd config file... */
/*
2007-05-19 19:16:28 +00:00
* Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
1995-11-29 07:40:04 +00:00
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
1995-11-29 07:40:04 +00:00
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1995-11-29 07:40:04 +00:00
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
* http://www.isc.org/
2000-03-17 04:00:32 +00:00
*
* This software has been written for Internet Systems Consortium
2000-03-17 04:00:32 +00:00
* by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
* To learn more about Internet Systems Consortium, see
2000-03-17 04:00:32 +00:00
* ``http://www.isc.org/''. To learn more about Vixie Enterprises,
* see ``http://www.vix.com''. To learn more about Nominum, Inc., see
* ``http://www.nominum.com''.
1995-11-29 07:40:04 +00:00
*/
#include "dhcpd.h"
#include <ctype.h>
static int get_char PROTO ((struct parse *));
static void skip_to_eol PROTO ((struct parse *));
static enum dhcp_token read_whitespace(int c, struct parse *cfile);
static enum dhcp_token read_string PROTO ((struct parse *));
static enum dhcp_token read_number PROTO ((int, struct parse *));
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
1995-11-29 07:40:04 +00:00
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
struct parse **cfile;
int file;
char *inbuf;
unsigned buflen;
const char *name;
int eolp;
{
struct parse *tmp;
tmp = dmalloc(sizeof(struct parse), MDL);
if (tmp == NULL) {
return ISC_R_NOMEMORY;
}
/*
* We don't need to initialize things to zero here, since
* dmalloc() returns memory that is set to zero.
*/
/* tmp->token = 0; */
/* tmp->warnings_occurred = 0; */
/* tmp->bufix = 0; */
/* tmp->saved_state = NULL; */
tmp->tlname = name;
tmp->lpos = tmp -> line = 1;
tmp->cur_line = tmp->line1;
tmp->prev_line = tmp->line2;
tmp->token_line = tmp->cur_line;
tmp->cur_line[0] = tmp->prev_line[0] = 0;
tmp->file = file;
tmp->eol_token = eolp;
if (inbuf != NULL) {
tmp->inbuf = inbuf;
tmp->buflen = buflen;
tmp->bufsiz = 0;
} else {
struct stat sb;
if (fstat(file, &sb) < 0)
return ISC_R_IOERROR;
tmp->bufsiz = tmp->buflen = (size_t)sb.st_size;
tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
file, 0);
if (tmp->inbuf == MAP_FAILED) {
return ISC_R_IOERROR;
}
}
*cfile = tmp;
return ISC_R_SUCCESS;
}
isc_result_t end_parse (cfile)
struct parse **cfile;
{
/* "Memory" config files have no file. */
if ((*cfile)->file != -1) {
munmap((*cfile)->inbuf, (*cfile)->bufsiz);
close((*cfile)->file);
}
if ((*cfile)->saved_state != NULL) {
dfree((*cfile)->saved_state, MDL);
}
dfree(*cfile, MDL);
*cfile = NULL;
return ISC_R_SUCCESS;
}
/*
* Save the current state of the parser.
*
* Only one state may be saved. Any previous saved state is
* lost.
*/
isc_result_t
save_parse_state(struct parse *cfile) {
/*
* Free any previous saved state.
*/
if (cfile->saved_state != NULL) {
dfree(cfile->saved_state, MDL);
}
/*
* Save our current state.
*/
cfile->saved_state = dmalloc(sizeof(struct parse), MDL);
if (cfile->saved_state == NULL) {
return ISC_R_NOMEMORY;
}
memcpy(cfile->saved_state, cfile, sizeof(*cfile));
return ISC_R_SUCCESS;
}
/*
* Return the parser to the previous saved state.
*
* You must call save_parse_state() before calling
* restore_parse_state(), but you can call restore_parse_state() any
* number of times after that.
*/
isc_result_t
restore_parse_state(struct parse *cfile) {
struct parse *saved_state;
if (cfile->saved_state == NULL) {
return ISC_R_NOTYET;
}
saved_state = cfile->saved_state;
memcpy(cfile, saved_state, sizeof(*cfile));
cfile->saved_state = saved_state;
return ISC_R_SUCCESS;
}
1995-11-29 07:40:04 +00:00
static int get_char (cfile)
struct parse *cfile;
1995-11-29 07:40:04 +00:00
{
/* My kingdom for WITH... */
int c;
if (cfile->bufix == cfile->buflen)
c = EOF;
else {
c = cfile->inbuf [cfile->bufix];
cfile->bufix++;
}
if (!cfile->ugflag) {
1995-11-29 07:40:04 +00:00
if (c == EOL) {
if (cfile->cur_line == cfile->line1) {
cfile->cur_line = cfile->line2;
cfile->prev_line = cfile->line1;
} else {
cfile->cur_line = cfile->line1;
cfile->prev_line = cfile->line2;
}
cfile->line++;
cfile->lpos = 1;
cfile->cur_line [0] = 0;
} else if (c != EOF) {
if (cfile->lpos <= 80) {
cfile->cur_line [cfile->lpos - 1] = c;
cfile->cur_line [cfile->lpos] = 0;
}
cfile->lpos++;
1995-11-29 07:40:04 +00:00
}
} else
cfile->ugflag = 0;
1995-11-29 07:40:04 +00:00
return c;
}
/*
* Return a character to our input buffer.
*/
static int
unget_char(struct parse *cfile, int c) {
if (c != EOF) {
cfile->bufix--;
cfile->ugflag = 1; /* do not put characters into
our error buffer on the next
call to get_char() */
}
}
/*
* GENERAL NOTE ABOUT TOKENS
*
* We normally only want non-whitespace tokens. There are some
* circumstances where we *do* want to see whitespace (for example
* when parsing IPv6 addresses).
*
* Generally we use the next_token() function to read tokens. This
* in turn calls get_next_token, which does *not* return tokens for
* whitespace. Rather, it skips these.
*
* When we need to see whitespace, we us next_raw_token(), which also
* returns the WHITESPACE token.
*
* The peek_token() and peek_raw_token() functions work as expected.
*
* Warning: if you invoke peek_token(), then if there is a whitespace
* token, it will be lost, and subsequent use of next_raw_token() or
* peek_raw_token() will NOT see it.
*/
static enum dhcp_token
get_raw_token(struct parse *cfile) {
1995-11-29 07:40:04 +00:00
int c;
enum dhcp_token ttok;
static char tb [2];
int l, p, u;
1995-11-29 07:40:04 +00:00
do {
l = cfile -> line;
p = cfile -> lpos;
1995-11-29 07:40:04 +00:00
c = get_char (cfile);
if (!((c == '\n') && cfile->eol_token) &&
isascii(c) && isspace(c)) {
ttok = read_whitespace(c, cfile);
break;
}
1995-11-29 07:40:04 +00:00
if (c == '#') {
skip_to_eol (cfile);
continue;
}
if (c == '"') {
cfile -> lexline = l;
cfile -> lexchar = p;
1995-11-29 07:40:04 +00:00
ttok = read_string (cfile);
break;
}
1996-03-16 17:50:30 +00:00
if ((isascii (c) && isdigit (c)) || c == '-') {
cfile -> lexline = l;
cfile -> lexchar = p;
1995-11-29 07:40:04 +00:00
ttok = read_number (c, cfile);
break;
} else if (isascii (c) && isalpha (c)) {
cfile -> lexline = l;
cfile -> lexchar = p;
1996-08-29 09:13:41 +00:00
ttok = read_num_or_name (c, cfile);
1995-11-29 07:40:04 +00:00
break;
} else if (c == EOF) {
ttok = END_OF_FILE;
cfile -> tlen = 0;
break;
1995-11-29 07:40:04 +00:00
} else {
cfile -> lexline = l;
cfile -> lexchar = p;
tb [0] = c;
tb [1] = 0;
cfile -> tval = tb;
cfile -> tlen = 1;
1995-11-29 07:40:04 +00:00
ttok = c;
break;
}
} while (1);
return ttok;
}
/*
* The get_next_token() function consumes the next token and
* returns it to the caller.
*
* Since the code is almost the same for "normal" and "raw"
* input, we pass a flag to alter the way it works.
*/
static enum dhcp_token
get_next_token(const char **rval, unsigned *rlen,
struct parse *cfile, isc_boolean_t raw) {
1995-11-29 07:40:04 +00:00
int rv;
if (cfile -> token) {
if (cfile -> lexline != cfile -> tline)
cfile -> token_line = cfile -> cur_line;
cfile -> lexchar = cfile -> tlpos;
cfile -> lexline = cfile -> tline;
rv = cfile -> token;
cfile -> token = 0;
1995-11-29 07:40:04 +00:00
} else {
rv = get_raw_token(cfile);
cfile -> token_line = cfile -> cur_line;
1995-11-29 07:40:04 +00:00
}
if (!raw) {
while (rv == WHITESPACE) {
rv = get_raw_token(cfile);
cfile->token_line = cfile->cur_line;
}
}
1995-11-29 07:40:04 +00:00
if (rval)
*rval = cfile -> tval;
if (rlen)
*rlen = cfile -> tlen;
#ifdef DEBUG_TOKENS
fprintf (stderr, "%s:%d ", cfile -> tval, rv);
#endif
1995-11-29 07:40:04 +00:00
return rv;
}
/*
* Get the next token from cfile and return it.
*
* If rval is non-NULL, set the pointer it contains to
* the contents of the token.
*
* If rlen is non-NULL, set the integer it contains to
* the length of the token.
*/
enum dhcp_token
next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
return get_next_token(rval, rlen, cfile, ISC_FALSE);
}
/*
* The same as the next_token() function above, but will return space
* as the WHITESPACE token.
*/
enum dhcp_token
next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
return get_next_token(rval, rlen, cfile, ISC_TRUE);
}
/*
* The do_peek_token() function checks the next token without
* consuming it, and returns it to the caller.
*
* Since the code is almost the same for "normal" and "raw"
* input, we pass a flag to alter the way it works. (See the
* warning in the GENERAL NOTES ABOUT TOKENS above though.)
*/
enum dhcp_token
do_peek_token(const char **rval, unsigned int *rlen,
struct parse *cfile, isc_boolean_t raw) {
int x;
if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
cfile -> tlpos = cfile -> lexchar;
cfile -> tline = cfile -> lexline;
do {
cfile->token = get_raw_token(cfile);
} while (!raw && (cfile->token == WHITESPACE));
if (cfile -> lexline != cfile -> tline)
cfile -> token_line = cfile -> prev_line;
x = cfile -> lexchar;
cfile -> lexchar = cfile -> tlpos;
cfile -> tlpos = x;
x = cfile -> lexline;
cfile -> lexline = cfile -> tline;
cfile -> tline = x;
}
1995-11-29 07:40:04 +00:00
if (rval)
*rval = cfile -> tval;
if (rlen)
*rlen = cfile -> tlen;
#ifdef DEBUG_TOKENS
fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
#endif
return cfile -> token;
1995-11-29 07:40:04 +00:00
}
/*
* Get the next token from cfile and return it, leaving it for a
* subsequent call to next_token().
*
* Note that it WILL consume whitespace tokens.
*
* If rval is non-NULL, set the pointer it contains to
* the contents of the token.
*
* If rlen is non-NULL, set the integer it contains to
* the length of the token.
*/
enum dhcp_token
peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
return do_peek_token(rval, rlen, cfile, ISC_FALSE);
}
/*
* The same as the peek_token() function above, but will return space
* as the WHITESPACE token.
*/
enum dhcp_token
peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
return do_peek_token(rval, rlen, cfile, ISC_TRUE);
}
1995-11-29 07:40:04 +00:00
static void skip_to_eol (cfile)
struct parse *cfile;
1995-11-29 07:40:04 +00:00
{
int c;
do {
c = get_char (cfile);
if (c == EOF)
return;
if (c == EOL) {
return;
}
} while (1);
}
static enum dhcp_token
read_whitespace(int c, struct parse *cfile) {
int ofs;
/*
* Read as much whitespace as we have available.
*/
ofs = 0;
do {
cfile->tokbuf[ofs++] = c;
c = get_char(cfile);
} while (!((c == '\n') && cfile->eol_token) &&
isascii(c) && isspace(c));
/*
* Put the last (non-whitespace) character back.
*/
unget_char(cfile, c);
/*
* Return our token.
*/
cfile->tokbuf[ofs] = '\0';
cfile->tlen = ofs;
cfile->tval = cfile->tokbuf;
return WHITESPACE;
}
static enum dhcp_token read_string (cfile)
struct parse *cfile;
1995-11-29 07:40:04 +00:00
{
int i;
int bs = 0;
int c;
int value = 0;
int hex = 0;
1995-11-29 07:40:04 +00:00
for (i = 0; i < sizeof cfile -> tokbuf; i++) {
again:
1995-11-29 07:40:04 +00:00
c = get_char (cfile);
if (c == EOF) {
parse_warn (cfile, "eof in string constant");
1995-11-29 07:40:04 +00:00
break;
}
if (bs == 1) {
switch (c) {
case 't':
cfile -> tokbuf [i] = '\t';
break;
case 'r':
cfile -> tokbuf [i] = '\r';
break;
case 'n':
cfile -> tokbuf [i] = '\n';
break;
case 'b':
cfile -> tokbuf [i] = '\b';
break;
case '0':
case '1':
case '2':
case '3':
hex = 0;
value = c - '0';
++bs;
goto again;
case 'x':
hex = 1;
value = 0;
++bs;
goto again;
default:
cfile -> tokbuf [i] = c;
bs = 0;
break;
}
1995-11-29 07:40:04 +00:00
bs = 0;
} else if (bs > 1) {
if (hex) {
if (c >= '0' && c <= '9') {
value = value * 16 + (c - '0');
} else if (c >= 'a' && c <= 'f') {
value = value * 16 + (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
value = value * 16 + (c - 'A' + 10);
} else {
parse_warn (cfile,
"invalid hex digit: %x",
c);
bs = 0;
continue;
}
if (++bs == 4) {
cfile -> tokbuf [i] = value;
bs = 0;
} else
goto again;
} else {
if (c >= '0' && c <= '7') {
value = value * 8 + (c - '0');
} else {
if (value != 0) {
parse_warn (cfile,
"invalid octal digit %x",
c);
continue;
} else
cfile -> tokbuf [i] = 0;
bs = 0;
}
if (++bs == 4) {
cfile -> tokbuf [i] = value;
bs = 0;
} else
goto again;
}
} else if (c == '\\') {
1995-11-29 07:40:04 +00:00
bs = 1;
goto again;
} else if (c == '"')
1995-11-29 07:40:04 +00:00
break;
else
cfile -> tokbuf [i] = c;
1995-11-29 07:40:04 +00:00
}
/* Normally, I'd feel guilty about this, but we're talking about
strings that'll fit in a DHCP packet here... */
if (i == sizeof cfile -> tokbuf) {
parse_warn (cfile,
"string constant larger than internal buffer");
1995-11-29 07:40:04 +00:00
--i;
}
cfile -> tokbuf [i] = 0;
cfile -> tlen = i;
cfile -> tval = cfile -> tokbuf;
1995-11-29 07:40:04 +00:00
return STRING;
}
static enum dhcp_token read_number (c, cfile)
1995-11-29 07:40:04 +00:00
int c;
struct parse *cfile;
1995-11-29 07:40:04 +00:00
{
int i = 0;
int token = NUMBER;
cfile -> tokbuf [i++] = c;
for (; i < sizeof cfile -> tokbuf; i++) {
1995-11-29 07:40:04 +00:00
c = get_char (cfile);
/* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
* Except in the case of '0x' syntax hex, which gets called
* a NAME at '0x', and returned to NUMBER_OR_NAME once it's
* verified to be at least 0xf or less.
*/
switch(isascii(c) ? token : BREAK) {
case NUMBER:
if(isdigit(c))
break;
/* FALLTHROUGH */
case NUMBER_OR_NAME:
if(isxdigit(c)) {
token = NUMBER_OR_NAME;
break;
}
/* FALLTHROUGH */
case NAME:
if((i == 2) && isxdigit(c) &&
(cfile->tokbuf[0] == '0') &&
((cfile->tokbuf[1] == 'x') ||
(cfile->tokbuf[1] == 'X'))) {
token = NUMBER_OR_NAME;
break;
} else if(((c == '-') || (c == '_') || isalnum(c))) {
token = NAME;
break;
}
/* FALLTHROUGH */
case BREAK:
/* At this point c is either EOF or part of the next
* token. If not EOF, rewind the file one byte so
* the next token is read from there.
*/
unget_char(cfile, c);
goto end_read;
default:
log_fatal("read_number():%s:%d: impossible case", MDL);
}
cfile -> tokbuf [i] = c;
1995-11-29 07:40:04 +00:00
}
if (i == sizeof cfile -> tokbuf) {
parse_warn (cfile,
"numeric token larger than internal buffer");
1995-11-29 07:40:04 +00:00
--i;
}
end_read:
cfile -> tokbuf [i] = 0;
cfile -> tlen = i;
cfile -> tval = cfile -> tokbuf;
return token;
1995-11-29 07:40:04 +00:00
}
static enum dhcp_token read_num_or_name (c, cfile)
1995-11-29 07:40:04 +00:00
int c;
struct parse *cfile;
1995-11-29 07:40:04 +00:00
{
int i = 0;
enum dhcp_token rv = NUMBER_OR_NAME;
cfile -> tokbuf [i++] = c;
for (; i < sizeof cfile -> tokbuf; i++) {
1995-11-29 07:40:04 +00:00
c = get_char (cfile);
if (!isascii (c) ||
(c != '-' && c != '_' && !isalnum (c))) {
unget_char(cfile, c);
1995-11-29 07:40:04 +00:00
break;
}
if (!isxdigit (c))
1996-08-29 09:13:41 +00:00
rv = NAME;
cfile -> tokbuf [i] = c;
1995-11-29 07:40:04 +00:00
}
if (i == sizeof cfile -> tokbuf) {
parse_warn (cfile, "token larger than internal buffer");
1995-11-29 07:40:04 +00:00
--i;
}
cfile -> tokbuf [i] = 0;
cfile -> tlen = i;
cfile -> tval = cfile -> tokbuf;
return intern(cfile->tval, rv);
1995-11-29 07:40:04 +00:00
}
static enum dhcp_token
intern(char *atom, enum dhcp_token dfv) {
if (!isascii(atom[0]))
1996-05-22 08:05:19 +00:00
return dfv;
switch (tolower((unsigned char)atom[0])) {
case '-':
if (atom [1] == 0)
return MINUS;
break;
1997-02-22 08:29:24 +00:00
case 'a':
if (!strncasecmp (atom + 1, "uth", 3)) {
if (!strncasecmp (atom + 3, "uthenticat", 10)) {
if (!strcasecmp (atom + 13, "ed"))
return AUTHENTICATED;
if (!strcasecmp (atom + 13, "ion"))
return AUTHENTICATION;
break;
}
if (!strcasecmp (atom + 1, "uthoritative"))
return AUTHORITATIVE;
break;
}
1998-04-20 18:02:40 +00:00
if (!strcasecmp (atom + 1, "nd"))
return AND;
if (!strcasecmp (atom + 1, "ppend"))
return APPEND;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "llow"))
return ALLOW;
1997-02-22 12:25:32 +00:00
if (!strcasecmp (atom + 1, "lias"))
return ALIAS;
if (!strcasecmp (atom + 1, "lgorithm"))
return ALGORITHM;
if (!strcasecmp (atom + 1, "lso"))
return TOKEN_ALSO;
1997-03-06 19:27:57 +00:00
if (!strcasecmp (atom + 1, "bandoned"))
return TOKEN_ABANDONED;
if (!strcasecmp (atom + 1, "dd"))
return TOKEN_ADD;
if (!strcasecmp (atom + 1, "ll"))
return ALL;
if (!strcasecmp (atom + 1, "t"))
return AT;
if (!strcasecmp (atom + 1, "rray"))
return ARRAY;
if (!strcasecmp (atom + 1, "ddress"))
return ADDRESS;
if (!strcasecmp (atom + 1, "ctive"))
return TOKEN_ACTIVE;
if (!strcasecmp (atom + 1, "tsfp"))
return ATSFP;
1997-02-22 08:29:24 +00:00
break;
case 'b':
if (!strcasecmp (atom + 1, "ackup"))
return TOKEN_BACKUP;
if (!strcasecmp (atom + 1, "ootp"))
return TOKEN_BOOTP;
if (!strcasecmp (atom + 1, "inding"))
return BINDING;
if (!strcasecmp (atom + 1, "inary-to-ascii"))
return BINARY_TO_ASCII;
if (!strcasecmp (atom + 1, "ackoff-cutoff"))
return BACKOFF_CUTOFF;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "ooting"))
return BOOTING;
if (!strcasecmp (atom + 1, "oot-unknown-clients"))
return BOOT_UNKNOWN_CLIENTS;
if (!strcasecmp (atom + 1, "reak"))
return BREAK;
1998-11-11 07:50:06 +00:00
if (!strcasecmp (atom + 1, "illing"))
return BILLING;
if (!strcasecmp (atom + 1, "oolean"))
return BOOLEAN;
if (!strcasecmp (atom + 1, "alance"))
return BALANCE;
2000-12-05 07:12:18 +00:00
if (!strcasecmp (atom + 1, "ound"))
return BOUND;
break;
case 'c':
if (!strcasecmp (atom + 1, "ase"))
return CASE;
if (!strcasecmp (atom + 1, "ommit"))
return COMMIT;
if (!strcasecmp (atom + 1, "ode"))
return CODE;
if (!strcasecmp (atom + 1, "onfig-option"))
return CONFIG_OPTION;
1998-04-20 18:02:40 +00:00
if (!strcasecmp (atom + 1, "heck"))
return CHECK;
if (!strcasecmp (atom + 1, "lass"))
return CLASS;
if (!strcasecmp (atom + 1, "lose"))
return TOKEN_CLOSE;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 1, "ompressed"))
return COMPRESSED;
if (!strcasecmp (atom + 1, "reate"))
return TOKEN_CREATE;
if (!strcasecmp (atom + 1, "iaddr"))
return CIADDR;
if (!strncasecmp (atom + 1, "lient", 5)) {
if (!strcasecmp (atom + 6, "-identifier"))
return CLIENT_IDENTIFIER;
if (!strcasecmp (atom + 6, "-hostname"))
return CLIENT_HOSTNAME;
2000-11-28 22:11:52 +00:00
if (!strcasecmp (atom + 6, "-state"))
return CLIENT_STATE;
2001-01-11 23:13:27 +00:00
if (!strcasecmp (atom + 6, "-updates"))
return CLIENT_UPDATES;
if (!strcasecmp (atom + 6, "s"))
return CLIENTS;
}
if (!strcasecmp (atom + 1, "oncat"))
1999-05-06 20:13:31 +00:00
return CONCAT;
if (!strcasecmp (atom + 1, "onnect"))
return CONNECT;
if (!strcasecmp (atom + 1, "ommunications-interrupted"))
return COMMUNICATIONS_INTERRUPTED;
if (!strcasecmp (atom + 1, "ltt"))
return CLTT;
break;
case 'd':
if (!strcasecmp(atom + 1, "b-time-format"))
return DB_TIME_FORMAT;
if (!strcasecmp (atom + 1, "ns-update"))
return DNS_UPDATE;
if (!strcasecmp (atom + 1, "ns-delete"))
return DNS_DELETE;
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
if (!strncasecmp (atom + 1, "omain-", 6)) {
if (!strcasecmp(atom + 7, "name"))
return DOMAIN_NAME;
if (!strcasecmp(atom + 7, "list"))
return DOMAIN_LIST;
}
if (!strcasecmp (atom + 1, "o-forward-update"))
return DO_FORWARD_UPDATE;
if (!strcasecmp (atom + 1, "ebug"))
return TOKEN_DEBUG;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "eny"))
return DENY;
1999-09-09 23:25:29 +00:00
if (!strcasecmp (atom + 1, "eleted"))
return TOKEN_DELETED;
if (!strcasecmp (atom + 1, "elete"))
return TOKEN_DELETE;
1997-02-22 08:29:24 +00:00
if (!strncasecmp (atom + 1, "efault", 6)) {
if (!atom [7])
return DEFAULT;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 7, "-duid"))
return DEFAULT_DUID;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 7, "-lease-time"))
return DEFAULT_LEASE_TIME;
break;
}
if (!strncasecmp (atom + 1, "ynamic", 6)) {
if (!atom [7])
return DYNAMIC;
if (!strncasecmp (atom + 7, "-bootp", 6)) {
if (!atom [13])
return DYNAMIC_BOOTP;
if (!strcasecmp (atom + 13, "-lease-cutoff"))
return DYNAMIC_BOOTP_LEASE_CUTOFF;
if (!strcasecmp (atom + 13, "-lease-length"))
return DYNAMIC_BOOTP_LEASE_LENGTH;
break;
}
}
1999-10-20 20:55:48 +00:00
if (!strcasecmp (atom + 1, "uplicates"))
return DUPLICATES;
1999-10-21 02:33:40 +00:00
if (!strcasecmp (atom + 1, "eclines"))
return DECLINES;
if (!strncasecmp (atom + 1, "efine", 5)) {
if (!strcasecmp (atom + 6, "d"))
return DEFINED;
if (!atom [6])
return DEFINE;
}
break;
case 'e':
if (isascii (atom [1]) &&
tolower((unsigned char)atom[1]) == 'x') {
1998-10-17 13:34:31 +00:00
if (!strcasecmp (atom + 2, "tract-int"))
return EXTRACT_INT;
if (!strcasecmp (atom + 2, "ists"))
return EXISTS;
1999-10-01 03:33:44 +00:00
if (!strcasecmp (atom + 2, "piry"))
return EXPIRY;
if (!strcasecmp (atom + 2, "pire"))
return EXPIRE;
if (!strcasecmp (atom + 2, "pired"))
return TOKEN_EXPIRED;
1998-10-17 13:34:31 +00:00
}
1999-10-20 20:55:48 +00:00
if (!strcasecmp (atom + 1, "ncode-int"))
1999-10-01 03:33:44 +00:00
return ENCODE_INT;
if (!strcasecmp(atom + 1, "poch"))
return EPOCH;
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
if (!strcasecmp (atom + 1, "nds"))
return ENDS;
if (!strncasecmp (atom + 1, "ls", 2)) {
if (!strcasecmp (atom + 3, "e"))
return ELSE;
if (!strcasecmp (atom + 3, "if"))
return ELSIF;
break;
}
if (!strcasecmp (atom + 1, "rror"))
return ERROR;
2000-01-25 01:03:36 +00:00
if (!strcasecmp (atom + 1, "val"))
return EVAL;
if (!strcasecmp (atom + 1, "ncapsulate"))
return ENCAPSULATE;
if (!strcasecmp(atom + 1, "xecute"))
return EXECUTE;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom+1, "n")) {
return EN;
}
1995-11-29 07:40:04 +00:00
break;
case 'f':
if (!strcasecmp (atom + 1, "atal"))
return FATAL;
1995-11-29 07:40:04 +00:00
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
2007-05-08 23:05:22 +00:00
if (!strcasecmp (atom + 1, "ixed-address6"))
return FIXED_ADDR6;
if (!strcasecmp (atom + 1, "ddi"))
return FDDI;
if (!strcasecmp (atom + 1, "ormerr"))
return NS_FORMERR;
if (!strcasecmp (atom + 1, "unction"))
return FUNCTION;
if (!strcasecmp (atom + 1, "ailover"))
return FAILOVER;
if (!strcasecmp (atom + 1, "ree"))
return TOKEN_FREE;
1995-11-29 07:40:04 +00:00
break;
case 'g':
if (!strcasecmp (atom + 1, "iaddr"))
return GIADDR;
if (!strcasecmp (atom + 1, "roup"))
return GROUP;
1996-08-29 23:02:40 +00:00
if (!strcasecmp (atom + 1, "et-lease-hostnames"))
return GET_LEASE_HOSTNAMES;
break;
case 'h':
if (!strcasecmp(atom + 1, "ash"))
return HASH;
if (!strcasecmp (atom + 1, "ba"))
return HBA;
if (!strcasecmp (atom + 1, "ost"))
return HOST;
if (!strcasecmp (atom + 1, "ost-decl-name"))
return HOST_DECL_NAME;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 1, "ost-identifier"))
return HOST_IDENTIFIER;
if (!strcasecmp (atom + 1, "ardware"))
return HARDWARE;
1997-10-29 18:32:53 +00:00
if (!strcasecmp (atom + 1, "ostname"))
return HOSTNAME;
if (!strcasecmp (atom + 1, "elp"))
return TOKEN_HELP;
break;
1997-02-18 14:32:30 +00:00
case 'i':
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom+1, "a-na"))
return IA_NA;
if (!strcasecmp(atom+1, "aaddr"))
return IAADDR;
if (!strcasecmp (atom + 1, "nclude"))
return INCLUDE;
if (!strcasecmp (atom + 1, "nteger"))
return INTEGER;
if (!strcasecmp (atom + 1, "nfinite"))
return INFINITE;
if (!strcasecmp (atom + 1, "nfo"))
return INFO;
if (!strcasecmp (atom + 1, "p-address"))
return IP_ADDRESS;
2007-05-08 23:05:22 +00:00
if (!strcasecmp (atom + 1, "p6-address"))
return IP6_ADDRESS;
if (!strcasecmp (atom + 1, "nitial-interval"))
return INITIAL_INTERVAL;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "nterface"))
return INTERFACE;
if (!strcasecmp (atom + 1, "dentifier"))
return IDENTIFIER;
if (!strcasecmp (atom + 1, "f"))
return IF;
if (!strcasecmp (atom + 1, "s"))
return IS;
1999-10-21 03:08:00 +00:00
if (!strcasecmp (atom + 1, "gnore"))
return IGNORE;
1997-02-18 14:32:30 +00:00
break;
case 'k':
if (!strncasecmp (atom + 1, "nown", 4)) {
if (!strcasecmp (atom + 5, "-clients"))
return KNOWN_CLIENTS;
if (!atom[5])
return KNOWN;
break;
}
if (!strcasecmp (atom + 1, "ey"))
return KEY;
break;
case 'l':
if (!strcasecmp (atom + 1, "case"))
return LCASE;
if (!strcasecmp (atom + 1, "ease"))
return LEASE;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 1, "ease6"))
return LEASE6;
if (!strcasecmp (atom + 1, "eased-address"))
return LEASED_ADDRESS;
1999-07-19 15:32:54 +00:00
if (!strcasecmp (atom + 1, "ease-time"))
return LEASE_TIME;
2006-07-25 13:26:00 +00:00
if (!strcasecmp(atom + 1, "easequery"))
return LEASEQUERY;
if (!strcasecmp(atom + 1, "ength"))
return LENGTH;
1998-11-11 07:50:06 +00:00
if (!strcasecmp (atom + 1, "imit"))
return LIMIT;
2000-01-25 01:03:36 +00:00
if (!strcasecmp (atom + 1, "et"))
return LET;
if (!strcasecmp (atom + 1, "oad"))
return LOAD;
if (!strcasecmp(atom + 1, "ocal"))
return LOCAL;
if (!strcasecmp (atom + 1, "og"))
return LOG;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom+1, "lt")) {
return LLT;
}
if (!strcasecmp(atom+1, "l")) {
return LL;
}
1995-11-29 07:40:04 +00:00
break;
case 'm':
if (!strncasecmp (atom + 1, "ax", 2)) {
if (!atom [3])
return TOKEN_MAX;
if (!strcasecmp (atom + 3, "-balance"))
return MAX_BALANCE;
if (!strncasecmp (atom + 3, "-lease-", 7)) {
if (!strcasecmp(atom + 10, "misbalance"))
return MAX_LEASE_MISBALANCE;
if (!strcasecmp(atom + 10, "ownership"))
return MAX_LEASE_OWNERSHIP;
if (!strcasecmp(atom + 10, "time"))
return MAX_LEASE_TIME;
}
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 3, "-life"))
return MAX_LIFE;
if (!strcasecmp (atom + 3, "-transmit-idle"))
return MAX_TRANSMIT_IDLE;
if (!strcasecmp (atom + 3, "-response-delay"))
return MAX_RESPONSE_DELAY;
if (!strcasecmp (atom + 3, "-unacked-updates"))
return MAX_UNACKED_UPDATES;
}
if (!strncasecmp (atom + 1, "in-", 3)) {
if (!strcasecmp (atom + 4, "balance"))
return MIN_BALANCE;
if (!strcasecmp (atom + 4, "lease-time"))
return MIN_LEASE_TIME;
if (!strcasecmp (atom + 4, "secs"))
return MIN_SECS;
break;
}
1997-02-22 08:29:24 +00:00
if (!strncasecmp (atom + 1, "edi", 3)) {
if (!strcasecmp (atom + 4, "a"))
return MEDIA;
if (!strcasecmp (atom + 4, "um"))
return MEDIUM;
break;
}
if (!strcasecmp (atom + 1, "atch"))
return MATCH;
if (!strcasecmp (atom + 1, "embers"))
return MEMBERS;
if (!strcasecmp (atom + 1, "y"))
return MY;
if (!strcasecmp (atom + 1, "clt"))
return MCLT;
break;
case 'n':
if (!strcasecmp (atom + 1, "ormal"))
return NORMAL;
if (!strcasecmp (atom + 1, "ameserver"))
return NAMESERVER;
if (!strcasecmp (atom + 1, "etmask"))
return NETMASK;
if (!strcasecmp (atom + 1, "ever"))
return NEVER;
if (!strcasecmp (atom + 1, "ext-server"))
return NEXT_SERVER;
if (!strcasecmp (atom + 1, "ot"))
return TOKEN_NOT;
if (!strcasecmp (atom + 1, "o"))
return TOKEN_NO;
if (!strcasecmp (atom + 1, "s-update"))
return NS_UPDATE;
if (!strcasecmp (atom + 1, "oerror"))
return NS_NOERROR;
if (!strcasecmp (atom + 1, "otauth"))
return NS_NOTAUTH;
if (!strcasecmp (atom + 1, "otimp"))
return NS_NOTIMP;
if (!strcasecmp (atom + 1, "otzone"))
return NS_NOTZONE;
if (!strcasecmp (atom + 1, "xdomain"))
return NS_NXDOMAIN;
if (!strcasecmp (atom + 1, "xrrset"))
return NS_NXRRSET;
if (!strcasecmp (atom + 1, "ull"))
return TOKEN_NULL;
if (!strcasecmp (atom + 1, "ext"))
return TOKEN_NEXT;
2001-01-16 22:50:05 +00:00
if (!strcasecmp (atom + 1, "ew"))
return TOKEN_NEW;
break;
1995-11-29 07:40:04 +00:00
case 'o':
2000-06-24 06:17:55 +00:00
if (!strcasecmp (atom + 1, "mapi"))
return OMAPI;
1998-04-20 18:02:40 +00:00
if (!strcasecmp (atom + 1, "r"))
return OR;
if (!strcasecmp (atom + 1, "n"))
return ON;
if (!strcasecmp (atom + 1, "pen"))
return TOKEN_OPEN;
1995-11-29 07:40:04 +00:00
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
if (!strcasecmp (atom + 1, "ne-lease-per-client"))
return ONE_LEASE_PER_CLIENT;
if (!strcasecmp (atom + 1, "f"))
return OF;
if (!strcasecmp (atom + 1, "wner"))
return OWNER;
break;
case 'p':
if (!strcasecmp (atom + 1, "repend"))
return PREPEND;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 1, "referred-life"))
return PREFERRED_LIFE;
if (!strcasecmp (atom + 1, "acket"))
return PACKET;
if (!strcasecmp (atom + 1, "ool"))
return POOL;
if (!strcasecmp (atom + 1, "seudo"))
return PSEUDO;
if (!strcasecmp (atom + 1, "eer"))
return PEER;
if (!strcasecmp (atom + 1, "rimary"))
return PRIMARY;
if (!strncasecmp (atom + 1, "artner", 6)) {
if (!atom [7])
return PARTNER;
if (!strcasecmp (atom + 7, "-down"))
return PARTNER_DOWN;
}
if (!strcasecmp (atom + 1, "ort"))
return PORT;
if (!strcasecmp (atom + 1, "otential-conflict"))
return POTENTIAL_CONFLICT;
2000-01-25 01:03:36 +00:00
if (!strcasecmp (atom + 1, "ick-first-value") ||
!strcasecmp (atom + 1, "ick"))
return PICK;
2000-08-31 04:39:41 +00:00
if (!strcasecmp (atom + 1, "aused"))
return PAUSED;
1995-11-29 07:40:04 +00:00
break;
case 'r':
if (!strcasecmp (atom + 1, "esolution-interrupted"))
return RESOLUTION_INTERRUPTED;
if (!strcasecmp (atom + 1, "ange"))
return RANGE;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 1, "ange6")) {
return RANGE6;
}
if (!strcasecmp (atom + 1, "ecover"))
return RECOVER;
2000-08-31 04:39:41 +00:00
if (!strcasecmp (atom + 1, "ecover-done"))
return RECOVER_DONE;
2001-04-20 18:07:29 +00:00
if (!strcasecmp (atom + 1, "ecover-wait"))
return RECOVER_WAIT;
2000-12-05 07:12:18 +00:00
if (!strcasecmp (atom + 1, "econtact-interval"))
return RECONTACT_INTERVAL;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "equest"))
return REQUEST;
if (!strcasecmp (atom + 1, "equire"))
return REQUIRE;
if (!strcasecmp (atom + 1, "equire"))
return REQUIRE;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "etry"))
return RETRY;
2000-08-28 19:36:39 +00:00
if (!strcasecmp (atom + 1, "eturn"))
return RETURN;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "enew"))
return RENEW;
if (!strcasecmp (atom + 1, "ebind"))
return REBIND;
1997-03-05 06:33:36 +00:00
if (!strcasecmp (atom + 1, "eboot"))
return REBOOT;
1997-06-02 22:30:52 +00:00
if (!strcasecmp (atom + 1, "eject"))
return REJECT;
if (!strcasecmp (atom + 1, "everse"))
return REVERSE;
if (!strcasecmp (atom + 1, "elease"))
return RELEASE;
if (!strcasecmp (atom + 1, "efused"))
return NS_REFUSED;
if (!strcasecmp (atom + 1, "eleased"))
return TOKEN_RELEASED;
if (!strcasecmp (atom + 1, "eset"))
return TOKEN_RESET;
if (!strcasecmp (atom + 1, "eserved"))
return TOKEN_RESERVED;
2001-05-17 19:04:09 +00:00
if (!strcasecmp (atom + 1, "emove"))
return REMOVE;
if (!strcasecmp (atom + 1, "efresh"))
return REFRESH;
break;
case 's':
if (!strcasecmp(atom + 1, "cript"))
return SCRIPT;
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 'e') {
if (!strcasecmp(atom + 2, "arch"))
return SEARCH;
if (isascii(atom[2]) &&
tolower((unsigned char)atom[2]) == 'c') {
if (!strncasecmp(atom + 3, "ond", 3)) {
if (!strcasecmp(atom + 6, "ary"))
return SECONDARY;
if (!strcasecmp(atom + 6, "s"))
return SECONDS;
break;
}
if (!strcasecmp(atom + 3, "ret"))
return SECRET;
break;
}
if (!strncasecmp(atom + 2, "lect", 4)) {
if (atom[6] == '\0')
return SELECT;
if (!strcasecmp(atom + 6, "-timeout"))
return SELECT_TIMEOUT;
break;
}
if (!strcasecmp(atom + 2, "nd"))
return SEND;
if (!strncasecmp(atom + 2, "rv", 2)) {
if (!strncasecmp(atom + 4, "er", 2)) {
if (atom[6] == '\0')
return TOKEN_SERVER;
if (atom[6] == '-') {
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 7,
"duid"))
return SERVER_DUID;
if (!strcasecmp(atom + 7,
"name"))
return SERVER_NAME;
if (!strcasecmp(atom + 7,
"identifier"))
return SERVER_IDENTIFIER;
break;
}
break;
}
if (!strcasecmp(atom + 4, "fail"))
return NS_SERVFAIL;
break;
}
if (!strcasecmp(atom + 2, "t"))
return TOKEN_SET;
break;
}
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 'h') {
if (!strcasecmp(atom + 2, "ared-network"))
return SHARED_NETWORK;
if (!strcasecmp(atom + 2, "utdown"))
return SHUTDOWN;
break;
}
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 'i') {
if (!strcasecmp(atom + 2, "addr"))
return SIADDR;
if (!strcasecmp(atom + 2, "gned"))
return SIGNED;
if (!strcasecmp(atom + 2, "ze"))
return SIZE;
break;
}
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 'p') {
if (isascii(atom[2]) &&
tolower((unsigned char)atom[2]) == 'a') {
if (!strcasecmp(atom + 3, "ce"))
return SPACE;
if (!strcasecmp(atom + 3, "wn"))
return SPAWN;
break;
}
if (!strcasecmp(atom + 2, "lit"))
return SPLIT;
break;
}
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 't') {
if (isascii(atom[2]) &&
tolower((unsigned char)atom[2]) == 'a') {
if(!strncasecmp(atom + 3, "rt", 2)) {
if (!strcasecmp(atom + 5, "s"))
return STARTS;
if (!strcasecmp(atom + 5, "up"))
return STARTUP;
break;
}
if (isascii(atom[3]) &&
tolower((unsigned char)atom[3]) == 't') {
if (!strcasecmp(atom + 4, "e"))
return STATE;
if (!strcasecmp(atom + 4, "ic"))
return STATIC;
break;
}
}
if (!strcasecmp(atom + 2, "ring"))
return STRING_TOKEN;
break;
}
if (!strncasecmp(atom + 1, "ub", 2)) {
if (!strcasecmp(atom + 3, "class"))
return SUBCLASS;
if (!strcasecmp(atom + 3, "net"))
return SUBNET;
2007-05-08 23:05:22 +00:00
if (!strcasecmp(atom + 3, "net6"))
return SUBNET6;
if (!strcasecmp(atom + 3, "string"))
return SUBSTRING;
break;
}
if (isascii(atom[1]) &&
tolower((unsigned char)atom[1]) == 'u') {
if (!strcasecmp(atom + 2, "ffix"))
return SUFFIX;
if (!strcasecmp(atom + 2, "persede"))
return SUPERSEDE;
}
if (!strcasecmp(atom + 1, "witch"))
return SWITCH;
break;
case 't':
1996-05-22 08:05:19 +00:00
if (!strcasecmp (atom + 1, "imestamp"))
return TIMESTAMP;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "imeout"))
return TIMEOUT;
if (!strcasecmp (atom + 1, "oken-ring"))
return TOKEN_RING;
if (!strcasecmp (atom + 1, "ext"))
return TEXT;
if (!strcasecmp (atom + 1, "stp"))
return TSTP;
if (!strcasecmp (atom + 1, "sfp"))
return TSFP;
2001-01-25 08:20:24 +00:00
if (!strcasecmp (atom + 1, "ransmission"))
return TRANSMISSION;
break;
case 'u':
if (!strcasecmp (atom + 1, "case"))
return UCASE;
2000-01-25 01:03:36 +00:00
if (!strcasecmp (atom + 1, "nset"))
return UNSET;
if (!strcasecmp (atom + 1, "nsigned"))
return UNSIGNED;
if (!strcasecmp (atom + 1, "id"))
return UID;
if (!strncasecmp (atom + 1, "se", 2)) {
if (!strcasecmp (atom + 3, "r-class"))
return USER_CLASS;
if (!strcasecmp (atom + 3, "-host-decl-names"))
return USE_HOST_DECL_NAMES;
if (!strcasecmp (atom + 3,
"-lease-addr-for-default-route"))
return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
break;
}
if (!strncasecmp (atom + 1, "nknown", 6)) {
if (!strcasecmp (atom + 7, "-clients"))
return UNKNOWN_CLIENTS;
if (!strcasecmp (atom + 7, "-state"))
return UNKNOWN_STATE;
if (!atom [7])
return UNKNOWN;
break;
}
if (!strcasecmp (atom + 1, "nauthenticated"))
return AUTHENTICATED;
if (!strcasecmp (atom + 1, "pdated-dns-rr"))
return UPDATED_DNS_RR;
if (!strcasecmp (atom + 1, "pdate"))
return UPDATE;
1996-02-29 18:06:29 +00:00
break;
case 'v':
if (!strcasecmp (atom + 1, "endor-class"))
return VENDOR_CLASS;
if (!strcasecmp (atom + 1, "endor"))
return VENDOR;
break;
case 'w':
if (!strcasecmp (atom + 1, "ith"))
return WITH;
if (!strcasecmp(atom + 1, "idth"))
return WIDTH;
break;
case 'y':
if (!strcasecmp (atom + 1, "iaddr"))
return YIADDR;
if (!strcasecmp (atom + 1, "xdomain"))
return NS_YXDOMAIN;
if (!strcasecmp (atom + 1, "xrrset"))
return NS_YXRRSET;
break;
2000-03-06 20:08:05 +00:00
case 'z':
if (!strcasecmp (atom + 1, "one"))
return ZONE;
break;
1995-11-29 07:40:04 +00:00
}
return dfv;
}