2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 05:47:45 +00:00

Rehash nomenclature; allow range declaration to take a single address

This commit is contained in:
Ted Lemon 1996-08-29 09:14:39 +00:00
parent 50b025a3d7
commit 2d59f5901f
2 changed files with 328 additions and 298 deletions

View File

@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: confpars.c,v 1.26 1996/08/28 01:28:27 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; "$Id: confpars.c,v 1.27 1996/08/29 09:14:39 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -50,16 +50,16 @@ static char copyright[] =
static TIME parsed_time; static TIME parsed_time;
/* conf-file :== declarations statements EOF /* conf-file :== parameters declarations EOF
declarations :== <nil> | declaration | declarations declaration parameters :== <nil> | parameter | parameters parameter
statements :== <nil> | statement | statements statement */ declarations :== <nil> | declaration | declarations declaration */
void readconf () void readconf ()
{ {
FILE *cfile; FILE *cfile;
char *val; char *val;
int token; int token;
int statement = 0; int declaration = 0;
new_parse (_PATH_DHCPD_CONF); new_parse (_PATH_DHCPD_CONF);
@ -78,17 +78,18 @@ void readconf ()
token = peek_token (&val, cfile); token = peek_token (&val, cfile);
if (token == EOF) if (token == EOF)
break; break;
statement = parse_statement (cfile, &root_group, declaration = parse_statement (cfile, &root_group,
ROOT_GROUP, (struct host_decl *)0, ROOT_GROUP,
statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
token = next_token (&val, cfile); token = next_token (&val, cfile);
} }
/* lease-file :== lease-statements EOF /* lease-file :== lease-declarations EOF
lease-statments :== <nil> lease-statments :== <nil>
| lease-statement | lease-declaration
| lease-statements lease-statement */ | lease-declarations lease-declaration */
void read_leases () void read_leases ()
{ {
@ -121,7 +122,7 @@ void read_leases ()
skip_to_semi (cfile); skip_to_semi (cfile);
} else { } else {
struct lease *lease; struct lease *lease;
lease = parse_lease_statement (cfile); lease = parse_lease_declaration (cfile);
if (lease) if (lease)
enter_lease (lease); enter_lease (lease);
else else
@ -131,35 +132,37 @@ void read_leases ()
} while (1); } while (1);
} }
/* declaration :== timestamp /* statement :== parameter | declaration
| DEFAULT_LEASE_TIME lease_time
| MAX_LEASE_TIME lease_time
| DYNAMIC_BOOTP_LEASE_CUTOFF date
| DYNAMIC_BOOTP_LEASE_LENGTH lease_time
| BOOT_UNKNOWN_CLIENTS boolean
| ONE_LEASE_PER_CLIENT boolean
| NEXT_SERVER ip-addr-or-hostname SEMI
| option_declaration
| SERVER-IDENTIFIER ip-addr-or-hostname SEMI
| FILENAME string-declaration
| SERVER_NAME string-declaration
| hardware-declaration
| fixed-address-declaration
statement :== host-statement parameter :== timestamp
| group-statement | DEFAULT_LEASE_TIME lease_time
| shared-network-statment | MAX_LEASE_TIME lease_time
| subnet-statement | DYNAMIC_BOOTP_LEASE_CUTOFF date
| VENDOR_CLASS class-statement | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
| USER_CLASS class-statement | BOOT_UNKNOWN_CLIENTS boolean
| RANGE address-range-statement */ | ONE_LEASE_PER_CLIENT boolean
| NEXT_SERVER ip-addr-or-hostname SEMI
| option_parameter
| SERVER-IDENTIFIER ip-addr-or-hostname SEMI
| FILENAME string-parameter
| SERVER_NAME string-parameter
| hardware-parameter
| fixed-address-parameter
int parse_statement (cfile, group, type, host_decl, statement) declaration :== host-declaration
| group-declaration
| shared-network-declaration
| subnet-declaration
| VENDOR_CLASS class-declaration
| USER_CLASS class-declaration
| RANGE address-range-declaration */
int parse_statement (cfile, group, type, host_decl, declaration)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
int type; int type;
struct host_decl *host_decl; struct host_decl *host_decl;
int statement; int declaration;
{ {
int token; int token;
char *val; char *val;
@ -172,19 +175,19 @@ int parse_statement (cfile, group, type, host_decl, statement)
switch (next_token (&val, cfile)) { switch (next_token (&val, cfile)) {
case HOST: case HOST:
if (type != HOST_STMT) if (type != HOST_DECL)
parse_host_statement (cfile, group); parse_host_declaration (cfile, group);
else { else {
parse_warn ("host statements not allowed here."); parse_warn ("host declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
} }
return 1; return 1;
case GROUP: case GROUP:
if (type != HOST_STMT) if (type != HOST_DECL)
parse_group_statement (cfile, group); parse_group_declaration (cfile, group);
else { else {
parse_warn ("host statements not allowed here."); parse_warn ("host declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
} }
return 1; return 1;
@ -194,29 +197,29 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case SHARED_NETWORK: case SHARED_NETWORK:
if (type == SHARED_NET_STMT || if (type == SHARED_NET_DECL ||
type == HOST_STMT || type == HOST_DECL ||
type == SUBNET_STMT) { type == SUBNET_DECL) {
parse_warn ("shared-network declarations not %s.", parse_warn ("shared-network parameters not %s.",
"allowed here"); "allowed here");
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_shared_net_statement (cfile, group); parse_shared_net_declaration (cfile, group);
return 1; return 1;
case SUBNET: case SUBNET:
if (type == HOST_STMT || type == SUBNET_STMT) { if (type == HOST_DECL || type == SUBNET_DECL) {
parse_warn ("subnet statements not allowed here."); parse_warn ("subnet declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
return 1; return 1;
} }
/* If we're in a subnet statement, just do the parse. */ /* If we're in a subnet declaration, just do the parse. */
if (group -> shared_network) { if (group -> shared_network) {
parse_subnet_statement (cfile, parse_subnet_declaration (cfile,
group -> shared_network); group -> shared_network);
break; break;
} }
@ -229,7 +232,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
share -> group = clone_group (group, "parse_statement:subnet"); share -> group = clone_group (group, "parse_statement:subnet");
share -> group -> shared_network = share; share -> group -> shared_network = share;
parse_subnet_statement (cfile, share); parse_subnet_declaration (cfile, share);
if (share -> subnets) { if (share -> subnets) {
share -> interface = share -> interface =
share -> subnets -> interface; share -> subnets -> interface;
@ -245,11 +248,11 @@ int parse_statement (cfile, group, type, host_decl, statement)
return 1; return 1;
case VENDOR_CLASS: case VENDOR_CLASS:
parse_class_statement (cfile, group, 0); parse_class_declaration (cfile, group, 0);
return 1; return 1;
case USER_CLASS: case USER_CLASS:
parse_class_statement (cfile, group, 1); parse_class_declaration (cfile, group, 1);
return 1; return 1;
case DEFAULT_LEASE_TIME: case DEFAULT_LEASE_TIME:
@ -269,13 +272,13 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case BOOT_UNKNOWN_CLIENTS: case BOOT_UNKNOWN_CLIENTS:
if (type == HOST_STMT) if (type == HOST_DECL)
parse_warn ("boot-unknown-clients not allowed here."); parse_warn ("boot-unknown-clients not allowed here.");
group -> boot_unknown_clients = parse_boolean (cfile); group -> boot_unknown_clients = parse_boolean (cfile);
break; break;
case ONE_LEASE_PER_CLIENT: case ONE_LEASE_PER_CLIENT:
if (type == HOST_STMT) if (type == HOST_DECL)
parse_warn ("one-lease-per-client not allowed here."); parse_warn ("one-lease-per-client not allowed here.");
group -> one_lease_per_client = parse_boolean (cfile); group -> one_lease_per_client = parse_boolean (cfile);
break; break;
@ -294,7 +297,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case OPTION: case OPTION:
parse_option_decl (cfile, group); parse_option_param (cfile, group);
break; break;
case SERVER_IDENTIFIER: case SERVER_IDENTIFIER:
@ -303,7 +306,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
"level."); "level.");
tree = parse_ip_addr_or_hostname (cfile, 0); tree = parse_ip_addr_or_hostname (cfile, 0);
if (!tree) if (!tree)
return statement; return declaration;
cache = tree_cache (tree); cache = tree_cache (tree);
if (type == ROOT_GROUP) { if (type == ROOT_GROUP) {
if (!tree_evaluate (cache)) if (!tree_evaluate (cache))
@ -324,43 +327,43 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case HARDWARE: case HARDWARE:
parse_hardware_decl (cfile, &hardware); parse_hardware_param (cfile, &hardware);
if (host_decl) if (host_decl)
host_decl -> interface = hardware; host_decl -> interface = hardware;
else else
parse_warn ("hardware address declaration %s", parse_warn ("hardware address parameter %s",
"not allowed here."); "not allowed here.");
break; break;
case FIXED_ADDR: case FIXED_ADDR:
cache = parse_fixed_addr_decl (cfile); cache = parse_fixed_addr_param (cfile);
if (host_decl) if (host_decl)
host_decl -> fixed_addr = cache; host_decl -> fixed_addr = cache;
else else
parse_warn ("fixed-address declaration not %s", parse_warn ("fixed-address parameter not %s",
"allowed here."); "allowed here.");
break; break;
case RANGE: case RANGE:
if (type != SUBNET_STMT || !group -> subnet) { if (type != SUBNET_DECL || !group -> subnet) {
parse_warn ("range statement not allowed here."); parse_warn ("range declaration not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
return statement; return declaration;
} }
parse_address_range (cfile, group -> subnet); parse_address_range (cfile, group -> subnet);
return statement; return declaration;
default: default:
if (statement) if (declaration)
parse_warn ("expecting a statement."); parse_warn ("expecting a declaration.");
else else
parse_warn ("expecting a declaration or statement."); parse_warn ("expecting a parameter or declaration.");
skip_to_semi (cfile); skip_to_semi (cfile);
return statement; return declaration;
} }
if (statement) { if (declaration) {
parse_warn ("declarations not allowed after first statement."); parse_warn ("parameters not allowed after first declaration.");
return 1; return 1;
} }
@ -466,9 +469,9 @@ int parse_lbrace (cfile)
} }
/* host-statement :== hostname RBRACE declarations statements LBRACE */ /* host-declaration :== hostname RBRACE parameters declarations LBRACE */
void parse_host_statement (cfile, group) void parse_host_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -476,18 +479,18 @@ void parse_host_statement (cfile, group)
int token; int token;
struct host_decl *host; struct host_decl *host;
char *name = parse_host_name (cfile); char *name = parse_host_name (cfile);
int statement = 0; int declaration = 0;
if (!name) if (!name)
return; return;
host = (struct host_decl *)dmalloc (sizeof (struct host_decl), host = (struct host_decl *)dmalloc (sizeof (struct host_decl),
"parse_host_statement"); "parse_host_declaration");
if (!host) if (!host)
error ("can't allocate host decl struct %s.", name); error ("can't allocate host decl struct %s.", name);
host -> name = name; host -> name = name;
host -> group = clone_group (group, "parse_host_statement"); host -> group = clone_group (group, "parse_host_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -503,14 +506,14 @@ void parse_host_statement (cfile, group)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, host -> group, declaration = parse_statement (cfile, host -> group,
HOST_STMT, host, HOST_DECL, host,
statement); declaration);
} while (1); } while (1);
if (!host -> group -> options [DHO_HOST_NAME]) { if (!host -> group -> options [DHO_HOST_NAME]) {
host -> group -> options [DHO_HOST_NAME] = host -> group -> options [DHO_HOST_NAME] =
new_tree_cache ("parse_host_statement"); new_tree_cache ("parse_host_declaration");
if (!host -> group -> options [DHO_HOST_NAME]) if (!host -> group -> options [DHO_HOST_NAME])
error ("can't allocate a tree cache for hostname."); error ("can't allocate a tree cache for hostname.");
host -> group -> options [DHO_HOST_NAME] -> len = host -> group -> options [DHO_HOST_NAME] -> len =
@ -581,10 +584,10 @@ char *parse_host_name (cfile)
return s; return s;
} }
/* class-statement :== STRING LBRACE declarations statements RBRACE /* class-declaration :== STRING LBRACE parameters declarations RBRACE
*/ */
void parse_class_statement (cfile, group, type) void parse_class_declaration (cfile, group, type)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
int type; int type;
@ -592,7 +595,7 @@ void parse_class_statement (cfile, group, type)
char *val; char *val;
int token; int token;
struct class *class; struct class *class;
int statement; int declaration;
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != STRING) { if (token != STRING) {
@ -604,7 +607,7 @@ void parse_class_statement (cfile, group, type)
class = add_class (type, val); class = add_class (type, val);
if (!class) if (!class)
error ("No memory for class %s.", val); error ("No memory for class %s.", val);
class -> group = clone_group (group, "parse_class_statement"); class -> group = clone_group (group, "parse_class_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -619,10 +622,10 @@ void parse_class_statement (cfile, group, type)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} else { } else {
statement = parse_statement (cfile, class -> group, declaration = parse_statement (cfile, class -> group,
CLASS_STMT, CLASS_DECL,
(struct host_decl *)0, (struct host_decl *)0,
statement); declaration);
} }
} while (1); } while (1);
} }
@ -649,9 +652,10 @@ void parse_lease_time (cfile, timep)
parse_semi (cfile); parse_semi (cfile);
} }
/* shared-network-statement :== LBRACE statements declarations RBRACE */ /* shared-network-declaration :==
hostname LBRACE declarations parameters RBRACE */
void parse_shared_net_statement (cfile, group) void parse_shared_net_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -663,9 +667,9 @@ void parse_shared_net_statement (cfile, group)
struct subnet *next_net; struct subnet *next_net;
char *name; char *name;
struct tree_cache *server_next; struct tree_cache *server_next;
int statement = 0; int declaration = 0;
share = new_shared_network ("parse_shared_net_statement"); share = new_shared_network ("parse_shared_net_declaration");
if (!share) if (!share)
error ("No memory for shared subnet"); error ("No memory for shared subnet");
share -> leases = (struct lease *)0; share -> leases = (struct lease *)0;
@ -673,7 +677,7 @@ void parse_shared_net_statement (cfile, group)
share -> insertion_point = (struct lease *)0; share -> insertion_point = (struct lease *)0;
share -> next = (struct shared_network *)0; share -> next = (struct shared_network *)0;
share -> interface = (struct interface_info *)0; share -> interface = (struct interface_info *)0;
share -> group = clone_group (group, "parse_shared_net_statement"); share -> group = clone_group (group, "parse_shared_net_declaration");
share -> group -> shared_network = share; share -> group -> shared_network = share;
/* Get the name of the shared network... */ /* Get the name of the shared network... */
@ -715,16 +719,17 @@ void parse_shared_net_statement (cfile, group)
break; break;
} }
statement = parse_statement (cfile, share -> group, declaration = parse_statement (cfile, share -> group,
SHARED_NET_STMT, SHARED_NET_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
} }
/* subnet-statement :== /* subnet-declaration :==
net NETMASK netmask RBRACE declarations statements LBRACE */ net NETMASK netmask RBRACE parameters declarations LBRACE */
void parse_subnet_statement (cfile, share) void parse_subnet_declaration (cfile, share)
FILE *cfile; FILE *cfile;
struct shared_network *share; struct shared_network *share;
{ {
@ -734,15 +739,15 @@ void parse_subnet_statement (cfile, share)
struct iaddr iaddr; struct iaddr iaddr;
unsigned char addr [4]; unsigned char addr [4];
int len = sizeof addr; int len = sizeof addr;
int statement = 0; int declaration = 0;
subnet = new_subnet ("parse_subnet_statement"); subnet = new_subnet ("parse_subnet_declaration");
if (!subnet) if (!subnet)
error ("No memory for new subnet"); error ("No memory for new subnet");
subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0; subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0;
subnet -> shared_network = share; subnet -> shared_network = share;
subnet -> group = clone_group (share -> group, subnet -> group = clone_group (share -> group,
"parse_subnet_statement"); "parse_subnet_declaration");
subnet -> group -> subnet = subnet; subnet -> group -> subnet = subnet;
/* Get the network number... */ /* Get the network number... */
@ -781,9 +786,10 @@ void parse_subnet_statement (cfile, share)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, subnet -> group, declaration = parse_statement (cfile, subnet -> group,
SUBNET_STMT, SUBNET_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
/* If this subnet supports dynamic bootp, flag it so in the /* If this subnet supports dynamic bootp, flag it so in the
@ -803,18 +809,18 @@ void parse_subnet_statement (cfile, share)
} }
} }
/* group-statement :== RBRACE declarations statements LBRACE */ /* group-declaration :== RBRACE parameters declarations LBRACE */
void parse_group_statement (cfile, group) void parse_group_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
char *val; char *val;
int token; int token;
struct group *g; struct group *g;
int statement = 0; int declaration = 0;
g = clone_group (group, "parse_group_statement"); g = clone_group (group, "parse_group_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -829,15 +835,16 @@ void parse_group_statement (cfile, group)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, g, GROUP_STMT, declaration = parse_statement (cfile, g, GROUP_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
} }
/* hardware-declaration :== HARDWARE ETHERNET csns SEMI /* hardware-parameter :== HARDWARE ETHERNET csns SEMI
csns :== NUMBER | csns COLON NUMBER */ csns :== NUMBER | csns COLON NUMBER */
void parse_hardware_decl (cfile, hardware) void parse_hardware_param (cfile, hardware)
FILE *cfile; FILE *cfile;
struct hardware *hardware; struct hardware *hardware;
{ {
@ -891,7 +898,7 @@ void parse_hardware_decl (cfile, hardware)
} }
} }
/* string-declaration :== STRING SEMI */ /* string-parameter :== STRING SEMI */
char *parse_string (cfile) char *parse_string (cfile)
FILE *cfile; FILE *cfile;
@ -960,11 +967,11 @@ struct tree *parse_ip_addr_or_hostname (cfile, uniform)
} }
/* fixed-addr-declaration :== ip-addrs-or-hostnames SEMI /* fixed-addr-parameter :== ip-addrs-or-hostnames SEMI
ip-addrs-or-hostnames :== ip-addr-or-hostname | ip-addrs-or-hostnames :== ip-addr-or-hostname
ip-addrs-or-hostnames ip-addr-or-hostname */ | ip-addrs-or-hostnames ip-addr-or-hostname */
struct tree_cache *parse_fixed_addr_decl (cfile) struct tree_cache *parse_fixed_addr_param (cfile)
FILE *cfile; FILE *cfile;
{ {
char *val; char *val;
@ -988,14 +995,14 @@ struct tree_cache *parse_fixed_addr_decl (cfile)
return tree_cache (tree); return tree_cache (tree);
} }
/* option_declaration :== identifier DOT identifier <syntax> SEMI | /* option_parameter :== identifier DOT identifier <syntax> SEMI
identifier <syntax> SEMI | identifier <syntax> SEMI
Option syntax is handled specially through format strings, so it Option syntax is handled specially through format strings, so it
would be painful to come up with BNF for it. However, it always would be painful to come up with BNF for it. However, it always
starts as above and ends in a SEMI. */ starts as above and ends in a SEMI. */
void parse_option_decl (cfile, group) void parse_option_param (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -1037,7 +1044,7 @@ void parse_option_decl (cfile, group)
universe = (struct universe *)hash_lookup (&universe_hash, universe = (struct universe *)hash_lookup (&universe_hash,
vendor, 0); vendor, 0);
/* If it's not there, we can't parse the rest of the /* If it's not there, we can't parse the rest of the
statement. */ declaration. */
if (!universe) { if (!universe) {
parse_warn ("no vendor named %s.", vendor); parse_warn ("no vendor named %s.", vendor);
skip_to_semi (cfile); skip_to_semi (cfile);
@ -1080,13 +1087,13 @@ void parse_option_decl (cfile, group)
switch (*fmt) { switch (*fmt) {
case 'X': case 'X':
token = peek_token (&val, cfile); token = peek_token (&val, cfile);
if (token == NUMBER_OR_ATOM || if (token == NUMBER_OR_NAME ||
token == NUMBER) { token == NUMBER) {
do { do {
token = next_token token = next_token
(&val, cfile); (&val, cfile);
if (token != NUMBER if (token != NUMBER
&& token != NUMBER_OR_ATOM) && token != NUMBER_OR_NAME)
goto need_number; goto need_number;
convert_num (buf, val, 16, 8); convert_num (buf, val, 16, 8);
tree = tree_concat tree = tree_concat
@ -1184,7 +1191,7 @@ void parse_option_decl (cfile, group)
tree = tree_concat (tree, tree_const (buf, 1)); tree = tree_concat (tree, tree_const (buf, 1));
break; break;
default: default:
warn ("Bad format %c in parse_option_decl.", warn ("Bad format %c in parse_option_param.",
*fmt); *fmt);
skip_to_semi (cfile); skip_to_semi (cfile);
return; return;
@ -1226,20 +1233,22 @@ TIME parse_timestamp (cfile)
return rv; return rv;
} }
/* lease_statement :== LEASE ip_address LBRACE lease_declarations RBRACE /* lease_declaration :== LEASE ip_address LBRACE lease_parameters RBRACE
lease_declarations :== <nil>
| lease_declaration
| lease_declarations lease_declaration
lease_declaration :== STARTS date
| ENDS date
| TIMESTAMP date
| HARDWARE hardware-declaration
| UID hex_numbers SEMI
| HOST hostname SEMI
| CLASS identifier SEMI
| DYNAMIC_BOOTP SEMI */
struct lease *parse_lease_statement (cfile) lease_parameters :== <nil>
| lease_parameter
| lease_parameters lease_parameter
lease_parameter :== STARTS date
| ENDS date
| TIMESTAMP date
| HARDWARE hardware-parameter
| UID hex_numbers SEMI
| HOST hostname SEMI
| CLASS identifier SEMI
| DYNAMIC_BOOTP SEMI */
struct lease *parse_lease_declaration (cfile)
FILE *cfile; FILE *cfile;
{ {
char *val; char *val;
@ -1342,7 +1351,7 @@ struct lease *parse_lease_statement (cfile)
case HARDWARE: case HARDWARE:
seenbit = 64; seenbit = 64;
parse_hardware_decl (cfile, parse_hardware_param (cfile,
&lease.hardware_addr); &lease.hardware_addr);
break; break;
@ -1367,7 +1376,7 @@ struct lease *parse_lease_statement (cfile)
} }
} }
if (seenmask & seenbit) { if (seenmask & seenbit) {
parse_warn ("Too many %s declarations in lease %s\n", parse_warn ("Too many %s parameters in lease %s\n",
tbuf, piaddr (lease.ip_addr)); tbuf, piaddr (lease.ip_addr));
} else } else
seenmask |= seenbit; seenmask |= seenbit;
@ -1376,8 +1385,8 @@ struct lease *parse_lease_statement (cfile)
return &lease; return &lease;
} }
/* address-range-statement :== ip-address ip-address SEMI | /* address-range-declaration :== ip-address ip-address SEMI
DYNAMIC_BOOTP ip-address ip-address SEMI */ | DYNAMIC_BOOTP ip-address ip-address SEMI */
void parse_address_range (cfile, subnet) void parse_address_range (cfile, subnet)
FILE *cfile; FILE *cfile;
@ -1406,11 +1415,17 @@ void parse_address_range (cfile, subnet)
memcpy (low.iabuf, addr, len); memcpy (low.iabuf, addr, len);
low.len = len; low.len = len;
/* Only one address? */
token = peek_token (&val, cfile);
if (token == SEMI)
high = low;
else {
/* Get the top address in the range... */ /* Get the top address in the range... */
if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
return; return;
memcpy (high.iabuf, addr, len); memcpy (high.iabuf, addr, len);
high.len = len; high.len = len;
}
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != SEMI) { if (token != SEMI) {
@ -1635,9 +1650,9 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
break; break;
} }
/* Allow NUMBER_OR_ATOM if base is 16. */ /* Allow NUMBER_OR_NAME if base is 16. */
if (token != NUMBER && if (token != NUMBER &&
(base != 16 || token != NUMBER_OR_ATOM)) { (base != 16 || token != NUMBER_OR_NAME)) {
parse_warn ("expecting numeric value."); parse_warn ("expecting numeric value.");
skip_to_semi (cfile); skip_to_semi (cfile);
return (unsigned char *)0; return (unsigned char *)0;

View File

@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: confpars.c,v 1.26 1996/08/28 01:28:27 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; "$Id: confpars.c,v 1.27 1996/08/29 09:14:39 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -50,16 +50,16 @@ static char copyright[] =
static TIME parsed_time; static TIME parsed_time;
/* conf-file :== declarations statements EOF /* conf-file :== parameters declarations EOF
declarations :== <nil> | declaration | declarations declaration parameters :== <nil> | parameter | parameters parameter
statements :== <nil> | statement | statements statement */ declarations :== <nil> | declaration | declarations declaration */
void readconf () void readconf ()
{ {
FILE *cfile; FILE *cfile;
char *val; char *val;
int token; int token;
int statement = 0; int declaration = 0;
new_parse (_PATH_DHCPD_CONF); new_parse (_PATH_DHCPD_CONF);
@ -78,17 +78,18 @@ void readconf ()
token = peek_token (&val, cfile); token = peek_token (&val, cfile);
if (token == EOF) if (token == EOF)
break; break;
statement = parse_statement (cfile, &root_group, declaration = parse_statement (cfile, &root_group,
ROOT_GROUP, (struct host_decl *)0, ROOT_GROUP,
statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
token = next_token (&val, cfile); token = next_token (&val, cfile);
} }
/* lease-file :== lease-statements EOF /* lease-file :== lease-declarations EOF
lease-statments :== <nil> lease-statments :== <nil>
| lease-statement | lease-declaration
| lease-statements lease-statement */ | lease-declarations lease-declaration */
void read_leases () void read_leases ()
{ {
@ -121,7 +122,7 @@ void read_leases ()
skip_to_semi (cfile); skip_to_semi (cfile);
} else { } else {
struct lease *lease; struct lease *lease;
lease = parse_lease_statement (cfile); lease = parse_lease_declaration (cfile);
if (lease) if (lease)
enter_lease (lease); enter_lease (lease);
else else
@ -131,35 +132,37 @@ void read_leases ()
} while (1); } while (1);
} }
/* declaration :== timestamp /* statement :== parameter | declaration
| DEFAULT_LEASE_TIME lease_time
| MAX_LEASE_TIME lease_time
| DYNAMIC_BOOTP_LEASE_CUTOFF date
| DYNAMIC_BOOTP_LEASE_LENGTH lease_time
| BOOT_UNKNOWN_CLIENTS boolean
| ONE_LEASE_PER_CLIENT boolean
| NEXT_SERVER ip-addr-or-hostname SEMI
| option_declaration
| SERVER-IDENTIFIER ip-addr-or-hostname SEMI
| FILENAME string-declaration
| SERVER_NAME string-declaration
| hardware-declaration
| fixed-address-declaration
statement :== host-statement parameter :== timestamp
| group-statement | DEFAULT_LEASE_TIME lease_time
| shared-network-statment | MAX_LEASE_TIME lease_time
| subnet-statement | DYNAMIC_BOOTP_LEASE_CUTOFF date
| VENDOR_CLASS class-statement | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
| USER_CLASS class-statement | BOOT_UNKNOWN_CLIENTS boolean
| RANGE address-range-statement */ | ONE_LEASE_PER_CLIENT boolean
| NEXT_SERVER ip-addr-or-hostname SEMI
| option_parameter
| SERVER-IDENTIFIER ip-addr-or-hostname SEMI
| FILENAME string-parameter
| SERVER_NAME string-parameter
| hardware-parameter
| fixed-address-parameter
int parse_statement (cfile, group, type, host_decl, statement) declaration :== host-declaration
| group-declaration
| shared-network-declaration
| subnet-declaration
| VENDOR_CLASS class-declaration
| USER_CLASS class-declaration
| RANGE address-range-declaration */
int parse_statement (cfile, group, type, host_decl, declaration)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
int type; int type;
struct host_decl *host_decl; struct host_decl *host_decl;
int statement; int declaration;
{ {
int token; int token;
char *val; char *val;
@ -172,19 +175,19 @@ int parse_statement (cfile, group, type, host_decl, statement)
switch (next_token (&val, cfile)) { switch (next_token (&val, cfile)) {
case HOST: case HOST:
if (type != HOST_STMT) if (type != HOST_DECL)
parse_host_statement (cfile, group); parse_host_declaration (cfile, group);
else { else {
parse_warn ("host statements not allowed here."); parse_warn ("host declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
} }
return 1; return 1;
case GROUP: case GROUP:
if (type != HOST_STMT) if (type != HOST_DECL)
parse_group_statement (cfile, group); parse_group_declaration (cfile, group);
else { else {
parse_warn ("host statements not allowed here."); parse_warn ("host declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
} }
return 1; return 1;
@ -194,29 +197,29 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case SHARED_NETWORK: case SHARED_NETWORK:
if (type == SHARED_NET_STMT || if (type == SHARED_NET_DECL ||
type == HOST_STMT || type == HOST_DECL ||
type == SUBNET_STMT) { type == SUBNET_DECL) {
parse_warn ("shared-network declarations not %s.", parse_warn ("shared-network parameters not %s.",
"allowed here"); "allowed here");
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_shared_net_statement (cfile, group); parse_shared_net_declaration (cfile, group);
return 1; return 1;
case SUBNET: case SUBNET:
if (type == HOST_STMT || type == SUBNET_STMT) { if (type == HOST_DECL || type == SUBNET_DECL) {
parse_warn ("subnet statements not allowed here."); parse_warn ("subnet declarations not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
return 1; return 1;
} }
/* If we're in a subnet statement, just do the parse. */ /* If we're in a subnet declaration, just do the parse. */
if (group -> shared_network) { if (group -> shared_network) {
parse_subnet_statement (cfile, parse_subnet_declaration (cfile,
group -> shared_network); group -> shared_network);
break; break;
} }
@ -229,7 +232,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
share -> group = clone_group (group, "parse_statement:subnet"); share -> group = clone_group (group, "parse_statement:subnet");
share -> group -> shared_network = share; share -> group -> shared_network = share;
parse_subnet_statement (cfile, share); parse_subnet_declaration (cfile, share);
if (share -> subnets) { if (share -> subnets) {
share -> interface = share -> interface =
share -> subnets -> interface; share -> subnets -> interface;
@ -245,11 +248,11 @@ int parse_statement (cfile, group, type, host_decl, statement)
return 1; return 1;
case VENDOR_CLASS: case VENDOR_CLASS:
parse_class_statement (cfile, group, 0); parse_class_declaration (cfile, group, 0);
return 1; return 1;
case USER_CLASS: case USER_CLASS:
parse_class_statement (cfile, group, 1); parse_class_declaration (cfile, group, 1);
return 1; return 1;
case DEFAULT_LEASE_TIME: case DEFAULT_LEASE_TIME:
@ -269,13 +272,13 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case BOOT_UNKNOWN_CLIENTS: case BOOT_UNKNOWN_CLIENTS:
if (type == HOST_STMT) if (type == HOST_DECL)
parse_warn ("boot-unknown-clients not allowed here."); parse_warn ("boot-unknown-clients not allowed here.");
group -> boot_unknown_clients = parse_boolean (cfile); group -> boot_unknown_clients = parse_boolean (cfile);
break; break;
case ONE_LEASE_PER_CLIENT: case ONE_LEASE_PER_CLIENT:
if (type == HOST_STMT) if (type == HOST_DECL)
parse_warn ("one-lease-per-client not allowed here."); parse_warn ("one-lease-per-client not allowed here.");
group -> one_lease_per_client = parse_boolean (cfile); group -> one_lease_per_client = parse_boolean (cfile);
break; break;
@ -294,7 +297,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case OPTION: case OPTION:
parse_option_decl (cfile, group); parse_option_param (cfile, group);
break; break;
case SERVER_IDENTIFIER: case SERVER_IDENTIFIER:
@ -303,7 +306,7 @@ int parse_statement (cfile, group, type, host_decl, statement)
"level."); "level.");
tree = parse_ip_addr_or_hostname (cfile, 0); tree = parse_ip_addr_or_hostname (cfile, 0);
if (!tree) if (!tree)
return statement; return declaration;
cache = tree_cache (tree); cache = tree_cache (tree);
if (type == ROOT_GROUP) { if (type == ROOT_GROUP) {
if (!tree_evaluate (cache)) if (!tree_evaluate (cache))
@ -324,43 +327,43 @@ int parse_statement (cfile, group, type, host_decl, statement)
break; break;
case HARDWARE: case HARDWARE:
parse_hardware_decl (cfile, &hardware); parse_hardware_param (cfile, &hardware);
if (host_decl) if (host_decl)
host_decl -> interface = hardware; host_decl -> interface = hardware;
else else
parse_warn ("hardware address declaration %s", parse_warn ("hardware address parameter %s",
"not allowed here."); "not allowed here.");
break; break;
case FIXED_ADDR: case FIXED_ADDR:
cache = parse_fixed_addr_decl (cfile); cache = parse_fixed_addr_param (cfile);
if (host_decl) if (host_decl)
host_decl -> fixed_addr = cache; host_decl -> fixed_addr = cache;
else else
parse_warn ("fixed-address declaration not %s", parse_warn ("fixed-address parameter not %s",
"allowed here."); "allowed here.");
break; break;
case RANGE: case RANGE:
if (type != SUBNET_STMT || !group -> subnet) { if (type != SUBNET_DECL || !group -> subnet) {
parse_warn ("range statement not allowed here."); parse_warn ("range declaration not allowed here.");
skip_to_semi (cfile); skip_to_semi (cfile);
return statement; return declaration;
} }
parse_address_range (cfile, group -> subnet); parse_address_range (cfile, group -> subnet);
return statement; return declaration;
default: default:
if (statement) if (declaration)
parse_warn ("expecting a statement."); parse_warn ("expecting a declaration.");
else else
parse_warn ("expecting a declaration or statement."); parse_warn ("expecting a parameter or declaration.");
skip_to_semi (cfile); skip_to_semi (cfile);
return statement; return declaration;
} }
if (statement) { if (declaration) {
parse_warn ("declarations not allowed after first statement."); parse_warn ("parameters not allowed after first declaration.");
return 1; return 1;
} }
@ -466,9 +469,9 @@ int parse_lbrace (cfile)
} }
/* host-statement :== hostname RBRACE declarations statements LBRACE */ /* host-declaration :== hostname RBRACE parameters declarations LBRACE */
void parse_host_statement (cfile, group) void parse_host_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -476,18 +479,18 @@ void parse_host_statement (cfile, group)
int token; int token;
struct host_decl *host; struct host_decl *host;
char *name = parse_host_name (cfile); char *name = parse_host_name (cfile);
int statement = 0; int declaration = 0;
if (!name) if (!name)
return; return;
host = (struct host_decl *)dmalloc (sizeof (struct host_decl), host = (struct host_decl *)dmalloc (sizeof (struct host_decl),
"parse_host_statement"); "parse_host_declaration");
if (!host) if (!host)
error ("can't allocate host decl struct %s.", name); error ("can't allocate host decl struct %s.", name);
host -> name = name; host -> name = name;
host -> group = clone_group (group, "parse_host_statement"); host -> group = clone_group (group, "parse_host_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -503,14 +506,14 @@ void parse_host_statement (cfile, group)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, host -> group, declaration = parse_statement (cfile, host -> group,
HOST_STMT, host, HOST_DECL, host,
statement); declaration);
} while (1); } while (1);
if (!host -> group -> options [DHO_HOST_NAME]) { if (!host -> group -> options [DHO_HOST_NAME]) {
host -> group -> options [DHO_HOST_NAME] = host -> group -> options [DHO_HOST_NAME] =
new_tree_cache ("parse_host_statement"); new_tree_cache ("parse_host_declaration");
if (!host -> group -> options [DHO_HOST_NAME]) if (!host -> group -> options [DHO_HOST_NAME])
error ("can't allocate a tree cache for hostname."); error ("can't allocate a tree cache for hostname.");
host -> group -> options [DHO_HOST_NAME] -> len = host -> group -> options [DHO_HOST_NAME] -> len =
@ -581,10 +584,10 @@ char *parse_host_name (cfile)
return s; return s;
} }
/* class-statement :== STRING LBRACE declarations statements RBRACE /* class-declaration :== STRING LBRACE parameters declarations RBRACE
*/ */
void parse_class_statement (cfile, group, type) void parse_class_declaration (cfile, group, type)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
int type; int type;
@ -592,7 +595,7 @@ void parse_class_statement (cfile, group, type)
char *val; char *val;
int token; int token;
struct class *class; struct class *class;
int statement; int declaration;
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != STRING) { if (token != STRING) {
@ -604,7 +607,7 @@ void parse_class_statement (cfile, group, type)
class = add_class (type, val); class = add_class (type, val);
if (!class) if (!class)
error ("No memory for class %s.", val); error ("No memory for class %s.", val);
class -> group = clone_group (group, "parse_class_statement"); class -> group = clone_group (group, "parse_class_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -619,10 +622,10 @@ void parse_class_statement (cfile, group, type)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} else { } else {
statement = parse_statement (cfile, class -> group, declaration = parse_statement (cfile, class -> group,
CLASS_STMT, CLASS_DECL,
(struct host_decl *)0, (struct host_decl *)0,
statement); declaration);
} }
} while (1); } while (1);
} }
@ -649,9 +652,10 @@ void parse_lease_time (cfile, timep)
parse_semi (cfile); parse_semi (cfile);
} }
/* shared-network-statement :== LBRACE statements declarations RBRACE */ /* shared-network-declaration :==
hostname LBRACE declarations parameters RBRACE */
void parse_shared_net_statement (cfile, group) void parse_shared_net_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -663,9 +667,9 @@ void parse_shared_net_statement (cfile, group)
struct subnet *next_net; struct subnet *next_net;
char *name; char *name;
struct tree_cache *server_next; struct tree_cache *server_next;
int statement = 0; int declaration = 0;
share = new_shared_network ("parse_shared_net_statement"); share = new_shared_network ("parse_shared_net_declaration");
if (!share) if (!share)
error ("No memory for shared subnet"); error ("No memory for shared subnet");
share -> leases = (struct lease *)0; share -> leases = (struct lease *)0;
@ -673,7 +677,7 @@ void parse_shared_net_statement (cfile, group)
share -> insertion_point = (struct lease *)0; share -> insertion_point = (struct lease *)0;
share -> next = (struct shared_network *)0; share -> next = (struct shared_network *)0;
share -> interface = (struct interface_info *)0; share -> interface = (struct interface_info *)0;
share -> group = clone_group (group, "parse_shared_net_statement"); share -> group = clone_group (group, "parse_shared_net_declaration");
share -> group -> shared_network = share; share -> group -> shared_network = share;
/* Get the name of the shared network... */ /* Get the name of the shared network... */
@ -715,16 +719,17 @@ void parse_shared_net_statement (cfile, group)
break; break;
} }
statement = parse_statement (cfile, share -> group, declaration = parse_statement (cfile, share -> group,
SHARED_NET_STMT, SHARED_NET_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
} }
/* subnet-statement :== /* subnet-declaration :==
net NETMASK netmask RBRACE declarations statements LBRACE */ net NETMASK netmask RBRACE parameters declarations LBRACE */
void parse_subnet_statement (cfile, share) void parse_subnet_declaration (cfile, share)
FILE *cfile; FILE *cfile;
struct shared_network *share; struct shared_network *share;
{ {
@ -734,15 +739,15 @@ void parse_subnet_statement (cfile, share)
struct iaddr iaddr; struct iaddr iaddr;
unsigned char addr [4]; unsigned char addr [4];
int len = sizeof addr; int len = sizeof addr;
int statement = 0; int declaration = 0;
subnet = new_subnet ("parse_subnet_statement"); subnet = new_subnet ("parse_subnet_declaration");
if (!subnet) if (!subnet)
error ("No memory for new subnet"); error ("No memory for new subnet");
subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0; subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0;
subnet -> shared_network = share; subnet -> shared_network = share;
subnet -> group = clone_group (share -> group, subnet -> group = clone_group (share -> group,
"parse_subnet_statement"); "parse_subnet_declaration");
subnet -> group -> subnet = subnet; subnet -> group -> subnet = subnet;
/* Get the network number... */ /* Get the network number... */
@ -781,9 +786,10 @@ void parse_subnet_statement (cfile, share)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, subnet -> group, declaration = parse_statement (cfile, subnet -> group,
SUBNET_STMT, SUBNET_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
/* If this subnet supports dynamic bootp, flag it so in the /* If this subnet supports dynamic bootp, flag it so in the
@ -803,18 +809,18 @@ void parse_subnet_statement (cfile, share)
} }
} }
/* group-statement :== RBRACE declarations statements LBRACE */ /* group-declaration :== RBRACE parameters declarations LBRACE */
void parse_group_statement (cfile, group) void parse_group_declaration (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
char *val; char *val;
int token; int token;
struct group *g; struct group *g;
int statement = 0; int declaration = 0;
g = clone_group (group, "parse_group_statement"); g = clone_group (group, "parse_group_declaration");
if (!parse_lbrace (cfile)) if (!parse_lbrace (cfile))
return; return;
@ -829,15 +835,16 @@ void parse_group_statement (cfile, group)
parse_warn ("unexpected end of file"); parse_warn ("unexpected end of file");
break; break;
} }
statement = parse_statement (cfile, g, GROUP_STMT, declaration = parse_statement (cfile, g, GROUP_DECL,
(struct host_decl *)0, statement); (struct host_decl *)0,
declaration);
} while (1); } while (1);
} }
/* hardware-declaration :== HARDWARE ETHERNET csns SEMI /* hardware-parameter :== HARDWARE ETHERNET csns SEMI
csns :== NUMBER | csns COLON NUMBER */ csns :== NUMBER | csns COLON NUMBER */
void parse_hardware_decl (cfile, hardware) void parse_hardware_param (cfile, hardware)
FILE *cfile; FILE *cfile;
struct hardware *hardware; struct hardware *hardware;
{ {
@ -891,7 +898,7 @@ void parse_hardware_decl (cfile, hardware)
} }
} }
/* string-declaration :== STRING SEMI */ /* string-parameter :== STRING SEMI */
char *parse_string (cfile) char *parse_string (cfile)
FILE *cfile; FILE *cfile;
@ -960,11 +967,11 @@ struct tree *parse_ip_addr_or_hostname (cfile, uniform)
} }
/* fixed-addr-declaration :== ip-addrs-or-hostnames SEMI /* fixed-addr-parameter :== ip-addrs-or-hostnames SEMI
ip-addrs-or-hostnames :== ip-addr-or-hostname | ip-addrs-or-hostnames :== ip-addr-or-hostname
ip-addrs-or-hostnames ip-addr-or-hostname */ | ip-addrs-or-hostnames ip-addr-or-hostname */
struct tree_cache *parse_fixed_addr_decl (cfile) struct tree_cache *parse_fixed_addr_param (cfile)
FILE *cfile; FILE *cfile;
{ {
char *val; char *val;
@ -988,14 +995,14 @@ struct tree_cache *parse_fixed_addr_decl (cfile)
return tree_cache (tree); return tree_cache (tree);
} }
/* option_declaration :== identifier DOT identifier <syntax> SEMI | /* option_parameter :== identifier DOT identifier <syntax> SEMI
identifier <syntax> SEMI | identifier <syntax> SEMI
Option syntax is handled specially through format strings, so it Option syntax is handled specially through format strings, so it
would be painful to come up with BNF for it. However, it always would be painful to come up with BNF for it. However, it always
starts as above and ends in a SEMI. */ starts as above and ends in a SEMI. */
void parse_option_decl (cfile, group) void parse_option_param (cfile, group)
FILE *cfile; FILE *cfile;
struct group *group; struct group *group;
{ {
@ -1037,7 +1044,7 @@ void parse_option_decl (cfile, group)
universe = (struct universe *)hash_lookup (&universe_hash, universe = (struct universe *)hash_lookup (&universe_hash,
vendor, 0); vendor, 0);
/* If it's not there, we can't parse the rest of the /* If it's not there, we can't parse the rest of the
statement. */ declaration. */
if (!universe) { if (!universe) {
parse_warn ("no vendor named %s.", vendor); parse_warn ("no vendor named %s.", vendor);
skip_to_semi (cfile); skip_to_semi (cfile);
@ -1080,13 +1087,13 @@ void parse_option_decl (cfile, group)
switch (*fmt) { switch (*fmt) {
case 'X': case 'X':
token = peek_token (&val, cfile); token = peek_token (&val, cfile);
if (token == NUMBER_OR_ATOM || if (token == NUMBER_OR_NAME ||
token == NUMBER) { token == NUMBER) {
do { do {
token = next_token token = next_token
(&val, cfile); (&val, cfile);
if (token != NUMBER if (token != NUMBER
&& token != NUMBER_OR_ATOM) && token != NUMBER_OR_NAME)
goto need_number; goto need_number;
convert_num (buf, val, 16, 8); convert_num (buf, val, 16, 8);
tree = tree_concat tree = tree_concat
@ -1184,7 +1191,7 @@ void parse_option_decl (cfile, group)
tree = tree_concat (tree, tree_const (buf, 1)); tree = tree_concat (tree, tree_const (buf, 1));
break; break;
default: default:
warn ("Bad format %c in parse_option_decl.", warn ("Bad format %c in parse_option_param.",
*fmt); *fmt);
skip_to_semi (cfile); skip_to_semi (cfile);
return; return;
@ -1226,20 +1233,22 @@ TIME parse_timestamp (cfile)
return rv; return rv;
} }
/* lease_statement :== LEASE ip_address LBRACE lease_declarations RBRACE /* lease_declaration :== LEASE ip_address LBRACE lease_parameters RBRACE
lease_declarations :== <nil>
| lease_declaration
| lease_declarations lease_declaration
lease_declaration :== STARTS date
| ENDS date
| TIMESTAMP date
| HARDWARE hardware-declaration
| UID hex_numbers SEMI
| HOST hostname SEMI
| CLASS identifier SEMI
| DYNAMIC_BOOTP SEMI */
struct lease *parse_lease_statement (cfile) lease_parameters :== <nil>
| lease_parameter
| lease_parameters lease_parameter
lease_parameter :== STARTS date
| ENDS date
| TIMESTAMP date
| HARDWARE hardware-parameter
| UID hex_numbers SEMI
| HOST hostname SEMI
| CLASS identifier SEMI
| DYNAMIC_BOOTP SEMI */
struct lease *parse_lease_declaration (cfile)
FILE *cfile; FILE *cfile;
{ {
char *val; char *val;
@ -1342,7 +1351,7 @@ struct lease *parse_lease_statement (cfile)
case HARDWARE: case HARDWARE:
seenbit = 64; seenbit = 64;
parse_hardware_decl (cfile, parse_hardware_param (cfile,
&lease.hardware_addr); &lease.hardware_addr);
break; break;
@ -1367,7 +1376,7 @@ struct lease *parse_lease_statement (cfile)
} }
} }
if (seenmask & seenbit) { if (seenmask & seenbit) {
parse_warn ("Too many %s declarations in lease %s\n", parse_warn ("Too many %s parameters in lease %s\n",
tbuf, piaddr (lease.ip_addr)); tbuf, piaddr (lease.ip_addr));
} else } else
seenmask |= seenbit; seenmask |= seenbit;
@ -1376,8 +1385,8 @@ struct lease *parse_lease_statement (cfile)
return &lease; return &lease;
} }
/* address-range-statement :== ip-address ip-address SEMI | /* address-range-declaration :== ip-address ip-address SEMI
DYNAMIC_BOOTP ip-address ip-address SEMI */ | DYNAMIC_BOOTP ip-address ip-address SEMI */
void parse_address_range (cfile, subnet) void parse_address_range (cfile, subnet)
FILE *cfile; FILE *cfile;
@ -1406,11 +1415,17 @@ void parse_address_range (cfile, subnet)
memcpy (low.iabuf, addr, len); memcpy (low.iabuf, addr, len);
low.len = len; low.len = len;
/* Only one address? */
token = peek_token (&val, cfile);
if (token == SEMI)
high = low;
else {
/* Get the top address in the range... */ /* Get the top address in the range... */
if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
return; return;
memcpy (high.iabuf, addr, len); memcpy (high.iabuf, addr, len);
high.len = len; high.len = len;
}
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != SEMI) { if (token != SEMI) {
@ -1635,9 +1650,9 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
break; break;
} }
/* Allow NUMBER_OR_ATOM if base is 16. */ /* Allow NUMBER_OR_NAME if base is 16. */
if (token != NUMBER && if (token != NUMBER &&
(base != 16 || token != NUMBER_OR_ATOM)) { (base != 16 || token != NUMBER_OR_NAME)) {
parse_warn ("expecting numeric value."); parse_warn ("expecting numeric value.");
skip_to_semi (cfile); skip_to_semi (cfile);
return (unsigned char *)0; return (unsigned char *)0;