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);
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)
231 for (i = 0; i < sizeof(tokbuf); i++) {
234 parse_warn("eof in string constant");
241 } else if (c == '\\')
249 * Normally, I'd feel guilty about this, but we're talking about
250 * strings that'll fit in a DHCP packet here...
252 if (i == sizeof(tokbuf)) {
253 parse_warn("string constant larger than internal buffer");
262 read_number(int c, FILE *cfile)
264 int seenx = 0, i = 0, token = NUMBER;
267 for (; i < sizeof(tokbuf); i++) {
269 if (!seenx && c == 'x')
271 else if (!isascii(c) || !isxdigit(c)) {
278 if (i == sizeof(tokbuf)) {
279 parse_warn("numeric token larger than internal buffer");
289 read_num_or_name(int c, FILE *cfile)
292 int rv = NUMBER_OR_NAME;
295 for (; i < sizeof(tokbuf); i++) {
297 if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
306 if (i == sizeof(tokbuf)) {
307 parse_warn("token larger than internal buffer");
313 return (intern(tval, rv));
317 intern(char *atom, int dfv)
319 if (!isascii(atom[0]))
322 switch (tolower(atom[0])) {
324 if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
325 return (ALWAYS_REPLY_RFC1048);
326 if (!strcasecmp(atom + 1, "ppend"))
328 if (!strcasecmp(atom + 1, "llow"))
330 if (!strcasecmp(atom + 1, "lias"))
332 if (!strcasecmp(atom + 1, "bandoned"))
334 if (!strcasecmp(atom + 1, "uthoritative"))
335 return (AUTHORITATIVE);
338 if (!strcasecmp(atom + 1, "ackoff-cutoff"))
339 return (BACKOFF_CUTOFF);
340 if (!strcasecmp(atom + 1, "ootp"))
342 if (!strcasecmp(atom + 1, "ooting"))
344 if (!strcasecmp(atom + 1, "oot-unknown-clients"))
345 return (BOOT_UNKNOWN_CLIENTS);
347 if (!strcasecmp(atom + 1, "lass"))
349 if (!strcasecmp(atom + 1, "iaddr"))
351 if (!strcasecmp(atom + 1, "lient-identifier"))
352 return (CLIENT_IDENTIFIER);
353 if (!strcasecmp(atom + 1, "lient-hostname"))
354 return (CLIENT_HOSTNAME);
357 if (!strcasecmp(atom + 1, "omain"))
359 if (!strcasecmp(atom + 1, "eny"))
361 if (!strncasecmp(atom + 1, "efault", 6)) {
364 if (!strcasecmp(atom + 7, "-lease-time"))
365 return (DEFAULT_LEASE_TIME);
368 if (!strncasecmp(atom + 1, "ynamic-bootp", 12)) {
370 return (DYNAMIC_BOOTP);
371 if (!strcasecmp(atom + 13, "-lease-cutoff"))
372 return (DYNAMIC_BOOTP_LEASE_CUTOFF);
373 if (!strcasecmp(atom + 13, "-lease-length"))
374 return (DYNAMIC_BOOTP_LEASE_LENGTH);
379 if (!strcasecmp(atom + 1, "thernet"))
381 if (!strcasecmp(atom + 1, "nds"))
383 if (!strcasecmp(atom + 1, "xpire"))
387 if (!strcasecmp(atom + 1, "ilename"))
389 if (!strcasecmp(atom + 1, "ixed-address"))
391 if (!strcasecmp(atom + 1, "ddi"))
395 if (!strcasecmp(atom + 1, "iaddr"))
397 if (!strcasecmp(atom + 1, "roup"))
399 if (!strcasecmp(atom + 1, "et-lease-hostnames"))
400 return (GET_LEASE_HOSTNAMES);
403 if (!strcasecmp(atom + 1, "ost"))
405 if (!strcasecmp(atom + 1, "ardware"))
407 if (!strcasecmp(atom + 1, "ostname"))
411 if (!strcasecmp(atom + 1, "nitial-interval"))
412 return (INITIAL_INTERVAL);
413 if (!strcasecmp(atom + 1, "nterface"))
417 if (!strcasecmp(atom + 1, "ease"))
421 if (!strcasecmp(atom + 1, "ax-lease-time"))
422 return (MAX_LEASE_TIME);
423 if (!strncasecmp(atom + 1, "edi", 3)) {
424 if (!strcasecmp(atom + 4, "a"))
426 if (!strcasecmp(atom + 4, "um"))
432 if (!strcasecmp(atom + 1, "ameserver"))
434 if (!strcasecmp(atom + 1, "etmask"))
436 if (!strcasecmp(atom + 1, "ext-server"))
437 return (NEXT_SERVER);
438 if (!strcasecmp(atom + 1, "ot"))
442 if (!strcasecmp(atom + 1, "ption"))
444 if (!strcasecmp(atom + 1, "ne-lease-per-client"))
445 return (ONE_LEASE_PER_CLIENT);
448 if (!strcasecmp(atom + 1, "repend"))
450 if (!strcasecmp(atom + 1, "acket"))
454 if (!strcasecmp(atom + 1, "ange"))
456 if (!strcasecmp(atom + 1, "equest"))
458 if (!strcasecmp(atom + 1, "equire"))
460 if (!strcasecmp(atom + 1, "etry"))
462 if (!strcasecmp(atom + 1, "enew"))
464 if (!strcasecmp(atom + 1, "ebind"))
466 if (!strcasecmp(atom + 1, "eboot"))
468 if (!strcasecmp(atom + 1, "eject"))
472 if (!strcasecmp(atom + 1, "earch"))
474 if (!strcasecmp(atom + 1, "tarts"))
476 if (!strcasecmp(atom + 1, "iaddr"))
478 if (!strcasecmp(atom + 1, "ubnet"))
480 if (!strcasecmp(atom + 1, "hared-network"))
481 return (SHARED_NETWORK);
482 if (!strcasecmp(atom + 1, "erver-name"))
483 return (SERVER_NAME);
484 if (!strcasecmp(atom + 1, "erver-identifier"))
485 return (SERVER_IDENTIFIER);
486 if (!strcasecmp(atom + 1, "elect-timeout"))
487 return (SELECT_TIMEOUT);
488 if (!strcasecmp(atom + 1, "end"))
490 if (!strcasecmp(atom + 1, "cript"))
492 if (!strcasecmp(atom + 1, "upersede"))
496 if (!strcasecmp(atom + 1, "imestamp"))
498 if (!strcasecmp(atom + 1, "imeout"))
500 if (!strcasecmp(atom + 1, "oken-ring"))
504 if (!strncasecmp(atom + 1, "se", 2)) {
505 if (!strcasecmp(atom + 3, "r-class"))
507 if (!strcasecmp(atom + 3, "-host-decl-names"))
508 return (USE_HOST_DECL_NAMES);
509 if (!strcasecmp(atom + 3,
510 "-lease-addr-for-default-route"))
511 return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
514 if (!strcasecmp(atom + 1, "id"))
516 if (!strcasecmp(atom + 1, "nknown-clients"))
517 return (UNKNOWN_CLIENTS);
520 if (!strcasecmp(atom + 1, "endor-class"))
521 return (VENDOR_CLASS);
524 if (!strcasecmp(atom + 1, "iaddr"))