conflex.c 27.3 KB
Newer Older
Ted Lemon's avatar
Ted Lemon committed
1 2 3 4 5
/* conflex.c

   Lexical scanner for dhcpd config file... */

/*
6
 * Copyright (c) 1995-2001 Internet Software Consortium.
Ted Lemon's avatar
Ted Lemon committed
7
 * All rights reserved.
Ted Lemon's avatar
Ted Lemon committed
8
 *
Ted Lemon's avatar
Ted Lemon committed
9 10 11
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
Ted Lemon's avatar
Ted Lemon committed
12
 *
Ted Lemon's avatar
Ted Lemon committed
13 14 15 16 17 18 19 20
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of The Internet Software Consortium nor the names
 *    of its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
Ted Lemon's avatar
Ted Lemon committed
21
 *
Ted Lemon's avatar
Ted Lemon committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This software has been written for the Internet Software Consortium
 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
 * To learn more about the Internet Software Consortium, see
 * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
 * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
 * ``http://www.nominum.com''.
Ted Lemon's avatar
Ted Lemon committed
42 43 44 45
 */

#ifndef lint
static char copyright[] =
Ted Lemon's avatar
Ted Lemon committed
46
"$Id: conflex.c,v 1.93 2001/05/17 19:03:43 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium.  All rights reserved.\n";
Ted Lemon's avatar
Ted Lemon committed
47 48 49 50 51
#endif /* not lint */

#include "dhcpd.h"
#include <ctype.h>

52 53 54 55 56 57 58
static int get_char PROTO ((struct parse *));
static enum dhcp_token get_token PROTO ((struct parse *));
static void skip_to_eol PROTO ((struct parse *));
static enum dhcp_token read_string PROTO ((struct parse *));
static enum dhcp_token read_number PROTO ((int, struct parse *));
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
Ted Lemon's avatar
Ted Lemon committed
59

60
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
61 62 63
	struct parse **cfile;
	int file;
	char *inbuf;
64 65
	unsigned buflen;
	const char *name;
66
	int eolp;
67 68
{
	struct parse *tmp;
69

70
	tmp = dmalloc (sizeof (struct parse), MDL);
71 72 73
	if (!tmp)
		return ISC_R_NOMEMORY;
	memset (tmp, 0, sizeof *tmp);
74

Ted Lemon's avatar
Ted Lemon committed
75
	tmp -> token = 0;
76 77 78 79 80 81 82 83
	tmp -> tlname = name;
	tmp -> lpos = tmp -> line = 1;
	tmp -> cur_line = tmp -> line1;
	tmp -> prev_line = tmp -> line2;
	tmp -> token_line = tmp -> cur_line;
	tmp -> cur_line [0] = tmp -> prev_line [0] = 0;
	tmp -> warnings_occurred = 0;
	tmp -> file = file;
84
	tmp -> eol_token = eolp;
Ted Lemon's avatar
Ted Lemon committed
85

86 87 88 89 90 91
	tmp -> bufix = 0;
	tmp -> buflen = buflen;
	if (inbuf) {
		tmp -> bufsiz = 0;
		tmp -> inbuf = inbuf;
	} else {
92
		tmp -> inbuf = dmalloc (8192, MDL);
93
		if (!tmp -> inbuf) {
94
			dfree (tmp, MDL);
95 96 97 98 99 100 101 102 103 104 105
			return ISC_R_NOMEMORY;
		}
		tmp -> bufsiz = 8192;
	}

	*cfile = tmp;
	return ISC_R_SUCCESS;
}

isc_result_t end_parse (cfile)
	struct parse **cfile;
106
{
107
	if ((*cfile) -> bufsiz)
108 109
		dfree ((*cfile) -> inbuf, MDL);
	dfree (*cfile, MDL);
110 111
	*cfile = (struct parse *)0;
	return ISC_R_SUCCESS;
112 113
}

Ted Lemon's avatar
Ted Lemon committed
114
static int get_char (cfile)
115
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
116
{
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	/* My kingdom for WITH... */
	int c;

	if (cfile -> bufix == cfile -> buflen) {
		if (cfile -> file != -1) {
			cfile -> buflen =
				read (cfile -> file,
				      cfile -> inbuf, cfile -> bufsiz);
			if (cfile -> buflen == 0) {
				c = EOF;
				cfile -> bufix = 0;
			} else if (cfile -> buflen < 0) {
				c = EOF;
				cfile -> bufix = cfile -> buflen = 0;
			} else {
				c = cfile -> inbuf [0];
				cfile -> bufix = 1;
			}
		} else
			c = EOF;
	} else {
		c = cfile -> inbuf [cfile -> bufix];
		cfile -> bufix++;
	}

	if (!cfile -> ugflag) {
Ted Lemon's avatar
Ted Lemon committed
143
		if (c == EOL) {
144 145 146
			if (cfile -> cur_line == cfile -> line1) {	
				cfile -> cur_line = cfile -> line2;
				cfile -> prev_line = cfile -> line1;
147
			} else {
148 149
				cfile -> cur_line = cfile -> line1;
				cfile -> prev_line = cfile -> line2;
150
			}
151 152 153
			cfile -> line++;
			cfile -> lpos = 1;
			cfile -> cur_line [0] = 0;
154
		} else if (c != EOF) {
155 156 157
			if (cfile -> lpos <= 80) {
				cfile -> cur_line [cfile -> lpos - 1] = c;
				cfile -> cur_line [cfile -> lpos] = 0;
158
			}
159
			cfile -> lpos++;
Ted Lemon's avatar
Ted Lemon committed
160 161
		}
	} else
162
		cfile -> ugflag = 0;
Ted Lemon's avatar
Ted Lemon committed
163 164 165
	return c;		
}

