#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.58 2000/01/08 01:36:39 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.59 2000/01/25 01:13:21 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
skip_to_semi (cfile);
return (char *)0;
}
- s = (char *)malloc (strlen (val) + 1);
+ s = (char *)dmalloc (strlen (val) + 1, MDL);
if (!s)
log_fatal ("no memory for string %s.", val);
strcpy (s, val);
token = next_token (&val, cfile);
/* Store this identifier... */
- if (!(s = (char *)malloc (strlen (val) + 1)))
+ if (!(s = (char *)dmalloc (strlen (val) + 1, MDL)))
log_fatal ("can't allocate temp space for hostname.");
strcpy (s, val);
c = cons ((caddr_t)s, c);
} while (token == DOT);
/* Assemble the hostname together into a string. */
- if (!(s = (char *)malloc (len)))
+ if (!(s = (char *)dmalloc (len, MDL)))
log_fatal ("can't allocate space for hostname.");
t = s + len;
*--t = 0;
t -= l;
memcpy (t, (char *)(c -> car), l);
/* Free up temp space. */
- free (c -> car);
- free (c);
+ dfree (c -> car, MDL);
+ dfree (c, MDL);
c = cdr;
if (t != s)
*--t = '.';
if (!t)
return;
if (hlen + 1 > sizeof hardware -> hbuf) {
- free (t);
+ dfree (t, MDL);
parse_warn (cfile, "hardware address too long");
} else {
hardware -> hlen = hlen + 1;
if (hlen + 1 < sizeof hardware -> hbuf)
memset (&hardware -> hbuf [hlen + 1], 0,
(sizeof hardware -> hbuf) - hlen - 1);
- free (t);
+ dfree (t, MDL);
}
token = next_token (&val, cfile);
pair c = (pair)0;
if (!bufp && *max) {
- bufp = (unsigned char *)malloc (*max * size / 8);
+ bufp = (unsigned char *)dmalloc (*max * size / 8, MDL);
if (!bufp)
log_fatal ("no space for numeric aggregate");
s = 0;
convert_num (cfile, s, val, base, size);
s += size / 8;
} else {
- t = (unsigned char *)malloc (strlen (val) + 1);
+ t = (unsigned char *)dmalloc (strlen (val) + 1, MDL);
if (!t)
log_fatal ("no temp space for number.");
strcpy ((char *)t, val);
/* If we had to cons up a list, convert it now. */
if (c) {
- bufp = (unsigned char *)malloc (count * size / 8);
+ bufp = (unsigned char *)dmalloc (count * size / 8, MDL);
if (!bufp)
log_fatal ("no space for numeric aggregate.");
s = bufp + count - size / 8;
convert_num (cfile, s, (char *)(c -> car), base, size);
s -= size / 8;
/* Free up temp space. */
- free (c -> car);
- free (c);
+ dfree (c -> car, MDL);
+ dfree (c, MDL);
c = cdr;
}
return bufp;
skip_to_semi (cfile);
return (struct option *)0;
}
- uname = malloc (strlen (val) + 1);
+ uname = dmalloc (strlen (val) + 1, MDL);
if (!uname)
log_fatal ("no memory for uname information.");
strcpy (uname, val);
option -> name = val;
else {
char *s;
- free (uname);
- s = dmalloc (strlen (val) + 1,
- "parse_option_name");
+ dfree (uname, MDL);
+ s = dmalloc (strlen (val) + 1, MDL);
if (!s)
log_fatal ("no memory for option %s.%s",
universe -> name, val);
}
/* Free the initial identifier token. */
- free (uname);
+ dfree (uname, MDL);
return option;
}
log_fatal ("No memory for new option space.");
/* Set up the server option universe... */
- s = dmalloc (strlen (val) + 1, "parse_option_space_decl");
+ s = dmalloc (strlen (val) + 1, MDL);
if (!s)
log_fatal ("No memory for new option space name.");
strcpy (s, val);
nu -> store_length = putUChar;
nu -> index = universe_count++;
if (nu -> index >= universe_max) {
- ua = dmalloc (universe_max * 2 * sizeof *ua,
- "parse_option_space_decl");
+ ua = dmalloc (universe_max * 2 * sizeof *ua, MDL);
if (!ua)
log_fatal ("No memory to expand option space array.");
memcpy (ua, universes, universe_max * sizeof *ua);
universe_max *= 2;
- dfree (universes, "parse_option_space_decl");
+ dfree (universes, MDL);
universes = ua;
}
universes [nu -> index] = nu;
skip_to_semi (cfile);
return 0;
}
- s = dmalloc (tokix + arrayp + 1, "parse_option_code_definition");
+ s = dmalloc (tokix + arrayp + 1, MDL);
if (!s)
log_fatal ("no memory for option format.");
memcpy (s, tokbuf, tokix);
skip_to_semi (cfile);
for (; sl; sl = next) {
next = sl -> next;
- dfree (sl, "parse_cshl");
+ dfree (sl, MDL);
}
return 0;
}
if (ilen == sizeof ibuf) {
next = (struct option_tag *)
dmalloc (ilen - 1 +
- sizeof (struct option_tag),
- "parse_cshl");
+ sizeof (struct option_tag), MDL);
if (!next)
log_fatal ("no memory for string list.");
memcpy (next -> data, ibuf, ilen);
next = sl -> next;
memcpy (rvp, sl -> data, sizeof ibuf);
rvp += sizeof ibuf;
- dfree (sl, "parse_cshl");
+ dfree (sl, MDL);
sl = next;
}
case TOKEN_SET:
token = next_token (&val, cfile);
- token = next_token (&val, cfile);
token = next_token (&val, cfile);
if (token != NAME && token != NUMBER_OR_NAME) {
(result,
"parse_executable_statement"))
log_fatal ("no memory for set statement.");
- (*result) -> op = default_statement;
- (*result) -> data.set.name = dmalloc (strlen (val) + 1,
- "parse_executable_stmt");
+ (*result) -> op = set_statement;
+ (*result) -> data.set.name = dmalloc (strlen (val) + 1, MDL);
if (!(*result)->data.set.name)
log_fatal ("can't allocate variable name");
strcpy ((*result) -> data.set.name, val);
parse_semi (cfile);
break;
+ case UNSET:
+ token = next_token (&val, cfile);
+
+ token = next_token (&val, cfile);
+ if (token != NAME && token != NUMBER_OR_NAME) {
+ parse_warn (cfile,
+ "%s can't be a variable name", val);
+ badunset:
+ skip_to_semi (cfile);
+ *lose = 1;
+ return 0;
+ }
+
+ if (!executable_statement_allocate
+ (result,
+ "parse_executable_statement"))
+ log_fatal ("no memory for set statement.");
+ (*result) -> op = unset_statement;
+ (*result) -> data.unset = dmalloc (strlen (val) + 1, MDL);
+ if (!(*result)->data.unset)
+ log_fatal ("can't allocate variable name");
+ strcpy ((*result) -> data.unset, val);
+ parse_semi (cfile);
+ break;
+
+ case EVAL:
+ token = next_token (&val, cfile);
+
+ if (!executable_statement_allocate
+ (result,
+ "parse_executable_statement"))
+ log_fatal ("no memory for eval statement.");
+ (*result) -> op = eval_statement;
+
+ if (!parse_expression (&(*result) -> data.eval,
+ cfile, lose, context_data, /* XXX */
+ (struct expression **)0, expr_none)) {
+ if (!*lose)
+ parse_warn (cfile,
+ "expecting data expression.");
+ else
+ *lose = 1;
+ skip_to_semi (cfile);
+ executable_statement_dereference
+ (result, "parse_executable_statement");
+ return 0;
+ }
+ parse_semi (cfile);
+ break;
+
default:
*lose = 0;
return 0;
break;
case COMMIT:
- (*result) -> data.on.evtypes = ON_COMMIT;
+ (*result) -> data.on.evtypes |= ON_COMMIT;
break;
case RELEASE:
- (*result) -> data.on.evtypes = ON_RELEASE;
+ (*result) -> data.on.evtypes |= ON_RELEASE;
break;
default:
*lose = 1;
executable_statement_dereference
(result, "parse_on_statement");
- break;
+ return 0;
}
token = next_token (&val, cfile);
} while (token == OR);
{
enum dhcp_token token;
const char *val;
+ int parenp;
if (!executable_statement_allocate (result, "parse_if_statement"))
log_fatal ("no memory for if statement.");
(*result) -> op = if_statement;
+ token = peek_token (&val, cfile);
+ if (token == LPAREN) {
+ parenp = 1;
+ next_token (&val, cfile);
+ } else
+ parenp = 0;
+
+
if (!parse_boolean_expression (&(*result) -> data.ie.expr,
cfile, lose)) {
if (!*lose)
#if defined (DEBUG_EXPRESSION_PARSE)
print_expression ("if condition", if_condition);
#endif
+ if (parenp) {
+ token = next_token (&val, cfile);
+ if (token != RPAREN) {
+ parse_warn (cfile, "expecting right paren.");
+ *lose = 1;
+ executable_statement_dereference
+ (result, "parse_if_statement");
+ return 0;
+ }
+ }
token = next_token (&val, cfile);
if (token != LBRACE) {
parse_warn (cfile, "left brace expected.");
int known;
enum expr_op opcode;
const char *s;
+ struct executable_statement *stmt;
+ int i;
token = peek_token (&val, cfile);
goto norparen;
break;
- case PICK_FIRST_VALUE:
+ case PICK:
/* pick (a, b, c) actually produces an internal representation
that looks like pick (a, pick (b, pick (c, nil))). */
token = next_token (&val, cfile);
parse_warn (cfile,
"Please rebuild dhcpd with --with-nsupdate.");
#endif
+ token = next_token (&val, cfile);
if (token == DNS_UPDATE)
opcode = expr_ns_add;
else
opcode = expr_ns_delete;
- token = next_token (&val, cfile);
- if (!expression_allocate (expr,
- "parse_expression: DNS_UPDATE"))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_dns_transaction;
-
token = next_token (&val, cfile);
if (token != LPAREN)
goto nolparen;
- nexp = (struct expression *)0;
- if (!expression_allocate (&nexp,
- "parse_expression: DNS_UPDATE1"))
- log_fatal ("can't allocate expression");
- nexp -> op = opcode;
- (*expr) -> data.dns_transaction.car = nexp;
-
token = next_token (&val, cfile);
if (token != STRING) {
parse_warn (cfile,
"parse_expression: expecting string.");
badnsupdate:
- expression_dereference
- (expr, "parse_expression");
skip_to_semi (cfile);
*lose = 1;
return 0;
}
if (!strcasecmp (val, "a"))
- nexp -> data.ns_add.rrtype = T_A;
+ i = T_A;
else if (!strcasecmp (val, "ptr"))
- nexp -> data.ns_add.rrtype = T_PTR;
+ i = T_PTR;
else if (!strcasecmp (val, "mx"))
- nexp -> data.ns_add.rrtype = T_MX;
+ i = T_MX;
else if (!strcasecmp (val, "cname"))
- nexp -> data.ns_add.rrtype = T_CNAME;
+ i = T_CNAME;
else if (!strcasecmp (val, "TXT"))
- nexp -> data.ns_add.rrtype = T_TXT;
+ i = T_TXT;
else {
parse_warn (cfile, "unexpected rrtype: %s", val);
goto badnsupdate;
}
- nexp -> data.ns_add.rrclass = C_IN;
+
+ if (!expression_allocate (expr,
+ "parse_expression: DNS_UPDATE"))
+ log_fatal ("can't allocate expression");
+#if 0
+ (*expr) -> op = expr_funcall;
+ (*expr) -> data.funcall.context = context_boolean;
+ (*expr) -> data.funcall.name =
+
+ if (!make_let (&(*expr) -> data.funcall.statements, "rrtype"))
+ log_fatal ("can't allocate rrtype let.");
+ stmt = (*expr) -> data.funcall.statements;
+ if (!make_const_int (stmt -> data.let.value, i))
+ log_fatal ("can't allocate rrtype value.");
token = next_token (&val, cfile);
if (token != COMMA)
goto nocomma;
- if (!(parse_data_expression
- (&nexp -> data.ns_add.rrname, cfile, lose)))
+ if (!make_let (&stmt -> data.let.statements, "rrname"))
+ log_fatal ("can't allocate rrname let.");
+ stmt = stmt -> data.let.statements;
+ if (!(parse_data_expression (&stmt -> data.let.expr,
+ cfile, lose)))
goto nodata;
token = next_token (&val, cfile);
if (token != COMMA)
goto nocomma;
- if (!(parse_data_expression
- (&nexp -> data.ns_add.rrdata, cfile, lose)))
+ if (!make_let (&stmt -> data.let.statements, "rrdata"))
+ log_fatal ("can't allocate rrname let.");
+ stmt = stmt -> data.let.statements;
+ if (!(parse_data_expression (&stmt -> data.let.expr,
+ cfile, lose)))
goto nodata;
if (opcode == expr_ns_add) {
if (token != COMMA)
goto nocomma;
+ if (!make_let (&stmt -> data.let.statements, "ttl"))
+ log_fatal ("can't allocate rrname let.");
+ stmt = stmt -> data.let.statements;
+
if (!(parse_numeric_expression
- (&nexp -> data.ns_add.ttl, cfile, lose))) {
+ (&stmt -> data.let.expr, cfile, lose))) {
parse_warn (cfile,
- "expecting data expression.");
+ "expecting numeric expression.");
goto badnsupdate;
}
}
-
+#endif
token = next_token (&val, cfile);
if (token != RPAREN)
goto norparen;
/* NOT EXISTS is special cased above... */
not_exists:
- token = next_token (&val, cfile);
+ token = peek_token (&val, cfile);
+ if (token != EXISTS) {
+ parse_warn (cfile, "expecting DNS prerequisite.");
+ *lose = 1;
+ return 0;
+ }
opcode = expr_ns_not_exists;
goto nsupdatecode;
case TOKEN_ADD:
(*expr) -> op = expr_leased_address;
break;
+ case FILENAME:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr,
+ "parse_expression: FILENAME"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_filename;
+ break;
+
+ case SERVER_NAME:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr,
+ "parse_expression: SERVER_NAME"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_sname;
+ break;
+
case LEASE_TIME:
token = next_token (&val, cfile);
if (!expression_allocate (expr,
log_fatal ("can't allocate expression");
(*expr) -> op = expr_variable_reference;
(*expr) -> data.variable =
- dmalloc (strlen (s) + 1, "parse_expression");
+ dmalloc (strlen (s) + 1, MDL);
if (!(*expr) -> data.variable)
log_fatal ("can't allocate variable name.");
strcpy ((*expr) -> data.variable, s);
if (!expression_allocate (expr, "parse_expression"))
log_fatal ("can't allocate expression");
(*expr) -> op = expr_variable_exists;
- (*expr) -> data.variable = dmalloc (strlen (val) + 1,
- "parse_expression");
+ (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
if (!(*expr)->data.variable)
log_fatal ("can't allocate variable name");
strcpy ((*expr) -> data.variable, val);
if (!expression_allocate (expr, "parse_expression"))
log_fatal ("can't allocate expression");
(*expr) -> op = expr_variable_reference;
- (*expr) -> data.variable = dmalloc (strlen (val) + 1,
- "parse_expression");
+ (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
if (!(*expr)->data.variable)
log_fatal ("can't allocate variable name");
strcpy ((*expr) -> data.variable, val);
int len;
unsigned char *ob;
struct iaddr addr;
+ int num;
switch (*fmt) {
case 'U':
}
break;
+ case 'T': /* Lease interval. */
+ token = next_token (&val, cfile);
+ if (token != INFINITE)
+ goto check_number;
+ putLong (buf, -1);
+ if (!make_const_data (&t, buf, 4, 0, 1))
+ return 0;
+ break;
+
case 'L': /* Unsigned 32-bit integer... */
case 'l': /* Signed 32-bit integer... */
token = next_token (&val, cfile);
+ check_number:
if (token != NUMBER) {
need_number:
parse_warn (cfile, "expecting number.");