1 /* $OpenBSD: conflex.c,v 1.13 2006/12/17 17:41:56 stevesk Exp $ */
2 /* $DragonFly: src/sbin/dhclient/conflex.c,v 1.1 2008/08/30 16:07:58 hasso Exp $ */
4 /* Lexical scanner for dhclient config file... */
7 * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of The Internet Software Consortium nor the names
20 * of its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This software has been written for the Internet Software Consortium
38 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
39 * Enterprises. To learn more about the Internet Software Consortium,
40 * see ``http://www.vix.com/isc''. To learn more about Vixie
41 * 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 int kw_cmp(const void *, const void *);
74 static int intern(char *, int);
83 token_line = cur_line;
84 cur_line[0] = prev_line[0] = 0;
85 warnings_occurred = 0;
94 if (cur_line == line1) {
104 } else if (c != EOF) {
105 if (lpos < sizeof(line1)) {
106 cur_line[lpos - 1] = c;
117 get_token(FILE *cfile)
129 if (isascii(c) && isspace(c))
138 ttok = read_string(cfile);
141 if ((isascii(c) && isdigit(c)) || c == '-') {
144 ttok = read_number(c, cfile);
146 } else if (isascii(c) && isalpha(c)) {
149 ttok = read_num_or_name(c, cfile);
165 next_token(char **rval, FILE *cfile)
170 if (lexline != tline)
171 token_line = cur_line;
177 rv = get_token(cfile);
178 token_line = cur_line;
187 peek_token(char **rval, FILE *cfile)
194 token = get_token(cfile);
195 if (lexline != tline)
196 token_line = prev_line;
211 skip_to_eol(FILE *cfile)
225 read_string(FILE *cfile)
230 for (i = 0; i < sizeof(tokbuf); i++) {
233 parse_warn("eof in string constant");
239 } else if (c == '\\')
247 * Normally, I'd feel guilty about this, but we're talking about
248 * strings that'll fit in a DHCP packet here...
250 if (i == sizeof(tokbuf)) {
251 parse_warn("string constant larger than internal buffer");
260 read_number(int c, FILE *cfile)
263 int seenx = 0, token = TOK_NUMBER;
266 for (; i < sizeof(tokbuf); i++) {
268 if (!seenx && c == 'x')
270 else if (!isascii(c) || !isxdigit(c)) {
277 if (i == sizeof(tokbuf)) {
278 parse_warn("numeric token larger than internal buffer");
288 read_num_or_name(int c, FILE *cfile)
291 int rv = TOK_NUMBER_OR_NAME;
294 for (; i < sizeof(tokbuf); i++) {
296 if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
305 if (i == sizeof(tokbuf)) {
306 parse_warn("token larger than internal buffer");
312 return (intern(tval, rv));
315 static const struct keywords {
319 { "alias", TOK_ALIAS },
320 { "append", TOK_APPEND },
321 { "backoff-cutoff", TOK_BACKOFF_CUTOFF },
322 { "bootp", TOK_BOOTP },
323 { "default", TOK_DEFAULT },
324 { "deny", TOK_DENY },
325 { "ethernet", TOK_ETHERNET },
326 { "expire", TOK_EXPIRE },
327 { "fddi", TOK_FDDI },
328 { "filename", TOK_FILENAME },
329 { "fixed-address", TOK_FIXED_ADDR },
330 { "hardware", TOK_HARDWARE },
331 { "initial-interval", TOK_INITIAL_INTERVAL },
332 { "interface", TOK_INTERFACE },
333 { "lease", TOK_LEASE },
334 { "link-timeout", TOK_LINK_TIMEOUT },
335 { "media", TOK_MEDIA },
336 { "medium", TOK_MEDIUM },
337 { "option", TOK_OPTION },
338 { "prepend", TOK_PREPEND },
339 { "rebind", TOK_REBIND },
340 { "reboot", TOK_REBOOT },
341 { "reject", TOK_REJECT },
342 { "renew", TOK_RENEW },
343 { "request", TOK_REQUEST },
344 { "require", TOK_REQUIRE },
345 { "retry", TOK_RETRY },
346 { "script", TOK_SCRIPT },
347 { "select-timeout", TOK_SELECT_TIMEOUT },
348 { "send", TOK_SEND },
349 { "server-name", TOK_SERVER_NAME },
350 { "supersede", TOK_SUPERSEDE },
351 { "timeout", TOK_TIMEOUT },
352 { "token-ring", TOK_TOKEN_RING }
356 kw_cmp(const void *k, const void *e)
358 return (strcasecmp(k, ((const struct keywords *)e)->k_name));
362 intern(char *atom, int dfv)
364 const struct keywords *p;
366 p = bsearch(atom, keywords, sizeof(keywords)/sizeof(keywords[0]),
367 sizeof(keywords[0]), kw_cmp);