166
static enum dhcp_token get_token (cfile)
167
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
168 169
{
	int c;
170
	enum dhcp_token ttok;
171
	static char tb [2];
172
	int l, p, u;
Ted Lemon's avatar
Ted Lemon committed
173 174

	do {
175 176 177
		l = cfile -> line;
		p = cfile -> lpos;
		u = cfile -> ugflag;
178

Ted Lemon's avatar
Ted Lemon committed
179
		c = get_char (cfile);
180 181
#ifdef OLD_LEXER
		if (c == '\n' && p == 1 && !u
182 183
		    && cfile -> comment_index < sizeof cfile -> comments)
			cfile -> comments [cfile -> comment_index++] = '\n';
184 185
#endif

186 187
		if (!(c == '\n' && cfile -> eol_token)
		    && isascii (c) && isspace (c))
Ted Lemon's avatar
Ted Lemon committed
188 189
			continue;
		if (c == '#') {
190
#ifdef OLD_LEXER
191 192
			if (cfile -> comment_index < sizeof cfile -> comments)
			    cfile -> comments [cfile -> comment_index++] = '#';
193
#endif
Ted Lemon's avatar
Ted Lemon committed
194 195 196 197
			skip_to_eol (cfile);
			continue;
		}
		if (c == '"') {
198 199
			cfile -> lexline = l;
			cfile -> lexchar = p;
Ted Lemon's avatar
Ted Lemon committed
200 201 202
			ttok = read_string (cfile);
			break;
		}
Ted Lemon's avatar
Ted Lemon committed
203
		if ((isascii (c) && isdigit (c)) || c == '-') {
204 205
			cfile -> lexline = l;
			cfile -> lexchar = p;
Ted Lemon's avatar
Ted Lemon committed
206 207 208
			ttok = read_number (c, cfile);
			break;
		} else if (isascii (c) && isalpha (c)) {
209 210
			cfile -> lexline = l;
			cfile -> lexchar = p;
Ted Lemon's avatar
Ted Lemon committed
211
			ttok = read_num_or_name (c, cfile);
Ted Lemon's avatar
Ted Lemon committed
212
			break;
213 214
		} else if (c == EOF) {
			ttok = END_OF_FILE;
215
			cfile -> tlen = 0;
216
			break;
Ted Lemon's avatar
Ted Lemon committed
217
		} else {
218 219
			cfile -> lexline = l;
			cfile -> lexchar = p;
220 221
			tb [0] = c;
			tb [1] = 0;
222
			cfile -> tval = tb;
223
			cfile -> tlen = 1;
Ted Lemon's avatar
Ted Lemon committed
224 225 226 227 228 229 230
			ttok = c;
			break;
		}
	} while (1);
	return ttok;
}

231
enum dhcp_token next_token (rval, rlen, cfile)
232
	const char **rval;
233
	unsigned *rlen;
234
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
235 236 237
{
	int rv;

238 239 240 241 242 243 244
	if (cfile -> token) {
		if (cfile -> lexline != cfile -> tline)
			cfile -> token_line = cfile -> cur_line;
		cfile -> lexchar = cfile -> tlpos;
		cfile -> lexline = cfile -> tline;
		rv = cfile -> token;
		cfile -> token = 0;
Ted Lemon's avatar
Ted Lemon committed
245 246
	} else {
		rv = get_token (cfile);
247
		cfile -> token_line = cfile -> cur_line;
Ted Lemon's avatar
Ted Lemon committed
248 249
	}
	if (rval)
250
		*rval = cfile -> tval;
251 252
	if (rlen)
		*rlen = cfile -> tlen;
253
#ifdef DEBUG_TOKENS
254
	fprintf (stderr, "%s:%d ", cfile -> tval, rv);
255
#endif
Ted Lemon's avatar
Ted Lemon committed
256 257 258
	return rv;
}

259
enum dhcp_token peek_token (rval, rlen, cfile)
260
	const char **rval;
261
	unsigned int *rlen;
