2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 06:15:55 +00:00

Move some general functions into the common parser.

This commit is contained in:
Ted Lemon
2000-11-28 22:07:09 +00:00
parent 812022ffd6
commit 2e7a6cd54f

View File

@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: clparse.c,v 1.51 2000/11/24 03:38:18 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: clparse.c,v 1.52 2000/11/28 22:07:09 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -568,56 +568,6 @@ void parse_client_statement (cfile, ip, config)
parse_semi (cfile);
}
int parse_X (cfile, buf, max)
struct parse *cfile;
u_int8_t *buf;
unsigned max;
{
int token;
const char *val;
unsigned len;
u_int8_t *s;
token = peek_token (&val, cfile);
if (token == NUMBER_OR_NAME || token == NUMBER) {
len = 0;
do {
token = next_token (&val, cfile);
if (token != NUMBER && token != NUMBER_OR_NAME) {
parse_warn (cfile,
"expecting hexadecimal constant.");
skip_to_semi (cfile);
return 0;
}
convert_num (cfile, &buf [len], val, 16, 8);
if (len++ > max) {
parse_warn (cfile,
"hexadecimal constant too long.");
skip_to_semi (cfile);
return 0;
}
token = peek_token (&val, cfile);
if (token == COLON)
token = next_token (&val, cfile);
} while (token == COLON);
val = (char *)buf;
} else if (token == STRING) {
token = next_token (&val, cfile);
len = strlen (val);
if (len + 1 > max) {
parse_warn (cfile, "string constant too long.");
skip_to_semi (cfile);
return 0;
}
memcpy (buf, val, len + 1);
} else {
parse_warn (cfile, "expecting string or hexadecimal data");
skip_to_semi (cfile);
return 0;
}
return len;
}
/* option-list :== option_name |
option_list COMMA option_name */
@@ -1070,188 +1020,6 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp)
}
}
int parse_option_decl (oc, cfile)
struct option_cache **oc;
struct parse *cfile;
{
const char *val;
int token;
u_int8_t buf [4];
u_int8_t hunkbuf [1024];
unsigned hunkix = 0;
const char *fmt;
struct option *option;
struct iaddr ip_addr;
u_int8_t *dp;
unsigned len;
int nul_term = 0;
struct buffer *bp;
int known = 0;
option = parse_option_name (cfile, 0, &known);
if (!option)
return 0;
/* Parse the option data... */
do {
/* Set a flag if this is an array of a simple type (i.e.,
not an array of pairs of IP addresses, or something
like that. */
int uniform = option -> format [1] == 'A';
for (fmt = option -> format; *fmt; fmt++) {
if (*fmt == 'A')
break;
switch (*fmt) {
case 'E':
fmt = strchr (fmt, '.');
if (!fmt) {
parse_warn (cfile,
"malformed %s (bug!)",
"encapsulation format");
skip_to_semi (cfile);
return 0;
}
case 'X':
len = parse_X (cfile, &hunkbuf [hunkix],
sizeof hunkbuf - hunkix);
hunkix += len;
break;
case 't': /* Text string... */
token = next_token (&val, cfile);
if (token != STRING) {
parse_warn (cfile,
"expecting string.");
skip_to_semi (cfile);
return 0;
}
len = strlen (val);
if (hunkix + len + 1 > sizeof hunkbuf) {
parse_warn (cfile,
"option data buffer %s",
"overflow");
skip_to_semi (cfile);
return 0;
}
memcpy (&hunkbuf [hunkix], val, len + 1);
nul_term = 1;
hunkix += len;
break;
case 'I': /* IP address. */
if (!parse_ip_addr (cfile, &ip_addr))
return 0;
len = ip_addr.len;
dp = ip_addr.iabuf;
alloc:
if (hunkix + len > sizeof hunkbuf) {
parse_warn (cfile,
"option data buffer %s",
"overflow");
skip_to_semi (cfile);
return 0;
}
memcpy (&hunkbuf [hunkix], dp, len);
hunkix += len;
break;
case 'L': /* Unsigned 32-bit integer... */
case 'l': /* Signed 32-bit integer... */
token = next_token (&val, cfile);
if (token != NUMBER) {
need_number:
parse_warn (cfile,
"expecting number.");
if (token != SEMI)
skip_to_semi (cfile);
return 0;
}
convert_num (cfile, buf, val, 0, 32);
len = 4;
dp = buf;
goto alloc;
case 's': /* Signed 16-bit integer. */
case 'S': /* Unsigned 16-bit integer. */
token = next_token (&val, cfile);
if (token != NUMBER)
goto need_number;
convert_num (cfile, buf, val, 0, 16);
len = 2;
dp = buf;
goto alloc;
case 'b': /* Signed 8-bit integer. */
case 'B': /* Unsigned 8-bit integer. */
token = next_token (&val, cfile);
if (token != NUMBER)
goto need_number;
convert_num (cfile, buf, val, 0, 8);
len = 1;
dp = buf;
goto alloc;
case 'f': /* Boolean flag. */
token = next_token (&val, cfile);
if (!is_identifier (token)) {
parse_warn (cfile,
"expecting identifier.");
bad_flag:
if (token != SEMI)
skip_to_semi (cfile);
return 0;
}
if (!strcasecmp (val, "true")
|| !strcasecmp (val, "on"))
buf [0] = 1;
else if (!strcasecmp (val, "false")
|| !strcasecmp (val, "off"))
buf [0] = 0;
else {
parse_warn (cfile,
"expecting boolean.");
goto bad_flag;
}
len = 1;
dp = buf;
goto alloc;
default:
log_error ("parse_option_param: Bad format %c",
*fmt);
skip_to_semi (cfile);
return 0;
}
}
token = next_token (&val, cfile);
} while (*fmt == 'A' && token == COMMA);
if (token != SEMI) {
parse_warn (cfile, "semicolon expected.");
skip_to_semi (cfile);
return 0;
}
bp = (struct buffer *)0;
if (!buffer_allocate (&bp, hunkix + nul_term, MDL))
log_fatal ("no memory to store option declaration.");
if (!bp -> data)
log_fatal ("out of memory allocating option data.");
memcpy (bp -> data, hunkbuf, hunkix + nul_term);
if (!option_cache_allocate (oc, MDL))
log_fatal ("out of memory allocating option cache.");
(*oc) -> data.buffer = bp;
(*oc) -> data.data = &bp -> data [0];
(*oc) -> data.terminated = nul_term;
(*oc) -> data.len = hunkix;
(*oc) -> option = option;
return 1;
}
void parse_string_list (cfile, lp, multiple)
struct parse *cfile;
struct string_list **lp;