#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.32 1999/07/17 17:59:02 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.33 1999/10/01 03:11:20 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
-#include "dhctoken.h"
static TIME parsed_time;
| client-declaration
| client-declarations client-declaration */
-int read_client_conf ()
+isc_result_t read_client_conf ()
{
- FILE *cfile;
+ int file;
+ struct parse *cfile;
char *val;
int token;
int declaration = 0;
struct client_config *config;
struct client_state *state;
struct interface_info *ip;
-
- new_parse (path_dhclient_conf);
+ isc_result_t status;
/* Set up the initial dhcp option universe. */
initialize_universes ();
if (!top_level_config.on_transmission)
log_fatal ("no memory for top-level on_transmission group");
- if ((cfile = fopen (path_dhclient_conf, "r")) != NULL) {
+ if ((file = open (path_dhclient_conf, O_RDONLY)) >= 0) {
+ cfile = (struct parse *)0;
+ new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf);
+
do {
token = peek_token (&val, cfile);
if (token == EOF)
&top_level_config);
} while (1);
token = next_token (&val, cfile); /* Clear the peek buffer */
- fclose (cfile);
+ status = (cfile -> warnings_occurred
+ ? ISC_R_BADPARSE
+ : ISC_R_SUCCESS);
+ close (file);
+ end_parse (&cfile);
}
/* Set up state and config structures for clients that don't
config = (struct client_config *)
malloc (sizeof (struct client_config));
if (!config)
- log_fatal ("no memory for client config.");
+ log_fatal ("no memory for client config.");
memcpy (config, &top_level_config,
sizeof top_level_config);
}
ip -> client -> config = config;
}
}
-
- return !warnings_occurred;
+ return status;
}
/* lease-file :== client-lease-statements EOF
void read_client_leases ()
{
- FILE *cfile;
+ int file;
+ struct parse *cfile;
char *val;
int token;
- new_parse (path_dhclient_db);
-
/* Open the lease file. If we can't open it, just return -
we can safely trust the server to remember our state. */
- if ((cfile = fopen (path_dhclient_db, "r")) == NULL)
+ if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
return;
+ cfile = (struct parse *)0;
+ new_parse (&cfile, file, (char *)0, 0, path_dhclient_db);
+
do {
token = next_token (&val, cfile);
if (token == EOF)
parse_client_lease_statement (cfile, 0);
} while (1);
+
+ close (file);
+ end_parse (&cfile);
}
/* client-declaration :==
AUTH_KEY key_id key_data */
void parse_client_statement (cfile, ip, config)
- FILE *cfile;
+ struct parse *cfile;
struct interface_info *ip;
struct client_config *config;
{
want to lull them into believing they've gotten
their way. This is a bit contrived, but people
tend not to be entirely rational about security. */
- parse_warn ("auth-key not allowed here.");
+ parse_warn (cfile, "auth-key not allowed here.");
skip_to_semi (cfile);
break;
}
if (policy != P_PREFER &&
policy != P_REQUIRE &&
policy != P_DONT) {
- parse_warn ("invalid authentication policy.");
+ parse_warn (cfile,
+ "invalid authentication policy.");
skip_to_semi (cfile);
return;
}
if (policy != P_PREFER &&
policy != P_IGNORE &&
policy != P_ACCEPT) {
- parse_warn ("invalid bootp policy.");
+ parse_warn (cfile, "invalid bootp policy.");
skip_to_semi (cfile);
return;
}
config -> bootp_policy = policy;
} else {
- parse_warn ("expecting a policy type.");
+ parse_warn (cfile, "expecting a policy type.");
skip_to_semi (cfile);
return;
}
token = peek_token (&val, cfile);
if (token == SPACE) {
if (ip) {
- parse_warn ("option space definitions %s",
+ parse_warn (cfile,
+ "option space definitions %s",
" may not be scoped.");
skip_to_semi (cfile);
free_option (option, "parse_statement");
token = next_token (&val, cfile);
if (token != CODE) {
- parse_warn ("expecting \"code\" keyword.");
+ parse_warn (cfile, "expecting \"code\" keyword.");
skip_to_semi (cfile);
return;
}
if (ip) {
- parse_warn ("option definitions may only appear in %s",
+ parse_warn (cfile,
+ "option definitions may only appear in %s",
"the outermost scope.");
skip_to_semi (cfile);
free_option (option, "parse_statement");
if (ip) {
parse_hardware_param (cfile, &ip -> hw_address);
} else {
- parse_warn ("hardware address parameter %s",
+ parse_warn (cfile, "hardware address parameter %s",
"not allowed here.");
skip_to_semi (cfile);
}
case INTERFACE:
token = next_token (&val, cfile);
if (ip)
- parse_warn ("nested interface declaration.");
+ parse_warn (cfile, "nested interface declaration.");
parse_interface_declaration (cfile, config, (char *)0);
return;
stmt = (struct executable_statement *)0;
if (!parse_executable_statement (&stmt, cfile, &lose)) {
if (!lose) {
- parse_warn ("expecting a statement.");
+ parse_warn (cfile, "expecting a statement.");
skip_to_semi (cfile);
}
} else {
}
int parse_X (cfile, buf, max)
- FILE *cfile;
+ struct parse *cfile;
u_int8_t *buf;
int max;
{
do {
token = next_token (&val, cfile);
if (token != NUMBER && token != NUMBER_OR_NAME) {
- parse_warn ("expecting hexadecimal constant.");
+ parse_warn (cfile,
+ "expecting hexadecimal constant.");
skip_to_semi (cfile);
return 0;
}
- convert_num (&buf [len], val, 16, 8);
+ convert_num (cfile, &buf [len], val, 16, 8);
if (len++ > max) {
- parse_warn ("hexadecimal constant too long.");
+ parse_warn (cfile,
+ "hexadecimal constant too long.");
skip_to_semi (cfile);
return 0;
}
token = next_token (&val, cfile);
len = strlen (val);
if (len + 1 > max) {
- parse_warn ("string constant too long.");
+ parse_warn (cfile, "string constant too long.");
skip_to_semi (cfile);
return 0;
}
memcpy (buf, val, len + 1);
} else {
- parse_warn ("expecting string or hexadecimal data");
+ parse_warn (cfile, "expecting string or hexadecimal data");
skip_to_semi (cfile);
return 0;
}
option_list COMMA option_name */
void parse_option_list (cfile, list)
- FILE *cfile;
+ struct parse *cfile;
u_int32_t **list;
{
int ix, i;
do {
token = next_token (&val, cfile);
if (!is_identifier (token)) {
- parse_warn ("expected option name.");
+ parse_warn (cfile, "expected option name.");
skip_to_semi (cfile);
return;
}
break;
}
if (i == 256) {
- parse_warn ("%s: expected option name.");
+ parse_warn (cfile, "%s: expected option name.");
skip_to_semi (cfile);
return;
}
token = next_token (&val, cfile);
} while (token == COMMA);
if (token != SEMI) {
- parse_warn ("expecting semicolon.");
+ parse_warn (cfile, "expecting semicolon.");
skip_to_semi (cfile);
return;
}
INTERFACE string LBRACE client-declarations RBRACE */
void parse_interface_declaration (cfile, outer_config, name)
- FILE *cfile;
+ struct parse *cfile;
struct client_config *outer_config;
char *name;
{
token = next_token (&val, cfile);
if (token != STRING) {
- parse_warn ("expecting interface name (in quotes).");
+ parse_warn (cfile, "expecting interface name (in quotes).");
skip_to_semi (cfile);
return;
}
token = next_token (&val, cfile);
if (token != LBRACE) {
- parse_warn ("expecting left brace.");
+ parse_warn (cfile, "expecting left brace.");
skip_to_semi (cfile);
return;
}
do {
token = peek_token (&val, cfile);
if (token == EOF) {
- parse_warn ("unterminated interface declaration.");
+ parse_warn (cfile,
+ "unterminated interface declaration.");
return;
}
if (token == RBRACE)
void parse_client_lease_statement (cfile, is_static)
- FILE *cfile;
+ struct parse *cfile;
int is_static;
{
struct client_lease *lease, *lp, *pl;
token = next_token (&val, cfile);
if (token != LBRACE) {
- parse_warn ("expecting left brace.");
+ parse_warn (cfile, "expecting left brace.");
skip_to_semi (cfile);
return;
}
do {
token = peek_token (&val, cfile);
if (token == EOF) {
- parse_warn ("unterminated lease declaration.");
+ parse_warn (cfile, "unterminated lease declaration.");
return;
}
if (token == RBRACE)
AUTH_KEY id */
void parse_client_lease_declaration (cfile, lease, ipp, clientp)
- FILE *cfile;
+ struct parse *cfile;
struct client_lease *lease;
struct interface_info **ipp;
struct client_state **clientp;
case INTERFACE:
token = next_token (&val, cfile);
if (token != STRING) {
- parse_warn ("expecting interface name (in quotes).");
+ parse_warn (cfile,
+ "expecting interface name (in quotes).");
skip_to_semi (cfile);
break;
}
token = next_token (&val, cfile);
ip = *ipp;
if (!ip) {
- parse_warn ("state name precedes interface.");
+ parse_warn (cfile, "state name precedes interface.");
break;
}
for (client = ip -> client; client; client = client -> next)
if (client -> name && !strcmp (client -> name, val))
break;
if (!client)
- parse_warn ("lease specified for unknown pseudo.");
+ parse_warn (cfile,
+ "lease specified for unknown pseudo.");
*clientp = client;
break;
return;
default:
- parse_warn ("expecting lease declaration.");
+ parse_warn (cfile, "expecting lease declaration.");
skip_to_semi (cfile);
break;
}
token = next_token (&val, cfile);
if (token != SEMI) {
- parse_warn ("expecting semicolon.");
+ parse_warn (cfile, "expecting semicolon.");
skip_to_semi (cfile);
}
}
int parse_option_decl (oc, cfile)
struct option_cache **oc;
- FILE *cfile;
+ struct parse *cfile;
{
char *val;
int token;
case 't': /* Text string... */
token = next_token (&val, cfile);
if (token != STRING) {
- parse_warn ("expecting string.");
+ parse_warn (cfile,
+ "expecting string.");
skip_to_semi (cfile);
return 0;
}
len = strlen (val);
if (hunkix + len + 1 > sizeof hunkbuf) {
- parse_warn ("option data buffer %s",
+ parse_warn (cfile,
+ "option data buffer %s",
"overflow");
skip_to_semi (cfile);
return 0;
alloc:
if (hunkix + len > sizeof hunkbuf) {
- parse_warn ("option data buffer %s",
+ parse_warn (cfile,
+ "option data buffer %s",
"overflow");
skip_to_semi (cfile);
return 0;
token = next_token (&val, cfile);
if (token != NUMBER) {
need_number:
- parse_warn ("expecting number.");
+ parse_warn (cfile,
+ "expecting number.");
if (token != SEMI)
skip_to_semi (cfile);
return 0;
}
- convert_num (buf, val, 0, 32);
+ convert_num (cfile, buf, val, 0, 32);
len = 4;
dp = buf;
goto alloc;
token = next_token (&val, cfile);
if (token != NUMBER)
goto need_number;
- convert_num (buf, val, 0, 16);
+ convert_num (cfile, buf, val, 0, 16);
len = 2;
dp = buf;
goto alloc;
token = next_token (&val, cfile);
if (token != NUMBER)
goto need_number;
- convert_num (buf, val, 0, 8);
+ 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 ("expecting identifier.");
+ parse_warn (cfile,
+ "expecting identifier.");
bad_flag:
if (token != SEMI)
skip_to_semi (cfile);
|| !strcasecmp (val, "off"))
buf [0] = 0;
else {
- parse_warn ("expecting boolean.");
+ parse_warn (cfile,
+ "expecting boolean.");
goto bad_flag;
}
len = 1;
} while (*fmt == 'A' && token == COMMA);
if (token != SEMI) {
- parse_warn ("semicolon expected.");
+ parse_warn (cfile, "semicolon expected.");
skip_to_semi (cfile);
return 0;
}
}
void parse_string_list (cfile, lp, multiple)
- FILE *cfile;
+ struct parse *cfile;
struct string_list **lp;
int multiple;
{
do {
token = next_token (&val, cfile);
if (token != STRING) {
- parse_warn ("Expecting media options.");
+ parse_warn (cfile, "Expecting media options.");
skip_to_semi (cfile);
return;
}
} while (multiple && token == COMMA);
if (token != SEMI) {
- parse_warn ("expecting semicolon.");
+ parse_warn (cfile, "expecting semicolon.");
skip_to_semi (cfile);
}
}
void parse_reject_statement (cfile, config)
- FILE *cfile;
+ struct parse *cfile;
struct client_config *config;
{
int token;
do {
if (!parse_ip_addr (cfile, &addr)) {
- parse_warn ("expecting IP address.");
+ parse_warn (cfile, "expecting IP address.");
skip_to_semi (cfile);
return;
}
} while (token == COMMA);
if (token != SEMI) {
- parse_warn ("expecting semicolon.");
+ parse_warn (cfile, "expecting semicolon.");
skip_to_semi (cfile);
}
}