262
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
263
{
264 265
	int x;

266 267 268 269 270 271 272 273 274 275 276 277 278 279
	if (!cfile -> token) {
		cfile -> tlpos = cfile -> lexchar;
		cfile -> tline = cfile -> lexline;
		cfile -> token = get_token (cfile);
		if (cfile -> lexline != cfile -> tline)
			cfile -> token_line = cfile -> prev_line;

		x = cfile -> lexchar;
		cfile -> lexchar = cfile -> tlpos;
		cfile -> tlpos = x;

		x = cfile -> lexline;
		cfile -> lexline = cfile -> tline;
		cfile -> tline = x;
280
	}
Ted Lemon's avatar
Ted Lemon committed
281
	if (rval)
282
		*rval = cfile -> tval;
283 284
	if (rlen)
		*rlen = cfile -> tlen;
285
#ifdef DEBUG_TOKENS
286
	fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
287
#endif
288
	return cfile -> token;
Ted Lemon's avatar
Ted Lemon committed
289 290 291
}

static void skip_to_eol (cfile)
292
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
293 294 295 296 297 298
{
	int c;
	do {
		c = get_char (cfile);
		if (c == EOF)
			return;
299
#ifdef OLD_LEXER
300 301
		if (cfile -> comment_index < sizeof (cfile -> comments))
			comments [cfile -> comment_index++] = c;
302
#endif
Ted Lemon's avatar
Ted Lemon committed
303 304 305 306 307 308
		if (c == EOL) {
			return;
		}
	} while (1);
}

309
static enum dhcp_token read_string (cfile)
310
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
311 312 313 314
{
	int i;
	int bs = 0;
	int c;
315 316
	int value;
	int hex;
Ted Lemon's avatar
Ted Lemon committed
317

318
	for (i = 0; i < sizeof cfile -> tokbuf; i++) {
319
	      again:
Ted Lemon's avatar
Ted Lemon committed
320 321
		c = get_char (cfile);
		if (c == EOF) {
322
			parse_warn (cfile, "eof in string constant");
Ted Lemon's avatar
Ted Lemon committed
323 324
			break;
		}
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
		if (bs == 1) {
			switch (c) {
			      case 't':
				cfile -> tokbuf [i] = '\t';
				break;
			      case 'r':
				cfile -> tokbuf [i] = '\r';
				break;
			      case 'n':
				cfile -> tokbuf [i] = '\n';
				break;
			      case 'b':
				cfile -> tokbuf [i] = '\b';
				break;
			      case '0':
			      case '1':
			      case '2':
			      case '3':
				hex = 0;
				value = c - '0';
				++bs;
				goto again;
			      case 'x':
				hex = 1;
				value = 0;
				++bs;
				goto again;
			      default:
				cfile -> tokbuf [i] = c;
				bs = 0;
				break;
			}
Ted Lemon's avatar
Ted Lemon committed
357
			bs = 0;
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
		} else if (bs > 1) {
			if (hex) {
				if (c >= '0' && c <= '9') {
					value = value * 16 + (c - '0');
				} else if (c >= 'a' && c <= 'f') {
					value = value * 16 + (c - 'a' + 10);
				} else if (c >= 'A' && c <= 'F') {
					value = value * 16 + (c - 'A' + 10);
				} else {
					parse_warn (cfile,
						    "invalid hex digit: %x",
						    c);
					bs = 0;
					continue;
				}
				if (++bs == 4) {
					cfile -> tokbuf [i] = value;
					bs = 0;
				} else
					goto again;
			} else {
				if (c >= '0' && c <= '9') {
					value = value * 8 + (c - '0');
				} else {
				    if (value != 0) {
					parse_warn (cfile,
						    "invalid octal digit %x",
						    c);
					continue;
				    } else
					cfile -> tokbuf [i] = 0;
				    bs = 0;
				}
				if (++bs == 4) {
					cfile -> tokbuf [i] = value;
					bs = 0;
				} else
					goto again;
			}
		} else if (c == '\\') {
Ted Lemon's avatar
Ted Lemon committed
398
			bs = 1;
399 400
			goto again;
		} else if (c == '"')
Ted Lemon's avatar
Ted Lemon committed
401 402
			break;
		else
403
			cfile -> tokbuf [i] = c;
Ted Lemon's avatar
Ted Lemon committed
404 405 406
	}
	/* Normally, I'd feel guilty about this, but we're talking about
	   strings that'll fit in a DHCP packet here... */
407 408 409
	if (i == sizeof cfile -> tokbuf) {
		parse_warn (cfile,
			    "string constant larger than internal buffer");
Ted Lemon's avatar
Ted Lemon committed
410 411
		--i;
	}
412
	cfile -> tokbuf [i] = 0;
413
	cfile -> tlen = i;
414
	cfile -> tval = cfile -> tokbuf;
Ted Lemon's avatar
Ted Lemon committed
415 416 417
	return STRING;
}

418
static enum dhcp_token read_number (c, cfile)
Ted Lemon's avatar
Ted Lemon committed
419
	int c;
