1 /* $OpenBSD: src/sbin/dhclient/conflex.c,v 1.15 2012/08/22 00:14:42 tedu 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 { "ignore", TOK_IGNORE
},
344 { "initial-interval", TOK_INITIAL_INTERVAL
},
345 { "interface", TOK_INTERFACE
},
346 { "lease", TOK_LEASE
},
347 { "link-timeout", TOK_LINK_TIMEOUT
},
348 { "media", TOK_MEDIA
},
349 { "medium", TOK_MEDIUM
},
350 { "option", TOK_OPTION
},
351 { "prepend", TOK_PREPEND
},
352 { "rebind", TOK_REBIND
},
353 { "reboot", TOK_REBOOT
},
354 { "reject", TOK_REJECT
},
355 { "renew", TOK_RENEW
},
356 { "request", TOK_REQUEST
},
357 { "require", TOK_REQUIRE
},
358 { "retry", TOK_RETRY
},
359 { "script", TOK_SCRIPT
},
360 { "select-timeout", TOK_SELECT_TIMEOUT
},
361 { "send", TOK_SEND
},
362 { "server-name", TOK_SERVER_NAME
},
363 { "supersede", TOK_SUPERSEDE
},
364 { "timeout", TOK_TIMEOUT
},
365 { "token-ring", TOK_TOKEN_RING
}
369 kw_cmp(const void *k
, const void *e
)
371 return (strcasecmp(k
, ((const struct keywords
*)e
)->k_name
));
375 intern(char *atom
, int dfv
)
377 const struct keywords
*p
;
379 p
= bsearch(atom
, keywords
, sizeof(keywords
)/sizeof(keywords
[0]),
380 sizeof(keywords
[0]), kw_cmp
);