conflex.c revision 1.1 1 1.1 christos /* $NetBSD: conflex.c,v 1.1 2020/08/03 21:09:09 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 2017 by Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.1 christos * Permission to use, copy, modify, and distribute this software for any
7 1.1 christos * purpose with or without fee is hereby granted, provided that the above
8 1.1 christos * copyright notice and this permission notice appear in all copies.
9 1.1 christos *
10 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 1.1 christos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 christos *
18 1.1 christos * Internet Systems Consortium, Inc.
19 1.1 christos * 950 Charter Street
20 1.1 christos * Redwood City, CA 94063
21 1.1 christos * <info (at) isc.org>
22 1.1 christos * https://www.isc.org/
23 1.1 christos *
24 1.1 christos */
25 1.1 christos
26 1.1 christos #include <sys/cdefs.h>
27 1.1 christos __RCSID("$NetBSD: conflex.c,v 1.1 2020/08/03 21:09:09 christos Exp $");
28 1.1 christos
29 1.1 christos /* From common/conflex.c */
30 1.1 christos
31 1.1 christos #include "keama.h"
32 1.1 christos
33 1.1 christos #include <sys/types.h>
34 1.1 christos #include <sys/stat.h>
35 1.1 christos #include <sys/mman.h>
36 1.1 christos #include <assert.h>
37 1.1 christos #include <ctype.h>
38 1.1 christos #include <fcntl.h>
39 1.1 christos #include <stdlib.h>
40 1.1 christos #include <string.h>
41 1.1 christos #include <unistd.h>
42 1.1 christos
43 1.1 christos static int get_char(struct parse *);
44 1.1 christos static void unget_char(struct parse *, int);
45 1.1 christos static void skip_to_eol(struct parse *);
46 1.1 christos static enum dhcp_token read_whitespace(int c, struct parse *cfile);
47 1.1 christos static enum dhcp_token read_string(struct parse *);
48 1.1 christos static enum dhcp_token read_number(int, struct parse *);
49 1.1 christos static enum dhcp_token read_num_or_name(int, struct parse *);
50 1.1 christos static enum dhcp_token intern(char *, enum dhcp_token);
51 1.1 christos
52 1.1 christos struct parse *
53 1.1 christos new_parse(int file, char *inbuf, size_t buflen, const char *name, int eolp)
54 1.1 christos {
55 1.1 christos struct parse *tmp;
56 1.1 christos
57 1.1 christos tmp = (struct parse *)malloc(sizeof(struct parse));
58 1.1 christos assert(tmp != NULL);
59 1.1 christos memset(tmp, 0, sizeof(struct parse));
60 1.1 christos
61 1.1 christos TAILQ_INSERT_TAIL(&parses, tmp);
62 1.1 christos
63 1.1 christos tmp->tlname = name;
64 1.1 christos tmp->lpos = tmp->line = 1;
65 1.1 christos tmp->cur_line = tmp->line1;
66 1.1 christos tmp->prev_line = tmp->line2;
67 1.1 christos tmp->token_line = tmp->cur_line;
68 1.1 christos tmp->cur_line[0] = tmp->prev_line[0] = 0;
69 1.1 christos tmp->file = file;
70 1.1 christos tmp->eol_token = eolp;
71 1.1 christos TAILQ_INIT(&tmp->comments);
72 1.1 christos
73 1.1 christos if (inbuf != NULL) {
74 1.1 christos tmp->inbuf = inbuf;
75 1.1 christos tmp->buflen = buflen;
76 1.1 christos tmp->bufsiz = 0;
77 1.1 christos } else {
78 1.1 christos struct stat sb;
79 1.1 christos
80 1.1 christos if (fstat(file, &sb) < 0) {
81 1.1 christos fprintf(stderr, "can't stat input\n");
82 1.1 christos exit(1);
83 1.1 christos }
84 1.1 christos
85 1.1 christos if (sb.st_size == 0)
86 1.1 christos return tmp;
87 1.1 christos
88 1.1 christos tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
89 1.1 christos tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
90 1.1 christos file, 0);
91 1.1 christos
92 1.1 christos if (tmp->inbuf == MAP_FAILED) {
93 1.1 christos fprintf(stderr, "can't map input\n");
94 1.1 christos exit(1);
95 1.1 christos }
96 1.1 christos }
97 1.1 christos
98 1.1 christos return tmp;
99 1.1 christos }
100 1.1 christos
101 1.1 christos void
102 1.1 christos end_parse(struct parse *cfile)
103 1.1 christos {
104 1.1 christos /* "Memory" config files have no file. */
105 1.1 christos if (cfile->file != -1) {
106 1.1 christos munmap(cfile->inbuf, cfile->bufsiz);
107 1.1 christos close(cfile->file);
108 1.1 christos }
109 1.1 christos
110 1.1 christos while (TAILQ_NEXT(cfile) != NULL) {
111 1.1 christos struct parse *saved_state;
112 1.1 christos
113 1.1 christos saved_state = TAILQ_NEXT(cfile);
114 1.1 christos TAILQ_REMOVE(&parses, saved_state);
115 1.1 christos free(saved_state);
116 1.1 christos }
117 1.1 christos
118 1.1 christos cfile->stack_size = 0;
119 1.1 christos if (cfile->stack != NULL)
120 1.1 christos free(cfile->stack);
121 1.1 christos cfile->stack = NULL;
122 1.1 christos TAILQ_REMOVE(&parses, cfile);
123 1.1 christos free(cfile);
124 1.1 christos }
125 1.1 christos
126 1.1 christos /*
127 1.1 christos * Save the current state of the parser.
128 1.1 christos *
129 1.1 christos * Only one state may be saved. Any previous saved state is
130 1.1 christos * lost.
131 1.1 christos */
132 1.1 christos void
133 1.1 christos save_parse_state(struct parse *cfile) {
134 1.1 christos struct parse *tmp;
135 1.1 christos
136 1.1 christos /*
137 1.1 christos * Free any previous saved states.
138 1.1 christos */
139 1.1 christos while (TAILQ_NEXT(cfile) != NULL) {
140 1.1 christos struct parse *saved_state;
141 1.1 christos
142 1.1 christos saved_state = TAILQ_NEXT(cfile);
143 1.1 christos TAILQ_REMOVE(&parses, saved_state);
144 1.1 christos free(saved_state);
145 1.1 christos }
146 1.1 christos
147 1.1 christos /*
148 1.1 christos * Save our current state.
149 1.1 christos */
150 1.1 christos tmp = (struct parse *)malloc(sizeof(struct parse));
151 1.1 christos if (tmp == NULL)
152 1.1 christos parse_error(cfile, "can't allocate state to be saved");
153 1.1 christos memset(tmp, 0, sizeof(struct parse));
154 1.1 christos /* save up to comments field */
155 1.1 christos memcpy(tmp, cfile, (size_t)&(((struct parse *)0)->comments));
156 1.1 christos TAILQ_INSERT_AFTER(&parses, cfile, tmp);
157 1.1 christos }
158 1.1 christos
159 1.1 christos /*
160 1.1 christos * Return the parser to the previous saved state.
161 1.1 christos *
162 1.1 christos * You must call save_parse_state() every time before calling
163 1.1 christos * restore_parse_state().
164 1.1 christos */
165 1.1 christos void
166 1.1 christos restore_parse_state(struct parse *cfile) {
167 1.1 christos struct parse *saved_state;
168 1.1 christos
169 1.1 christos if (TAILQ_NEXT(cfile) == NULL)
170 1.1 christos parse_error(cfile, "can't find saved state");
171 1.1 christos
172 1.1 christos saved_state = TAILQ_NEXT(cfile);
173 1.1 christos TAILQ_REMOVE(&parses, saved_state);
174 1.1 christos /* restore up to comments field */
175 1.1 christos memcpy(cfile, saved_state, (size_t)&(((struct parse *)0)->comments));
176 1.1 christos free(saved_state);
177 1.1 christos }
178 1.1 christos
179 1.1 christos static int
180 1.1 christos get_char(struct parse *cfile)
181 1.1 christos {
182 1.1 christos /* My kingdom for WITH... */
183 1.1 christos int c;
184 1.1 christos
185 1.1 christos if (cfile->bufix == cfile->buflen) {
186 1.1 christos c = EOF;
187 1.1 christos } else {
188 1.1 christos c = cfile->inbuf[cfile->bufix];
189 1.1 christos cfile->bufix++;
190 1.1 christos }
191 1.1 christos
192 1.1 christos if (!cfile->ugflag) {
193 1.1 christos if (c == EOL) {
194 1.1 christos if (cfile->cur_line == cfile->line1) {
195 1.1 christos cfile->cur_line = cfile->line2;
196 1.1 christos cfile->prev_line = cfile->line1;
197 1.1 christos } else {
198 1.1 christos cfile->cur_line = cfile->line1;
199 1.1 christos cfile->prev_line = cfile->line2;
200 1.1 christos }
201 1.1 christos cfile->line++;
202 1.1 christos cfile->lpos = 1;
203 1.1 christos cfile->cur_line[0] = 0;
204 1.1 christos } else if (c != EOF) {
205 1.1 christos if (cfile->lpos <= 80) {
206 1.1 christos cfile->cur_line[cfile->lpos - 1] = c;
207 1.1 christos cfile->cur_line[cfile->lpos] = 0;
208 1.1 christos }
209 1.1 christos cfile->lpos++;
210 1.1 christos }
211 1.1 christos } else
212 1.1 christos cfile->ugflag = 0;
213 1.1 christos return c;
214 1.1 christos }
215 1.1 christos
216 1.1 christos /*
217 1.1 christos * Return a character to our input buffer.
218 1.1 christos */
219 1.1 christos static void
220 1.1 christos unget_char(struct parse *cfile, int c) {
221 1.1 christos if (c != EOF) {
222 1.1 christos cfile->bufix--;
223 1.1 christos cfile->ugflag = 1; /* do not put characters into
224 1.1 christos our error buffer on the next
225 1.1 christos call to get_char() */
226 1.1 christos }
227 1.1 christos }
228 1.1 christos
229 1.1 christos /*
230 1.1 christos * GENERAL NOTE ABOUT TOKENS
231 1.1 christos *
232 1.1 christos * We normally only want non-whitespace tokens. There are some
233 1.1 christos * circumstances where we *do* want to see whitespace (for example
234 1.1 christos * when parsing IPv6 addresses).
235 1.1 christos *
236 1.1 christos * Generally we use the next_token() function to read tokens. This
237 1.1 christos * in turn calls get_next_token, which does *not* return tokens for
238 1.1 christos * whitespace. Rather, it skips these.
239 1.1 christos *
240 1.1 christos * When we need to see whitespace, we us next_raw_token(), which also
241 1.1 christos * returns the WHITESPACE token.
242 1.1 christos *
243 1.1 christos * The peek_token() and peek_raw_token() functions work as expected.
244 1.1 christos *
245 1.1 christos * Warning: if you invoke peek_token(), then if there is a whitespace
246 1.1 christos * token, it will be lost, and subsequent use of next_raw_token() or
247 1.1 christos * peek_raw_token() will NOT see it.
248 1.1 christos */
249 1.1 christos
250 1.1 christos static enum dhcp_token
251 1.1 christos get_raw_token(struct parse *cfile) {
252 1.1 christos int c;
253 1.1 christos enum dhcp_token ttok;
254 1.1 christos static char tb[2];
255 1.1 christos int l, p;
256 1.1 christos
257 1.1 christos for (;;) {
258 1.1 christos l = cfile->line;
259 1.1 christos p = cfile->lpos;
260 1.1 christos
261 1.1 christos c = get_char(cfile);
262 1.1 christos if (!((c == '\n') && cfile->eol_token) &&
263 1.1 christos isascii(c) && isspace(c)) {
264 1.1 christos ttok = read_whitespace(c, cfile);
265 1.1 christos break;
266 1.1 christos }
267 1.1 christos if (c == '#') {
268 1.1 christos skip_to_eol(cfile);
269 1.1 christos continue;
270 1.1 christos }
271 1.1 christos if (c == '"') {
272 1.1 christos cfile->lexline = l;
273 1.1 christos cfile->lexchar = p;
274 1.1 christos ttok = read_string(cfile);
275 1.1 christos break;
276 1.1 christos }
277 1.1 christos if ((isascii(c) && isdigit(c)) || c == '-') {
278 1.1 christos cfile->lexline = l;
279 1.1 christos cfile->lexchar = p;
280 1.1 christos ttok = read_number(c, cfile);
281 1.1 christos break;
282 1.1 christos } else if (isascii(c) && isalpha(c)) {
283 1.1 christos cfile->lexline = l;
284 1.1 christos cfile->lexchar = p;
285 1.1 christos ttok = read_num_or_name(c, cfile);
286 1.1 christos break;
287 1.1 christos } else if (c == EOF) {
288 1.1 christos ttok = END_OF_FILE;
289 1.1 christos cfile->tlen = 0;
290 1.1 christos break;
291 1.1 christos } else {
292 1.1 christos cfile->lexline = l;
293 1.1 christos cfile->lexchar = p;
294 1.1 christos tb[0] = c;
295 1.1 christos tb[1] = 0;
296 1.1 christos cfile->tval = tb;
297 1.1 christos cfile->tlen = 1;
298 1.1 christos ttok = c;
299 1.1 christos break;
300 1.1 christos }
301 1.1 christos }
302 1.1 christos return ttok;
303 1.1 christos }
304 1.1 christos
305 1.1 christos /*
306 1.1 christos * The get_next_token() function consumes the next token and
307 1.1 christos * returns it to the caller.
308 1.1 christos *
309 1.1 christos * Since the code is almost the same for "normal" and "raw"
310 1.1 christos * input, we pass a flag to alter the way it works.
311 1.1 christos */
312 1.1 christos
313 1.1 christos static enum dhcp_token
314 1.1 christos get_next_token(const char **rval, unsigned *rlen,
315 1.1 christos struct parse *cfile, isc_boolean_t raw) {
316 1.1 christos int rv;
317 1.1 christos
318 1.1 christos if (cfile->token) {
319 1.1 christos if (cfile->lexline != cfile->tline)
320 1.1 christos cfile->token_line = cfile->cur_line;
321 1.1 christos cfile->lexchar = cfile->tlpos;
322 1.1 christos cfile->lexline = cfile->tline;
323 1.1 christos rv = cfile->token;
324 1.1 christos cfile->token = 0;
325 1.1 christos } else {
326 1.1 christos rv = get_raw_token(cfile);
327 1.1 christos cfile->token_line = cfile->cur_line;
328 1.1 christos }
329 1.1 christos
330 1.1 christos if (!raw) {
331 1.1 christos while (rv == WHITESPACE) {
332 1.1 christos rv = get_raw_token(cfile);
333 1.1 christos cfile->token_line = cfile->cur_line;
334 1.1 christos }
335 1.1 christos }
336 1.1 christos
337 1.1 christos if (rval)
338 1.1 christos *rval = cfile->tval;
339 1.1 christos if (rlen)
340 1.1 christos *rlen = cfile->tlen;
341 1.1 christos return rv;
342 1.1 christos }
343 1.1 christos
344 1.1 christos /*
345 1.1 christos * Get the next token from cfile and return it.
346 1.1 christos *
347 1.1 christos * If rval is non-NULL, set the pointer it contains to
348 1.1 christos * the contents of the token.
349 1.1 christos *
350 1.1 christos * If rlen is non-NULL, set the integer it contains to
351 1.1 christos * the length of the token.
352 1.1 christos */
353 1.1 christos
354 1.1 christos enum dhcp_token
355 1.1 christos next_token(const char **rval, unsigned *rlen, struct parse *cfile) {
356 1.1 christos return get_next_token(rval, rlen, cfile, ISC_FALSE);
357 1.1 christos }
358 1.1 christos
359 1.1 christos
360 1.1 christos /*
361 1.1 christos * The same as the next_token() function above, but will return space
362 1.1 christos * as the WHITESPACE token.
363 1.1 christos */
364 1.1 christos
365 1.1 christos enum dhcp_token
366 1.1 christos next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
367 1.1 christos return get_next_token(rval, rlen, cfile, ISC_TRUE);
368 1.1 christos }
369 1.1 christos
370 1.1 christos
371 1.1 christos /*
372 1.1 christos * The do_peek_token() function checks the next token without
373 1.1 christos * consuming it, and returns it to the caller.
374 1.1 christos *
375 1.1 christos * Since the code is almost the same for "normal" and "raw"
376 1.1 christos * input, we pass a flag to alter the way it works. (See the
377 1.1 christos * warning in the GENERAL NOTES ABOUT TOKENS above though.)
378 1.1 christos */
379 1.1 christos
380 1.1 christos enum dhcp_token
381 1.1 christos do_peek_token(const char **rval, unsigned int *rlen,
382 1.1 christos struct parse *cfile, isc_boolean_t raw) {
383 1.1 christos int x;
384 1.1 christos
385 1.1 christos if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
386 1.1 christos cfile->tlpos = cfile->lexchar;
387 1.1 christos cfile->tline = cfile->lexline;
388 1.1 christos
389 1.1 christos do {
390 1.1 christos cfile->token = get_raw_token(cfile);
391 1.1 christos } while (!raw && (cfile->token == WHITESPACE));
392 1.1 christos
393 1.1 christos if (cfile->lexline != cfile->tline)
394 1.1 christos cfile->token_line = cfile->prev_line;
395 1.1 christos
396 1.1 christos x = cfile->lexchar;
397 1.1 christos cfile->lexchar = cfile->tlpos;
398 1.1 christos cfile->tlpos = x;
399 1.1 christos
400 1.1 christos x = cfile->lexline;
401 1.1 christos cfile->lexline = cfile->tline;
402 1.1 christos cfile->tline = x;
403 1.1 christos }
404 1.1 christos if (rval)
405 1.1 christos *rval = cfile->tval;
406 1.1 christos if (rlen)
407 1.1 christos *rlen = cfile->tlen;
408 1.1 christos return cfile->token;
409 1.1 christos }
410 1.1 christos
411 1.1 christos
412 1.1 christos /*
413 1.1 christos * Get the next token from cfile and return it, leaving it for a
414 1.1 christos * subsequent call to next_token().
415 1.1 christos *
416 1.1 christos * Note that it WILL consume whitespace tokens.
417 1.1 christos *
418 1.1 christos * If rval is non-NULL, set the pointer it contains to
419 1.1 christos * the contents of the token.
420 1.1 christos *
421 1.1 christos * If rlen is non-NULL, set the integer it contains to
422 1.1 christos * the length of the token.
423 1.1 christos */
424 1.1 christos
425 1.1 christos enum dhcp_token
426 1.1 christos peek_token(const char **rval, unsigned *rlen, struct parse *cfile) {
427 1.1 christos return do_peek_token(rval, rlen, cfile, ISC_FALSE);
428 1.1 christos }
429 1.1 christos
430 1.1 christos
431 1.1 christos /*
432 1.1 christos * The same as the peek_token() function above, but will return space
433 1.1 christos * as the WHITESPACE token.
434 1.1 christos */
435 1.1 christos
436 1.1 christos enum dhcp_token
437 1.1 christos peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) {
438 1.1 christos return do_peek_token(rval, rlen, cfile, ISC_TRUE);
439 1.1 christos }
440 1.1 christos
441 1.1 christos /*
442 1.1 christos * The comment up to but not including EOL is saved.
443 1.1 christos */
444 1.1 christos
445 1.1 christos static void
446 1.1 christos skip_to_eol(struct parse *cfile)
447 1.1 christos {
448 1.1 christos char buf[128];
449 1.1 christos unsigned cc = 0;
450 1.1 christos struct comment *comment;
451 1.1 christos
452 1.1 christos memset(buf, 0, sizeof(buf));
453 1.1 christos buf[0] = '#';
454 1.1 christos for (;;) {
455 1.1 christos int c;
456 1.1 christos
457 1.1 christos c = get_char(cfile);
458 1.1 christos if (c == EOF)
459 1.1 christos break;
460 1.1 christos if (c == EOL) {
461 1.1 christos break;
462 1.1 christos }
463 1.1 christos if (++cc < sizeof(buf) - 1)
464 1.1 christos buf[cc] = c;
465 1.1 christos }
466 1.1 christos comment = createComment(buf);
467 1.1 christos TAILQ_INSERT_TAIL(&cfile->comments, comment);
468 1.1 christos }
469 1.1 christos
470 1.1 christos static enum dhcp_token
471 1.1 christos read_whitespace(int c, struct parse *cfile) {
472 1.1 christos int ofs;
473 1.1 christos
474 1.1 christos /*
475 1.1 christos * Read as much whitespace as we have available.
476 1.1 christos */
477 1.1 christos ofs = 0;
478 1.1 christos do {
479 1.1 christos if (ofs >= (sizeof(cfile->tokbuf) - 1)) {
480 1.1 christos /*
481 1.1 christos * As the file includes a huge amount of whitespace,
482 1.1 christos * it's probably broken.
483 1.1 christos * Print out a warning and bail out.
484 1.1 christos */
485 1.1 christos parse_error(cfile,
486 1.1 christos "whitespace too long, buffer overflow.");
487 1.1 christos }
488 1.1 christos cfile->tokbuf[ofs++] = c;
489 1.1 christos c = get_char(cfile);
490 1.1 christos if (c == EOF)
491 1.1 christos return END_OF_FILE;
492 1.1 christos } while (!((c == '\n') && cfile->eol_token) &&
493 1.1 christos isascii(c) && isspace(c));
494 1.1 christos
495 1.1 christos /*
496 1.1 christos * Put the last (non-whitespace) character back.
497 1.1 christos */
498 1.1 christos unget_char(cfile, c);
499 1.1 christos
500 1.1 christos /*
501 1.1 christos * Return our token.
502 1.1 christos */
503 1.1 christos cfile->tokbuf[ofs] = '\0';
504 1.1 christos cfile->tlen = ofs;
505 1.1 christos cfile->tval = cfile->tokbuf;
506 1.1 christos return WHITESPACE;
507 1.1 christos }
508 1.1 christos
509 1.1 christos static enum dhcp_token
510 1.1 christos read_string(struct parse *cfile)
511 1.1 christos {
512 1.1 christos unsigned i;
513 1.1 christos int bs = 0;
514 1.1 christos int c;
515 1.1 christos int value = 0;
516 1.1 christos int hex = 0;
517 1.1 christos
518 1.1 christos for (i = 0; i < sizeof(cfile->tokbuf); i++) {
519 1.1 christos again:
520 1.1 christos c = get_char(cfile);
521 1.1 christos if (c == EOF)
522 1.1 christos parse_error(cfile, "eof in string constant");
523 1.1 christos if (bs == 1) {
524 1.1 christos switch (c) {
525 1.1 christos case 't':
526 1.1 christos cfile->tokbuf[i] = '\t';
527 1.1 christos break;
528 1.1 christos case 'r':
529 1.1 christos cfile->tokbuf[i] = '\r';
530 1.1 christos break;
531 1.1 christos case 'n':
532 1.1 christos cfile->tokbuf[i] = '\n';
533 1.1 christos break;
534 1.1 christos case 'b':
535 1.1 christos cfile->tokbuf[i] = '\b';
536 1.1 christos break;
537 1.1 christos case '0':
538 1.1 christos case '1':
539 1.1 christos case '2':
540 1.1 christos case '3':
541 1.1 christos hex = 0;
542 1.1 christos value = c - '0';
543 1.1 christos ++bs;
544 1.1 christos goto again;
545 1.1 christos case 'x':
546 1.1 christos hex = 1;
547 1.1 christos value = 0;
548 1.1 christos ++bs;
549 1.1 christos goto again;
550 1.1 christos default:
551 1.1 christos cfile->tokbuf[i] = c;
552 1.1 christos break;
553 1.1 christos }
554 1.1 christos bs = 0;
555 1.1 christos } else if (bs > 1) {
556 1.1 christos if (hex) {
557 1.1 christos if (c >= '0' && c <= '9') {
558 1.1 christos value = value * 16 + (c - '0');
559 1.1 christos } else if (c >= 'a' && c <= 'f') {
560 1.1 christos value = value * 16 + (c - 'a' + 10);
561 1.1 christos } else if (c >= 'A' && c <= 'F') {
562 1.1 christos value = value * 16 + (c - 'A' + 10);
563 1.1 christos } else
564 1.1 christos parse_error(cfile,
565 1.1 christos "invalid hex digit: %x",
566 1.1 christos c);
567 1.1 christos if (++bs == 4) {
568 1.1 christos cfile->tokbuf[i] = value;
569 1.1 christos bs = 0;
570 1.1 christos } else
571 1.1 christos goto again;
572 1.1 christos } else {
573 1.1 christos if (c >= '0' && c <= '7') {
574 1.1 christos value = value * 8 + (c - '0');
575 1.1 christos } else {
576 1.1 christos if (value != 0)
577 1.1 christos parse_error(cfile,
578 1.1 christos "invalid octal digit %x",
579 1.1 christos c);
580 1.1 christos else
581 1.1 christos cfile->tokbuf[i] = 0;
582 1.1 christos bs = 0;
583 1.1 christos }
584 1.1 christos if (++bs == 4) {
585 1.1 christos cfile->tokbuf[i] = value;
586 1.1 christos bs = 0;
587 1.1 christos } else
588 1.1 christos goto again;
589 1.1 christos }
590 1.1 christos } else if (c == '\\') {
591 1.1 christos bs = 1;
592 1.1 christos goto again;
593 1.1 christos } else if (c == '"')
594 1.1 christos break;
595 1.1 christos else
596 1.1 christos cfile->tokbuf[i] = c;
597 1.1 christos }
598 1.1 christos /* Normally, I'd feel guilty about this, but we're talking about
599 1.1 christos strings that'll fit in a DHCP packet here... */
600 1.1 christos if (i == sizeof(cfile->tokbuf))
601 1.1 christos parse_error(cfile,
602 1.1 christos "string constant larger than internal buffer");
603 1.1 christos cfile->tokbuf[i] = 0;
604 1.1 christos cfile->tlen = i;
605 1.1 christos cfile->tval = cfile->tokbuf;
606 1.1 christos return STRING;
607 1.1 christos }
608 1.1 christos
609 1.1 christos static enum dhcp_token
610 1.1 christos read_number(int c, struct parse *cfile)
611 1.1 christos {
612 1.1 christos unsigned i = 0;
613 1.1 christos int token = NUMBER;
614 1.1 christos
615 1.1 christos cfile->tokbuf[i++] = c;
616 1.1 christos for (; i < sizeof(cfile->tokbuf); i++) {
617 1.1 christos c = get_char(cfile);
618 1.1 christos
619 1.1 christos /* Promote NUMBER->NUMBER_OR_NAME->NAME, never demote.
620 1.1 christos * Except in the case of '0x' syntax hex, which gets called
621 1.1 christos * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
622 1.1 christos * verified to be at least 0xf or less.
623 1.1 christos */
624 1.1 christos switch (isascii(c) ? token : BREAK) {
625 1.1 christos case NUMBER:
626 1.1 christos if (isdigit(c))
627 1.1 christos break;
628 1.1 christos /* FALLTHROUGH */
629 1.1 christos case NUMBER_OR_NAME:
630 1.1 christos if (isxdigit(c)) {
631 1.1 christos token = NUMBER_OR_NAME;
632 1.1 christos break;
633 1.1 christos }
634 1.1 christos /* FALLTHROUGH */
635 1.1 christos case NAME:
636 1.1 christos if ((i == 2) && isxdigit(c) &&
637 1.1 christos (cfile->tokbuf[0] == '0') &&
638 1.1 christos ((cfile->tokbuf[1] == 'x') ||
639 1.1 christos (cfile->tokbuf[1] == 'X'))) {
640 1.1 christos token = NUMBER_OR_NAME;
641 1.1 christos break;
642 1.1 christos } else if (((c == '-') || (c == '_') || isalnum(c))) {
643 1.1 christos token = NAME;
644 1.1 christos break;
645 1.1 christos }
646 1.1 christos /* FALLTHROUGH */
647 1.1 christos case BREAK:
648 1.1 christos /* At this point c is either EOF or part of the next
649 1.1 christos * token. If not EOF, rewind the file one byte so
650 1.1 christos * the next token is read from there.
651 1.1 christos */
652 1.1 christos unget_char(cfile, c);
653 1.1 christos goto end_read;
654 1.1 christos
655 1.1 christos default:
656 1.1 christos parse_error(cfile,
657 1.1 christos "read_number(): impossible case");
658 1.1 christos }
659 1.1 christos
660 1.1 christos cfile->tokbuf[i] = c;
661 1.1 christos }
662 1.1 christos
663 1.1 christos if (i == sizeof(cfile->tokbuf))
664 1.1 christos parse_error(cfile,
665 1.1 christos "numeric token larger than internal buffer");
666 1.1 christos
667 1.1 christos end_read:
668 1.1 christos cfile->tokbuf[i] = 0;
669 1.1 christos cfile->tlen = i;
670 1.1 christos cfile->tval = cfile->tokbuf;
671 1.1 christos
672 1.1 christos /*
673 1.1 christos * If this entire token from start to finish was "-", such as
674 1.1 christos * the middle parameter in "42 - 7", return just the MINUS token.
675 1.1 christos */
676 1.1 christos if ((i == 1) && (cfile->tokbuf[i] == '-'))
677 1.1 christos return MINUS;
678 1.1 christos else
679 1.1 christos return token;
680 1.1 christos }
681 1.1 christos
682 1.1 christos static enum dhcp_token
683 1.1 christos read_num_or_name(int c, struct parse *cfile)
684 1.1 christos {
685 1.1 christos unsigned i = 0;
686 1.1 christos enum dhcp_token rv = NUMBER_OR_NAME;
687 1.1 christos
688 1.1 christos cfile->tokbuf[i++] = c;
689 1.1 christos for (; i < sizeof(cfile->tokbuf); i++) {
690 1.1 christos c = get_char(cfile);
691 1.1 christos if (!isascii(c) ||
692 1.1 christos (c != '-' && c != '_' && !isalnum(c))) {
693 1.1 christos unget_char(cfile, c);
694 1.1 christos break;
695 1.1 christos }
696 1.1 christos if (!isxdigit(c))
697 1.1 christos rv = NAME;
698 1.1 christos cfile->tokbuf[i] = c;
699 1.1 christos }
700 1.1 christos if (i == sizeof(cfile->tokbuf))
701 1.1 christos parse_error(cfile, "token larger than internal buffer");
702 1.1 christos cfile->tokbuf[i] = 0;
703 1.1 christos cfile->tlen = i;
704 1.1 christos cfile->tval = cfile->tokbuf;
705 1.1 christos return intern(cfile->tval, rv);
706 1.1 christos }
707 1.1 christos
708 1.1 christos static enum dhcp_token
709 1.1 christos intern(char *atom, enum dhcp_token dfv) {
710 1.1 christos if (!isascii(atom[0]))
711 1.1 christos return dfv;
712 1.1 christos
713 1.1 christos switch (tolower((unsigned char)atom[0])) {
714 1.1 christos case '-':
715 1.1 christos if (atom [1] == 0)
716 1.1 christos return MINUS;
717 1.1 christos break;
718 1.1 christos
719 1.1 christos case 'a':
720 1.1 christos if (!strcasecmp(atom + 1, "bandoned"))
721 1.1 christos return TOKEN_ABANDONED;
722 1.1 christos if (!strcasecmp(atom + 1, "ctive"))
723 1.1 christos return TOKEN_ACTIVE;
724 1.1 christos if (!strncasecmp(atom + 1, "dd", 2)) {
725 1.1 christos if (atom[3] == '\0')
726 1.1 christos return TOKEN_ADD;
727 1.1 christos else if (!strcasecmp(atom + 3, "ress"))
728 1.1 christos return ADDRESS;
729 1.1 christos break;
730 1.1 christos }
731 1.1 christos if (!strcasecmp(atom + 1, "fter"))
732 1.1 christos return AFTER;
733 1.1 christos if (isascii(atom[1]) &&
734 1.1 christos (tolower((unsigned char)atom[1]) == 'l')) {
735 1.1 christos if (!strcasecmp(atom + 2, "gorithm"))
736 1.1 christos return ALGORITHM;
737 1.1 christos if (!strcasecmp(atom + 2, "ias"))
738 1.1 christos return ALIAS;
739 1.1 christos if (isascii(atom[2]) &&
740 1.1 christos (tolower((unsigned char)atom[2]) == 'l')) {
741 1.1 christos if (atom[3] == '\0')
742 1.1 christos return ALL;
743 1.1 christos else if (!strcasecmp(atom + 3, "ow"))
744 1.1 christos return ALLOW;
745 1.1 christos break;
746 1.1 christos }
747 1.1 christos if (!strcasecmp(atom + 2, "so"))
748 1.1 christos return TOKEN_ALSO;
749 1.1 christos break;
750 1.1 christos }
751 1.1 christos if (isascii(atom[1]) &&
752 1.1 christos (tolower((unsigned char)atom[1]) == 'n')) {
753 1.1 christos if (!strcasecmp(atom + 2, "d"))
754 1.1 christos return AND;
755 1.1 christos if (!strcasecmp(atom + 2, "ycast-mac"))
756 1.1 christos return ANYCAST_MAC;
757 1.1 christos break;
758 1.1 christos }
759 1.1 christos if (!strcasecmp(atom + 1, "ppend"))
760 1.1 christos return APPEND;
761 1.1 christos if (!strcasecmp(atom + 1, "rray"))
762 1.1 christos return ARRAY;
763 1.1 christos if (isascii(atom[1]) &&
764 1.1 christos (tolower((unsigned char)atom[1]) == 't')) {
765 1.1 christos if (atom[2] == '\0')
766 1.1 christos return AT;
767 1.1 christos if (!strcasecmp(atom + 2, "sfp"))
768 1.1 christos return ATSFP;
769 1.1 christos break;
770 1.1 christos }
771 1.1 christos if (!strcasecmp(atom + 1, "uthoring-byte-order"))
772 1.1 christos return AUTHORING_BYTE_ORDER;
773 1.1 christos if (!strncasecmp(atom + 1, "ut", 2)) {
774 1.1 christos if (isascii(atom[3]) &&
775 1.1 christos (tolower((unsigned char)atom[3]) == 'h')) {
776 1.1 christos if (!strncasecmp(atom + 4, "enticat", 7)) {
777 1.1 christos if (!strcasecmp(atom + 11, "ed"))
778 1.1 christos return AUTHENTICATED;
779 1.1 christos if (!strcasecmp(atom + 11, "ion"))
780 1.1 christos return AUTHENTICATION;
781 1.1 christos break;
782 1.1 christos }
783 1.1 christos if (!strcasecmp(atom + 4, "oritative"))
784 1.1 christos return AUTHORITATIVE;
785 1.1 christos break;
786 1.1 christos }
787 1.1 christos if (!strcasecmp(atom + 3, "o-partner-down"))
788 1.1 christos return AUTO_PARTNER_DOWN;
789 1.1 christos break;
790 1.1 christos }
791 1.1 christos break;
792 1.1 christos case 'b':
793 1.1 christos if (!strcasecmp(atom + 1, "ackup"))
794 1.1 christos return TOKEN_BACKUP;
795 1.1 christos if (!strcasecmp(atom + 1, "ootp"))
796 1.1 christos return TOKEN_BOOTP;
797 1.1 christos if (!strcasecmp(atom + 1, "inding"))
798 1.1 christos return BINDING;
799 1.1 christos if (!strcasecmp(atom + 1, "inary-to-ascii"))
800 1.1 christos return BINARY_TO_ASCII;
801 1.1 christos if (!strcasecmp(atom + 1, "ackoff-cutoff"))
802 1.1 christos return BACKOFF_CUTOFF;
803 1.1 christos if (!strcasecmp(atom + 1, "ooting"))
804 1.1 christos return BOOTING;
805 1.1 christos if (!strcasecmp(atom + 1, "oot-unknown-clients"))
806 1.1 christos return BOOT_UNKNOWN_CLIENTS;
807 1.1 christos if (!strcasecmp(atom + 1, "reak"))
808 1.1 christos return BREAK;
809 1.1 christos if (!strcasecmp(atom + 1, "illing"))
810 1.1 christos return BILLING;
811 1.1 christos if (!strcasecmp(atom + 1, "oolean"))
812 1.1 christos return BOOLEAN;
813 1.1 christos if (!strcasecmp(atom + 1, "alance"))
814 1.1 christos return BALANCE;
815 1.1 christos if (!strcasecmp(atom + 1, "ound"))
816 1.1 christos return BOUND;
817 1.1 christos if (!strcasecmp(atom+1, "ig-endian")) {
818 1.1 christos return TOKEN_BIG_ENDIAN;
819 1.1 christos }
820 1.1 christos break;
821 1.1 christos case 'c':
822 1.1 christos if (!strcasecmp(atom + 1, "ase"))
823 1.1 christos return CASE;
824 1.1 christos if (!strcasecmp(atom + 1, "heck"))
825 1.1 christos return CHECK;
826 1.1 christos if (!strcasecmp(atom + 1, "iaddr"))
827 1.1 christos return CIADDR;
828 1.1 christos if (isascii(atom[1]) &&
829 1.1 christos tolower((unsigned char)atom[1]) == 'l') {
830 1.1 christos if (!strcasecmp(atom + 2, "ass"))
831 1.1 christos return CLASS;
832 1.1 christos if (!strncasecmp(atom + 2, "ient", 4)) {
833 1.1 christos if (!strcasecmp(atom + 6, "s"))
834 1.1 christos return CLIENTS;
835 1.1 christos if (atom[6] == '-') {
836 1.1 christos if (!strcasecmp(atom + 7, "hostname"))
837 1.1 christos return CLIENT_HOSTNAME;
838 1.1 christos if (!strcasecmp(atom + 7, "identifier"))
839 1.1 christos return CLIENT_IDENTIFIER;
840 1.1 christos if (!strcasecmp(atom + 7, "state"))
841 1.1 christos return CLIENT_STATE;
842 1.1 christos if (!strcasecmp(atom + 7, "updates"))
843 1.1 christos return CLIENT_UPDATES;
844 1.1 christos break;
845 1.1 christos }
846 1.1 christos break;
847 1.1 christos }
848 1.1 christos if (!strcasecmp(atom + 2, "ose"))
849 1.1 christos return TOKEN_CLOSE;
850 1.1 christos if (!strcasecmp(atom + 2, "tt"))
851 1.1 christos return CLTT;
852 1.1 christos break;
853 1.1 christos }
854 1.1 christos if (isascii(atom[1]) &&
855 1.1 christos tolower((unsigned char)atom[1]) == 'o') {
856 1.1 christos if (!strcasecmp(atom + 2, "de"))
857 1.1 christos return CODE;
858 1.1 christos if (isascii(atom[2]) &&
859 1.1 christos tolower((unsigned char)atom[2]) == 'm') {
860 1.1 christos if (!strcasecmp(atom + 3, "mit"))
861 1.1 christos return COMMIT;
862 1.1 christos if (!strcasecmp(atom + 3,
863 1.1 christos "munications-interrupted"))
864 1.1 christos return COMMUNICATIONS_INTERRUPTED;
865 1.1 christos if (!strcasecmp(atom + 3, "pressed"))
866 1.1 christos return COMPRESSED;
867 1.1 christos break;
868 1.1 christos }
869 1.1 christos if (isascii(atom[2]) &&
870 1.1 christos tolower((unsigned char)atom[2]) == 'n') {
871 1.1 christos if (!strcasecmp(atom + 3, "cat"))
872 1.1 christos return CONCAT;
873 1.1 christos if (!strcasecmp(atom + 3, "fig-option"))
874 1.1 christos return CONFIG_OPTION;
875 1.1 christos if (!strcasecmp(atom + 3, "flict-done"))
876 1.1 christos return CONFLICT_DONE;
877 1.1 christos if (!strcasecmp(atom + 3, "nect"))
878 1.1 christos return CONNECT;
879 1.1 christos break;
880 1.1 christos }
881 1.1 christos break;
882 1.1 christos }
883 1.1 christos if (!strcasecmp(atom + 1, "reate"))
884 1.1 christos return TOKEN_CREATE;
885 1.1 christos break;
886 1.1 christos case 'd':
887 1.1 christos if (!strcasecmp(atom + 1, "b-time-format"))
888 1.1 christos return DB_TIME_FORMAT;
889 1.1 christos if (!strcasecmp(atom + 1, "omain"))
890 1.1 christos return DOMAIN;
891 1.1 christos if (!strncasecmp(atom + 1, "omain-", 6)) {
892 1.1 christos if (!strcasecmp(atom + 7, "name"))
893 1.1 christos return DOMAIN_NAME;
894 1.1 christos if (!strcasecmp(atom + 7, "list"))
895 1.1 christos return DOMAIN_LIST;
896 1.1 christos }
897 1.1 christos if (!strcasecmp(atom + 1, "o-forward-updates"))
898 1.1 christos return DO_FORWARD_UPDATE;
899 1.1 christos /* do-forward-update is included for historical reasons */
900 1.1 christos if (!strcasecmp(atom + 1, "o-forward-update"))
901 1.1 christos return DO_FORWARD_UPDATE;
902 1.1 christos if (!strcasecmp(atom + 1, "ebug"))
903 1.1 christos return TOKEN_DEBUG;
904 1.1 christos if (!strcasecmp(atom + 1, "eny"))
905 1.1 christos return DENY;
906 1.1 christos if (!strcasecmp(atom + 1, "eleted"))
907 1.1 christos return TOKEN_DELETED;
908 1.1 christos if (!strcasecmp(atom + 1, "elete"))
909 1.1 christos return TOKEN_DELETE;
910 1.1 christos if (!strncasecmp(atom + 1, "efault", 6)) {
911 1.1 christos if (!atom [7])
912 1.1 christos return DEFAULT;
913 1.1 christos if (!strcasecmp(atom + 7, "-duid"))
914 1.1 christos return DEFAULT_DUID;
915 1.1 christos if (!strcasecmp(atom + 7, "-lease-time"))
916 1.1 christos return DEFAULT_LEASE_TIME;
917 1.1 christos break;
918 1.1 christos }
919 1.1 christos if (!strncasecmp(atom + 1, "ynamic", 6)) {
920 1.1 christos if (!atom [7])
921 1.1 christos return DYNAMIC;
922 1.1 christos if (!strncasecmp(atom + 7, "-bootp", 6)) {
923 1.1 christos if (!atom [13])
924 1.1 christos return DYNAMIC_BOOTP;
925 1.1 christos if (!strcasecmp(atom + 13, "-lease-cutoff"))
926 1.1 christos return DYNAMIC_BOOTP_LEASE_CUTOFF;
927 1.1 christos if (!strcasecmp(atom + 13, "-lease-length"))
928 1.1 christos return DYNAMIC_BOOTP_LEASE_LENGTH;
929 1.1 christos break;
930 1.1 christos }
931 1.1 christos }
932 1.1 christos if (!strcasecmp(atom + 1, "uplicates"))
933 1.1 christos return DUPLICATES;
934 1.1 christos if (!strcasecmp(atom + 1, "eclines"))
935 1.1 christos return DECLINES;
936 1.1 christos if (!strncasecmp(atom + 1, "efine", 5)) {
937 1.1 christos if (!strcasecmp(atom + 6, "d"))
938 1.1 christos return DEFINED;
939 1.1 christos if (!atom [6])
940 1.1 christos return DEFINE;
941 1.1 christos }
942 1.1 christos break;
943 1.1 christos case 'e':
944 1.1 christos if (isascii(atom [1]) &&
945 1.1 christos tolower((unsigned char)atom[1]) == 'x') {
946 1.1 christos if (!strcasecmp(atom + 2, "tract-int"))
947 1.1 christos return EXTRACT_INT;
948 1.1 christos if (!strcasecmp(atom + 2, "ists"))
949 1.1 christos return EXISTS;
950 1.1 christos if (!strcasecmp(atom + 2, "piry"))
951 1.1 christos return EXPIRY;
952 1.1 christos if (!strcasecmp(atom + 2, "pire"))
953 1.1 christos return EXPIRE;
954 1.1 christos if (!strcasecmp(atom + 2, "pired"))
955 1.1 christos return TOKEN_EXPIRED;
956 1.1 christos }
957 1.1 christos if (!strcasecmp(atom + 1, "ncode-int"))
958 1.1 christos return ENCODE_INT;
959 1.1 christos if (!strcasecmp(atom + 1, "poch"))
960 1.1 christos return EPOCH;
961 1.1 christos if (!strcasecmp(atom + 1, "thernet"))
962 1.1 christos return ETHERNET;
963 1.1 christos if (!strcasecmp(atom + 1, "nds"))
964 1.1 christos return ENDS;
965 1.1 christos if (!strncasecmp(atom + 1, "ls", 2)) {
966 1.1 christos if (!strcasecmp(atom + 3, "e"))
967 1.1 christos return ELSE;
968 1.1 christos if (!strcasecmp(atom + 3, "if"))
969 1.1 christos return ELSIF;
970 1.1 christos break;
971 1.1 christos }
972 1.1 christos if (!strcasecmp(atom + 1, "rror"))
973 1.1 christos return ERROR;
974 1.1 christos if (!strcasecmp(atom + 1, "val"))
975 1.1 christos return EVAL;
976 1.1 christos if (!strcasecmp(atom + 1, "ncapsulate"))
977 1.1 christos return ENCAPSULATE;
978 1.1 christos if (!strcasecmp(atom + 1, "xecute"))
979 1.1 christos return EXECUTE;
980 1.1 christos if (!strcasecmp(atom+1, "n")) {
981 1.1 christos return EN;
982 1.1 christos }
983 1.1 christos break;
984 1.1 christos case 'f':
985 1.1 christos if (!strcasecmp(atom + 1, "atal"))
986 1.1 christos return FATAL;
987 1.1 christos if (!strcasecmp(atom + 1, "ilename"))
988 1.1 christos return FILENAME;
989 1.1 christos if (!strcasecmp(atom + 1, "ixed-address"))
990 1.1 christos return FIXED_ADDR;
991 1.1 christos if (!strcasecmp(atom + 1, "ixed-address6"))
992 1.1 christos return FIXED_ADDR6;
993 1.1 christos if (!strcasecmp(atom + 1, "ixed-prefix6"))
994 1.1 christos return FIXED_PREFIX6;
995 1.1 christos if (!strcasecmp(atom + 1, "ddi"))
996 1.1 christos return TOKEN_FDDI;
997 1.1 christos if (!strcasecmp(atom + 1, "ormerr"))
998 1.1 christos return NS_FORMERR;
999 1.1 christos if (!strcasecmp(atom + 1, "unction"))
1000 1.1 christos return FUNCTION;
1001 1.1 christos if (!strcasecmp(atom + 1, "ailover"))
1002 1.1 christos return FAILOVER;
1003 1.1 christos if (!strcasecmp(atom + 1, "ree"))
1004 1.1 christos return TOKEN_FREE;
1005 1.1 christos break;
1006 1.1 christos case 'g':
1007 1.1 christos if (!strncasecmp(atom + 1, "et", 2)) {
1008 1.1 christos if (!strcasecmp(atom + 3, "-lease-hostnames"))
1009 1.1 christos return GET_LEASE_HOSTNAMES;
1010 1.1 christos if (!strcasecmp(atom + 3, "hostbyname"))
1011 1.1 christos return GETHOSTBYNAME;
1012 1.1 christos if (!strcasecmp(atom + 3, "hostname"))
1013 1.1 christos return GETHOSTNAME;
1014 1.1 christos break;
1015 1.1 christos }
1016 1.1 christos if (!strcasecmp(atom + 1, "iaddr"))
1017 1.1 christos return GIADDR;
1018 1.1 christos if (!strcasecmp(atom + 1, "roup"))
1019 1.1 christos return GROUP;
1020 1.1 christos break;
1021 1.1 christos case 'h':
1022 1.1 christos if (!strcasecmp(atom + 1, "ash"))
1023 1.1 christos return HASH;
1024 1.1 christos if (!strcasecmp(atom + 1, "ba"))
1025 1.1 christos return HBA;
1026 1.1 christos if (!strcasecmp(atom + 1, "ost"))
1027 1.1 christos return HOST;
1028 1.1 christos if (!strcasecmp(atom + 1, "ost-decl-name"))
1029 1.1 christos return HOST_DECL_NAME;
1030 1.1 christos if (!strcasecmp(atom + 1, "ost-identifier"))
1031 1.1 christos return HOST_IDENTIFIER;
1032 1.1 christos if (!strcasecmp(atom + 1, "ardware"))
1033 1.1 christos return HARDWARE;
1034 1.1 christos if (!strcasecmp(atom + 1, "ostname"))
1035 1.1 christos return HOSTNAME;
1036 1.1 christos if (!strcasecmp(atom + 1, "elp"))
1037 1.1 christos return TOKEN_HELP;
1038 1.1 christos if (!strcasecmp(atom + 1, "ex")) {
1039 1.1 christos return TOKEN_HEX;
1040 1.1 christos }
1041 1.1 christos break;
1042 1.1 christos case 'i':
1043 1.1 christos if (!strcasecmp(atom+1, "a-na"))
1044 1.1 christos return IA_NA;
1045 1.1 christos if (!strcasecmp(atom+1, "a-ta"))
1046 1.1 christos return IA_TA;
1047 1.1 christos if (!strcasecmp(atom+1, "a-pd"))
1048 1.1 christos return IA_PD;
1049 1.1 christos if (!strcasecmp(atom+1, "aaddr"))
1050 1.1 christos return IAADDR;
1051 1.1 christos if (!strcasecmp(atom+1, "aprefix"))
1052 1.1 christos return IAPREFIX;
1053 1.1 christos if (!strcasecmp(atom + 1, "nclude"))
1054 1.1 christos return INCLUDE;
1055 1.1 christos if (!strcasecmp(atom + 1, "nteger"))
1056 1.1 christos return INTEGER;
1057 1.1 christos if (!strcasecmp(atom + 1, "nfiniband"))
1058 1.1 christos return TOKEN_INFINIBAND;
1059 1.1 christos if (!strcasecmp(atom + 1, "nfinite"))
1060 1.1 christos return INFINITE;
1061 1.1 christos if (!strcasecmp(atom + 1, "nfo"))
1062 1.1 christos return INFO;
1063 1.1 christos if (!strcasecmp(atom + 1, "p-address"))
1064 1.1 christos return IP_ADDRESS;
1065 1.1 christos if (!strcasecmp(atom + 1, "p6-address"))
1066 1.1 christos return IP6_ADDRESS;
1067 1.1 christos if (!strcasecmp(atom + 1, "nitial-interval"))
1068 1.1 christos return INITIAL_INTERVAL;
1069 1.1 christos if (!strcasecmp(atom + 1, "nitial-delay"))
1070 1.1 christos return INITIAL_DELAY;
1071 1.1 christos if (!strcasecmp(atom + 1, "nterface"))
1072 1.1 christos return INTERFACE;
1073 1.1 christos if (!strcasecmp(atom + 1, "dentifier"))
1074 1.1 christos return IDENTIFIER;
1075 1.1 christos if (!strcasecmp(atom + 1, "f"))
1076 1.1 christos return IF;
1077 1.1 christos if (!strcasecmp(atom + 1, "s"))
1078 1.1 christos return IS;
1079 1.1 christos if (!strcasecmp(atom + 1, "gnore"))
1080 1.1 christos return IGNORE;
1081 1.1 christos break;
1082 1.1 christos case 'k':
1083 1.1 christos if (!strncasecmp(atom + 1, "nown", 4)) {
1084 1.1 christos if (!strcasecmp(atom + 5, "-clients"))
1085 1.1 christos return KNOWN_CLIENTS;
1086 1.1 christos if (!atom[5])
1087 1.1 christos return KNOWN;
1088 1.1 christos break;
1089 1.1 christos }
1090 1.1 christos if (!strcasecmp(atom + 1, "ey"))
1091 1.1 christos return KEY;
1092 1.1 christos if (!strcasecmp (atom + 1, "ey-algorithm"))
1093 1.1 christos return KEY_ALGORITHM;
1094 1.1 christos break;
1095 1.1 christos case 'l':
1096 1.1 christos if (!strcasecmp(atom + 1, "case"))
1097 1.1 christos return LCASE;
1098 1.1 christos if (!strcasecmp(atom + 1, "ease"))
1099 1.1 christos return LEASE;
1100 1.1 christos if (!strcasecmp(atom + 1, "ease6"))
1101 1.1 christos return LEASE6;
1102 1.1 christos if (!strcasecmp(atom + 1, "eased-address"))
1103 1.1 christos return LEASED_ADDRESS;
1104 1.1 christos if (!strcasecmp(atom + 1, "ease-time"))
1105 1.1 christos return LEASE_TIME;
1106 1.1 christos if (!strcasecmp(atom + 1, "easequery"))
1107 1.1 christos return LEASEQUERY;
1108 1.1 christos if (!strcasecmp(atom + 1, "ength"))
1109 1.1 christos return LENGTH;
1110 1.1 christos if (!strcasecmp(atom + 1, "imit"))
1111 1.1 christos return LIMIT;
1112 1.1 christos if (!strcasecmp(atom + 1, "et"))
1113 1.1 christos return LET;
1114 1.1 christos if (!strcasecmp(atom + 1, "oad"))
1115 1.1 christos return LOAD;
1116 1.1 christos if (!strcasecmp(atom + 1, "ocal"))
1117 1.1 christos return LOCAL;
1118 1.1 christos if (!strcasecmp(atom + 1, "og"))
1119 1.1 christos return LOG;
1120 1.1 christos if (!strcasecmp(atom+1, "lt")) {
1121 1.1 christos return LLT;
1122 1.1 christos }
1123 1.1 christos if (!strcasecmp(atom+1, "l")) {
1124 1.1 christos return LL;
1125 1.1 christos }
1126 1.1 christos if (!strcasecmp(atom+1, "ittle-endian")) {
1127 1.1 christos return TOKEN_LITTLE_ENDIAN;
1128 1.1 christos }
1129 1.1 christos if (!strcasecmp(atom + 1, "ease-id-format")) {
1130 1.1 christos return LEASE_ID_FORMAT;
1131 1.1 christos }
1132 1.1 christos break;
1133 1.1 christos case 'm':
1134 1.1 christos if (!strncasecmp(atom + 1, "ax", 2)) {
1135 1.1 christos if (!atom [3])
1136 1.1 christos return TOKEN_MAX;
1137 1.1 christos if (!strcasecmp(atom + 3, "-balance"))
1138 1.1 christos return MAX_BALANCE;
1139 1.1 christos if (!strncasecmp(atom + 3, "-lease-", 7)) {
1140 1.1 christos if (!strcasecmp(atom + 10, "misbalance"))
1141 1.1 christos return MAX_LEASE_MISBALANCE;
1142 1.1 christos if (!strcasecmp(atom + 10, "ownership"))
1143 1.1 christos return MAX_LEASE_OWNERSHIP;
1144 1.1 christos if (!strcasecmp(atom + 10, "time"))
1145 1.1 christos return MAX_LEASE_TIME;
1146 1.1 christos }
1147 1.1 christos if (!strcasecmp(atom + 3, "-life"))
1148 1.1 christos return MAX_LIFE;
1149 1.1 christos if (!strcasecmp(atom + 3, "-transmit-idle"))
1150 1.1 christos return MAX_TRANSMIT_IDLE;
1151 1.1 christos if (!strcasecmp(atom + 3, "-response-delay"))
1152 1.1 christos return MAX_RESPONSE_DELAY;
1153 1.1 christos if (!strcasecmp(atom + 3, "-unacked-updates"))
1154 1.1 christos return MAX_UNACKED_UPDATES;
1155 1.1 christos }
1156 1.1 christos if (!strncasecmp(atom + 1, "in-", 3)) {
1157 1.1 christos if (!strcasecmp(atom + 4, "balance"))
1158 1.1 christos return MIN_BALANCE;
1159 1.1 christos if (!strcasecmp(atom + 4, "lease-time"))
1160 1.1 christos return MIN_LEASE_TIME;
1161 1.1 christos if (!strcasecmp(atom + 4, "secs"))
1162 1.1 christos return MIN_SECS;
1163 1.1 christos break;
1164 1.1 christos }
1165 1.1 christos if (!strncasecmp(atom + 1, "edi", 3)) {
1166 1.1 christos if (!strcasecmp(atom + 4, "a"))
1167 1.1 christos return MEDIA;
1168 1.1 christos if (!strcasecmp(atom + 4, "um"))
1169 1.1 christos return MEDIUM;
1170 1.1 christos break;
1171 1.1 christos }
1172 1.1 christos if (!strcasecmp(atom + 1, "atch"))
1173 1.1 christos return MATCH;
1174 1.1 christos if (!strcasecmp(atom + 1, "embers"))
1175 1.1 christos return MEMBERS;
1176 1.1 christos if (!strcasecmp(atom + 1, "y"))
1177 1.1 christos return MY;
1178 1.1 christos if (!strcasecmp(atom + 1, "clt"))
1179 1.1 christos return MCLT;
1180 1.1 christos break;
1181 1.1 christos case 'n':
1182 1.1 christos if (!strcasecmp(atom + 1, "ormal"))
1183 1.1 christos return NORMAL;
1184 1.1 christos if (!strcasecmp(atom + 1, "ameserver"))
1185 1.1 christos return NAMESERVER;
1186 1.1 christos if (!strcasecmp(atom + 1, "etmask"))
1187 1.1 christos return NETMASK;
1188 1.1 christos if (!strcasecmp(atom + 1, "ever"))
1189 1.1 christos return NEVER;
1190 1.1 christos if (!strcasecmp(atom + 1, "ext-server"))
1191 1.1 christos return NEXT_SERVER;
1192 1.1 christos if (!strcasecmp(atom + 1, "ot"))
1193 1.1 christos return TOKEN_NOT;
1194 1.1 christos if (!strcasecmp(atom + 1, "o"))
1195 1.1 christos return TOKEN_NO;
1196 1.1 christos if (!strcasecmp(atom + 1, "oerror"))
1197 1.1 christos return NS_NOERROR;
1198 1.1 christos if (!strcasecmp(atom + 1, "otauth"))
1199 1.1 christos return NS_NOTAUTH;
1200 1.1 christos if (!strcasecmp(atom + 1, "otimp"))
1201 1.1 christos return NS_NOTIMP;
1202 1.1 christos if (!strcasecmp(atom + 1, "otzone"))
1203 1.1 christos return NS_NOTZONE;
1204 1.1 christos if (!strcasecmp(atom + 1, "xdomain"))
1205 1.1 christos return NS_NXDOMAIN;
1206 1.1 christos if (!strcasecmp(atom + 1, "xrrset"))
1207 1.1 christos return NS_NXRRSET;
1208 1.1 christos if (!strcasecmp(atom + 1, "ull"))
1209 1.1 christos return TOKEN_NULL;
1210 1.1 christos if (!strcasecmp(atom + 1, "ext"))
1211 1.1 christos return TOKEN_NEXT;
1212 1.1 christos if (!strcasecmp(atom + 1, "ew"))
1213 1.1 christos return TOKEN_NEW;
1214 1.1 christos break;
1215 1.1 christos case 'o':
1216 1.1 christos if (!strcasecmp(atom + 1, "mapi"))
1217 1.1 christos return OMAPI;
1218 1.1 christos if (!strcasecmp(atom + 1, "r"))
1219 1.1 christos return OR;
1220 1.1 christos if (!strcasecmp(atom + 1, "n"))
1221 1.1 christos return ON;
1222 1.1 christos if (!strcasecmp(atom + 1, "pen"))
1223 1.1 christos return TOKEN_OPEN;
1224 1.1 christos if (!strcasecmp(atom + 1, "ption"))
1225 1.1 christos return OPTION;
1226 1.1 christos if (!strcasecmp(atom + 1, "ne-lease-per-client"))
1227 1.1 christos return ONE_LEASE_PER_CLIENT;
1228 1.1 christos if (!strcasecmp(atom + 1, "f"))
1229 1.1 christos return OF;
1230 1.1 christos if (!strcasecmp(atom + 1, "wner"))
1231 1.1 christos return OWNER;
1232 1.1 christos if (!strcasecmp(atom + 1, "ctal")) {
1233 1.1 christos return TOKEN_OCTAL;
1234 1.1 christos }
1235 1.1 christos break;
1236 1.1 christos case 'p':
1237 1.1 christos if (!strcasecmp(atom + 1, "arse-vendor-option"))
1238 1.1 christos return PARSE_VENDOR_OPT;
1239 1.1 christos if (!strcasecmp(atom + 1, "repend"))
1240 1.1 christos return PREPEND;
1241 1.1 christos if (!strcasecmp(atom + 1, "referred-life"))
1242 1.1 christos return PREFERRED_LIFE;
1243 1.1 christos if (!strcasecmp(atom + 1, "acket"))
1244 1.1 christos return PACKET;
1245 1.1 christos if (!strcasecmp(atom + 1, "ool"))
1246 1.1 christos return POOL;
1247 1.1 christos if (!strcasecmp(atom + 1, "ool6"))
1248 1.1 christos return POOL6;
1249 1.1 christos if (!strcasecmp(atom + 1, "refix6"))
1250 1.1 christos return PREFIX6;
1251 1.1 christos if (!strcasecmp(atom + 1, "seudo"))
1252 1.1 christos return PSEUDO;
1253 1.1 christos if (!strcasecmp(atom + 1, "eer"))
1254 1.1 christos return PEER;
1255 1.1 christos if (!strcasecmp(atom + 1, "rimary"))
1256 1.1 christos return PRIMARY;
1257 1.1 christos if (!strcasecmp(atom + 1, "rimary6"))
1258 1.1 christos return PRIMARY6;
1259 1.1 christos if (!strncasecmp(atom + 1, "artner", 6)) {
1260 1.1 christos if (!atom [7])
1261 1.1 christos return PARTNER;
1262 1.1 christos if (!strcasecmp(atom + 7, "-down"))
1263 1.1 christos return PARTNER_DOWN;
1264 1.1 christos }
1265 1.1 christos if (!strcasecmp(atom + 1, "ort"))
1266 1.1 christos return PORT;
1267 1.1 christos if (!strcasecmp(atom + 1, "otential-conflict"))
1268 1.1 christos return POTENTIAL_CONFLICT;
1269 1.1 christos if (!strcasecmp(atom + 1, "ick-first-value") ||
1270 1.1 christos !strcasecmp(atom + 1, "ick"))
1271 1.1 christos return PICK;
1272 1.1 christos if (!strcasecmp(atom + 1, "aused"))
1273 1.1 christos return PAUSED;
1274 1.1 christos break;
1275 1.1 christos case 'r':
1276 1.1 christos if (!strcasecmp(atom + 1, "ange"))
1277 1.1 christos return RANGE;
1278 1.1 christos if (!strcasecmp(atom + 1, "ange6"))
1279 1.1 christos return RANGE6;
1280 1.1 christos if (isascii(atom[1]) &&
1281 1.1 christos (tolower((unsigned char)atom[1]) == 'e')) {
1282 1.1 christos if (!strcasecmp(atom + 2, "bind"))
1283 1.1 christos return REBIND;
1284 1.1 christos if (!strcasecmp(atom + 2, "boot"))
1285 1.1 christos return REBOOT;
1286 1.1 christos if (!strcasecmp(atom + 2, "contact-interval"))
1287 1.1 christos return RECONTACT_INTERVAL;
1288 1.1 christos if (!strncasecmp(atom + 2, "cover", 5)) {
1289 1.1 christos if (atom[7] == '\0')
1290 1.1 christos return RECOVER;
1291 1.1 christos if (!strcasecmp(atom + 7, "-done"))
1292 1.1 christos return RECOVER_DONE;
1293 1.1 christos if (!strcasecmp(atom + 7, "-wait"))
1294 1.1 christos return RECOVER_WAIT;
1295 1.1 christos break;
1296 1.1 christos }
1297 1.1 christos if (!strcasecmp(atom + 2, "fresh"))
1298 1.1 christos return REFRESH;
1299 1.1 christos if (!strcasecmp(atom + 2, "fused"))
1300 1.1 christos return NS_REFUSED;
1301 1.1 christos if (!strcasecmp(atom + 2, "ject"))
1302 1.1 christos return REJECT;
1303 1.1 christos if (!strcasecmp(atom + 2, "lease"))
1304 1.1 christos return RELEASE;
1305 1.1 christos if (!strcasecmp(atom + 2, "leased"))
1306 1.1 christos return TOKEN_RELEASED;
1307 1.1 christos if (!strcasecmp(atom + 2, "move"))
1308 1.1 christos return REMOVE;
1309 1.1 christos if (!strcasecmp(atom + 2, "new"))
1310 1.1 christos return RENEW;
1311 1.1 christos if (!strcasecmp(atom + 2, "quest"))
1312 1.1 christos return REQUEST;
1313 1.1 christos if (!strcasecmp(atom + 2, "quire"))
1314 1.1 christos return REQUIRE;
1315 1.1 christos if (isascii(atom[2]) &&
1316 1.1 christos (tolower((unsigned char)atom[2]) == 's')) {
1317 1.1 christos if (!strcasecmp(atom + 3, "erved"))
1318 1.1 christos return TOKEN_RESERVED;
1319 1.1 christos if (!strcasecmp(atom + 3, "et"))
1320 1.1 christos return TOKEN_RESET;
1321 1.1 christos if (!strcasecmp(atom + 3,
1322 1.1 christos "olution-interrupted"))
1323 1.1 christos return RESOLUTION_INTERRUPTED;
1324 1.1 christos break;
1325 1.1 christos }
1326 1.1 christos if (!strcasecmp(atom + 2, "try"))
1327 1.1 christos return RETRY;
1328 1.1 christos if (!strcasecmp(atom + 2, "turn"))
1329 1.1 christos return RETURN;
1330 1.1 christos if (!strcasecmp(atom + 2, "verse"))
1331 1.1 christos return REVERSE;
1332 1.1 christos if (!strcasecmp(atom + 2, "wind"))
1333 1.1 christos return REWIND;
1334 1.1 christos break;
1335 1.1 christos }
1336 1.1 christos break;
1337 1.1 christos case 's':
1338 1.1 christos if (!strcasecmp(atom + 1, "cript"))
1339 1.1 christos return SCRIPT;
1340 1.1 christos if (isascii(atom[1]) &&
1341 1.1 christos tolower((unsigned char)atom[1]) == 'e') {
1342 1.1 christos if (!strcasecmp(atom + 2, "arch"))
1343 1.1 christos return SEARCH;
1344 1.1 christos if (isascii(atom[2]) &&
1345 1.1 christos tolower((unsigned char)atom[2]) == 'c') {
1346 1.1 christos if (!strncasecmp(atom + 3, "ond", 3)) {
1347 1.1 christos if (!strcasecmp(atom + 6, "ary"))
1348 1.1 christos return SECONDARY;
1349 1.1 christos if (!strcasecmp(atom + 6, "ary6"))
1350 1.1 christos return SECONDARY6;
1351 1.1 christos if (!strcasecmp(atom + 6, "s"))
1352 1.1 christos return SECONDS;
1353 1.1 christos break;
1354 1.1 christos }
1355 1.1 christos if (!strcasecmp(atom + 3, "ret"))
1356 1.1 christos return SECRET;
1357 1.1 christos break;
1358 1.1 christos }
1359 1.1 christos if (!strncasecmp(atom + 2, "lect", 4)) {
1360 1.1 christos if (atom[6] == '\0')
1361 1.1 christos return SELECT;
1362 1.1 christos if (!strcasecmp(atom + 6, "-timeout"))
1363 1.1 christos return SELECT_TIMEOUT;
1364 1.1 christos break;
1365 1.1 christos }
1366 1.1 christos if (!strcasecmp(atom + 2, "nd"))
1367 1.1 christos return SEND;
1368 1.1 christos if (!strncasecmp(atom + 2, "rv", 2)) {
1369 1.1 christos if (!strncasecmp(atom + 4, "er", 2)) {
1370 1.1 christos if (atom[6] == '\0')
1371 1.1 christos return TOKEN_SERVER;
1372 1.1 christos if (atom[6] == '-') {
1373 1.1 christos if (!strcasecmp(atom + 7,
1374 1.1 christos "duid"))
1375 1.1 christos return SERVER_DUID;
1376 1.1 christos if (!strcasecmp(atom + 7,
1377 1.1 christos "name"))
1378 1.1 christos return SERVER_NAME;
1379 1.1 christos if (!strcasecmp(atom + 7,
1380 1.1 christos "identifier"))
1381 1.1 christos return SERVER_IDENTIFIER;
1382 1.1 christos break;
1383 1.1 christos }
1384 1.1 christos break;
1385 1.1 christos }
1386 1.1 christos if (!strcasecmp(atom + 4, "fail"))
1387 1.1 christos return NS_SERVFAIL;
1388 1.1 christos break;
1389 1.1 christos }
1390 1.1 christos if (!strcasecmp(atom + 2, "t"))
1391 1.1 christos return TOKEN_SET;
1392 1.1 christos break;
1393 1.1 christos }
1394 1.1 christos if (isascii(atom[1]) &&
1395 1.1 christos tolower((unsigned char)atom[1]) == 'h') {
1396 1.1 christos if (!strcasecmp(atom + 2, "ared-network"))
1397 1.1 christos return SHARED_NETWORK;
1398 1.1 christos if (!strcasecmp(atom + 2, "utdown"))
1399 1.1 christos return SHUTDOWN;
1400 1.1 christos break;
1401 1.1 christos }
1402 1.1 christos if (isascii(atom[1]) &&
1403 1.1 christos tolower((unsigned char)atom[1]) == 'i') {
1404 1.1 christos if (!strcasecmp(atom + 2, "addr"))
1405 1.1 christos return SIADDR;
1406 1.1 christos if (!strcasecmp(atom + 2, "gned"))
1407 1.1 christos return SIGNED;
1408 1.1 christos if (!strcasecmp(atom + 2, "ze"))
1409 1.1 christos return SIZE;
1410 1.1 christos break;
1411 1.1 christos }
1412 1.1 christos if (isascii(atom[1]) &&
1413 1.1 christos tolower((unsigned char)atom[1]) == 'p') {
1414 1.1 christos if (isascii(atom[2]) &&
1415 1.1 christos tolower((unsigned char)atom[2]) == 'a') {
1416 1.1 christos if (!strcasecmp(atom + 3, "ce"))
1417 1.1 christos return SPACE;
1418 1.1 christos if (!strcasecmp(atom + 3, "wn"))
1419 1.1 christos return SPAWN;
1420 1.1 christos break;
1421 1.1 christos }
1422 1.1 christos if (!strcasecmp(atom + 2, "lit"))
1423 1.1 christos return SPLIT;
1424 1.1 christos break;
1425 1.1 christos }
1426 1.1 christos if (isascii(atom[1]) &&
1427 1.1 christos tolower((unsigned char)atom[1]) == 't') {
1428 1.1 christos if (isascii(atom[2]) &&
1429 1.1 christos tolower((unsigned char)atom[2]) == 'a') {
1430 1.1 christos if (!strncasecmp(atom + 3, "rt", 2)) {
1431 1.1 christos if (!strcasecmp(atom + 5, "s"))
1432 1.1 christos return STARTS;
1433 1.1 christos if (!strcasecmp(atom + 5, "up"))
1434 1.1 christos return STARTUP;
1435 1.1 christos break;
1436 1.1 christos }
1437 1.1 christos if (isascii(atom[3]) &&
1438 1.1 christos tolower((unsigned char)atom[3]) == 't') {
1439 1.1 christos if (!strcasecmp(atom + 4, "e"))
1440 1.1 christos return STATE;
1441 1.1 christos if (!strcasecmp(atom + 4, "ic"))
1442 1.1 christos return STATIC;
1443 1.1 christos break;
1444 1.1 christos }
1445 1.1 christos }
1446 1.1 christos if (!strcasecmp(atom + 2, "ring"))
1447 1.1 christos return STRING_TOKEN;
1448 1.1 christos break;
1449 1.1 christos }
1450 1.1 christos if (!strncasecmp(atom + 1, "ub", 2)) {
1451 1.1 christos if (!strcasecmp(atom + 3, "class"))
1452 1.1 christos return SUBCLASS;
1453 1.1 christos if (!strcasecmp(atom + 3, "net"))
1454 1.1 christos return SUBNET;
1455 1.1 christos if (!strcasecmp(atom + 3, "net6"))
1456 1.1 christos return SUBNET6;
1457 1.1 christos if (!strcasecmp(atom + 3, "string"))
1458 1.1 christos return SUBSTRING;
1459 1.1 christos break;
1460 1.1 christos }
1461 1.1 christos if (isascii(atom[1]) &&
1462 1.1 christos tolower((unsigned char)atom[1]) == 'u') {
1463 1.1 christos if (!strcasecmp(atom + 2, "ffix"))
1464 1.1 christos return SUFFIX;
1465 1.1 christos if (!strcasecmp(atom + 2, "persede"))
1466 1.1 christos return SUPERSEDE;
1467 1.1 christos }
1468 1.1 christos if (!strcasecmp(atom + 1, "witch"))
1469 1.1 christos return SWITCH;
1470 1.1 christos break;
1471 1.1 christos case 't':
1472 1.1 christos if (!strcasecmp(atom + 1, "imestamp"))
1473 1.1 christos return TIMESTAMP;
1474 1.1 christos if (!strcasecmp(atom + 1, "imeout"))
1475 1.1 christos return TIMEOUT;
1476 1.1 christos if (!strcasecmp(atom + 1, "oken-ring"))
1477 1.1 christos return TOKEN_RING;
1478 1.1 christos if (!strcasecmp(atom + 1, "ext"))
1479 1.1 christos return TEXT;
1480 1.1 christos if (!strcasecmp(atom + 1, "stp"))
1481 1.1 christos return TSTP;
1482 1.1 christos if (!strcasecmp(atom + 1, "sfp"))
1483 1.1 christos return TSFP;
1484 1.1 christos if (!strcasecmp(atom + 1, "ransmission"))
1485 1.1 christos return TRANSMISSION;
1486 1.1 christos if (!strcasecmp(atom + 1, "emporary"))
1487 1.1 christos return TEMPORARY;
1488 1.1 christos break;
1489 1.1 christos case 'u':
1490 1.1 christos if (!strcasecmp(atom + 1, "case"))
1491 1.1 christos return UCASE;
1492 1.1 christos if (!strcasecmp(atom + 1, "nset"))
1493 1.1 christos return UNSET;
1494 1.1 christos if (!strcasecmp(atom + 1, "nsigned"))
1495 1.1 christos return UNSIGNED;
1496 1.1 christos if (!strcasecmp(atom + 1, "id"))
1497 1.1 christos return UID;
1498 1.1 christos if (!strncasecmp(atom + 1, "se", 2)) {
1499 1.1 christos if (!strcasecmp(atom + 3, "r-class"))
1500 1.1 christos return USER_CLASS;
1501 1.1 christos if (!strcasecmp(atom + 3, "-host-decl-names"))
1502 1.1 christos return USE_HOST_DECL_NAMES;
1503 1.1 christos if (!strcasecmp(atom + 3,
1504 1.1 christos "-lease-addr-for-default-route"))
1505 1.1 christos return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
1506 1.1 christos break;
1507 1.1 christos }
1508 1.1 christos if (!strncasecmp(atom + 1, "nknown", 6)) {
1509 1.1 christos if (!strcasecmp(atom + 7, "-clients"))
1510 1.1 christos return UNKNOWN_CLIENTS;
1511 1.1 christos if (!strcasecmp(atom + 7, "-state"))
1512 1.1 christos return UNKNOWN_STATE;
1513 1.1 christos if (!atom [7])
1514 1.1 christos return UNKNOWN;
1515 1.1 christos break;
1516 1.1 christos }
1517 1.1 christos if (!strcasecmp(atom + 1, "nauthenticated"))
1518 1.1 christos return UNAUTHENTICATED;
1519 1.1 christos if (!strcasecmp(atom + 1, "pdate"))
1520 1.1 christos return UPDATE;
1521 1.1 christos break;
1522 1.1 christos case 'v':
1523 1.1 christos if (!strcasecmp(atom + 1, "6relay"))
1524 1.1 christos return V6RELAY;
1525 1.1 christos if (!strcasecmp(atom + 1, "6relopt"))
1526 1.1 christos return V6RELOPT;
1527 1.1 christos if (!strcasecmp(atom + 1, "endor-class"))
1528 1.1 christos return VENDOR_CLASS;
1529 1.1 christos if (!strcasecmp(atom + 1, "endor"))
1530 1.1 christos return VENDOR;
1531 1.1 christos break;
1532 1.1 christos case 'w':
1533 1.1 christos if (!strcasecmp(atom + 1, "ith"))
1534 1.1 christos return WITH;
1535 1.1 christos if (!strcasecmp(atom + 1, "idth"))
1536 1.1 christos return WIDTH;
1537 1.1 christos break;
1538 1.1 christos case 'y':
1539 1.1 christos if (!strcasecmp(atom + 1, "iaddr"))
1540 1.1 christos return YIADDR;
1541 1.1 christos if (!strcasecmp(atom + 1, "xdomain"))
1542 1.1 christos return NS_YXDOMAIN;
1543 1.1 christos if (!strcasecmp(atom + 1, "xrrset"))
1544 1.1 christos return NS_YXRRSET;
1545 1.1 christos break;
1546 1.1 christos case 'z':
1547 1.1 christos if (!strcasecmp(atom + 1, "erolen"))
1548 1.1 christos return ZEROLEN;
1549 1.1 christos if (!strcasecmp(atom + 1, "one"))
1550 1.1 christos return ZONE;
1551 1.1 christos break;
1552 1.1 christos }
1553 1.1 christos return dfv;
1554 1.1 christos }
1555 1.1 christos
1556