420
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
421 422 423
{
	int seenx = 0;
	int i = 0;
424 425
	int token = NUMBER;

426 427
	cfile -> tokbuf [i++] = c;
	for (; i < sizeof cfile -> tokbuf; i++) {
Ted Lemon's avatar
Ted Lemon committed
428
		c = get_char (cfile);
429
		if (!seenx && c == 'x') {
Ted Lemon's avatar
Ted Lemon committed
430
			seenx = 1;
431 432 433
#ifndef OLD_LEXER
		} else if (isascii (c) && !isxdigit (c) &&
			   (c == '-' || c == '_' || isalpha (c))) {
Ted Lemon's avatar
Ted Lemon committed
434
			token = NAME;
435
		} else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
Ted Lemon's avatar
Ted Lemon committed
436
			token = NUMBER_OR_NAME;
437 438
#endif
		} else if (!isascii (c) || !isxdigit (c)) {
439 440
			cfile -> bufix--;
			cfile -> ugflag = 1;
Ted Lemon's avatar
Ted Lemon committed
441 442
			break;
		}
443
		cfile -> tokbuf [i] = c;
Ted Lemon's avatar
Ted Lemon committed
444
	}
445 446 447
	if (i == sizeof cfile -> tokbuf) {
		parse_warn (cfile,
			    "numeric token larger than internal buffer");
Ted Lemon's avatar
Ted Lemon committed
448 449
		--i;
	}
450
	cfile -> tokbuf [i] = 0;
451
	cfile -> tlen = i;
452
	cfile -> tval = cfile -> tokbuf;
453
	return token;
Ted Lemon's avatar
Ted Lemon committed
454 455
}

456
static enum dhcp_token read_num_or_name (c, cfile)
Ted Lemon's avatar
Ted Lemon committed
457
	int c;
458
	struct parse *cfile;
Ted Lemon's avatar
Ted Lemon committed
459 460
{
	int i = 0;
461
	enum dhcp_token rv = NUMBER_OR_NAME;
462 463
	cfile -> tokbuf [i++] = c;
	for (; i < sizeof cfile -> tokbuf; i++) {
Ted Lemon's avatar
Ted Lemon committed
464 465 466
		c = get_char (cfile);
		if (!isascii (c) ||
		    (c != '-' && c != '_' && !isalnum (c))) {
467 468
			cfile -> bufix--;
			cfile -> ugflag = 1;
Ted Lemon's avatar
Ted Lemon committed
469 470 471
			break;
		}
		if (!isxdigit (c))
Ted Lemon's avatar
Ted Lemon committed
472
			rv = NAME;
473
		cfile -> tokbuf [i] = c;
Ted Lemon's avatar
Ted Lemon committed
474
	}
475 476
	if (i == sizeof cfile -> tokbuf) {
		parse_warn (cfile, "token larger than internal buffer");
Ted Lemon's avatar
Ted Lemon committed
477 478
		--i;
	}
479
	cfile -> tokbuf [i] = 0;
480
	cfile -> tlen = i;
481 482
	cfile -> tval = cfile -> tokbuf;
	return intern (cfile -> tval, rv);
Ted Lemon's avatar
Ted Lemon committed
483 484
}

485
static enum dhcp_token intern (atom, dfv)
Ted Lemon's avatar
Ted Lemon committed
486
	char *atom;
487
	enum dhcp_token dfv;
