1 /* $OpenBSD: conflex.c,v 1.7 2004/09/15 19:02:38 deraadt Exp $ */
3 /* Lexical scanner for dhcpd config file... */
6 * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38 * Enterprises. To learn more about the Internet Software Consortium,
39 * see ``http://www.vix.com/isc''. To learn more about Vixie
40 * Enterprises, see ``http://www.vix.com''.
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
59 static char line1[81];
60 static char line2[81];
68 static char tokbuf[1500];
70 static int get_char(FILE *);
71 static int get_token(FILE *);
72 static void skip_to_eol(FILE *);
73 static int read_string(FILE *);
74 static int read_number(int, FILE *);
75 static int read_num_or_name(int, FILE *);
76 static int intern(char *, int);
79 new_parse(const char *name)
85 token_line = cur_line;
86 cur_line[0] = prev_line[0] = 0;
87 warnings_occurred = 0;
96 if (cur_line == line1) {
106 } else if (c != EOF) {
107 if (lpos < sizeof(line1)) {
108 cur_line[lpos - 1] = c;
119 get_token(FILE *cfile)
131 if (!(c == '\n' && eol_token) && isascii(c) && isspace(c))
140 ttok = read_string(cfile);
143 if ((isascii(c) && isdigit(c)) || c == '-') {
146 ttok = read_number(c, cfile);
148 } else if (isascii(c) && isalpha(c)) {
151 ttok = read_num_or_name(c, cfile);
167 next_token(char **rval, FILE *cfile)
172 if (lexline != tline)
173 token_line = cur_line;
179 rv = get_token(cfile);
180 token_line = cur_line;
189 peek_token(char **rval, FILE *cfile)
196 token = get_token(cfile);
197 if (lexline != tline)
198 token_line = prev_line;
213 skip_to_eol(FILE *cfile)
227 read_string(FILE *cfile)
232 for (i = 0; i < sizeof(tokbuf); i++) {
235 parse_warn("eof in string constant");
242 } else if (c == '\\')
250 * Normally, I'd feel guilty about this, but we're talking about
251 * strings that'll fit in a DHCP packet here...
253 if (i == sizeof(tokbuf)) {
254 parse_warn("string constant larger than internal buffer");
263 read_number(int c, FILE *cfile)
265 int seenx = 0, _token = NUMBER;
269 for (; i < sizeof(tokbuf); i++) {
271 if (!seenx && c == 'x')
273 else if (!isascii(c) || !isxdigit(c)) {
280 if (i == sizeof(tokbuf)) {
281 parse_warn("numeric token larger than internal buffer");
291 read_num_or_name(int c, FILE *cfile)
294 int rv = NUMBER_OR_NAME;
297 for (; i < sizeof(tokbuf); i++) {
299 if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
308 if (i == sizeof(tokbuf)) {
309 parse_warn("token larger than internal buffer");
315 return (intern(tval, rv));
319 intern(char *atom, int dfv)
321 if (!isascii(atom[0]))
324 switch (tolower(atom[0])) {
326 if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
327 return (ALWAYS_REPLY_RFC1048);
328 if (!strcasecmp(atom + 1, "ppend"))
330 if (!strcasecmp(atom + 1, "llow"))
332 if (!strcasecmp(atom + 1, "lias"))
334 if (!strcasecmp(atom + 1, "bandoned"))
336 if (!strcasecmp(atom + 1, "uthoritative"))
337 return (AUTHORITATIVE);
340 if (!strcasecmp(atom + 1, "ackoff-cutoff"))
341 return (BACKOFF_CUTOFF);
342 if (!strcasecmp(atom + 1, "ootp"))
344 if (!strcasecmp(atom + 1, "ooting"))
346 if (!strcasecmp(atom + 1, "oot-unknown-clients"))
347 return (BOOT_UNKNOWN_CLIENTS);
349 if (!strcasecmp(atom + 1, "lass"))
351 if (!strcasecmp(atom + 1, "iaddr"))
353 if (!strcasecmp(atom + 1, "lient-identifier"))
354 return (CLIENT_IDENTIFIER);
355 if (!strcasecmp(atom + 1, "lient-hostname"))
356 return (CLIENT_HOSTNAME);
359 if (!strcasecmp(atom + 1, "omain"))
361 if (!strcasecmp(atom + 1, "eny"))
363 if (!strncasecmp(atom + 1, "efault", 6)) {
366 if (!strcasecmp(atom + 7, "-lease-time"))
367 return (DEFAULT_LEASE_TIME);
370 if (!strncasecmp(atom + 1, "ynamic-bootp", 12)) {
372 return (DYNAMIC_BOOTP);
373 if (!strcasecmp(atom + 13, "-lease-cutoff"))
374 return (DYNAMIC_BOOTP_LEASE_CUTOFF);
375 if (!strcasecmp(atom + 13, "-lease-length"))
376 return (DYNAMIC_BOOTP_LEASE_LENGTH);
381 if (!strcasecmp(atom + 1, "thernet"))
383 if (!strcasecmp(atom + 1, "nds"))
385 if (!strcasecmp(atom + 1, "xpire"))
389 if (!strcasecmp(atom + 1, "ilename"))
391 if (!strcasecmp(atom + 1, "ixed-address"))
393 if (!strcasecmp(atom + 1, "ddi"))
397 if (!strcasecmp(atom + 1, "iaddr"))
399 if (!strcasecmp(atom + 1, "roup"))
401 if (!strcasecmp(atom + 1, "et-lease-hostnames"))
402 return (GET_LEASE_HOSTNAMES);
405 if (!strcasecmp(atom + 1, "ost"))
407 if (!strcasecmp(atom + 1, "ardware"))
409 if (!strcasecmp(atom + 1, "ostname"))
413 if (!strcasecmp(atom + 1, "nitial-interval"))
414 return (INITIAL_INTERVAL);
415 if (!strcasecmp(atom + 1, "nterface"))
419 if (!strcasecmp(atom + 1, "ease"))
423 if (!strcasecmp(atom + 1, "ax-lease-time"))
424 return (MAX_LEASE_TIME);
425 if (!strncasecmp(atom + 1, "edi", 3)) {
426 if (!strcasecmp(atom + 4, "a"))
428 if (!strcasecmp(atom + 4, "um"))
434 if (!strcasecmp(atom + 1, "ameserver"))
436 if (!strcasecmp(atom + 1, "etmask"))
438 if (!strcasecmp(atom + 1, "ext-server"))
439 return (NEXT_SERVER);
440 if (!strcasecmp(atom + 1, "ot"))
444 if (!strcasecmp(atom + 1, "ption"))
446 if (!strcasecmp(atom + 1, "ne-lease-per-client"))
447 return (ONE_LEASE_PER_CLIENT);
450 if (!strcasecmp(atom + 1, "repend"))
452 if (!strcasecmp(atom + 1, "acket"))
456 if (!strcasecmp(atom + 1, "ange"))
458 if (!strcasecmp(atom + 1, "equest"))
460 if (!strcasecmp(atom + 1, "equire"))
462 if (!strcasecmp(atom + 1, "etry"))
464 if (!strcasecmp(atom + 1, "enew"))
466 if (!strcasecmp(atom + 1, "ebind"))
468 if (!strcasecmp(atom + 1, "eboot"))
470 if (!strcasecmp(atom + 1, "eject"))
474 if (!strcasecmp(atom + 1, "earch"))
476 if (!strcasecmp(atom + 1, "tarts"))
478 if (!strcasecmp(atom + 1, "iaddr"))
480 if (!strcasecmp(atom + 1, "ubnet"))
482 if (!strcasecmp(atom + 1, "hared-network"))
483 return (SHARED_NETWORK);
484 if (!strcasecmp(atom + 1, "erver-name"))
485 return (SERVER_NAME);
486 if (!strcasecmp(atom + 1, "erver-identifier"))
487 return (SERVER_IDENTIFIER);
488 if (!strcasecmp(atom + 1, "elect-timeout"))
489 return (SELECT_TIMEOUT);
490 if (!strcasecmp(atom + 1, "end"))
492 if (!strcasecmp(atom + 1, "cript"))
494 if (!strcasecmp(atom + 1, "upersede"))
498 if (!strcasecmp(atom + 1, "imestamp"))
500 if (!strcasecmp(atom + 1, "imeout"))
502 if (!strcasecmp(atom + 1, "oken-ring"))
506 if (!strncasecmp(atom + 1, "se", 2)) {
507 if (!strcasecmp(atom + 3, "r-class"))
509 if (!strcasecmp(atom + 3, "-host-decl-names"))
510 return (USE_HOST_DECL_NAMES);
511 if (!strcasecmp(atom + 3,
512 "-lease-addr-for-default-route"))
513 return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
516 if (!strcasecmp(atom + 1, "id"))
518 if (!strcasecmp(atom + 1, "nknown-clients"))
519 return (UNKNOWN_CLIENTS);
522 if (!strcasecmp(atom + 1, "endor-class"))
523 return (VENDOR_CLASS);
526 if (!strcasecmp(atom + 1, "iaddr"))