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
);