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''.
56 static char line1[81];
57 static char line2[81];
65 static char tokbuf[1500];
67 static int get_char(FILE *);
68 static int get_token(FILE *);
69 static void skip_to_eol(FILE *);
70 static int read_string(FILE *);
71 static int read_number(int, FILE *);
72 static int read_num_or_name(int, FILE *);
73 static int intern(char *, int);
82 token_line = cur_line;
83 cur_line[0] = prev_line[0] = 0;
84 warnings_occurred = 0;
93 if (cur_line == line1) {
103 } else if (c != EOF) {
105 cur_line[lpos - 1] = c;
116 get_token(FILE *cfile)
128 if (!(c == '\n' && eol_token) && isascii(c) && isspace(c))
137 ttok = read_string(cfile);
140 if ((isascii(c) && isdigit(c)) || c == '-') {
143 ttok = read_number(c, cfile);
145 } else if (isascii(c) && isalpha(c)) {
148 ttok = read_num_or_name(c, cfile);
164 next_token(char **rval, FILE *cfile)
169 if (lexline != tline)
170 token_line = cur_line;
176 rv = get_token(cfile);
177 token_line = cur_line;
186 peek_token(char **rval, FILE *cfile)
193 token = get_token(cfile);
194 if (lexline != tline)
195 token_line = prev_line;
210 skip_to_eol(FILE *cfile)
224 read_string(FILE *cfile)
228 for (i = 0; i < sizeof(tokbuf); i++) {
231 parse_warn("eof in string constant");
237 } else if (c == '\\')
245 * Normally, I'd feel guilty about this, but we're talking about
246 * strings that'll fit in a DHCP packet here...
248 if (i == sizeof(tokbuf)) {
249 parse_warn("string constant larger than internal buffer");
258 read_number(int c, FILE *cfile)
260 int seenx = 0, i = 0, token = NUMBER;
263 for (; i < sizeof(tokbuf); i++) {
265 if (!seenx && c == 'x')
267 else if (!isascii(c) || !isxdigit(c)) {
274 if (i == sizeof(tokbuf)) {
275 parse_warn("numeric token larger than internal buffer");
285 read_num_or_name(int c, FILE *cfile)
288 int rv = NUMBER_OR_NAME;
291 for (; i < sizeof(tokbuf); i++) {
293 if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
302 if (i == sizeof(tokbuf)) {
303 parse_warn("token larger than internal buffer");
309 return (intern(tval, rv));
313 intern(char *atom, int dfv)
315 if (!isascii(atom[0]))
318 switch (tolower(atom[0])) {
320 if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
321 return (ALWAYS_REPLY_RFC1048);
322 if (!strcasecmp(atom + 1, "ppend"))
324 if (!strcasecmp(atom + 1, "llow"))
326 if (!strcasecmp(atom + 1, "lias"))
328 if (!strcasecmp(atom + 1, "bandoned"))
330 if (!strcasecmp(atom + 1, "uthoritative"))
331 return (AUTHORITATIVE);
334 if (!strcasecmp(atom + 1, "ackoff-cutoff"))
335 return (BACKOFF_CUTOFF);
336 if (!strcasecmp(atom + 1, "ootp"))
338 if (!strcasecmp(atom + 1, "ooting"))
340 if (!strcasecmp(atom + 1, "oot-unknown-clients"))
341 return (BOOT_UNKNOWN_CLIENTS);
343 if (!strcasecmp(atom + 1, "lass"))
345 if (!strcasecmp(atom + 1, "iaddr"))
347 if (!strcasecmp(atom + 1, "lient-identifier"))
348 return (CLIENT_IDENTIFIER);
349 if (!strcasecmp(atom + 1, "lient-hostname"))
350 return (CLIENT_HOSTNAME);
353 if (!strcasecmp(atom + 1, "omain"))
355 if (!strcasecmp(atom + 1, "eny"))
357 if (!strncasecmp(atom + 1, "efault", 6)) {
360 if (!strcasecmp(atom + 7, "-lease-time"))
361 return (DEFAULT_LEASE_TIME);
364 if (!strncasecmp(atom + 1, "ynamic-bootp", 12)) {
366 return (DYNAMIC_BOOTP);
367 if (!strcasecmp(atom + 13, "-lease-cutoff"))
368 return (DYNAMIC_BOOTP_LEASE_CUTOFF);
369 if (!strcasecmp(atom + 13, "-lease-length"))
370 return (DYNAMIC_BOOTP_LEASE_LENGTH);
375 if (!strcasecmp(atom + 1, "thernet"))
377 if (!strcasecmp(atom + 1, "nds"))
379 if (!strcasecmp(atom + 1, "xpire"))
383 if (!strcasecmp(atom + 1, "ilename"))
385 if (!strcasecmp(atom + 1, "ixed-address"))
387 if (!strcasecmp(atom + 1, "ddi"))
391 if (!strcasecmp(atom + 1, "iaddr"))
393 if (!strcasecmp(atom + 1, "roup"))
395 if (!strcasecmp(atom + 1, "et-lease-hostnames"))
396 return (GET_LEASE_HOSTNAMES);
399 if (!strcasecmp(atom + 1, "ost"))
401 if (!strcasecmp(atom + 1, "ardware"))
403 if (!strcasecmp(atom + 1, "ostname"))
407 if (!strcasecmp(atom + 1, "nitial-interval"))
408 return (INITIAL_INTERVAL);
409 if (!strcasecmp(atom + 1, "nterface"))
413 if (!strcasecmp(atom + 1, "ease"))
417 if (!strcasecmp(atom + 1, "ax-lease-time"))
418 return (MAX_LEASE_TIME);
419 if (!strncasecmp(atom + 1, "edi", 3)) {
420 if (!strcasecmp(atom + 4, "a"))
422 if (!strcasecmp(atom + 4, "um"))
428 if (!strcasecmp(atom + 1, "ameserver"))
430 if (!strcasecmp(atom + 1, "etmask"))
432 if (!strcasecmp(atom + 1, "ext-server"))
433 return (NEXT_SERVER);
434 if (!strcasecmp(atom + 1, "ot"))
438 if (!strcasecmp(atom + 1, "ption"))
440 if (!strcasecmp(atom + 1, "ne-lease-per-client"))
441 return (ONE_LEASE_PER_CLIENT);
444 if (!strcasecmp(atom + 1, "repend"))
446 if (!strcasecmp(atom + 1, "acket"))
450 if (!strcasecmp(atom + 1, "ange"))
452 if (!strcasecmp(atom + 1, "equest"))
454 if (!strcasecmp(atom + 1, "equire"))
456 if (!strcasecmp(atom + 1, "etry"))
458 if (!strcasecmp(atom + 1, "enew"))
460 if (!strcasecmp(atom + 1, "ebind"))
462 if (!strcasecmp(atom + 1, "eboot"))
464 if (!strcasecmp(atom + 1, "eject"))
468 if (!strcasecmp(atom + 1, "earch"))
470 if (!strcasecmp(atom + 1, "tarts"))
472 if (!strcasecmp(atom + 1, "iaddr"))
474 if (!strcasecmp(atom + 1, "ubnet"))
476 if (!strcasecmp(atom + 1, "hared-network"))
477 return (SHARED_NETWORK);
478 if (!strcasecmp(atom + 1, "erver-name"))
479 return (SERVER_NAME);
480 if (!strcasecmp(atom + 1, "erver-identifier"))
481 return (SERVER_IDENTIFIER);
482 if (!strcasecmp(atom + 1, "elect-timeout"))
483 return (SELECT_TIMEOUT);
484 if (!strcasecmp(atom + 1, "end"))
486 if (!strcasecmp(atom + 1, "cript"))
488 if (!strcasecmp(atom + 1, "upersede"))
492 if (!strcasecmp(atom + 1, "imestamp"))
494 if (!strcasecmp(atom + 1, "imeout"))
496 if (!strcasecmp(atom + 1, "oken-ring"))
500 if (!strncasecmp(atom + 1, "se", 2)) {
501 if (!strcasecmp(atom + 3, "r-class"))
503 if (!strcasecmp(atom + 3, "-host-decl-names"))
504 return (USE_HOST_DECL_NAMES);
505 if (!strcasecmp(atom + 3,
506 "-lease-addr-for-default-route"))
507 return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
510 if (!strcasecmp(atom + 1, "id"))
512 if (!strcasecmp(atom + 1, "nknown-clients"))
513 return (UNKNOWN_CLIENTS);
516 if (!strcasecmp(atom + 1, "endor-class"))
517 return (VENDOR_CLASS);
520 if (!strcasecmp(atom + 1, "iaddr"))