2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00
isc-dhcp/common/conflex.c

522 lines
12 KiB
C
Raw Normal View History

1995-11-29 07:40:04 +00:00
/* conflex.c
Lexical scanner for dhcpd config file... */
/*
1997-02-22 12:25:32 +00:00
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
1995-11-29 07:40:04 +00:00
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
1997-02-22 12:25:32 +00:00
"$Id: conflex.c,v 1.22 1997/02/22 12:23:40 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
1995-11-29 07:40:04 +00:00
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h>
int lexline;
int lexchar;
char *token_line;
char *prev_line;
char *cur_line;
char *tlname;
static char line1 [81];
static char line2 [81];
1995-11-29 07:40:04 +00:00
static int lpos;
static int line;
static int tlpos;
static int tline;
1995-11-29 07:40:04 +00:00
static int token;
static int ugflag;
static char *tval;
static char tokbuf [1500];
#ifdef OLD_LEXER
char comments [4096];
int comment_index;
#endif
1995-11-29 07:40:04 +00:00
static int get_char PROTO ((FILE *));
static int get_token PROTO ((FILE *));
static void skip_to_eol PROTO ((FILE *));
static int read_string PROTO ((FILE *));
static int read_number PROTO ((int, FILE *));
1996-08-29 09:13:41 +00:00
static int read_num_or_name PROTO ((int, FILE *));
1995-11-29 07:40:04 +00:00
static int intern PROTO ((char *, int));
void new_parse (name)
char *name;
{
tlname = name;
lpos = line = 1;
cur_line = line1;
prev_line = line2;
token_line = cur_line;
cur_line [0] = prev_line [0] = 0;
warnings_occurred = 0;
}
1995-11-29 07:40:04 +00:00
static int get_char (cfile)
FILE *cfile;
{
1996-05-17 23:09:54 +00:00
int c = getc (cfile);
1995-11-29 07:40:04 +00:00
if (!ugflag) {
if (c == EOL) {
if (cur_line == line1) {
cur_line = line2;
prev_line = line1;
} else {
cur_line = line2;
prev_line = line1;
}
1995-11-29 07:40:04 +00:00
line++;
lpos = 1;
cur_line [0] = 0;
} else if (c != EOF) {
if (lpos <= 81) {
cur_line [lpos - 1] = c;
cur_line [lpos] = 0;
}
1995-11-29 07:40:04 +00:00
lpos++;
}
} else
ugflag = 0;
return c;
}
static int get_token (cfile)
FILE *cfile;
{
int c;
int ttok;
static char tb [2];
int l, p, u;
1995-11-29 07:40:04 +00:00
do {
l = line;
p = lpos;
u = ugflag;
1995-11-29 07:40:04 +00:00
c = get_char (cfile);
#ifdef OLD_LEXER
if (c == '\n' && p == 1 && !u
&& comment_index < sizeof comments)
comments [comment_index++] = '\n';
#endif
1995-11-29 07:40:04 +00:00
if (isascii (c) && isspace (c))
continue;
if (c == '#') {
#ifdef OLD_LEXER
if (comment_index < sizeof comments)
comments [comment_index++] = '#';
#endif
1995-11-29 07:40:04 +00:00
skip_to_eol (cfile);
continue;
}
if (c == '"') {
lexline = l;
lexchar = p;
1995-11-29 07:40:04 +00:00
ttok = read_string (cfile);
break;
}
1996-03-16 17:50:30 +00:00
if ((isascii (c) && isdigit (c)) || c == '-') {
lexline = l;
lexchar = p;
1995-11-29 07:40:04 +00:00
ttok = read_number (c, cfile);
break;
} else if (isascii (c) && isalpha (c)) {
lexline = l;
lexchar = p;
1996-08-29 09:13:41 +00:00
ttok = read_num_or_name (c, cfile);
1995-11-29 07:40:04 +00:00
break;
} else {
lexline = l;
lexchar = p;
tb [0] = c;
tb [1] = 0;
tval = tb;
1995-11-29 07:40:04 +00:00
ttok = c;
break;
}
} while (1);
return ttok;
}
int next_token (rval, cfile)
char **rval;
FILE *cfile;
{
int rv;
if (token) {
if (lexline != tline)
token_line = cur_line;
lexchar = tlpos;
lexline = tline;
1995-11-29 07:40:04 +00:00
rv = token;
token = 0;
} else {
rv = get_token (cfile);
token_line = cur_line;
1995-11-29 07:40:04 +00:00
}
if (rval)
*rval = tval;
#ifdef DEBUG_TOKENS
fprintf (stderr, "%s:%d ", tval, rv);
#endif
1995-11-29 07:40:04 +00:00
return rv;
}
int peek_token (rval, cfile)
char **rval;
FILE *cfile;
{
int x;
if (!token) {
tlpos = lexchar;
tline = lexline;
1995-11-29 07:40:04 +00:00
token = get_token (cfile);
if (lexline != tline)
token_line = prev_line;
x = lexchar; lexchar = tlpos; tlpos = x;
x = lexline; lexline = tline; tline = x;
}
1995-11-29 07:40:04 +00:00
if (rval)
*rval = tval;
#ifdef DEBUG_TOKENS
fprintf (stderr, "(%s:%d) ", tval, token);
#endif
1995-11-29 07:40:04 +00:00
return token;
}
static void skip_to_eol (cfile)
FILE *cfile;
{
int c;
do {
c = get_char (cfile);
if (c == EOF)
return;
#ifdef OLD_LEXER
if (comment_index < sizeof (comments))
comments [comment_index++] = c;
#endif
1995-11-29 07:40:04 +00:00
if (c == EOL) {
return;
}
} while (1);
}
static int read_string (cfile)
FILE *cfile;
{
int i;
int bs = 0;
int c;
for (i = 0; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (c == EOF) {
parse_warn ("eof in string constant");
break;
}
if (bs) {
bs = 0;
tokbuf [i] = c;
} else if (c == '\\')
bs = 1;
else if (c == '"')
break;
else
tokbuf [i] = c;
}
/* Normally, I'd feel guilty about this, but we're talking about
strings that'll fit in a DHCP packet here... */
if (i == sizeof tokbuf) {
parse_warn ("string constant larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return STRING;
}
static int read_number (c, cfile)
int c;
FILE *cfile;
{
int seenx = 0;
int i = 0;
int token = NUMBER;
1995-11-29 07:40:04 +00:00
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!seenx && c == 'x') {
1995-11-29 07:40:04 +00:00
seenx = 1;
#ifndef OLD_LEXER
} else if (isascii (c) && !isxdigit (c) &&
(c == '-' || c == '_' || isalpha (c))) {
1996-08-29 09:13:41 +00:00
token = NAME;
} else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
1996-08-29 09:13:41 +00:00
token = NUMBER_OR_NAME;
#endif
} else if (!isascii (c) || !isxdigit (c)) {
1995-11-29 07:40:04 +00:00
ungetc (c, cfile);
ugflag = 1;
break;
}
tokbuf [i] = c;
}
if (i == sizeof tokbuf) {
parse_warn ("numeric token larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return token;
1995-11-29 07:40:04 +00:00
}
1996-08-29 09:13:41 +00:00
static int read_num_or_name (c, cfile)
1995-11-29 07:40:04 +00:00
int c;
FILE *cfile;
{
int i = 0;
1996-08-29 09:13:41 +00:00
int rv = NUMBER_OR_NAME;
1995-11-29 07:40:04 +00:00
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!isascii (c) ||
(c != '-' && c != '_' && !isalnum (c))) {
ungetc (c, cfile);
ugflag = 1;
break;
}
if (!isxdigit (c))
1996-08-29 09:13:41 +00:00
rv = NAME;
1995-11-29 07:40:04 +00:00
tokbuf [i] = c;
}
if (i == sizeof tokbuf) {
parse_warn ("token larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return intern (tval, rv);
}
static int intern (atom, dfv)
char *atom;
int dfv;
{
1996-05-22 08:05:19 +00:00
if (!isascii (atom [0]))
return dfv;
switch (tolower (atom [0])) {
1997-02-22 08:29:24 +00:00
case 'a':
if (!strcasecmp (atom + 1, "llow"))
return ALLOW;
1997-02-22 12:25:32 +00:00
if (!strcasecmp (atom + 1, "lias"))
return ALIAS;
1997-02-22 08:29:24 +00:00
break;
case 'b':
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "ootp"))
return BOOTP;
if (!strcasecmp (atom + 1, "ooting"))
return BOOTING;
if (!strcasecmp (atom + 1, "oot-unknown-clients"))
return BOOT_UNKNOWN_CLIENTS;
case 'c':
if (!strcasecmp (atom + 1, "lass"))
return CLASS;
if (!strcasecmp (atom + 1, "iaddr"))
return CIADDR;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "lient-identifier"))
return CLIENT_IDENTIFIER;
break;
case 'd':
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "eny"))
return DENY;
if (!strncasecmp (atom + 1, "efault", 6)) {
if (!atom [7])
return DEFAULT;
if (!strcasecmp (atom + 7, "-lease-time"))
return DEFAULT_LEASE_TIME;
break;
}
if (!strncasecmp (atom + 1, "ynamic-bootp", 12)) {
if (!atom [13])
return DYNAMIC_BOOTP;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 13, "-lease-cutoff"))
return DYNAMIC_BOOTP_LEASE_CUTOFF;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 13, "-lease-length"))
return DYNAMIC_BOOTP_LEASE_LENGTH;
1997-02-22 08:29:24 +00:00
break;
}
break;
case 'e':
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
if (!strcasecmp (atom + 1, "nds"))
return ENDS;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "xpire"))
return EXPIRE;
1995-11-29 07:40:04 +00:00
break;
case 'f':
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
break;
case 'g':
if (!strcasecmp (atom + 1, "iaddr"))
return GIADDR;
if (!strcasecmp (atom + 1, "roup"))
return GROUP;
1996-08-29 23:02:40 +00:00
if (!strcasecmp (atom + 1, "et-lease-hostnames"))
return GET_LEASE_HOSTNAMES;
break;
case 'h':
if (!strcasecmp (atom + 1, "ost"))
return HOST;
if (!strcasecmp (atom + 1, "ardware"))
return HARDWARE;
break;
1997-02-18 14:32:30 +00:00
case 'i':
if (!strcasecmp (atom + 1, "nterface"))
return INTERFACE;
break;
case 'l':
if (!strcasecmp (atom + 1, "ease"))
return LEASE;
1995-11-29 07:40:04 +00:00
break;
case 'm':
if (!strcasecmp (atom + 1, "ax-lease-time"))
return MAX_LEASE_TIME;
1997-02-22 08:29:24 +00:00
if (!strncasecmp (atom + 1, "edi", 3)) {
if (!strcasecmp (atom + 4, "a"))
return MEDIA;
if (!strcasecmp (atom + 4, "um"))
return MEDIUM;
break;
}
break;
case 'n':
if (!strcasecmp (atom + 1, "etmask"))
return NETMASK;
if (!strcasecmp (atom + 1, "ext-server"))
return NEXT_SERVER;
break;
1995-11-29 07:40:04 +00:00
case 'o':
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
if (!strcasecmp (atom + 1, "ne-lease-per-client"))
return ONE_LEASE_PER_CLIENT;
break;
case 'p':
if (!strcasecmp (atom + 1, "acket"))
return PACKET;
1995-11-29 07:40:04 +00:00
break;
case 'r':
if (!strcasecmp (atom + 1, "ange"))
return RANGE;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "equest"))
return REQUEST;
if (!strcasecmp (atom + 1, "equire"))
return REQUIRE;
if (!strcasecmp (atom + 1, "etry"))
return RETRY;
if (!strcasecmp (atom + 1, "enew"))
return RENEW;
if (!strcasecmp (atom + 1, "ebind"))
return REBIND;
break;
case 's':
if (!strcasecmp (atom + 1, "tarts"))
return STARTS;
if (!strcasecmp (atom + 1, "iaddr"))
return SIADDR;
if (!strcasecmp (atom + 1, "ubnet"))
return SUBNET;
1996-05-22 08:05:19 +00:00
if (!strcasecmp (atom + 1, "hared-network"))
return SHARED_NETWORK;
if (!strcasecmp (atom + 1, "erver-name"))
return SERVER_NAME;
if (!strcasecmp (atom + 1, "erver-identifier"))
return SERVER_IDENTIFIER;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "elect-timeout"))
return SELECT_TIMEOUT;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "end"))
return SEND;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "cript"))
return SCRIPT;
break;
case 't':
1996-05-22 08:05:19 +00:00
if (!strcasecmp (atom + 1, "imestamp"))
return TIMESTAMP;
1997-02-18 14:32:30 +00:00
if (!strcasecmp (atom + 1, "imeout"))
return TIMEOUT;
if (!strcasecmp (atom + 1, "oken-ring"))
return TOKEN_RING;
break;
case 'u':
if (!strcasecmp (atom + 1, "id"))
return UID;
1996-02-29 18:06:29 +00:00
if (!strcasecmp (atom + 1, "ser-class"))
return USER_CLASS;
1996-09-09 07:04:29 +00:00
if (!strcasecmp (atom + 1, "se-host-decl-names"))
return USE_HOST_DECL_NAMES;
1997-02-22 08:29:24 +00:00
if (!strcasecmp (atom + 1, "nknown-clients"))
return UNKNOWN_CLIENTS;
1996-02-29 18:06:29 +00:00
break;
case 'v':
if (!strcasecmp (atom + 1, "endor-class"))
return VENDOR_CLASS;
break;
case 'y':
if (!strcasecmp (atom + 1, "iaddr"))
return YIADDR;
break;
1995-11-29 07:40:04 +00:00
}
return dfv;
}