Ted Lemon's avatar
Ted Lemon committed
488
{
Ted Lemon's avatar
Ted Lemon committed
489 490 491 492
	if (!isascii (atom [0]))
		return dfv;

	switch (tolower (atom [0])) {
493 494 495 496 497
	      case '-':
		if (atom [1] == 0)
			return MINUS;
		break;

Ted Lemon's avatar
Ted Lemon committed
498
	      case 'a':
499 500 501 502 503 504 505 506 507 508 509 510
		if (!strncasecmp (atom + 1, "uth", 3)) {
			if (!strncasecmp (atom + 3, "uthenticat", 10)) {
				if (!strcasecmp (atom + 13, "ed"))
					return AUTHENTICATED;
				if (!strcasecmp (atom + 13, "ion"))
					return AUTHENTICATION;
				break;
			}
			if (!strcasecmp (atom + 1, "uthoritative"))
				return AUTHORITATIVE;
			break;
		}
511 512
		if (!strcasecmp (atom + 1, "nd"))
			return AND;
513 514
		if (!strcasecmp (atom + 1, "ppend"))
			return APPEND;
Ted Lemon's avatar
Ted Lemon committed
515 516
		if (!strcasecmp (atom + 1, "llow"))
			return ALLOW;
Ted Lemon's avatar
Ted Lemon committed
517 518
		if (!strcasecmp (atom + 1, "lias"))
			return ALIAS;
519 520
		if (!strcasecmp (atom + 1, "lgorithm"))
			return ALGORITHM;
Ted Lemon's avatar
Ted Lemon committed
521
		if (!strcasecmp (atom + 1, "bandoned"))
522
			return TOKEN_ABANDONED;
523
		if (!strcasecmp (atom + 1, "dd"))
524
			return TOKEN_ADD;
525 526
		if (!strcasecmp (atom + 1, "ll"))
			return ALL;
527 528
		if (!strcasecmp (atom + 1, "t"))
			return AT;
529 530
		if (!strcasecmp (atom + 1, "rray"))
			return ARRAY;
531 532
		if (!strcasecmp (atom + 1, "ddress"))
			return ADDRESS;
533 534
		if (!strcasecmp (atom + 1, "ctive"))
			return TOKEN_ACTIVE;
Ted Lemon's avatar
Ted Lemon committed
535
		break;
536
	      case 'b':
537 538 539 540 541 542
		if (!strcasecmp (atom + 1, "ackup"))
			return TOKEN_BACKUP;
		if (!strcasecmp (atom + 1, "ootp"))
			return TOKEN_BOOTP;
		if (!strcasecmp (atom + 1, "inding"))
			return BINDING;
543 544
		if (!strcasecmp (atom + 1, "inary-to-ascii"))
			return BINARY_TO_ASCII;
545 546
		if (!strcasecmp (atom + 1, "ackoff-cutoff"))
			return BACKOFF_CUTOFF;
Ted Lemon's avatar
Ted Lemon committed
547 548
		if (!strcasecmp (atom + 1, "ooting"))
			return BOOTING;
549 550
		if (!strcasecmp (atom + 1, "oot-unknown-clients"))
			return BOOT_UNKNOWN_CLIENTS;
551 552
		if (!strcasecmp (atom + 1, "reak"))
			return BREAK;
Ted Lemon's avatar
Ted Lemon committed
553 554
		if (!strcasecmp (atom + 1, "illing"))
			return BILLING;
555 556
		if (!strcasecmp (atom + 1, "oolean"))
			return BOOLEAN;
557 558
		if (!strcasecmp (atom + 1, "alance"))
			return BALANCE;
Ted Lemon's avatar
Ted Lemon committed
559 560
		if (!strcasecmp (atom + 1, "ound"))
			return BOUND;
561
		break;
562
	      case 'c':
563 564
		if (!strcasecmp (atom + 1, "ase"))
			return CASE;
565 566
		if (!strcasecmp (atom + 1, "ommit"))
			return COMMIT;
567 568
		if (!strcasecmp (atom + 1, "ode"))
			return CODE;
569 570
		if (!strcasecmp (atom + 1, "onfig-option"))
			return CONFIG_OPTION;
571 572
		if (!strcasecmp (atom + 1, "heck"))
			return CHECK;
573 574
		if (!strcasecmp (atom + 1, "lass"))
			return CLASS;
575 576 577 578
		if (!strcasecmp (atom + 1, "lose"))
			return TOKEN_CLOSE;
		if (!strcasecmp (atom + 1, "reate"))
			return TOKEN_CREATE;
579 580
		if (!strcasecmp (atom + 1, "iaddr"))
			return CIADDR;
581 582 583 584 585
		if (!strncasecmp (atom + 1, "lient", 5)) {
			if (!strcasecmp (atom + 6, "-identifier"))
				return CLIENT_IDENTIFIER;
			if (!strcasecmp (atom + 6, "-hostname"))
				return CLIENT_HOSTNAME;
Ted Lemon's avatar
Ted Lemon committed
586 587
			if (!strcasecmp (atom + 6, "-state"))
				return CLIENT_STATE;
Ted Lemon's avatar
Ted Lemon committed
588 589
			if (!strcasecmp (atom + 6, "-updates"))
				return CLIENT_UPDATES;
590 591 592
			if (!strcasecmp (atom + 6, "s"))
				return CLIENTS;
		}
593
		if (!strcasecmp (atom + 1, "oncat"))
Ted Lemon's avatar
Ted Lemon committed
594
			return CONCAT;
595 596
		if (!strcasecmp (atom + 1, "onnect"))
			return CONNECT;
597 598
		if (!strcasecmp (atom + 1, "ommunications-interrupted"))
			return COMMUNICATIONS_INTERRUPTED;
599 600
		if (!strcasecmp (atom + 1, "ltt"))
			return CLTT;
601
		break;
602
	      case 'd':
603 604
		if (!strcasecmp (atom + 1, "ns-update"))
			return DNS_UPDATE;
605 606
		if (!strcasecmp (atom + 1, "ns-delete"))
			return DNS_DELETE;
607 608
		if (!strcasecmp (atom + 1, "omain"))
			return DOMAIN;
609 610
		if (!strcasecmp (atom + 1, "ebug"))
			return TOKEN_DEBUG;
Ted Lemon's avatar
Ted Lemon committed
611 612
		if (!strcasecmp (atom + 1, "eny"))
			return DENY;
Ted Lemon's avatar
Ted Lemon committed
613
		if (!strcasecmp (atom + 1, "eleted"))
614
			return TOKEN_DELETED;
615 616
		if (!strcasecmp (atom + 1, "elete"))
			return TOKEN_DELETE;
Ted Lemon's avatar
Ted Lemon committed
617 618 619 620 621 622 623
		if (!strncasecmp (atom + 1, "efault", 6)) {
			if (!atom [7])
				return DEFAULT;
			if (!strcasecmp (atom + 7, "-lease-time"))
				return DEFAULT_LEASE_TIME;
			break;
		}
624 625 626 627 628 629 630 631 632 633 634 635
		if (!strncasecmp (atom + 1, "ynamic", 6)) {
			if (!atom [7])
				return DYNAMIC;
			if (!strncasecmp (atom + 7, "-bootp", 6)) {
				if (!atom [13])
					return DYNAMIC_BOOTP;
				if (!strcasecmp (atom + 13, "-lease-cutoff"))
					return DYNAMIC_BOOTP_LEASE_CUTOFF;
				if (!strcasecmp (atom + 13, "-lease-length"))
					return DYNAMIC_BOOTP_LEASE_LENGTH;
				break;
			}
636
		}
Ted Lemon's avatar
Ted Lemon committed
637 638
		if (!strcasecmp (atom + 1, "uplicates"))
			return DUPLICATES;
Ted Lemon's avatar
Ted Lemon committed
639 640
		if (!strcasecmp (atom + 1, "eclines"))
			return DECLINES;
641 642 643 644 645 646
		if (!strncasecmp (atom + 1, "efine", 5)) {
			if (!strcasecmp (atom + 6, "d"))
				return DEFINED;
			if (!atom [6])
				return DEFINE;
		}
647
		break;
648
	      case 'e':
Ted Lemon's avatar
Ted Lemon committed
649 650 651 652 653
		if (isascii (atom [1]) && tolower (atom [1]) == 'x') {
			if (!strcasecmp (atom + 2, "tract-int"))
				return EXTRACT_INT;
			if (!strcasecmp (atom + 2, "ists"))
				return EXISTS;
Ted Lemon's avatar
Ted Lemon committed
654 655 656 657
			if (!strcasecmp (atom + 2, "piry"))
				return EXPIRY;
			if (!strcasecmp (atom + 2, "pire"))
				return EXPIRE;
658 659
			if (!strcasecmp (atom + 2, "pired"))
				return TOKEN_EXPIRED;
Ted Lemon's avatar
Ted Lemon committed
660
		}
Ted Lemon's avatar
Ted Lemon committed
661
		if (!strcasecmp (atom + 1, "ncode-int"))
Ted Lemon's avatar
Ted Lemon committed
662
			return ENCODE_INT;
663 664 665 666
		if (!strcasecmp (atom + 1, "thernet"))
			return ETHERNET;
		if (!strcasecmp (atom + 1, "nds"))
			return ENDS;
667 668 669 670 671 672 673
		if (!strncasecmp (atom + 1, "ls", 2)) {
			if (!strcasecmp (atom + 3, "e"))
				return ELSE;
			if (!strcasecmp (atom + 3, "if"))
				return ELSIF;
			break;
		}
674 675
		if (!strcasecmp (atom + 1, "rror"))
			return ERROR;
Ted Lemon's avatar
Ted Lemon committed
676 677
		if (!strcasecmp (atom + 1, "val"))
			return EVAL;
678 679
		if (!strcasecmp (atom + 1, "ncapsulate"))
			return ENCAPSULATE;
Ted Lemon's avatar
Ted Lemon committed
680 681
		break;
	      case 'f':
682 683
		if (!strcasecmp (atom + 1, "atal"))
			return FATAL;
Ted Lemon's avatar
Ted Lemon committed
684 685 686 687
		if (!strcasecmp (atom + 1, "ilename"))
			return FILENAME;
		if (!strcasecmp (atom + 1, "ixed-address"))
			return FIXED_ADDR;
688 689
		if (!strcasecmp (atom + 1, "ddi"))
			return FDDI;
690 691
		if (!strcasecmp (atom + 1, "ormerr"))
			return NS_FORMERR;
692 693
		if (!strcasecmp (atom + 1, "unction"))
			return FUNCTION;
694 695
		if (!strcasecmp (atom + 1, "ailover"))
			return FAILOVER;
696 697
		if (!strcasecmp (atom + 1, "ree"))
			return TOKEN_FREE;
Ted Lemon's avatar
Ted Lemon committed
698
		break;
699 700 701
	      case 'g':
		if (!strcasecmp (atom + 1, "iaddr"))
			return GIADDR;
702 703
		if (!strcasecmp (atom + 1, "roup"))
			return GROUP;
Ted Lemon's avatar
Ted Lemon committed
704 705
		if (!strcasecmp (atom + 1, "et-lease-hostnames"))
			return GET_LEASE_HOSTNAMES;
706
		break;
707
	      case 'h':
708 709
		if (!strcasecmp (atom + 1, "ba"))
			return HBA;
710 711
		if (!strcasecmp (atom + 1, "ost"))
			return HOST;
712 713
		if (!strcasecmp (atom + 1, "ost-decl-name"))
			return HOST_DECL_NAME;
714 715
		if (!strcasecmp (atom + 1, "ardware"))
			return HARDWARE;
Ted Lemon's avatar
Ted Lemon committed
716 717
		if (!strcasecmp (atom + 1, "ostname"))
			return HOSTNAME;
718 719
		if (!strcasecmp (atom + 1, "elp"))
			return TOKEN_HELP;
720
		break;
Ted Lemon's avatar
Ted Lemon committed
721
	      case 'i':
722 723
		if (!strcasecmp (atom + 1, "nclude"))
			return INCLUDE;
724 725
		if (!strcasecmp (atom + 1, "nteger"))
			return INTEGER;
726 727
		if (!strcasecmp (atom + 1, "nfinite"))
			return INFINITE;
728 729
		if (!strcasecmp (atom + 1, "nfo"))
			return INFO;
730 731
		if (!strcasecmp (atom + 1, "p-address"))
			return IP_ADDRESS;
732 733
		if (!strcasecmp (atom + 1, "nitial-interval"))
			return INITIAL_INTERVAL;
Ted Lemon's avatar
Ted Lemon committed
734 735
		if (!strcasecmp (atom + 1, "nterface"))
			return INTERFACE;
736 737
		if (!strcasecmp (atom + 1, "dentifier"))
			return IDENTIFIER;
738 739
		if (!strcasecmp (atom + 1, "f"))
			return IF;
740 741
		if (!strcasecmp (atom + 1, "s"))
			return IS;
Ted Lemon's avatar
Ted Lemon committed
742 743
		if (!strcasecmp (atom + 1, "gnore"))
			return IGNORE;
Ted Lemon's avatar
Ted Lemon committed
744
		break;
745 746 747
	      case 'k':
		if (!strcasecmp (atom + 1, "nown"))
			return KNOWN;
748 749
		if (!strcasecmp (atom + 1, "ey"))
			return KEY;
750
		break;
751 752 753
	      case 'l':
		if (!strcasecmp (atom + 1, "ease"))
			return LEASE;
754 755
		if (!strcasecmp (atom + 1, "eased-address"))
			return LEASED_ADDRESS;
Ted Lemon's avatar
Ted Lemon committed
756
		if (!strcasecmp (atom + 1, "ease-time"))
757
			return LEASE_TIME;
Ted Lemon's avatar
Ted Lemon committed
758 759
		if (!strcasecmp (atom + 1, "imit"))
			return LIMIT;
Ted Lemon's avatar
Ted Lemon committed
760 761
		if (!strcasecmp (atom + 1, "et"))
			return LET;
762 763
		if (!strcasecmp (atom + 1, "oad"))
			return LOAD;
764 765
		if (!strcasecmp (atom + 1, "og"))
			return LOG;
Ted Lemon's avatar
Ted Lemon committed
766
		break;
767
	      case 'm':
768 769 770 771
		if (!strncasecmp (atom + 1, "ax", 2)) {
			if (!atom [3])
				return TOKEN_MAX;
			if (!strcasecmp (atom + 3, "-lease-time"))
772
				return MAX_LEASE_TIME;
773
			if (!strcasecmp (atom + 3, "-transmit-idle"))
774
				return MAX_TRANSMIT_IDLE;
775
			if (!strcasecmp (atom + 3, "-response-delay"))
776
				return MAX_RESPONSE_DELAY;
777
			if (!strcasecmp (atom + 3, "-unacked-updates"))
778
				return MAX_UNACKED_UPDATES;
779
		}
780 781 782 783 784 785 786
		if (!strncasecmp (atom + 1, "in-", 3)) {
			if (!strcasecmp (atom + 4, "lease-time"))
				return MIN_LEASE_TIME;
			if (!strcasecmp (atom + 4, "secs"))
				return MIN_SECS;
			break;
		}
Ted Lemon's avatar
Ted Lemon committed
787 788 789 790 791 792 793
		if (!strncasecmp (atom + 1, "edi", 3)) {
			if (!strcasecmp (atom + 4, "a"))
				return MEDIA;
			if (!strcasecmp (atom + 4, "um"))
				return MEDIUM;
			break;
		}
794 795
		if (!strcasecmp (atom + 1, "atch"))
			return MATCH;
796 797
		if (!strcasecmp (atom + 1, "embers"))
			return MEMBERS;
798 799
		if (!strcasecmp (atom + 1, "y"))
			return MY;
800 801
		if (!strcasecmp (atom + 1, "clt"))
			return MCLT;
802 803
		break;
	      case 'n':
804 805
		if (!strcasecmp (atom + 1, "ormal"))
			return NORMAL;
806 807
		if (!strcasecmp (atom + 1, "ameserver"))
			return NAMESERVER;
808 809
		if (!strcasecmp (atom + 1, "etmask"))
			return NETMASK;
810 811
		if (!strcasecmp (atom + 1, "ever"))
			return NEVER;
812 813
		if (!strcasecmp (atom + 1, "ext-server"))
			return NEXT_SERVER;
814 815
		if (!strcasecmp (atom + 1, "ot"))
			return TOKEN_NOT;
816 817 818 819
		if (!strcasecmp (atom + 1, "o"))
			return NO;
		if (!strcasecmp (atom + 1, "s-update"))
			return NS_UPDATE;
820 821 822 823 824 825 826 827 828 829 830 831 832 833
		if (!strcasecmp (atom + 1, "oerror"))
			return NS_NOERROR;
		if (!strcasecmp (atom + 1, "otauth"))
			return NS_NOTAUTH;
		if (!strcasecmp (atom + 1, "otimp"))
			return NS_NOTIMP;
		if (!strcasecmp (atom + 1, "otzone"))
			return NS_NOTZONE;
		if (!strcasecmp (atom + 1, "xdomain"))
			return NS_NXDOMAIN;
		if (!strcasecmp (atom + 1, "xrrset"))
			return NS_NXRRSET;
		if (!strcasecmp (atom + 1, "ull"))
			return TOKEN_NULL;
834 835
		if (!strcasecmp (atom + 1, "ext"))
			return TOKEN_NEXT;
Ted Lemon's avatar
Ted Lemon committed
836 837
		if (!strcasecmp (atom + 1, "ew"))
			return TOKEN_NEW;
838
		break;
Ted Lemon's avatar
Ted Lemon committed
839
	      case 'o':
Ted Lemon's avatar
Ted Lemon committed
840 841
		if (!strcasecmp (atom + 1, "mapi"))
			return OMAPI;
842 843
		if (!strcasecmp (atom + 1, "r"))
			return OR;
844 845
		if (!strcasecmp (atom + 1, "n"))
			return ON;
846 847
		if (!strcasecmp (atom + 1, "pen"))
			return TOKEN_OPEN;
Ted Lemon's avatar
Ted Lemon committed
848 849
		if (!strcasecmp (atom + 1, "ption"))
			return OPTION;
850 851
		if (!strcasecmp (atom + 1, "ne-lease-per-client"))
			return ONE_LEASE_PER_CLIENT;
852 853
		if (!strcasecmp (atom + 1, "f"))
			return OF;
854 855
		if (!strcasecmp (atom + 1, "wner"))
			return OWNER;
856 857
		break;
	      case 'p':
858 859
		if (!strcasecmp (atom + 1, "repend"))
			return PREPEND;
860 861
		if (!strcasecmp (atom + 1, "acket"))
			return PACKET;
862 863 864 865
		if (!strcasecmp (atom + 1, "ool"))
			return POOL;
		if (!strcasecmp (atom + 1, "seudo"))
			return PSEUDO;
866 867 868 869 870 871 872 873 874 875 876 877 878 879
		if (!strcasecmp (atom + 1, "eer"))
			return PEER;
		if (!strcasecmp (atom + 1, "rimary"))
			return PRIMARY;
		if (!strncasecmp (atom + 1, "artner", 6)) {
			if (!atom [7])
				return PARTNER;
			if (!strcasecmp (atom + 7, "-down"))
				return PARTNER_DOWN;
		}
		if (!strcasecmp (atom + 1, "ort"))
			return PORT;
		if (!strcasecmp (atom + 1, "otential-conflict"))
			return POTENTIAL_CONFLICT;
Ted Lemon's avatar
Ted Lemon committed
880 881 882
		if (!strcasecmp (atom + 1, "ick-first-value") ||
		    !strcasecmp (atom + 1, "ick"))
			return PICK;
Ted Lemon's avatar
Ted Lemon committed
883 884
		if (!strcasecmp (atom + 1, "aused"))
			return PAUSED;
Ted Lemon's avatar
Ted Lemon committed
885
		break;
886
	      case 'r':
887 888
		if (!strcasecmp (atom + 1, "esolution-interrupted"))
			return RESOLUTION_INTERRUPTED;
889 890
		if (!strcasecmp (atom + 1, "ange"))
			return RANGE;
891 892
		if (!strcasecmp (atom + 1, "ecover"))
			return RECOVER;
Ted Lemon's avatar
Ted Lemon committed
893 894
		if (!strcasecmp (atom + 1, "ecover-done"))
			return RECOVER_DONE;
Ted Lemon's avatar
Ted Lemon committed
895 896
		if (!strcasecmp (atom + 1, "ecover-wait"))
			return RECOVER_WAIT;
Ted Lemon's avatar
Ted Lemon committed
897 898
		if (!strcasecmp (atom + 1, "econtact-interval"))
			return RECONTACT_INTERVAL;
Ted Lemon's avatar
Ted Lemon committed
899 900 901 902
		if (!strcasecmp (atom + 1, "equest"))
			return REQUEST;
		if (!strcasecmp (atom + 1, "equire"))
			return REQUIRE;
903 904
		if (!strcasecmp (atom + 1, "equire"))
			return REQUIRE;
Ted Lemon's avatar
Ted Lemon committed
905 906
		if (!strcasecmp (atom + 1, "etry"))
			return RETRY;
907 908
		if (!strcasecmp (atom + 1, "eturn"))
			return RETURN;
Ted Lemon's avatar
Ted Lemon committed
909 910 911 912
		if (!strcasecmp (atom + 1, "enew"))
			return RENEW;
		if (!strcasecmp (atom + 1, "ebind"))
			return REBIND;
Ted Lemon's avatar
Ted Lemon committed
913 914
		if (!strcasecmp (atom + 1, "eboot"))
			return REBOOT;
Ted Lemon's avatar
Ted Lemon committed
915 916
		if (!strcasecmp (atom + 1, "eject"))
			return REJECT;
917 918
		if (!strcasecmp (atom + 1, "everse"))
			return REVERSE;
919