1 /* $OpenBSD: src/sbin/dhclient/conflex.c,v 1.14 2011/12/10 17:36:40 krw Exp $ */
3 /* Lexical scanner for dhclient 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''.
55 static char line1[81];
56 static char line2[81];
64 static char tokbuf[1500];
66 static int get_char(FILE *);
67 static int get_token(FILE *);
68 static void skip_to_eol(FILE *);
69 static int read_string(FILE *);
70 static int read_number(int, FILE *);
71 static int read_num_or_name(int, FILE *);
72 int kw_cmp(const void *, const void *);
73 static int intern(char *, int);
79 * Initialize all parsing state, as we are starting to parse a
83 bzero(line1, sizeof(line1));
84 bzero(line2, sizeof(line2));
85 bzero(tokbuf, sizeof(tokbuf));
88 tlpos = tline = token = ugflag = 0;
91 lexline = lexchar = 0;
94 token_line = cur_line;
97 warnings_occurred = 0;
101 get_char(FILE *cfile)
106 if (cur_line == line1) {
116 } else if (c != EOF) {
117 if (lpos < sizeof(line1)) {
118 cur_line[lpos - 1] = c;
129 get_token(FILE *cfile)
141 if (isascii(c) && isspace(c))
150 ttok = read_string(cfile);
153 if ((isascii(c) && isdigit(c)) || c == '-') {
156 ttok = read_number(c, cfile);
158 } else if (isascii(c) && isalpha(c)) {
161 ttok = read_num_or_name(c, cfile);
177 next_token(char **rval, FILE *cfile)
182 if (lexline != tline)
183 token_line = cur_line;
189 rv = get_token(cfile);
190 token_line = cur_line;
199 peek_token(char **rval, FILE *cfile)
206 token = get_token(cfile);
207 if (lexline != tline)
208 token_line = prev_line;
223 skip_to_eol(FILE *cfile)
237 read_string(FILE *cfile)
242 for (i = 0; i < sizeof(tokbuf); i++) {
245 parse_warn("eof in string constant");
251 } else if (c == '\\')
259 * Normally, I'd feel guilty about this, but we're talking about
260 * strings that'll fit in a DHCP packet here...
262 if (i == sizeof(tokbuf)) {
263 parse_warn("string constant larger than internal buffer");
272 read_number(int c, FILE *cfile)
275 int seenx = 0, token = TOK_NUMBER;
278 for (; i < sizeof(tokbuf); i++) {
280 if (!seenx && c == 'x')
282 else if (!isascii(c) || !isxdigit(c)) {
289 if (i == sizeof(tokbuf)) {
290 parse_warn("numeric token larger than internal buffer");
300 read_num_or_name(int c, FILE *cfile)
303 int rv = TOK_NUMBER_OR_NAME;
306 for (; i < sizeof(tokbuf); i++) {
308 if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
317 if (i == sizeof(tokbuf)) {
318 parse_warn("token larger than internal buffer");
324 return (intern(tval, rv));
327 static const struct keywords {
331 { "alias", TOK_ALIAS },
332 { "append", TOK_APPEND },
333 { "backoff-cutoff", TOK_BACKOFF_CUTOFF },
334 { "bootp", TOK_BOOTP },
335 { "default", TOK_DEFAULT },
336 { "deny", TOK_DENY },
337 { "ethernet", TOK_ETHERNET },
338 { "expire", TOK_EXPIRE },
339 { "fddi", TOK_FDDI },
340 { "filename", TOK_FILENAME },
341 { "fixed-address", TOK_FIXED_ADDR },
342 { "hardware", TOK_HARDWARE },
343 { "initial-interval", TOK_INITIAL_INTERVAL },
344 { "interface", TOK_INTERFACE },
345 { "lease", TOK_LEASE },
346 { "link-timeout", TOK_LINK_TIMEOUT },
347 { "media", TOK_MEDIA },
348 { "medium", TOK_MEDIUM },
349 { "option", TOK_OPTION },
350 { "prepend", TOK_PREPEND },
351 { "rebind", TOK_REBIND },
352 { "reboot", TOK_REBOOT },
353 { "reject", TOK_REJECT },
354 { "renew", TOK_RENEW },
355 { "request", TOK_REQUEST },
356 { "require", TOK_REQUIRE },
357 { "retry", TOK_RETRY },
358 { "script", TOK_SCRIPT },
359 { "select-timeout", TOK_SELECT_TIMEOUT },
360 { "send", TOK_SEND },
361 { "server-name", TOK_SERVER_NAME },
362 { "supersede", TOK_SUPERSEDE },
363 { "timeout", TOK_TIMEOUT },
364 { "token-ring", TOK_TOKEN_RING }
368 kw_cmp(const void *k, const void *e)
370 return (strcasecmp(k, ((const struct keywords *)e)->k_name));
374 intern(char *atom, int dfv)
376 const struct keywords *p;
378 p = bsearch(atom, keywords, sizeof(keywords)/sizeof(keywords[0]),
379 sizeof(keywords[0]), kw_cmp);