xref: /minix3/external/bsd/dhcp/dist/common/conflex.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: conflex.c,v 1.4 2014/07/12 12:09:37 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* conflex.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Lexical scanner for dhcpd config file... */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 1995-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek  *
22*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek  *   950 Charter Street
24*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
26*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
27*83ee113eSDavid van Moolenbroek  *
28*83ee113eSDavid van Moolenbroek  */
29*83ee113eSDavid van Moolenbroek 
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: conflex.c,v 1.4 2014/07/12 12:09:37 spz Exp $");
32*83ee113eSDavid van Moolenbroek 
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek #include <ctype.h>
35*83ee113eSDavid van Moolenbroek 
36*83ee113eSDavid van Moolenbroek static int get_char (struct parse *);
37*83ee113eSDavid van Moolenbroek static void unget_char(struct parse *, int);
38*83ee113eSDavid van Moolenbroek static void skip_to_eol (struct parse *);
39*83ee113eSDavid van Moolenbroek static enum dhcp_token read_whitespace(int c, struct parse *cfile);
40*83ee113eSDavid van Moolenbroek static enum dhcp_token read_string (struct parse *);
41*83ee113eSDavid van Moolenbroek static enum dhcp_token read_number (int, struct parse *);
42*83ee113eSDavid van Moolenbroek static enum dhcp_token read_num_or_name (int, struct parse *);
43*83ee113eSDavid van Moolenbroek static enum dhcp_token intern (char *, enum dhcp_token);
44*83ee113eSDavid van Moolenbroek 
new_parse(cfile,file,inbuf,buflen,name,eolp)45*83ee113eSDavid van Moolenbroek isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
46*83ee113eSDavid van Moolenbroek 	struct parse **cfile;
47*83ee113eSDavid van Moolenbroek 	int file;
48*83ee113eSDavid van Moolenbroek 	char *inbuf;
49*83ee113eSDavid van Moolenbroek 	unsigned buflen;
50*83ee113eSDavid van Moolenbroek 	const char *name;
51*83ee113eSDavid van Moolenbroek 	int eolp;
52*83ee113eSDavid van Moolenbroek {
53*83ee113eSDavid van Moolenbroek 	isc_result_t status = ISC_R_SUCCESS;
54*83ee113eSDavid van Moolenbroek 	struct parse *tmp;
55*83ee113eSDavid van Moolenbroek 
56*83ee113eSDavid van Moolenbroek 	tmp = dmalloc(sizeof(struct parse), MDL);
57*83ee113eSDavid van Moolenbroek 	if (tmp == NULL) {
58*83ee113eSDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
59*83ee113eSDavid van Moolenbroek 	}
60*83ee113eSDavid van Moolenbroek 
61*83ee113eSDavid van Moolenbroek 	/*
62*83ee113eSDavid van Moolenbroek 	 * We don't need to initialize things to zero here, since
63*83ee113eSDavid van Moolenbroek 	 * dmalloc() returns memory that is set to zero.
64*83ee113eSDavid van Moolenbroek 	 */
65*83ee113eSDavid van Moolenbroek 	tmp->tlname = name;
66*83ee113eSDavid van Moolenbroek 	tmp->lpos = tmp -> line = 1;
67*83ee113eSDavid van Moolenbroek 	tmp->cur_line = tmp->line1;
68*83ee113eSDavid van Moolenbroek 	tmp->prev_line = tmp->line2;
69*83ee113eSDavid van Moolenbroek 	tmp->token_line = tmp->cur_line;
70*83ee113eSDavid van Moolenbroek 	tmp->cur_line[0] = tmp->prev_line[0] = 0;
71*83ee113eSDavid van Moolenbroek 	tmp->file = file;
72*83ee113eSDavid van Moolenbroek 	tmp->eol_token = eolp;
73*83ee113eSDavid van Moolenbroek 
74*83ee113eSDavid van Moolenbroek 	if (inbuf != NULL) {
75*83ee113eSDavid van Moolenbroek 		tmp->inbuf = inbuf;
76*83ee113eSDavid van Moolenbroek 		tmp->buflen = buflen;
77*83ee113eSDavid van Moolenbroek 		tmp->bufsiz = 0;
78*83ee113eSDavid van Moolenbroek 	} else {
79*83ee113eSDavid van Moolenbroek 		struct stat sb;
80*83ee113eSDavid van Moolenbroek 
81*83ee113eSDavid van Moolenbroek 		if (fstat(file, &sb) < 0) {
82*83ee113eSDavid van Moolenbroek 			status = ISC_R_IOERROR;
83*83ee113eSDavid van Moolenbroek 			goto cleanup;
84*83ee113eSDavid van Moolenbroek 		}
85*83ee113eSDavid van Moolenbroek 
86*83ee113eSDavid van Moolenbroek 		if (sb.st_size == 0)
87*83ee113eSDavid van Moolenbroek 			goto cleanup;
88*83ee113eSDavid van Moolenbroek 
89*83ee113eSDavid van Moolenbroek 		tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
90*83ee113eSDavid van Moolenbroek 		tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
91*83ee113eSDavid van Moolenbroek 				  file, 0);
92*83ee113eSDavid van Moolenbroek 
93*83ee113eSDavid van Moolenbroek 		if (tmp->inbuf == MAP_FAILED) {
94*83ee113eSDavid van Moolenbroek 			status = ISC_R_IOERROR;
95*83ee113eSDavid van Moolenbroek 			goto cleanup;
96*83ee113eSDavid van Moolenbroek 		}
97*83ee113eSDavid van Moolenbroek 	}
98*83ee113eSDavid van Moolenbroek 
99*83ee113eSDavid van Moolenbroek 	*cfile = tmp;
100*83ee113eSDavid van Moolenbroek 	return (ISC_R_SUCCESS);
101*83ee113eSDavid van Moolenbroek 
102*83ee113eSDavid van Moolenbroek cleanup:
103*83ee113eSDavid van Moolenbroek 	dfree(tmp, MDL);
104*83ee113eSDavid van Moolenbroek 	return (status);
105*83ee113eSDavid van Moolenbroek }
106*83ee113eSDavid van Moolenbroek 
end_parse(cfile)107*83ee113eSDavid van Moolenbroek isc_result_t end_parse (cfile)
108*83ee113eSDavid van Moolenbroek 	struct parse **cfile;
109*83ee113eSDavid van Moolenbroek {
110*83ee113eSDavid van Moolenbroek 	/* "Memory" config files have no file. */
111*83ee113eSDavid van Moolenbroek 	if ((*cfile)->file != -1) {
112*83ee113eSDavid van Moolenbroek 		munmap((*cfile)->inbuf, (*cfile)->bufsiz);
113*83ee113eSDavid van Moolenbroek 		close((*cfile)->file);
114*83ee113eSDavid van Moolenbroek 	}
115*83ee113eSDavid van Moolenbroek 
116*83ee113eSDavid van Moolenbroek 	if ((*cfile)->saved_state != NULL) {
117*83ee113eSDavid van Moolenbroek 		dfree((*cfile)->saved_state, MDL);
118*83ee113eSDavid van Moolenbroek 	}
119*83ee113eSDavid van Moolenbroek 
120*83ee113eSDavid van Moolenbroek 	dfree(*cfile, MDL);
121*83ee113eSDavid van Moolenbroek 	*cfile = NULL;
122*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
123*83ee113eSDavid van Moolenbroek }
124*83ee113eSDavid van Moolenbroek 
125*83ee113eSDavid van Moolenbroek /*
126*83ee113eSDavid van Moolenbroek  * Save the current state of the parser.
127*83ee113eSDavid van Moolenbroek  *
128*83ee113eSDavid van Moolenbroek  * Only one state may be saved. Any previous saved state is
129*83ee113eSDavid van Moolenbroek  * lost.
130*83ee113eSDavid van Moolenbroek  */
131*83ee113eSDavid van Moolenbroek isc_result_t
save_parse_state(struct parse * cfile)132*83ee113eSDavid van Moolenbroek save_parse_state(struct parse *cfile) {
133*83ee113eSDavid van Moolenbroek 	/*
134*83ee113eSDavid van Moolenbroek 	 * Free any previous saved state.
135*83ee113eSDavid van Moolenbroek 	 */
136*83ee113eSDavid van Moolenbroek 	if (cfile->saved_state != NULL) {
137*83ee113eSDavid van Moolenbroek 		dfree(cfile->saved_state, MDL);
138*83ee113eSDavid van Moolenbroek 	}
139*83ee113eSDavid van Moolenbroek 
140*83ee113eSDavid van Moolenbroek 	/*
141*83ee113eSDavid van Moolenbroek 	 * Save our current state.
142*83ee113eSDavid van Moolenbroek 	 */
143*83ee113eSDavid van Moolenbroek 	cfile->saved_state = dmalloc(sizeof(struct parse), MDL);
144*83ee113eSDavid van Moolenbroek 	if (cfile->saved_state == NULL) {
145*83ee113eSDavid van Moolenbroek 		return ISC_R_NOMEMORY;
146*83ee113eSDavid van Moolenbroek 	}
147*83ee113eSDavid van Moolenbroek 	memcpy(cfile->saved_state, cfile, sizeof(*cfile));
148*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
149*83ee113eSDavid van Moolenbroek }
150*83ee113eSDavid van Moolenbroek 
151*83ee113eSDavid van Moolenbroek /*
152*83ee113eSDavid van Moolenbroek  * Return the parser to the previous saved state.
153*83ee113eSDavid van Moolenbroek  *
154*83ee113eSDavid van Moolenbroek  * You must call save_parse_state() before calling
155*83ee113eSDavid van Moolenbroek  * restore_parse_state(), but you can call restore_parse_state() any
156*83ee113eSDavid van Moolenbroek  * number of times after that.
157*83ee113eSDavid van Moolenbroek  */
158*83ee113eSDavid van Moolenbroek isc_result_t
restore_parse_state(struct parse * cfile)159*83ee113eSDavid van Moolenbroek restore_parse_state(struct parse *cfile) {
160*83ee113eSDavid van Moolenbroek 	struct parse *saved_state;
161*83ee113eSDavid van Moolenbroek 
162*83ee113eSDavid van Moolenbroek 	if (cfile->saved_state == NULL) {
163*83ee113eSDavid van Moolenbroek 		return DHCP_R_NOTYET;
164*83ee113eSDavid van Moolenbroek 	}
165*83ee113eSDavid van Moolenbroek 
166*83ee113eSDavid van Moolenbroek 	saved_state = cfile->saved_state;
167*83ee113eSDavid van Moolenbroek 	memcpy(cfile, saved_state, sizeof(*cfile));
168*83ee113eSDavid van Moolenbroek 	cfile->saved_state = saved_state;
169*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
170*83ee113eSDavid van Moolenbroek }
171*83ee113eSDavid van Moolenbroek 
get_char(cfile)172*83ee113eSDavid van Moolenbroek static int get_char (cfile)
173*83ee113eSDavid van Moolenbroek 	struct parse *cfile;
174*83ee113eSDavid van Moolenbroek {
175*83ee113eSDavid van Moolenbroek 	/* My kingdom for WITH... */
176*83ee113eSDavid van Moolenbroek 	int c;
177*83ee113eSDavid van Moolenbroek 
178*83ee113eSDavid van Moolenbroek 	if (cfile->bufix == cfile->buflen) {
179*83ee113eSDavid van Moolenbroek #if !defined(LDAP_CONFIGURATION)
180*83ee113eSDavid van Moolenbroek 		c = EOF;
181*83ee113eSDavid van Moolenbroek #else /* defined(LDAP_CONFIGURATION) */
182*83ee113eSDavid van Moolenbroek 		if (cfile->read_function != NULL)
183*83ee113eSDavid van Moolenbroek 			c = cfile->read_function(cfile);
184*83ee113eSDavid van Moolenbroek 		else
185*83ee113eSDavid van Moolenbroek 			c = EOF;
186*83ee113eSDavid van Moolenbroek #endif
187*83ee113eSDavid van Moolenbroek 	} else {
188*83ee113eSDavid van Moolenbroek 		c = cfile->inbuf [cfile->bufix];
189*83ee113eSDavid van Moolenbroek 		cfile->bufix++;
190*83ee113eSDavid van Moolenbroek 	}
191*83ee113eSDavid van Moolenbroek 
192*83ee113eSDavid van Moolenbroek 	if (!cfile->ugflag) {
193*83ee113eSDavid van Moolenbroek 		if (c == EOL) {
194*83ee113eSDavid van Moolenbroek 			if (cfile->cur_line == cfile->line1) {
195*83ee113eSDavid van Moolenbroek 				cfile->cur_line = cfile->line2;
196*83ee113eSDavid van Moolenbroek 				cfile->prev_line = cfile->line1;
197*83ee113eSDavid van Moolenbroek 			} else {
198*83ee113eSDavid van Moolenbroek 				cfile->cur_line = cfile->line1;
199*83ee113eSDavid van Moolenbroek 				cfile->prev_line = cfile->line2;
200*83ee113eSDavid van Moolenbroek 			}
201*83ee113eSDavid van Moolenbroek 			cfile->line++;
202*83ee113eSDavid van Moolenbroek 			cfile->lpos = 1;
203*83ee113eSDavid van Moolenbroek 			cfile->cur_line [0] = 0;
204*83ee113eSDavid van Moolenbroek 		} else if (c != EOF) {
205*83ee113eSDavid van Moolenbroek 			if (cfile->lpos <= 80) {
206*83ee113eSDavid van Moolenbroek 				cfile->cur_line [cfile->lpos - 1] = c;
207*83ee113eSDavid van Moolenbroek 				cfile->cur_line [cfile->lpos] = 0;
208*83ee113eSDavid van Moolenbroek 			}
209*83ee113eSDavid van Moolenbroek 			cfile->lpos++;
210*83ee113eSDavid van Moolenbroek 		}
211*83ee113eSDavid van Moolenbroek 	} else
212*83ee113eSDavid van Moolenbroek 		cfile->ugflag = 0;
213*83ee113eSDavid van Moolenbroek 	return c;
214*83ee113eSDavid van Moolenbroek }
215*83ee113eSDavid van Moolenbroek 
216*83ee113eSDavid van Moolenbroek /*
217*83ee113eSDavid van Moolenbroek  * Return a character to our input buffer.
218*83ee113eSDavid van Moolenbroek  */
219*83ee113eSDavid van Moolenbroek static void
unget_char(struct parse * cfile,int c)220*83ee113eSDavid van Moolenbroek unget_char(struct parse *cfile, int c) {
221*83ee113eSDavid van Moolenbroek 	if (c != EOF) {
222*83ee113eSDavid van Moolenbroek 		cfile->bufix--;
223*83ee113eSDavid van Moolenbroek 		cfile->ugflag = 1;	/* do not put characters into
224*83ee113eSDavid van Moolenbroek 					   our error buffer on the next
225*83ee113eSDavid van Moolenbroek 					   call to get_char() */
226*83ee113eSDavid van Moolenbroek 	}
227*83ee113eSDavid van Moolenbroek }
228*83ee113eSDavid van Moolenbroek 
229*83ee113eSDavid van Moolenbroek /*
230*83ee113eSDavid van Moolenbroek  * GENERAL NOTE ABOUT TOKENS
231*83ee113eSDavid van Moolenbroek  *
232*83ee113eSDavid van Moolenbroek  * We normally only want non-whitespace tokens. There are some
233*83ee113eSDavid van Moolenbroek  * circumstances where we *do* want to see whitespace (for example
234*83ee113eSDavid van Moolenbroek  * when parsing IPv6 addresses).
235*83ee113eSDavid van Moolenbroek  *
236*83ee113eSDavid van Moolenbroek  * Generally we use the next_token() function to read tokens. This
237*83ee113eSDavid van Moolenbroek  * in turn calls get_next_token, which does *not* return tokens for
238*83ee113eSDavid van Moolenbroek  * whitespace. Rather, it skips these.
239*83ee113eSDavid van Moolenbroek  *
240*83ee113eSDavid van Moolenbroek  * When we need to see whitespace, we us next_raw_token(), which also
241*83ee113eSDavid van Moolenbroek  * returns the WHITESPACE token.
242*83ee113eSDavid van Moolenbroek  *
243*83ee113eSDavid van Moolenbroek  * The peek_token() and peek_raw_token() functions work as expected.
244*83ee113eSDavid van Moolenbroek  *
245*83ee113eSDavid van Moolenbroek  * Warning: if you invoke peek_token(), then if there is a whitespace
246*83ee113eSDavid van Moolenbroek  * token, it will be lost, and subsequent use of next_raw_token() or
247*83ee113eSDavid van Moolenbroek  * peek_raw_token() will NOT see it.
248*83ee113eSDavid van Moolenbroek  */
249*83ee113eSDavid van Moolenbroek 
250*83ee113eSDavid van Moolenbroek static enum dhcp_token
get_raw_token(struct parse * cfile)251*83ee113eSDavid van Moolenbroek get_raw_token(struct parse *cfile) {
252*83ee113eSDavid van Moolenbroek 	int c;
253*83ee113eSDavid van Moolenbroek 	enum dhcp_token ttok;
254*83ee113eSDavid van Moolenbroek 	static char tb [2];
255*83ee113eSDavid van Moolenbroek 	int l, p;
256*83ee113eSDavid van Moolenbroek 
257*83ee113eSDavid van Moolenbroek 	do {
258*83ee113eSDavid van Moolenbroek 		l = cfile -> line;
259*83ee113eSDavid van Moolenbroek 		p = cfile -> lpos;
260*83ee113eSDavid van Moolenbroek 
261*83ee113eSDavid van Moolenbroek 		c = get_char (cfile);
262*83ee113eSDavid van Moolenbroek 		if (!((c == '\n') && cfile->eol_token) &&
263*83ee113eSDavid van Moolenbroek 		    isascii(c) && isspace(c)) {
264*83ee113eSDavid van Moolenbroek 		    	ttok = read_whitespace(c, cfile);
265*83ee113eSDavid van Moolenbroek 			break;
266*83ee113eSDavid van Moolenbroek 		}
267*83ee113eSDavid van Moolenbroek 		if (c == '#') {
268*83ee113eSDavid van Moolenbroek 			skip_to_eol (cfile);
269*83ee113eSDavid van Moolenbroek 			continue;
270*83ee113eSDavid van Moolenbroek 		}
271*83ee113eSDavid van Moolenbroek 		if (c == '"') {
272*83ee113eSDavid van Moolenbroek 			cfile -> lexline = l;
273*83ee113eSDavid van Moolenbroek 			cfile -> lexchar = p;
274*83ee113eSDavid van Moolenbroek 			ttok = read_string (cfile);
275*83ee113eSDavid van Moolenbroek 			break;
276*83ee113eSDavid van Moolenbroek 		}
277*83ee113eSDavid van Moolenbroek 		if ((isascii (c) && isdigit (c)) || c == '-') {
278*83ee113eSDavid van Moolenbroek 			cfile -> lexline = l;
279*83ee113eSDavid van Moolenbroek 			cfile -> lexchar = p;
280*83ee113eSDavid van Moolenbroek 			ttok = read_number (c, cfile);
281*83ee113eSDavid van Moolenbroek 			break;
282*83ee113eSDavid van Moolenbroek 		} else if (isascii (c) && isalpha (c)) {
283*83ee113eSDavid van Moolenbroek 			cfile -> lexline = l;
284*83ee113eSDavid van Moolenbroek 			cfile -> lexchar = p;
285*83ee113eSDavid van Moolenbroek 			ttok = read_num_or_name (c, cfile);
286*83ee113eSDavid van Moolenbroek 			break;
287*83ee113eSDavid van Moolenbroek 		} else if (c == EOF) {
288*83ee113eSDavid van Moolenbroek 			ttok = END_OF_FILE;
289*83ee113eSDavid van Moolenbroek 			cfile -> tlen = 0;
290*83ee113eSDavid van Moolenbroek 			break;
291*83ee113eSDavid van Moolenbroek 		} else {
292*83ee113eSDavid van Moolenbroek 			cfile -> lexline = l;
293*83ee113eSDavid van Moolenbroek 			cfile -> lexchar = p;
294*83ee113eSDavid van Moolenbroek 			tb [0] = c;
295*83ee113eSDavid van Moolenbroek 			tb [1] = 0;
296*83ee113eSDavid van Moolenbroek 			cfile -> tval = tb;
297*83ee113eSDavid van Moolenbroek 			cfile -> tlen = 1;
298*83ee113eSDavid van Moolenbroek 			ttok = c;
299*83ee113eSDavid van Moolenbroek 			break;
300*83ee113eSDavid van Moolenbroek 		}
301*83ee113eSDavid van Moolenbroek 	} while (1);
302*83ee113eSDavid van Moolenbroek 	return ttok;
303*83ee113eSDavid van Moolenbroek }
304*83ee113eSDavid van Moolenbroek 
305*83ee113eSDavid van Moolenbroek /*
306*83ee113eSDavid van Moolenbroek  * The get_next_token() function consumes the next token and
307*83ee113eSDavid van Moolenbroek  * returns it to the caller.
308*83ee113eSDavid van Moolenbroek  *
309*83ee113eSDavid van Moolenbroek  * Since the code is almost the same for "normal" and "raw"
310*83ee113eSDavid van Moolenbroek  * input, we pass a flag to alter the way it works.
311*83ee113eSDavid van Moolenbroek  */
312*83ee113eSDavid van Moolenbroek 
313*83ee113eSDavid van Moolenbroek static enum dhcp_token
get_next_token(const char ** rval,unsigned * rlen,struct parse * cfile,isc_boolean_t raw)314*83ee113eSDavid van Moolenbroek get_next_token(const char **rval, unsigned *rlen,
315*83ee113eSDavid van Moolenbroek 	       struct parse *cfile, isc_boolean_t raw) {
316*83ee113eSDavid van Moolenbroek 	int rv;
317*83ee113eSDavid van Moolenbroek 
318*83ee113eSDavid van Moolenbroek 	if (cfile -> token) {
319*83ee113eSDavid van Moolenbroek 		if (cfile -> lexline != cfile -> tline)
320*83ee113eSDavid van Moolenbroek 			cfile -> token_line = cfile -> cur_line;
321*83ee113eSDavid van Moolenbroek 		cfile -> lexchar = cfile -> tlpos;
322*83ee113eSDavid van Moolenbroek 		cfile -> lexline = cfile -> tline;
323*83ee113eSDavid van Moolenbroek 		rv = cfile -> token;
324*83ee113eSDavid van Moolenbroek 		cfile -> token = 0;
325*83ee113eSDavid van Moolenbroek 	} else {
326*83ee113eSDavid van Moolenbroek 		rv = get_raw_token(cfile);
327*83ee113eSDavid van Moolenbroek 		cfile -> token_line = cfile -> cur_line;
328*83ee113eSDavid van Moolenbroek 	}
329*83ee113eSDavid van Moolenbroek 
330*83ee113eSDavid van Moolenbroek 	if (!raw) {
331*83ee113eSDavid van Moolenbroek 		while (rv == WHITESPACE) {
332*83ee113eSDavid van Moolenbroek 			rv = get_raw_token(cfile);
333*83ee113eSDavid van Moolenbroek 			cfile->token_line = cfile->cur_line;
334*83ee113eSDavid van Moolenbroek 		}
335*83ee113eSDavid van Moolenbroek 	}
336*83ee113eSDavid van Moolenbroek 
337*83ee113eSDavid van Moolenbroek 	if (rval)
338*83ee113eSDavid van Moolenbroek 		*rval = cfile -> tval;
339*83ee113eSDavid van Moolenbroek 	if (rlen)
340*83ee113eSDavid van Moolenbroek 		*rlen = cfile -> tlen;
341*83ee113eSDavid van Moolenbroek #ifdef DEBUG_TOKENS
342*83ee113eSDavid van Moolenbroek 	fprintf (stderr, "%s:%d ", cfile -> tval, rv);
343*83ee113eSDavid van Moolenbroek #endif
344*83ee113eSDavid van Moolenbroek 	return rv;
345*83ee113eSDavid van Moolenbroek }
346*83ee113eSDavid van Moolenbroek 
347*83ee113eSDavid van Moolenbroek 
348*83ee113eSDavid van Moolenbroek /*
349*83ee113eSDavid van Moolenbroek  * Get the next token from cfile and return it.
350*83ee113eSDavid van Moolenbroek  *
351*83ee113eSDavid van Moolenbroek  * If rval is non-NULL, set the pointer it contains to
352*83ee113eSDavid van Moolenbroek  * the contents of the token.
353*83ee113eSDavid van Moolenbroek  *
354*83ee113eSDavid van Moolenbroek  * If rlen is non-NULL, set the integer it contains to
355*83ee113eSDavid van Moolenbroek  * the length of the token.
356*83ee113eSDavid van Moolenbroek  */
357*83ee113eSDavid van Moolenbroek 
358*83ee113eSDavid van Moolenbroek enum dhcp_token
next_token(const char ** rval,unsigned * rlen,struct parse * cfile)359*83ee113eSDavid van Moolenbroek next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
360*83ee113eSDavid van Moolenbroek 	return get_next_token(rval, rlen, cfile, ISC_FALSE);
361*83ee113eSDavid van Moolenbroek }
362*83ee113eSDavid van Moolenbroek 
363*83ee113eSDavid van Moolenbroek 
364*83ee113eSDavid van Moolenbroek /*
365*83ee113eSDavid van Moolenbroek  * The same as the next_token() function above, but will return space
366*83ee113eSDavid van Moolenbroek  * as the WHITESPACE token.
367*83ee113eSDavid van Moolenbroek  */
368*83ee113eSDavid van Moolenbroek 
369*83ee113eSDavid van Moolenbroek enum dhcp_token
next_raw_token(const char ** rval,unsigned * rlen,struct parse * cfile)370*83ee113eSDavid van Moolenbroek next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
371*83ee113eSDavid van Moolenbroek 	return get_next_token(rval, rlen, cfile, ISC_TRUE);
372*83ee113eSDavid van Moolenbroek }
373*83ee113eSDavid van Moolenbroek 
374*83ee113eSDavid van Moolenbroek 
375*83ee113eSDavid van Moolenbroek /*
376*83ee113eSDavid van Moolenbroek  * The do_peek_token() function checks the next token without
377*83ee113eSDavid van Moolenbroek  * consuming it, and returns it to the caller.
378*83ee113eSDavid van Moolenbroek  *
379*83ee113eSDavid van Moolenbroek  * Since the code is almost the same for "normal" and "raw"
380*83ee113eSDavid van Moolenbroek  * input, we pass a flag to alter the way it works. (See the
381*83ee113eSDavid van Moolenbroek  * warning in the GENERAL NOTES ABOUT TOKENS above though.)
382*83ee113eSDavid van Moolenbroek  */
383*83ee113eSDavid van Moolenbroek 
384*83ee113eSDavid van Moolenbroek static enum dhcp_token
do_peek_token(const char ** rval,unsigned int * rlen,struct parse * cfile,isc_boolean_t raw)385*83ee113eSDavid van Moolenbroek do_peek_token(const char **rval, unsigned int *rlen,
386*83ee113eSDavid van Moolenbroek 	      struct parse *cfile, isc_boolean_t raw) {
387*83ee113eSDavid van Moolenbroek 	int x;
388*83ee113eSDavid van Moolenbroek 
389*83ee113eSDavid van Moolenbroek 	if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
390*83ee113eSDavid van Moolenbroek 		cfile -> tlpos = cfile -> lexchar;
391*83ee113eSDavid van Moolenbroek 		cfile -> tline = cfile -> lexline;
392*83ee113eSDavid van Moolenbroek 
393*83ee113eSDavid van Moolenbroek 		do {
394*83ee113eSDavid van Moolenbroek 			cfile->token = get_raw_token(cfile);
395*83ee113eSDavid van Moolenbroek 		} while (!raw && (cfile->token == WHITESPACE));
396*83ee113eSDavid van Moolenbroek 
397*83ee113eSDavid van Moolenbroek 		if (cfile -> lexline != cfile -> tline)
398*83ee113eSDavid van Moolenbroek 			cfile -> token_line = cfile -> prev_line;
399*83ee113eSDavid van Moolenbroek 
400*83ee113eSDavid van Moolenbroek 		x = cfile -> lexchar;
401*83ee113eSDavid van Moolenbroek 		cfile -> lexchar = cfile -> tlpos;
402*83ee113eSDavid van Moolenbroek 		cfile -> tlpos = x;
403*83ee113eSDavid van Moolenbroek 
404*83ee113eSDavid van Moolenbroek 		x = cfile -> lexline;
405*83ee113eSDavid van Moolenbroek 		cfile -> lexline = cfile -> tline;
406*83ee113eSDavid van Moolenbroek 		cfile -> tline = x;
407*83ee113eSDavid van Moolenbroek 	}
408*83ee113eSDavid van Moolenbroek 	if (rval)
409*83ee113eSDavid van Moolenbroek 		*rval = cfile -> tval;
410*83ee113eSDavid van Moolenbroek 	if (rlen)
411*83ee113eSDavid van Moolenbroek 		*rlen = cfile -> tlen;
412*83ee113eSDavid van Moolenbroek #ifdef DEBUG_TOKENS
413*83ee113eSDavid van Moolenbroek 	fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
414*83ee113eSDavid van Moolenbroek #endif
415*83ee113eSDavid van Moolenbroek 	return cfile -> token;
416*83ee113eSDavid van Moolenbroek }
417*83ee113eSDavid van Moolenbroek 
418*83ee113eSDavid van Moolenbroek 
419*83ee113eSDavid van Moolenbroek /*
420*83ee113eSDavid van Moolenbroek  * Get the next token from cfile and return it, leaving it for a
421*83ee113eSDavid van Moolenbroek  * subsequent call to next_token().
422*83ee113eSDavid van Moolenbroek  *
423*83ee113eSDavid van Moolenbroek  * Note that it WILL consume whitespace tokens.
424*83ee113eSDavid van Moolenbroek  *
425*83ee113eSDavid van Moolenbroek  * If rval is non-NULL, set the pointer it contains to
426*83ee113eSDavid van Moolenbroek  * the contents of the token.
427*83ee113eSDavid van Moolenbroek  *
428*83ee113eSDavid van Moolenbroek  * If rlen is non-NULL, set the integer it contains to
429*83ee113eSDavid van Moolenbroek  * the length of the token.
430*83ee113eSDavid van Moolenbroek  */
431*83ee113eSDavid van Moolenbroek 
432*83ee113eSDavid van Moolenbroek enum dhcp_token
peek_token(const char ** rval,unsigned * rlen,struct parse * cfile)433*83ee113eSDavid van Moolenbroek peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
434*83ee113eSDavid van Moolenbroek 	return do_peek_token(rval, rlen, cfile, ISC_FALSE);
435*83ee113eSDavid van Moolenbroek }
436*83ee113eSDavid van Moolenbroek 
437*83ee113eSDavid van Moolenbroek 
438*83ee113eSDavid van Moolenbroek /*
439*83ee113eSDavid van Moolenbroek  * The same as the peek_token() function above, but will return space
440*83ee113eSDavid van Moolenbroek  * as the WHITESPACE token.
441*83ee113eSDavid van Moolenbroek  */
442*83ee113eSDavid van Moolenbroek 
443*83ee113eSDavid van Moolenbroek enum dhcp_token
peek_raw_token(const char ** rval,unsigned * rlen,struct parse * cfile)444*83ee113eSDavid van Moolenbroek peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
445*83ee113eSDavid van Moolenbroek 	return do_peek_token(rval, rlen, cfile, ISC_TRUE);
446*83ee113eSDavid van Moolenbroek }
447*83ee113eSDavid van Moolenbroek 
skip_to_eol(cfile)448*83ee113eSDavid van Moolenbroek static void skip_to_eol (cfile)
449*83ee113eSDavid van Moolenbroek 	struct parse *cfile;
450*83ee113eSDavid van Moolenbroek {
451*83ee113eSDavid van Moolenbroek 	int c;
452*83ee113eSDavid van Moolenbroek 	do {
453*83ee113eSDavid van Moolenbroek 		c = get_char (cfile);
454*83ee113eSDavid van Moolenbroek 		if (c == EOF)
455*83ee113eSDavid van Moolenbroek 			return;
456*83ee113eSDavid van Moolenbroek 		if (c == EOL) {
457*83ee113eSDavid van Moolenbroek 			return;
458*83ee113eSDavid van Moolenbroek 		}
459*83ee113eSDavid van Moolenbroek 	} while (1);
460*83ee113eSDavid van Moolenbroek }
461*83ee113eSDavid van Moolenbroek 
462*83ee113eSDavid van Moolenbroek static enum dhcp_token
read_whitespace(int c,struct parse * cfile)463*83ee113eSDavid van Moolenbroek read_whitespace(int c, struct parse *cfile) {
464*83ee113eSDavid van Moolenbroek 	int ofs;
465*83ee113eSDavid van Moolenbroek 
466*83ee113eSDavid van Moolenbroek 	/*
467*83ee113eSDavid van Moolenbroek 	 * Read as much whitespace as we have available.
468*83ee113eSDavid van Moolenbroek 	 */
469*83ee113eSDavid van Moolenbroek 	ofs = 0;
470*83ee113eSDavid van Moolenbroek 	do {
471*83ee113eSDavid van Moolenbroek 		if (ofs >= sizeof(cfile->tokbuf)) {
472*83ee113eSDavid van Moolenbroek 			/*
473*83ee113eSDavid van Moolenbroek 			 * As the file includes a huge amount of whitespace,
474*83ee113eSDavid van Moolenbroek 			 * it's probably broken.
475*83ee113eSDavid van Moolenbroek 			 * Print out a warning and bail out.
476*83ee113eSDavid van Moolenbroek 			 */
477*83ee113eSDavid van Moolenbroek 			parse_warn(cfile,
478*83ee113eSDavid van Moolenbroek 				   "whitespace too long, buffer overflow.");
479*83ee113eSDavid van Moolenbroek 			log_fatal("Exiting");
480*83ee113eSDavid van Moolenbroek 		}
481*83ee113eSDavid van Moolenbroek 		cfile->tokbuf[ofs++] = c;
482*83ee113eSDavid van Moolenbroek 		c = get_char(cfile);
483*83ee113eSDavid van Moolenbroek 	} while (!((c == '\n') && cfile->eol_token) &&
484*83ee113eSDavid van Moolenbroek 		 isascii(c) && isspace(c));
485*83ee113eSDavid van Moolenbroek 
486*83ee113eSDavid van Moolenbroek 	/*
487*83ee113eSDavid van Moolenbroek 	 * Put the last (non-whitespace) character back.
488*83ee113eSDavid van Moolenbroek 	 */
489*83ee113eSDavid van Moolenbroek 	unget_char(cfile, c);
490*83ee113eSDavid van Moolenbroek 
491*83ee113eSDavid van Moolenbroek 	/*
492*83ee113eSDavid van Moolenbroek 	 * Return our token.
493*83ee113eSDavid van Moolenbroek 	 */
494*83ee113eSDavid van Moolenbroek 	cfile->tokbuf[ofs] = '\0';
495*83ee113eSDavid van Moolenbroek 	cfile->tlen = ofs;
496*83ee113eSDavid van Moolenbroek 	cfile->tval = cfile->tokbuf;
497*83ee113eSDavid van Moolenbroek 	return WHITESPACE;
498*83ee113eSDavid van Moolenbroek }
499*83ee113eSDavid van Moolenbroek 
read_string(cfile)500*83ee113eSDavid van Moolenbroek static enum dhcp_token read_string (cfile)
501*83ee113eSDavid van Moolenbroek 	struct parse *cfile;
502*83ee113eSDavid van Moolenbroek {
503*83ee113eSDavid van Moolenbroek 	int i;
504*83ee113eSDavid van Moolenbroek 	int bs = 0;
505*83ee113eSDavid van Moolenbroek 	int c;
506*83ee113eSDavid van Moolenbroek 	int value = 0;
507*83ee113eSDavid van Moolenbroek 	int hex = 0;
508*83ee113eSDavid van Moolenbroek 
509*83ee113eSDavid van Moolenbroek 	for (i = 0; i < sizeof cfile -> tokbuf; i++) {
510*83ee113eSDavid van Moolenbroek 	      again:
511*83ee113eSDavid van Moolenbroek 		c = get_char (cfile);
512*83ee113eSDavid van Moolenbroek 		if (c == EOF) {
513*83ee113eSDavid van Moolenbroek 			parse_warn (cfile, "eof in string constant");
514*83ee113eSDavid van Moolenbroek 			break;
515*83ee113eSDavid van Moolenbroek 		}
516*83ee113eSDavid van Moolenbroek 		if (bs == 1) {
517*83ee113eSDavid van Moolenbroek 			switch (c) {
518*83ee113eSDavid van Moolenbroek 			      case 't':
519*83ee113eSDavid van Moolenbroek 				cfile -> tokbuf [i] = '\t';
520*83ee113eSDavid van Moolenbroek 				break;
521*83ee113eSDavid van Moolenbroek 			      case 'r':
522*83ee113eSDavid van Moolenbroek 				cfile -> tokbuf [i] = '\r';
523*83ee113eSDavid van Moolenbroek 				break;
524*83ee113eSDavid van Moolenbroek 			      case 'n':
525*83ee113eSDavid van Moolenbroek 				cfile -> tokbuf [i] = '\n';
526*83ee113eSDavid van Moolenbroek 				break;
527*83ee113eSDavid van Moolenbroek 			      case 'b':
528*83ee113eSDavid van Moolenbroek 				cfile -> tokbuf [i] = '\b';
529*83ee113eSDavid van Moolenbroek 				break;
530*83ee113eSDavid van Moolenbroek 			      case '0':
531*83ee113eSDavid van Moolenbroek 			      case '1':
532*83ee113eSDavid van Moolenbroek 			      case '2':
533*83ee113eSDavid van Moolenbroek 			      case '3':
534*83ee113eSDavid van Moolenbroek 				hex = 0;
535*83ee113eSDavid van Moolenbroek 				value = c - '0';
536*83ee113eSDavid van Moolenbroek 				++bs;
537*83ee113eSDavid van Moolenbroek 				goto again;
538*83ee113eSDavid van Moolenbroek 			      case 'x':
539*83ee113eSDavid van Moolenbroek 				hex = 1;
540*83ee113eSDavid van Moolenbroek 				value = 0;
541*83ee113eSDavid van Moolenbroek 				++bs;
542*83ee113eSDavid van Moolenbroek 				goto again;
543*83ee113eSDavid van Moolenbroek 			      default:
544*83ee113eSDavid van Moolenbroek 				cfile -> tokbuf [i] = c;
545*83ee113eSDavid van Moolenbroek 				break;
546*83ee113eSDavid van Moolenbroek 			}
547*83ee113eSDavid van Moolenbroek 			bs = 0;
548*83ee113eSDavid van Moolenbroek 		} else if (bs > 1) {
549*83ee113eSDavid van Moolenbroek 			if (hex) {
550*83ee113eSDavid van Moolenbroek 				if (c >= '0' && c <= '9') {
551*83ee113eSDavid van Moolenbroek 					value = value * 16 + (c - '0');
552*83ee113eSDavid van Moolenbroek 				} else if (c >= 'a' && c <= 'f') {
553*83ee113eSDavid van Moolenbroek 					value = value * 16 + (c - 'a' + 10);
554*83ee113eSDavid van Moolenbroek 				} else if (c >= 'A' && c <= 'F') {
555*83ee113eSDavid van Moolenbroek 					value = value * 16 + (c - 'A' + 10);
556*83ee113eSDavid van Moolenbroek 				} else {
557*83ee113eSDavid van Moolenbroek 					parse_warn (cfile,
558*83ee113eSDavid van Moolenbroek 						    "invalid hex digit: %x",
559*83ee113eSDavid van Moolenbroek 						    c);
560*83ee113eSDavid van Moolenbroek 					bs = 0;
561*83ee113eSDavid van Moolenbroek 					continue;
562*83ee113eSDavid van Moolenbroek 				}
563*83ee113eSDavid van Moolenbroek 				if (++bs == 4) {
564*83ee113eSDavid van Moolenbroek 					cfile -> tokbuf [i] = value;
565*83ee113eSDavid van Moolenbroek 					bs = 0;
566*83ee113eSDavid van Moolenbroek 				} else
567*83ee113eSDavid van Moolenbroek 					goto again;
568*83ee113eSDavid van Moolenbroek 			} else {
569*83ee113eSDavid van Moolenbroek 				if (c >= '0' && c <= '7') {
570*83ee113eSDavid van Moolenbroek 					value = value * 8 + (c - '0');
571*83ee113eSDavid van Moolenbroek 				} else {
572*83ee113eSDavid van Moolenbroek 				    if (value != 0) {
573*83ee113eSDavid van Moolenbroek 					parse_warn (cfile,
574*83ee113eSDavid van Moolenbroek 						    "invalid octal digit %x",
575*83ee113eSDavid van Moolenbroek 						    c);
576*83ee113eSDavid van Moolenbroek 					continue;
577*83ee113eSDavid van Moolenbroek 				    } else
578*83ee113eSDavid van Moolenbroek 					cfile -> tokbuf [i] = 0;
579*83ee113eSDavid van Moolenbroek 				    bs = 0;
580*83ee113eSDavid van Moolenbroek 				}
581*83ee113eSDavid van Moolenbroek 				if (++bs == 4) {
582*83ee113eSDavid van Moolenbroek 					cfile -> tokbuf [i] = value;
583*83ee113eSDavid van Moolenbroek 					bs = 0;
584*83ee113eSDavid van Moolenbroek 				} else
585*83ee113eSDavid van Moolenbroek 					goto again;
586*83ee113eSDavid van Moolenbroek 			}
587*83ee113eSDavid van Moolenbroek 		} else if (c == '\\') {
588*83ee113eSDavid van Moolenbroek 			bs = 1;
589*83ee113eSDavid van Moolenbroek 			goto again;
590*83ee113eSDavid van Moolenbroek 		} else if (c == '"')
591*83ee113eSDavid van Moolenbroek 			break;
592*83ee113eSDavid van Moolenbroek 		else
593*83ee113eSDavid van Moolenbroek 			cfile -> tokbuf [i] = c;
594*83ee113eSDavid van Moolenbroek 	}
595*83ee113eSDavid van Moolenbroek 	/* Normally, I'd feel guilty about this, but we're talking about
596*83ee113eSDavid van Moolenbroek 	   strings that'll fit in a DHCP packet here... */
597*83ee113eSDavid van Moolenbroek 	if (i == sizeof cfile -> tokbuf) {
598*83ee113eSDavid van Moolenbroek 		parse_warn (cfile,
599*83ee113eSDavid van Moolenbroek 			    "string constant larger than internal buffer");
600*83ee113eSDavid van Moolenbroek 		--i;
601*83ee113eSDavid van Moolenbroek 	}
602*83ee113eSDavid van Moolenbroek 	cfile -> tokbuf [i] = 0;
603*83ee113eSDavid van Moolenbroek 	cfile -> tlen = i;
604*83ee113eSDavid van Moolenbroek 	cfile -> tval = cfile -> tokbuf;
605*83ee113eSDavid van Moolenbroek 	return STRING;
606*83ee113eSDavid van Moolenbroek }
607*83ee113eSDavid van Moolenbroek 
read_number(c,cfile)608*83ee113eSDavid van Moolenbroek static enum dhcp_token read_number (c, cfile)
609*83ee113eSDavid van Moolenbroek 	int c;
610*83ee113eSDavid van Moolenbroek 	struct parse *cfile;
611*83ee113eSDavid van Moolenbroek {
612*83ee113eSDavid van Moolenbroek 	int i = 0;
613*83ee113eSDavid van Moolenbroek 	int token = NUMBER;
614*83ee113eSDavid van Moolenbroek 
615*83ee113eSDavid van Moolenbroek 	cfile -> tokbuf [i++] = c;
616*83ee113eSDavid van Moolenbroek 	for (; i < sizeof cfile -> tokbuf; i++) {
617*83ee113eSDavid van Moolenbroek 		c = get_char (cfile);
618*83ee113eSDavid van Moolenbroek 
619*83ee113eSDavid van Moolenbroek 		/* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
620*83ee113eSDavid van Moolenbroek 		 * Except in the case of '0x' syntax hex, which gets called
621*83ee113eSDavid van Moolenbroek 		 * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
622*83ee113eSDavid van Moolenbroek 		 * verified to be at least 0xf or less.
623*83ee113eSDavid van Moolenbroek 		 */
624*83ee113eSDavid van Moolenbroek 		switch(isascii(c) ? token : BREAK) {
625*83ee113eSDavid van Moolenbroek 		    case NUMBER:
626*83ee113eSDavid van Moolenbroek 			if(isdigit(c))
627*83ee113eSDavid van Moolenbroek 				break;
628*83ee113eSDavid van Moolenbroek 			/* FALLTHROUGH */
629*83ee113eSDavid van Moolenbroek 		    case NUMBER_OR_NAME:
630*83ee113eSDavid van Moolenbroek 			if(isxdigit(c)) {
631*83ee113eSDavid van Moolenbroek 				token = NUMBER_OR_NAME;
632*83ee113eSDavid van Moolenbroek 				break;
633*83ee113eSDavid van Moolenbroek 			}
634*83ee113eSDavid van Moolenbroek 			/* FALLTHROUGH */
635*83ee113eSDavid van Moolenbroek 		    case NAME:
636*83ee113eSDavid van Moolenbroek 			if((i == 2) && isxdigit(c) &&
637*83ee113eSDavid van Moolenbroek 				(cfile->tokbuf[0] == '0') &&
638*83ee113eSDavid van Moolenbroek 				((cfile->tokbuf[1] == 'x') ||
639*83ee113eSDavid van Moolenbroek 				 (cfile->tokbuf[1] == 'X'))) {
640*83ee113eSDavid van Moolenbroek 				token = NUMBER_OR_NAME;
641*83ee113eSDavid van Moolenbroek 				break;
642*83ee113eSDavid van Moolenbroek 			} else if(((c == '-') || (c == '_') || isalnum(c))) {
643*83ee113eSDavid van Moolenbroek 				token = NAME;
644*83ee113eSDavid van Moolenbroek 				break;
645*83ee113eSDavid van Moolenbroek 			}
646*83ee113eSDavid van Moolenbroek 			/* FALLTHROUGH */
647*83ee113eSDavid van Moolenbroek 		    case BREAK:
648*83ee113eSDavid van Moolenbroek 			/* At this point c is either EOF or part of the next
649*83ee113eSDavid van Moolenbroek 			 * token.  If not EOF, rewind the file one byte so
650*83ee113eSDavid van Moolenbroek 			 * the next token is read from there.
651*83ee113eSDavid van Moolenbroek 			 */
652*83ee113eSDavid van Moolenbroek 			unget_char(cfile, c);
653*83ee113eSDavid van Moolenbroek 			goto end_read;
654*83ee113eSDavid van Moolenbroek 
655*83ee113eSDavid van Moolenbroek 		    default:
656*83ee113eSDavid van Moolenbroek 			log_fatal("read_number():%s:%d: impossible case", MDL);
657*83ee113eSDavid van Moolenbroek 		}
658*83ee113eSDavid van Moolenbroek 
659*83ee113eSDavid van Moolenbroek 		cfile -> tokbuf [i] = c;
660*83ee113eSDavid van Moolenbroek 	}
661*83ee113eSDavid van Moolenbroek 
662*83ee113eSDavid van Moolenbroek 	if (i == sizeof cfile -> tokbuf) {
663*83ee113eSDavid van Moolenbroek 		parse_warn (cfile,
664*83ee113eSDavid van Moolenbroek 			    "numeric token larger than internal buffer");
665*83ee113eSDavid van Moolenbroek 		--i;
666*83ee113eSDavid van Moolenbroek 	}
667*83ee113eSDavid van Moolenbroek 
668*83ee113eSDavid van Moolenbroek   end_read:
669*83ee113eSDavid van Moolenbroek 	cfile -> tokbuf [i] = 0;
670*83ee113eSDavid van Moolenbroek 	cfile -> tlen = i;
671*83ee113eSDavid van Moolenbroek 	cfile -> tval = cfile -> tokbuf;
672*83ee113eSDavid van Moolenbroek 
673*83ee113eSDavid van Moolenbroek 	/*
674*83ee113eSDavid van Moolenbroek 	 * If this entire token from start to finish was "-", such as
675*83ee113eSDavid van Moolenbroek 	 * the middle parameter in "42 - 7", return just the MINUS token.
676*83ee113eSDavid van Moolenbroek 	 */
677*83ee113eSDavid van Moolenbroek 	if ((i == 1) && (cfile->tokbuf[i] == '-'))
678*83ee113eSDavid van Moolenbroek 		return MINUS;
679*83ee113eSDavid van Moolenbroek 	else
680*83ee113eSDavid van Moolenbroek 		return token;
681*83ee113eSDavid van Moolenbroek }
682*83ee113eSDavid van Moolenbroek 
read_num_or_name(c,cfile)683*83ee113eSDavid van Moolenbroek static enum dhcp_token read_num_or_name (c, cfile)
684*83ee113eSDavid van Moolenbroek 	int c;
685*83ee113eSDavid van Moolenbroek 	struct parse *cfile;
686*83ee113eSDavid van Moolenbroek {
687*83ee113eSDavid van Moolenbroek 	int i = 0;
688*83ee113eSDavid van Moolenbroek 	enum dhcp_token rv = NUMBER_OR_NAME;
689*83ee113eSDavid van Moolenbroek 	cfile -> tokbuf [i++] = c;
690*83ee113eSDavid van Moolenbroek 	for (; i < sizeof cfile -> tokbuf; i++) {
691*83ee113eSDavid van Moolenbroek 		c = get_char (cfile);
692*83ee113eSDavid van Moolenbroek 		if (!isascii (c) ||
693*83ee113eSDavid van Moolenbroek 		    (c != '-' && c != '_' && !isalnum (c))) {
694*83ee113eSDavid van Moolenbroek 		    	unget_char(cfile, c);
695*83ee113eSDavid van Moolenbroek 			break;
696*83ee113eSDavid van Moolenbroek 		}
697*83ee113eSDavid van Moolenbroek 		if (!isxdigit (c))
698*83ee113eSDavid van Moolenbroek 			rv = NAME;
699*83ee113eSDavid van Moolenbroek 		cfile -> tokbuf [i] = c;
700*83ee113eSDavid van Moolenbroek 	}
701*83ee113eSDavid van Moolenbroek 	if (i == sizeof cfile -> tokbuf) {
702*83ee113eSDavid van Moolenbroek 		parse_warn (cfile, "token larger than internal buffer");
703*83ee113eSDavid van Moolenbroek 		--i;
704*83ee113eSDavid van Moolenbroek 	}
705*83ee113eSDavid van Moolenbroek 	cfile -> tokbuf [i] = 0;
706*83ee113eSDavid van Moolenbroek 	cfile -> tlen = i;
707*83ee113eSDavid van Moolenbroek 	cfile -> tval = cfile -> tokbuf;
708*83ee113eSDavid van Moolenbroek 	return intern(cfile->tval, rv);
709*83ee113eSDavid van Moolenbroek }
710*83ee113eSDavid van Moolenbroek 
711*83ee113eSDavid van Moolenbroek static enum dhcp_token
intern(char * atom,enum dhcp_token dfv)712*83ee113eSDavid van Moolenbroek intern(char *atom, enum dhcp_token dfv) {
713*83ee113eSDavid van Moolenbroek 	if (!isascii(atom[0]))
714*83ee113eSDavid van Moolenbroek 		return dfv;
715*83ee113eSDavid van Moolenbroek 
716*83ee113eSDavid van Moolenbroek 	switch (tolower((unsigned char)atom[0])) {
717*83ee113eSDavid van Moolenbroek 	      case '-':
718*83ee113eSDavid van Moolenbroek 		if (atom [1] == 0)
719*83ee113eSDavid van Moolenbroek 			return MINUS;
720*83ee113eSDavid van Moolenbroek 		break;
721*83ee113eSDavid van Moolenbroek 
722*83ee113eSDavid van Moolenbroek 	      case 'a':
723*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "bandoned"))
724*83ee113eSDavid van Moolenbroek 			return TOKEN_ABANDONED;
725*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ctive"))
726*83ee113eSDavid van Moolenbroek 			return TOKEN_ACTIVE;
727*83ee113eSDavid van Moolenbroek 		if (!strncasecmp(atom + 1, "dd", 2)) {
728*83ee113eSDavid van Moolenbroek 			if (atom[3] == '\0')
729*83ee113eSDavid van Moolenbroek 				return TOKEN_ADD;
730*83ee113eSDavid van Moolenbroek 			else if (!strcasecmp(atom + 3, "ress"))
731*83ee113eSDavid van Moolenbroek 				return ADDRESS;
732*83ee113eSDavid van Moolenbroek 			break;
733*83ee113eSDavid van Moolenbroek 		}
734*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "fter"))
735*83ee113eSDavid van Moolenbroek 			return AFTER;
736*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
737*83ee113eSDavid van Moolenbroek 		    (tolower((unsigned char)atom[1]) == 'l')) {
738*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "gorithm"))
739*83ee113eSDavid van Moolenbroek 				return ALGORITHM;
740*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "ias"))
741*83ee113eSDavid van Moolenbroek 				return ALIAS;
742*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
743*83ee113eSDavid van Moolenbroek 			    (tolower((unsigned char)atom[2]) == 'l')) {
744*83ee113eSDavid van Moolenbroek 				if (atom[3] == '\0')
745*83ee113eSDavid van Moolenbroek 					return ALL;
746*83ee113eSDavid van Moolenbroek 				else if (!strcasecmp(atom + 3, "ow"))
747*83ee113eSDavid van Moolenbroek 					return ALLOW;
748*83ee113eSDavid van Moolenbroek 				break;
749*83ee113eSDavid van Moolenbroek 			}
750*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "so"))
751*83ee113eSDavid van Moolenbroek 				return TOKEN_ALSO;
752*83ee113eSDavid van Moolenbroek 			break;
753*83ee113eSDavid van Moolenbroek 		}
754*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
755*83ee113eSDavid van Moolenbroek 		    (tolower((unsigned char)atom[1]) == 'n')) {
756*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "d"))
757*83ee113eSDavid van Moolenbroek 				return AND;
758*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "ycast-mac"))
759*83ee113eSDavid van Moolenbroek 				return ANYCAST_MAC;
760*83ee113eSDavid van Moolenbroek 			break;
761*83ee113eSDavid van Moolenbroek 		}
762*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ppend"))
763*83ee113eSDavid van Moolenbroek 			return APPEND;
764*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "rray"))
765*83ee113eSDavid van Moolenbroek 			return ARRAY;
766*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
767*83ee113eSDavid van Moolenbroek 		    (tolower((unsigned char)atom[1]) == 't')) {
768*83ee113eSDavid van Moolenbroek 			if (atom[2] == '\0')
769*83ee113eSDavid van Moolenbroek 				return AT;
770*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "sfp"))
771*83ee113eSDavid van Moolenbroek 				return ATSFP;
772*83ee113eSDavid van Moolenbroek 			break;
773*83ee113eSDavid van Moolenbroek 		}
774*83ee113eSDavid van Moolenbroek 		if (!strncasecmp(atom + 1, "ut", 2)) {
775*83ee113eSDavid van Moolenbroek 			if (isascii(atom[3]) &&
776*83ee113eSDavid van Moolenbroek 			    (tolower((unsigned char)atom[3]) == 'h')) {
777*83ee113eSDavid van Moolenbroek 				if (!strncasecmp(atom + 4, "enticat", 7)) {
778*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 11, "ed"))
779*83ee113eSDavid van Moolenbroek 						return AUTHENTICATED;
780*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 11, "ion"))
781*83ee113eSDavid van Moolenbroek 						return AUTHENTICATION;
782*83ee113eSDavid van Moolenbroek 					break;
783*83ee113eSDavid van Moolenbroek 				}
784*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 4, "oritative"))
785*83ee113eSDavid van Moolenbroek 					return AUTHORITATIVE;
786*83ee113eSDavid van Moolenbroek 				break;
787*83ee113eSDavid van Moolenbroek 			}
788*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 3, "o-partner-down"))
789*83ee113eSDavid van Moolenbroek 				return AUTO_PARTNER_DOWN;
790*83ee113eSDavid van Moolenbroek 			break;
791*83ee113eSDavid van Moolenbroek 		}
792*83ee113eSDavid van Moolenbroek 		break;
793*83ee113eSDavid van Moolenbroek 	      case 'b':
794*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ackup"))
795*83ee113eSDavid van Moolenbroek 			return TOKEN_BACKUP;
796*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ootp"))
797*83ee113eSDavid van Moolenbroek 			return TOKEN_BOOTP;
798*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "inding"))
799*83ee113eSDavid van Moolenbroek 			return BINDING;
800*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "inary-to-ascii"))
801*83ee113eSDavid van Moolenbroek 			return BINARY_TO_ASCII;
802*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ackoff-cutoff"))
803*83ee113eSDavid van Moolenbroek 			return BACKOFF_CUTOFF;
804*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ooting"))
805*83ee113eSDavid van Moolenbroek 			return BOOTING;
806*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "oot-unknown-clients"))
807*83ee113eSDavid van Moolenbroek 			return BOOT_UNKNOWN_CLIENTS;
808*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "reak"))
809*83ee113eSDavid van Moolenbroek 			return BREAK;
810*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "illing"))
811*83ee113eSDavid van Moolenbroek 			return BILLING;
812*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "oolean"))
813*83ee113eSDavid van Moolenbroek 			return BOOLEAN;
814*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "alance"))
815*83ee113eSDavid van Moolenbroek 			return BALANCE;
816*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ound"))
817*83ee113eSDavid van Moolenbroek 			return BOUND;
818*83ee113eSDavid van Moolenbroek 		break;
819*83ee113eSDavid van Moolenbroek 	      case 'c':
820*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ase"))
821*83ee113eSDavid van Moolenbroek 			return CASE;
822*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "heck"))
823*83ee113eSDavid van Moolenbroek 			return CHECK;
824*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "iaddr"))
825*83ee113eSDavid van Moolenbroek 			return CIADDR;
826*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
827*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'l') {
828*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "ass"))
829*83ee113eSDavid van Moolenbroek 				return CLASS;
830*83ee113eSDavid van Moolenbroek 			if (!strncasecmp(atom + 2, "ient", 4)) {
831*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 6, "s"))
832*83ee113eSDavid van Moolenbroek 					return CLIENTS;
833*83ee113eSDavid van Moolenbroek 				if (atom[6] == '-') {
834*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 7, "hostname"))
835*83ee113eSDavid van Moolenbroek 						return CLIENT_HOSTNAME;
836*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 7, "identifier"))
837*83ee113eSDavid van Moolenbroek 						return CLIENT_IDENTIFIER;
838*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 7, "state"))
839*83ee113eSDavid van Moolenbroek 						return CLIENT_STATE;
840*83ee113eSDavid van Moolenbroek 					if (!strcasecmp(atom + 7, "updates"))
841*83ee113eSDavid van Moolenbroek 						return CLIENT_UPDATES;
842*83ee113eSDavid van Moolenbroek 					break;
843*83ee113eSDavid van Moolenbroek 				}
844*83ee113eSDavid van Moolenbroek 				break;
845*83ee113eSDavid van Moolenbroek 			}
846*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "ose"))
847*83ee113eSDavid van Moolenbroek 				return TOKEN_CLOSE;
848*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "tt"))
849*83ee113eSDavid van Moolenbroek 				return CLTT;
850*83ee113eSDavid van Moolenbroek 			break;
851*83ee113eSDavid van Moolenbroek 		}
852*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
853*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'o') {
854*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "de"))
855*83ee113eSDavid van Moolenbroek 				return CODE;
856*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
857*83ee113eSDavid van Moolenbroek 			    tolower((unsigned char)atom[2]) == 'm') {
858*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "mit"))
859*83ee113eSDavid van Moolenbroek 					return COMMIT;
860*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3,
861*83ee113eSDavid van Moolenbroek 						"munications-interrupted"))
862*83ee113eSDavid van Moolenbroek 					return COMMUNICATIONS_INTERRUPTED;
863*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "pressed"))
864*83ee113eSDavid van Moolenbroek 					return COMPRESSED;
865*83ee113eSDavid van Moolenbroek 				break;
866*83ee113eSDavid van Moolenbroek 			}
867*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
868*83ee113eSDavid van Moolenbroek 			    tolower((unsigned char)atom[2]) == 'n') {
869*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "cat"))
870*83ee113eSDavid van Moolenbroek 					return CONCAT;
871*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "fig-option"))
872*83ee113eSDavid van Moolenbroek 					return CONFIG_OPTION;
873*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "flict-done"))
874*83ee113eSDavid van Moolenbroek 					return CONFLICT_DONE;
875*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "nect"))
876*83ee113eSDavid van Moolenbroek 					return CONNECT;
877*83ee113eSDavid van Moolenbroek 				break;
878*83ee113eSDavid van Moolenbroek 			}
879*83ee113eSDavid van Moolenbroek 			break;
880*83ee113eSDavid van Moolenbroek 		}
881*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "reate"))
882*83ee113eSDavid van Moolenbroek 			return TOKEN_CREATE;
883*83ee113eSDavid van Moolenbroek 		break;
884*83ee113eSDavid van Moolenbroek 	      case 'd':
885*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "b-time-format"))
886*83ee113eSDavid van Moolenbroek 			return DB_TIME_FORMAT;
887*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "omain"))
888*83ee113eSDavid van Moolenbroek 			return DOMAIN;
889*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "omain-", 6)) {
890*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 7, "name"))
891*83ee113eSDavid van Moolenbroek 				return DOMAIN_NAME;
892*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 7, "list"))
893*83ee113eSDavid van Moolenbroek 				return DOMAIN_LIST;
894*83ee113eSDavid van Moolenbroek 		}
895*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "o-forward-update"))
896*83ee113eSDavid van Moolenbroek 			return DO_FORWARD_UPDATE;
897*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ebug"))
898*83ee113eSDavid van Moolenbroek 			return TOKEN_DEBUG;
899*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "eny"))
900*83ee113eSDavid van Moolenbroek 			return DENY;
901*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "eleted"))
902*83ee113eSDavid van Moolenbroek 			return TOKEN_DELETED;
903*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "elete"))
904*83ee113eSDavid van Moolenbroek 			return TOKEN_DELETE;
905*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "efault", 6)) {
906*83ee113eSDavid van Moolenbroek 			if (!atom [7])
907*83ee113eSDavid van Moolenbroek 				return DEFAULT;
908*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 7, "-duid"))
909*83ee113eSDavid van Moolenbroek 				return DEFAULT_DUID;
910*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 7, "-lease-time"))
911*83ee113eSDavid van Moolenbroek 				return DEFAULT_LEASE_TIME;
912*83ee113eSDavid van Moolenbroek 			break;
913*83ee113eSDavid van Moolenbroek 		}
914*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "ynamic", 6)) {
915*83ee113eSDavid van Moolenbroek 			if (!atom [7])
916*83ee113eSDavid van Moolenbroek 				return DYNAMIC;
917*83ee113eSDavid van Moolenbroek 			if (!strncasecmp (atom + 7, "-bootp", 6)) {
918*83ee113eSDavid van Moolenbroek 				if (!atom [13])
919*83ee113eSDavid van Moolenbroek 					return DYNAMIC_BOOTP;
920*83ee113eSDavid van Moolenbroek 				if (!strcasecmp (atom + 13, "-lease-cutoff"))
921*83ee113eSDavid van Moolenbroek 					return DYNAMIC_BOOTP_LEASE_CUTOFF;
922*83ee113eSDavid van Moolenbroek 				if (!strcasecmp (atom + 13, "-lease-length"))
923*83ee113eSDavid van Moolenbroek 					return DYNAMIC_BOOTP_LEASE_LENGTH;
924*83ee113eSDavid van Moolenbroek 				break;
925*83ee113eSDavid van Moolenbroek 			}
926*83ee113eSDavid van Moolenbroek 		}
927*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "uplicates"))
928*83ee113eSDavid van Moolenbroek 			return DUPLICATES;
929*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "eclines"))
930*83ee113eSDavid van Moolenbroek 			return DECLINES;
931*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "efine", 5)) {
932*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 6, "d"))
933*83ee113eSDavid van Moolenbroek 				return DEFINED;
934*83ee113eSDavid van Moolenbroek 			if (!atom [6])
935*83ee113eSDavid van Moolenbroek 				return DEFINE;
936*83ee113eSDavid van Moolenbroek 		}
937*83ee113eSDavid van Moolenbroek 		break;
938*83ee113eSDavid van Moolenbroek 	      case 'e':
939*83ee113eSDavid van Moolenbroek 		if (isascii (atom [1]) &&
940*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'x') {
941*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 2, "tract-int"))
942*83ee113eSDavid van Moolenbroek 				return EXTRACT_INT;
943*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 2, "ists"))
944*83ee113eSDavid van Moolenbroek 				return EXISTS;
945*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 2, "piry"))
946*83ee113eSDavid van Moolenbroek 				return EXPIRY;
947*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 2, "pire"))
948*83ee113eSDavid van Moolenbroek 				return EXPIRE;
949*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 2, "pired"))
950*83ee113eSDavid van Moolenbroek 				return TOKEN_EXPIRED;
951*83ee113eSDavid van Moolenbroek 		}
952*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ncode-int"))
953*83ee113eSDavid van Moolenbroek 			return ENCODE_INT;
954*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "poch"))
955*83ee113eSDavid van Moolenbroek 			return EPOCH;
956*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "thernet"))
957*83ee113eSDavid van Moolenbroek 			return ETHERNET;
958*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nds"))
959*83ee113eSDavid van Moolenbroek 			return ENDS;
960*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "ls", 2)) {
961*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "e"))
962*83ee113eSDavid van Moolenbroek 				return ELSE;
963*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "if"))
964*83ee113eSDavid van Moolenbroek 				return ELSIF;
965*83ee113eSDavid van Moolenbroek 			break;
966*83ee113eSDavid van Moolenbroek 		}
967*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "rror"))
968*83ee113eSDavid van Moolenbroek 			return ERROR;
969*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "val"))
970*83ee113eSDavid van Moolenbroek 			return EVAL;
971*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ncapsulate"))
972*83ee113eSDavid van Moolenbroek 			return ENCAPSULATE;
973*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "xecute"))
974*83ee113eSDavid van Moolenbroek 			return EXECUTE;
975*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom+1, "n")) {
976*83ee113eSDavid van Moolenbroek 			return EN;
977*83ee113eSDavid van Moolenbroek 		}
978*83ee113eSDavid van Moolenbroek 		break;
979*83ee113eSDavid van Moolenbroek 	      case 'f':
980*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "atal"))
981*83ee113eSDavid van Moolenbroek 			return FATAL;
982*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ilename"))
983*83ee113eSDavid van Moolenbroek 			return FILENAME;
984*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ixed-address"))
985*83ee113eSDavid van Moolenbroek 			return FIXED_ADDR;
986*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ixed-address6"))
987*83ee113eSDavid van Moolenbroek 			return FIXED_ADDR6;
988*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ixed-prefix6"))
989*83ee113eSDavid van Moolenbroek 			return FIXED_PREFIX6;
990*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ddi"))
991*83ee113eSDavid van Moolenbroek 			return TOKEN_FDDI;
992*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ormerr"))
993*83ee113eSDavid van Moolenbroek 			return NS_FORMERR;
994*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "unction"))
995*83ee113eSDavid van Moolenbroek 			return FUNCTION;
996*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ailover"))
997*83ee113eSDavid van Moolenbroek 			return FAILOVER;
998*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ree"))
999*83ee113eSDavid van Moolenbroek 			return TOKEN_FREE;
1000*83ee113eSDavid van Moolenbroek 		break;
1001*83ee113eSDavid van Moolenbroek 	      case 'g':
1002*83ee113eSDavid van Moolenbroek 		if (!strncasecmp(atom + 1, "et", 2)) {
1003*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 3, "-lease-hostnames"))
1004*83ee113eSDavid van Moolenbroek 				return GET_LEASE_HOSTNAMES;
1005*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 3, "hostbyname"))
1006*83ee113eSDavid van Moolenbroek 				return GETHOSTBYNAME;
1007*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 3, "hostname"))
1008*83ee113eSDavid van Moolenbroek 				return GETHOSTNAME;
1009*83ee113eSDavid van Moolenbroek 			break;
1010*83ee113eSDavid van Moolenbroek 		}
1011*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "iaddr"))
1012*83ee113eSDavid van Moolenbroek 			return GIADDR;
1013*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "roup"))
1014*83ee113eSDavid van Moolenbroek 			return GROUP;
1015*83ee113eSDavid van Moolenbroek 		break;
1016*83ee113eSDavid van Moolenbroek 	      case 'h':
1017*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ash"))
1018*83ee113eSDavid van Moolenbroek 			return HASH;
1019*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ba"))
1020*83ee113eSDavid van Moolenbroek 			return HBA;
1021*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ost"))
1022*83ee113eSDavid van Moolenbroek 			return HOST;
1023*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ost-decl-name"))
1024*83ee113eSDavid van Moolenbroek 			return HOST_DECL_NAME;
1025*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ost-identifier"))
1026*83ee113eSDavid van Moolenbroek 			return HOST_IDENTIFIER;
1027*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ardware"))
1028*83ee113eSDavid van Moolenbroek 			return HARDWARE;
1029*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ostname"))
1030*83ee113eSDavid van Moolenbroek 			return HOSTNAME;
1031*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "elp"))
1032*83ee113eSDavid van Moolenbroek 			return TOKEN_HELP;
1033*83ee113eSDavid van Moolenbroek 		break;
1034*83ee113eSDavid van Moolenbroek 	      case 'i':
1035*83ee113eSDavid van Moolenbroek 	      	if (!strcasecmp(atom+1, "a-na"))
1036*83ee113eSDavid van Moolenbroek 			return IA_NA;
1037*83ee113eSDavid van Moolenbroek 	      	if (!strcasecmp(atom+1, "a-ta"))
1038*83ee113eSDavid van Moolenbroek 			return IA_TA;
1039*83ee113eSDavid van Moolenbroek 	      	if (!strcasecmp(atom+1, "a-pd"))
1040*83ee113eSDavid van Moolenbroek 			return IA_PD;
1041*83ee113eSDavid van Moolenbroek 	      	if (!strcasecmp(atom+1, "aaddr"))
1042*83ee113eSDavid van Moolenbroek 			return IAADDR;
1043*83ee113eSDavid van Moolenbroek 	      	if (!strcasecmp(atom+1, "aprefix"))
1044*83ee113eSDavid van Moolenbroek 			return IAPREFIX;
1045*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nclude"))
1046*83ee113eSDavid van Moolenbroek 			return INCLUDE;
1047*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nteger"))
1048*83ee113eSDavid van Moolenbroek 			return INTEGER;
1049*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom  + 1, "nfiniband"))
1050*83ee113eSDavid van Moolenbroek 			return TOKEN_INFINIBAND;
1051*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nfinite"))
1052*83ee113eSDavid van Moolenbroek 			return INFINITE;
1053*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nfo"))
1054*83ee113eSDavid van Moolenbroek 			return INFO;
1055*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "p-address"))
1056*83ee113eSDavid van Moolenbroek 			return IP_ADDRESS;
1057*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "p6-address"))
1058*83ee113eSDavid van Moolenbroek 			return IP6_ADDRESS;
1059*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nitial-interval"))
1060*83ee113eSDavid van Moolenbroek 			return INITIAL_INTERVAL;
1061*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nitial-delay"))
1062*83ee113eSDavid van Moolenbroek 			return INITIAL_DELAY;
1063*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nterface"))
1064*83ee113eSDavid van Moolenbroek 			return INTERFACE;
1065*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "dentifier"))
1066*83ee113eSDavid van Moolenbroek 			return IDENTIFIER;
1067*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "f"))
1068*83ee113eSDavid van Moolenbroek 			return IF;
1069*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "s"))
1070*83ee113eSDavid van Moolenbroek 			return IS;
1071*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "gnore"))
1072*83ee113eSDavid van Moolenbroek 			return IGNORE;
1073*83ee113eSDavid van Moolenbroek 		break;
1074*83ee113eSDavid van Moolenbroek 	      case 'k':
1075*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "nown", 4)) {
1076*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 5, "-clients"))
1077*83ee113eSDavid van Moolenbroek 				return KNOWN_CLIENTS;
1078*83ee113eSDavid van Moolenbroek 			if (!atom[5])
1079*83ee113eSDavid van Moolenbroek 				return KNOWN;
1080*83ee113eSDavid van Moolenbroek 			break;
1081*83ee113eSDavid van Moolenbroek 		}
1082*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ey"))
1083*83ee113eSDavid van Moolenbroek 			return KEY;
1084*83ee113eSDavid van Moolenbroek 		break;
1085*83ee113eSDavid van Moolenbroek 	      case 'l':
1086*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "case"))
1087*83ee113eSDavid van Moolenbroek 			return LCASE;
1088*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ease"))
1089*83ee113eSDavid van Moolenbroek 			return LEASE;
1090*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ease6"))
1091*83ee113eSDavid van Moolenbroek 			return LEASE6;
1092*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "eased-address"))
1093*83ee113eSDavid van Moolenbroek 			return LEASED_ADDRESS;
1094*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ease-time"))
1095*83ee113eSDavid van Moolenbroek 			return LEASE_TIME;
1096*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "easequery"))
1097*83ee113eSDavid van Moolenbroek 			return LEASEQUERY;
1098*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ength"))
1099*83ee113eSDavid van Moolenbroek 			return LENGTH;
1100*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "imit"))
1101*83ee113eSDavid van Moolenbroek 			return LIMIT;
1102*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "et"))
1103*83ee113eSDavid van Moolenbroek 			return LET;
1104*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "oad"))
1105*83ee113eSDavid van Moolenbroek 			return LOAD;
1106*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ocal"))
1107*83ee113eSDavid van Moolenbroek 			return LOCAL;
1108*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "og"))
1109*83ee113eSDavid van Moolenbroek 			return LOG;
1110*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom+1, "lt")) {
1111*83ee113eSDavid van Moolenbroek 			return LLT;
1112*83ee113eSDavid van Moolenbroek 		}
1113*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom+1, "l")) {
1114*83ee113eSDavid van Moolenbroek 			return LL;
1115*83ee113eSDavid van Moolenbroek 		}
1116*83ee113eSDavid van Moolenbroek 		break;
1117*83ee113eSDavid van Moolenbroek 	      case 'm':
1118*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "ax", 2)) {
1119*83ee113eSDavid van Moolenbroek 			if (!atom [3])
1120*83ee113eSDavid van Moolenbroek 				return TOKEN_MAX;
1121*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "-balance"))
1122*83ee113eSDavid van Moolenbroek 				return MAX_BALANCE;
1123*83ee113eSDavid van Moolenbroek 			if (!strncasecmp (atom + 3, "-lease-", 7)) {
1124*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 10, "misbalance"))
1125*83ee113eSDavid van Moolenbroek 					return MAX_LEASE_MISBALANCE;
1126*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 10, "ownership"))
1127*83ee113eSDavid van Moolenbroek 					return MAX_LEASE_OWNERSHIP;
1128*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 10, "time"))
1129*83ee113eSDavid van Moolenbroek 					return MAX_LEASE_TIME;
1130*83ee113eSDavid van Moolenbroek 			}
1131*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 3, "-life"))
1132*83ee113eSDavid van Moolenbroek 				return MAX_LIFE;
1133*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "-transmit-idle"))
1134*83ee113eSDavid van Moolenbroek 				return MAX_TRANSMIT_IDLE;
1135*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "-response-delay"))
1136*83ee113eSDavid van Moolenbroek 				return MAX_RESPONSE_DELAY;
1137*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "-unacked-updates"))
1138*83ee113eSDavid van Moolenbroek 				return MAX_UNACKED_UPDATES;
1139*83ee113eSDavid van Moolenbroek 		}
1140*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "in-", 3)) {
1141*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 4, "balance"))
1142*83ee113eSDavid van Moolenbroek 				return MIN_BALANCE;
1143*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 4, "lease-time"))
1144*83ee113eSDavid van Moolenbroek 				return MIN_LEASE_TIME;
1145*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 4, "secs"))
1146*83ee113eSDavid van Moolenbroek 				return MIN_SECS;
1147*83ee113eSDavid van Moolenbroek 			break;
1148*83ee113eSDavid van Moolenbroek 		}
1149*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "edi", 3)) {
1150*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 4, "a"))
1151*83ee113eSDavid van Moolenbroek 				return MEDIA;
1152*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 4, "um"))
1153*83ee113eSDavid van Moolenbroek 				return MEDIUM;
1154*83ee113eSDavid van Moolenbroek 			break;
1155*83ee113eSDavid van Moolenbroek 		}
1156*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "atch"))
1157*83ee113eSDavid van Moolenbroek 			return MATCH;
1158*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "embers"))
1159*83ee113eSDavid van Moolenbroek 			return MEMBERS;
1160*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "y"))
1161*83ee113eSDavid van Moolenbroek 			return MY;
1162*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "clt"))
1163*83ee113eSDavid van Moolenbroek 			return MCLT;
1164*83ee113eSDavid van Moolenbroek 		break;
1165*83ee113eSDavid van Moolenbroek 	      case 'n':
1166*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ormal"))
1167*83ee113eSDavid van Moolenbroek 			return NORMAL;
1168*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ameserver"))
1169*83ee113eSDavid van Moolenbroek 			return NAMESERVER;
1170*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "etmask"))
1171*83ee113eSDavid van Moolenbroek 			return NETMASK;
1172*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ever"))
1173*83ee113eSDavid van Moolenbroek 			return NEVER;
1174*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ext-server"))
1175*83ee113eSDavid van Moolenbroek 			return NEXT_SERVER;
1176*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ot"))
1177*83ee113eSDavid van Moolenbroek 			return TOKEN_NOT;
1178*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "o"))
1179*83ee113eSDavid van Moolenbroek 			return TOKEN_NO;
1180*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "oerror"))
1181*83ee113eSDavid van Moolenbroek 			return NS_NOERROR;
1182*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "otauth"))
1183*83ee113eSDavid van Moolenbroek 			return NS_NOTAUTH;
1184*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "otimp"))
1185*83ee113eSDavid van Moolenbroek 			return NS_NOTIMP;
1186*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "otzone"))
1187*83ee113eSDavid van Moolenbroek 			return NS_NOTZONE;
1188*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "xdomain"))
1189*83ee113eSDavid van Moolenbroek 			return NS_NXDOMAIN;
1190*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "xrrset"))
1191*83ee113eSDavid van Moolenbroek 			return NS_NXRRSET;
1192*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ull"))
1193*83ee113eSDavid van Moolenbroek 			return TOKEN_NULL;
1194*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ext"))
1195*83ee113eSDavid van Moolenbroek 			return TOKEN_NEXT;
1196*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ew"))
1197*83ee113eSDavid van Moolenbroek 			return TOKEN_NEW;
1198*83ee113eSDavid van Moolenbroek 		break;
1199*83ee113eSDavid van Moolenbroek 	      case 'o':
1200*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "mapi"))
1201*83ee113eSDavid van Moolenbroek 			return OMAPI;
1202*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "r"))
1203*83ee113eSDavid van Moolenbroek 			return OR;
1204*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "n"))
1205*83ee113eSDavid van Moolenbroek 			return ON;
1206*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "pen"))
1207*83ee113eSDavid van Moolenbroek 			return TOKEN_OPEN;
1208*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ption"))
1209*83ee113eSDavid van Moolenbroek 			return OPTION;
1210*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1211*83ee113eSDavid van Moolenbroek 			return ONE_LEASE_PER_CLIENT;
1212*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "f"))
1213*83ee113eSDavid van Moolenbroek 			return OF;
1214*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "wner"))
1215*83ee113eSDavid van Moolenbroek 			return OWNER;
1216*83ee113eSDavid van Moolenbroek 		break;
1217*83ee113eSDavid van Moolenbroek 	      case 'p':
1218*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "repend"))
1219*83ee113eSDavid van Moolenbroek 			return PREPEND;
1220*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "referred-life"))
1221*83ee113eSDavid van Moolenbroek 			return PREFERRED_LIFE;
1222*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "acket"))
1223*83ee113eSDavid van Moolenbroek 			return PACKET;
1224*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ool"))
1225*83ee113eSDavid van Moolenbroek 			return POOL;
1226*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ool6"))
1227*83ee113eSDavid van Moolenbroek 			return POOL6;
1228*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "refix6"))
1229*83ee113eSDavid van Moolenbroek 			return PREFIX6;
1230*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "seudo"))
1231*83ee113eSDavid van Moolenbroek 			return PSEUDO;
1232*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "eer"))
1233*83ee113eSDavid van Moolenbroek 			return PEER;
1234*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "rimary"))
1235*83ee113eSDavid van Moolenbroek 			return PRIMARY;
1236*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "rimary6"))
1237*83ee113eSDavid van Moolenbroek 			return PRIMARY6;
1238*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "artner", 6)) {
1239*83ee113eSDavid van Moolenbroek 			if (!atom [7])
1240*83ee113eSDavid van Moolenbroek 				return PARTNER;
1241*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 7, "-down"))
1242*83ee113eSDavid van Moolenbroek 				return PARTNER_DOWN;
1243*83ee113eSDavid van Moolenbroek 		}
1244*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ort"))
1245*83ee113eSDavid van Moolenbroek 			return PORT;
1246*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "otential-conflict"))
1247*83ee113eSDavid van Moolenbroek 			return POTENTIAL_CONFLICT;
1248*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ick-first-value") ||
1249*83ee113eSDavid van Moolenbroek 		    !strcasecmp (atom + 1, "ick"))
1250*83ee113eSDavid van Moolenbroek 			return PICK;
1251*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "aused"))
1252*83ee113eSDavid van Moolenbroek 			return PAUSED;
1253*83ee113eSDavid van Moolenbroek 		break;
1254*83ee113eSDavid van Moolenbroek 	      case 'r':
1255*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ange"))
1256*83ee113eSDavid van Moolenbroek 			return RANGE;
1257*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "ange6"))
1258*83ee113eSDavid van Moolenbroek 			return RANGE6;
1259*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1260*83ee113eSDavid van Moolenbroek 		    (tolower((unsigned char)atom[1]) == 'e')) {
1261*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "bind"))
1262*83ee113eSDavid van Moolenbroek 				return REBIND;
1263*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "boot"))
1264*83ee113eSDavid van Moolenbroek 				return REBOOT;
1265*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "contact-interval"))
1266*83ee113eSDavid van Moolenbroek 				return RECONTACT_INTERVAL;
1267*83ee113eSDavid van Moolenbroek 			if (!strncasecmp(atom + 2, "cover", 5)) {
1268*83ee113eSDavid van Moolenbroek 				if (atom[7] == '\0')
1269*83ee113eSDavid van Moolenbroek 					return RECOVER;
1270*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 7, "-done"))
1271*83ee113eSDavid van Moolenbroek 					return RECOVER_DONE;
1272*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 7, "-wait"))
1273*83ee113eSDavid van Moolenbroek 					return RECOVER_WAIT;
1274*83ee113eSDavid van Moolenbroek 				break;
1275*83ee113eSDavid van Moolenbroek 			}
1276*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "fresh"))
1277*83ee113eSDavid van Moolenbroek 				return REFRESH;
1278*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "fused"))
1279*83ee113eSDavid van Moolenbroek 				return NS_REFUSED;
1280*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "ject"))
1281*83ee113eSDavid van Moolenbroek 				return REJECT;
1282*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "lease"))
1283*83ee113eSDavid van Moolenbroek 				return RELEASE;
1284*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "leased"))
1285*83ee113eSDavid van Moolenbroek 				return TOKEN_RELEASED;
1286*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "move"))
1287*83ee113eSDavid van Moolenbroek 				return REMOVE;
1288*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "new"))
1289*83ee113eSDavid van Moolenbroek 				return RENEW;
1290*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "quest"))
1291*83ee113eSDavid van Moolenbroek 				return REQUEST;
1292*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "quire"))
1293*83ee113eSDavid van Moolenbroek 				return REQUIRE;
1294*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
1295*83ee113eSDavid van Moolenbroek 			    (tolower((unsigned char)atom[2]) == 's')) {
1296*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "erved"))
1297*83ee113eSDavid van Moolenbroek 					return TOKEN_RESERVED;
1298*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3, "et"))
1299*83ee113eSDavid van Moolenbroek 					return TOKEN_RESET;
1300*83ee113eSDavid van Moolenbroek 				if (!strcasecmp(atom + 3,
1301*83ee113eSDavid van Moolenbroek 						"olution-interrupted"))
1302*83ee113eSDavid van Moolenbroek 					return RESOLUTION_INTERRUPTED;
1303*83ee113eSDavid van Moolenbroek 				break;
1304*83ee113eSDavid van Moolenbroek 			}
1305*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "try"))
1306*83ee113eSDavid van Moolenbroek 				return RETRY;
1307*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "turn"))
1308*83ee113eSDavid van Moolenbroek 				return RETURN;
1309*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "verse"))
1310*83ee113eSDavid van Moolenbroek 				return REVERSE;
1311*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "wind"))
1312*83ee113eSDavid van Moolenbroek 				return REWIND;
1313*83ee113eSDavid van Moolenbroek 			break;
1314*83ee113eSDavid van Moolenbroek 		}
1315*83ee113eSDavid van Moolenbroek 		break;
1316*83ee113eSDavid van Moolenbroek 	      case 's':
1317*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "cript"))
1318*83ee113eSDavid van Moolenbroek 			return SCRIPT;
1319*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1320*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'e') {
1321*83ee113eSDavid van Moolenbroek 			if (!strcasecmp(atom + 2, "arch"))
1322*83ee113eSDavid van Moolenbroek 				return SEARCH;
1323*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
1324*83ee113eSDavid van Moolenbroek 			    tolower((unsigned char)atom[2]) == 'c') {
1325*83ee113eSDavid van Moolenbroek 				if (!strncasecmp(atom + 3, "ond", 3)) {
1326*83ee113eSDavid van Moolenbroek                                         if (!strcasecmp(atom + 6, "ary"))
1327*83ee113eSDavid van Moolenbroek 						return SECONDARY;
1328*83ee113eSDavid van Moolenbroek                                         if (!strcasecmp(atom + 6, "ary6"))
1329*83ee113eSDavid van Moolenbroek 						return SECONDARY6;
1330*83ee113eSDavid van Moolenbroek                                         if (!strcasecmp(atom + 6, "s"))
1331*83ee113eSDavid van Moolenbroek                                                 return SECONDS;
1332*83ee113eSDavid van Moolenbroek 					break;
1333*83ee113eSDavid van Moolenbroek 				}
1334*83ee113eSDavid van Moolenbroek                                 if (!strcasecmp(atom + 3, "ret"))
1335*83ee113eSDavid van Moolenbroek                                         return SECRET;
1336*83ee113eSDavid van Moolenbroek 				break;
1337*83ee113eSDavid van Moolenbroek 			}
1338*83ee113eSDavid van Moolenbroek 			if (!strncasecmp(atom + 2, "lect", 4)) {
1339*83ee113eSDavid van Moolenbroek                                 if (atom[6] == '\0')
1340*83ee113eSDavid van Moolenbroek                                         return SELECT;
1341*83ee113eSDavid van Moolenbroek                                 if (!strcasecmp(atom + 6, "-timeout"))
1342*83ee113eSDavid van Moolenbroek                                         return SELECT_TIMEOUT;
1343*83ee113eSDavid van Moolenbroek 				break;
1344*83ee113eSDavid van Moolenbroek 			}
1345*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "nd"))
1346*83ee113eSDavid van Moolenbroek                                 return SEND;
1347*83ee113eSDavid van Moolenbroek 			if (!strncasecmp(atom + 2, "rv", 2)) {
1348*83ee113eSDavid van Moolenbroek 				if (!strncasecmp(atom + 4, "er", 2)) {
1349*83ee113eSDavid van Moolenbroek                                         if (atom[6] == '\0')
1350*83ee113eSDavid van Moolenbroek                                                 return TOKEN_SERVER;
1351*83ee113eSDavid van Moolenbroek 					if (atom[6] == '-') {
1352*83ee113eSDavid van Moolenbroek 						if (!strcasecmp(atom + 7,
1353*83ee113eSDavid van Moolenbroek 								"duid"))
1354*83ee113eSDavid van Moolenbroek 							return SERVER_DUID;
1355*83ee113eSDavid van Moolenbroek                                                 if (!strcasecmp(atom + 7,
1356*83ee113eSDavid van Moolenbroek 								"name"))
1357*83ee113eSDavid van Moolenbroek                                                         return SERVER_NAME;
1358*83ee113eSDavid van Moolenbroek                                                 if (!strcasecmp(atom + 7,
1359*83ee113eSDavid van Moolenbroek 								"identifier"))
1360*83ee113eSDavid van Moolenbroek                                                       return SERVER_IDENTIFIER;
1361*83ee113eSDavid van Moolenbroek 						break;
1362*83ee113eSDavid van Moolenbroek 					}
1363*83ee113eSDavid van Moolenbroek 					break;
1364*83ee113eSDavid van Moolenbroek 				}
1365*83ee113eSDavid van Moolenbroek                                 if (!strcasecmp(atom + 4, "fail"))
1366*83ee113eSDavid van Moolenbroek                                         return NS_SERVFAIL;
1367*83ee113eSDavid van Moolenbroek 				break;
1368*83ee113eSDavid van Moolenbroek 			}
1369*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "t"))
1370*83ee113eSDavid van Moolenbroek                                 return TOKEN_SET;
1371*83ee113eSDavid van Moolenbroek 			break;
1372*83ee113eSDavid van Moolenbroek 		}
1373*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1374*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'h') {
1375*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "ared-network"))
1376*83ee113eSDavid van Moolenbroek                                 return SHARED_NETWORK;
1377*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "utdown"))
1378*83ee113eSDavid van Moolenbroek                                 return SHUTDOWN;
1379*83ee113eSDavid van Moolenbroek 			break;
1380*83ee113eSDavid van Moolenbroek 		}
1381*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1382*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'i') {
1383*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "addr"))
1384*83ee113eSDavid van Moolenbroek                                 return SIADDR;
1385*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "gned"))
1386*83ee113eSDavid van Moolenbroek                                 return SIGNED;
1387*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "ze"))
1388*83ee113eSDavid van Moolenbroek                                 return SIZE;
1389*83ee113eSDavid van Moolenbroek 			break;
1390*83ee113eSDavid van Moolenbroek 		}
1391*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1392*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'p') {
1393*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
1394*83ee113eSDavid van Moolenbroek 			    tolower((unsigned char)atom[2]) == 'a') {
1395*83ee113eSDavid van Moolenbroek                                 if (!strcasecmp(atom + 3, "ce"))
1396*83ee113eSDavid van Moolenbroek                                         return SPACE;
1397*83ee113eSDavid van Moolenbroek                                 if (!strcasecmp(atom + 3, "wn"))
1398*83ee113eSDavid van Moolenbroek                                         return SPAWN;
1399*83ee113eSDavid van Moolenbroek 				break;
1400*83ee113eSDavid van Moolenbroek 			}
1401*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "lit"))
1402*83ee113eSDavid van Moolenbroek                                 return SPLIT;
1403*83ee113eSDavid van Moolenbroek 			break;
1404*83ee113eSDavid van Moolenbroek 		}
1405*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1406*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 't') {
1407*83ee113eSDavid van Moolenbroek 			if (isascii(atom[2]) &&
1408*83ee113eSDavid van Moolenbroek 			    tolower((unsigned char)atom[2]) == 'a') {
1409*83ee113eSDavid van Moolenbroek 				if(!strncasecmp(atom + 3, "rt", 2)) {
1410*83ee113eSDavid van Moolenbroek                                          if (!strcasecmp(atom + 5, "s"))
1411*83ee113eSDavid van Moolenbroek                                                  return STARTS;
1412*83ee113eSDavid van Moolenbroek                                          if (!strcasecmp(atom + 5, "up"))
1413*83ee113eSDavid van Moolenbroek                                                  return STARTUP;
1414*83ee113eSDavid van Moolenbroek 					break;
1415*83ee113eSDavid van Moolenbroek 				}
1416*83ee113eSDavid van Moolenbroek 				if (isascii(atom[3]) &&
1417*83ee113eSDavid van Moolenbroek 				    tolower((unsigned char)atom[3]) == 't') {
1418*83ee113eSDavid van Moolenbroek                                         if (!strcasecmp(atom + 4, "e"))
1419*83ee113eSDavid van Moolenbroek                                                 return STATE;
1420*83ee113eSDavid van Moolenbroek                                         if (!strcasecmp(atom + 4, "ic"))
1421*83ee113eSDavid van Moolenbroek                                                 return STATIC;
1422*83ee113eSDavid van Moolenbroek 					break;
1423*83ee113eSDavid van Moolenbroek 				}
1424*83ee113eSDavid van Moolenbroek 			}
1425*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "ring"))
1426*83ee113eSDavid van Moolenbroek                                 return STRING_TOKEN;
1427*83ee113eSDavid van Moolenbroek 			break;
1428*83ee113eSDavid van Moolenbroek 		}
1429*83ee113eSDavid van Moolenbroek                 if (!strncasecmp(atom + 1, "ub", 2)) {
1430*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 3, "class"))
1431*83ee113eSDavid van Moolenbroek                                 return SUBCLASS;
1432*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 3, "net"))
1433*83ee113eSDavid van Moolenbroek                                 return SUBNET;
1434*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 3, "net6"))
1435*83ee113eSDavid van Moolenbroek                                 return SUBNET6;
1436*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 3, "string"))
1437*83ee113eSDavid van Moolenbroek                                 return SUBSTRING;
1438*83ee113eSDavid van Moolenbroek                         break;
1439*83ee113eSDavid van Moolenbroek                 }
1440*83ee113eSDavid van Moolenbroek 		if (isascii(atom[1]) &&
1441*83ee113eSDavid van Moolenbroek 		    tolower((unsigned char)atom[1]) == 'u') {
1442*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "ffix"))
1443*83ee113eSDavid van Moolenbroek                                 return SUFFIX;
1444*83ee113eSDavid van Moolenbroek                         if (!strcasecmp(atom + 2, "persede"))
1445*83ee113eSDavid van Moolenbroek                                 return SUPERSEDE;
1446*83ee113eSDavid van Moolenbroek 		}
1447*83ee113eSDavid van Moolenbroek                 if (!strcasecmp(atom + 1, "witch"))
1448*83ee113eSDavid van Moolenbroek                         return SWITCH;
1449*83ee113eSDavid van Moolenbroek 		break;
1450*83ee113eSDavid van Moolenbroek 	      case 't':
1451*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "imestamp"))
1452*83ee113eSDavid van Moolenbroek 			return TIMESTAMP;
1453*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "imeout"))
1454*83ee113eSDavid van Moolenbroek 			return TIMEOUT;
1455*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "oken-ring"))
1456*83ee113eSDavid van Moolenbroek 			return TOKEN_RING;
1457*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ext"))
1458*83ee113eSDavid van Moolenbroek 			return TEXT;
1459*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "stp"))
1460*83ee113eSDavid van Moolenbroek 			return TSTP;
1461*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "sfp"))
1462*83ee113eSDavid van Moolenbroek 			return TSFP;
1463*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ransmission"))
1464*83ee113eSDavid van Moolenbroek 			return TRANSMISSION;
1465*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "emporary"))
1466*83ee113eSDavid van Moolenbroek 			return TEMPORARY;
1467*83ee113eSDavid van Moolenbroek 		break;
1468*83ee113eSDavid van Moolenbroek 	      case 'u':
1469*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "case"))
1470*83ee113eSDavid van Moolenbroek 			return UCASE;
1471*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nset"))
1472*83ee113eSDavid van Moolenbroek 			return UNSET;
1473*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nsigned"))
1474*83ee113eSDavid van Moolenbroek 			return UNSIGNED;
1475*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "id"))
1476*83ee113eSDavid van Moolenbroek 			return UID;
1477*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "se", 2)) {
1478*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "r-class"))
1479*83ee113eSDavid van Moolenbroek 				return USER_CLASS;
1480*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3, "-host-decl-names"))
1481*83ee113eSDavid van Moolenbroek 				return USE_HOST_DECL_NAMES;
1482*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 3,
1483*83ee113eSDavid van Moolenbroek 					 "-lease-addr-for-default-route"))
1484*83ee113eSDavid van Moolenbroek 				return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1485*83ee113eSDavid van Moolenbroek 			break;
1486*83ee113eSDavid van Moolenbroek 		}
1487*83ee113eSDavid van Moolenbroek 		if (!strncasecmp (atom + 1, "nknown", 6)) {
1488*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 7, "-clients"))
1489*83ee113eSDavid van Moolenbroek 				return UNKNOWN_CLIENTS;
1490*83ee113eSDavid van Moolenbroek 			if (!strcasecmp (atom + 7, "-state"))
1491*83ee113eSDavid van Moolenbroek 				return UNKNOWN_STATE;
1492*83ee113eSDavid van Moolenbroek 			if (!atom [7])
1493*83ee113eSDavid van Moolenbroek 				return UNKNOWN;
1494*83ee113eSDavid van Moolenbroek 			break;
1495*83ee113eSDavid van Moolenbroek 		}
1496*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "nauthenticated"))
1497*83ee113eSDavid van Moolenbroek 			return UNAUTHENTICATED;
1498*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "pdate"))
1499*83ee113eSDavid van Moolenbroek 			return UPDATE;
1500*83ee113eSDavid van Moolenbroek 		break;
1501*83ee113eSDavid van Moolenbroek 	      case 'v':
1502*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "6relay"))
1503*83ee113eSDavid van Moolenbroek 			return V6RELAY;
1504*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "6relopt"))
1505*83ee113eSDavid van Moolenbroek 			return V6RELOPT;
1506*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "endor-class"))
1507*83ee113eSDavid van Moolenbroek 			return VENDOR_CLASS;
1508*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "endor"))
1509*83ee113eSDavid van Moolenbroek 			return VENDOR;
1510*83ee113eSDavid van Moolenbroek 		break;
1511*83ee113eSDavid van Moolenbroek 	      case 'w':
1512*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "ith"))
1513*83ee113eSDavid van Moolenbroek 			return WITH;
1514*83ee113eSDavid van Moolenbroek 		if (!strcasecmp(atom + 1, "idth"))
1515*83ee113eSDavid van Moolenbroek 			return WIDTH;
1516*83ee113eSDavid van Moolenbroek 		break;
1517*83ee113eSDavid van Moolenbroek 	      case 'y':
1518*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "iaddr"))
1519*83ee113eSDavid van Moolenbroek 			return YIADDR;
1520*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "xdomain"))
1521*83ee113eSDavid van Moolenbroek 			return NS_YXDOMAIN;
1522*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "xrrset"))
1523*83ee113eSDavid van Moolenbroek 			return NS_YXRRSET;
1524*83ee113eSDavid van Moolenbroek 		break;
1525*83ee113eSDavid van Moolenbroek 	      case 'z':
1526*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "erolen"))
1527*83ee113eSDavid van Moolenbroek 			return ZEROLEN;
1528*83ee113eSDavid van Moolenbroek 		if (!strcasecmp (atom + 1, "one"))
1529*83ee113eSDavid van Moolenbroek 			return ZONE;
1530*83ee113eSDavid van Moolenbroek 		break;
1531*83ee113eSDavid van Moolenbroek 	}
1532*83ee113eSDavid van Moolenbroek 	return dfv;
1533*83ee113eSDavid van Moolenbroek }
1534*83ee113eSDavid van Moolenbroek 
1535