#ifndef lint
static char copyright[] =
-"$Id: execute.c,v 1.28 2000/02/02 20:01:41 mellon Exp $ Copyright (c) 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: execute.c,v 1.29 2000/02/05 18:07:17 mellon Exp $ Copyright (c) 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
break;
case eval_statement:
- if (is_boolean_expression (r -> data.eval)) {
- status = (evaluate_boolean_expression
- (&result, packet, lease, in_options,
- out_options, scope,
- r -> data.eval));
- } else if (is_numeric_expression (r -> data.eval)) {
- status = (evaluate_numeric_expression
- (&num, packet, lease, in_options,
- out_options, scope,
- r -> data.eval));
- } else if (is_data_expression (r -> data.eval)) {
- memset (&ds, 0, sizeof ds);
- status = (evaluate_data_expression
- (&ds, packet, lease, in_options,
- out_options, scope,
- r -> data.eval));
- if (status && ds.data)
- data_string_forget (&ds, MDL);
- } else if (is_dns_expression (r -> data.eval)) {
-#if defined (NSUPDATE)
- ns_updrec *nut;
- nut = 0;
- status = (evaluate_dns_expression
- (&nut, packet, lease, in_options,
- out_options, scope,
- r -> data.eval));
- if (status) {
- if (nut -> r_data) {
- dfree (nut -> r_data, MDL);
- nut -> r_data =
- (unsigned char *)0;
- }
- if (nut -> r_dname) {
- dfree (nut -> r_dname, MDL);
- nut -> r_dname = (char *)0;
- }
- minires_freeupdrec (nut);
- }
-#endif
- } else {
- log_error ("%s: invalid expression type: %d",
- "execute_statements",
- r -> data.eval -> op);
- }
-
+ status = evaluate_expression
+ ((struct binding_value **)0,
+ packet, lease, in_options,
+ out_options, scope, r -> data.eval);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: evaluate: %s",
(status "succeeded" : "failed"));
break;
case set_statement:
- memset (&ds, 0, sizeof ds);
- status = (evaluate_data_expression
- (&ds, packet, lease, in_options, out_options,
- scope, r -> data.set.expr));
-
binding = find_binding (scope, r -> data.set.name);
if (!binding && status) {
binding = dmalloc (sizeof *binding, MDL);
}
}
if (binding) {
- if (binding -> value.data)
- data_string_forget (&binding -> value,
- MDL);
- if (status)
- data_string_copy (&binding -> value, &ds,
- MDL);
+ if (binding -> value)
+ binding_value_dereference
+ (&binding -> value, MDL);
+ status = (evaluate_expression
+ (&binding -> value, packet, lease,
+ in_options, out_options,
+ scope, r -> data.set.expr));
}
- if (status)
- data_string_forget (&ds, MDL);
#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: set %s = %s", r -> data.set.name,
- (status && binding
- ? print_hex_1 (binding -> value.len,
- binding -> value.data, 50)
- : "NULL"));
+ log_debug ("exec: set %s%s", r -> data.set.name,
+ (binding && status ? "" : " (failed)"));
#endif
break;
case unset_statement:
binding = find_binding (scope, r -> data.unset);
if (binding) {
- if (binding -> value.data)
- data_string_forget (&binding -> value,
- MDL);
+ if (binding -> value)
+ binding_value_dereference
+ (&binding -> value, MDL);
status = 1;
} else
status = 0;
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: unset %s: %s", r -> data.unset,
- (status ? "found" : "NULL"));
+ (status ? "found" : "not found"));
#endif
break;
case let_statement:
- memset (&ds, 0, sizeof ds);
- status = (evaluate_data_expression
- (&ds, packet, lease, in_options, out_options,
- scope, r -> data.let.expr));
-
ns = (struct binding_scope *)0;
binding_scope_allocate (&ns, MDL);
+ e = r;
next_let:
if (ns) {
} else {
binding -> name =
dmalloc (strlen
- (r -> data.let.name + 1),
+ (e -> data.let.name + 1),
MDL);
if (binding -> name)
strcpy (binding -> name,
- r -> data.let.name);
+ e -> data.let.name);
else {
dfree (binding, MDL);
binding = (struct binding *)0;
}
}
}
- if (ns && binding && status) {
- data_string_copy (&binding -> value, &ds, MDL);
+ if (ns && binding) {
+ status = (evaluate_expression
+ (&binding -> value, packet, lease,
+ in_options, out_options,
+ scope, e -> data.set.expr));
binding -> next = ns -> bindings;
ns -> bindings = binding;
}
- if (status)
- data_string_forget (&ds, MDL);
#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: let %s = %s", r -> data.let.name,
- (status && binding
- ? print_hex_1 (binding -> value.len,
- binding -> value.data, 50)
- : "NULL"));
+ log_debug ("exec: let %s%s", e -> data.let.name,
+ (binding && status ? "" : "failed"));
#endif
- if (!r -> data.let.statements) {
- } else if (r -> data.let.statements -> op ==
+ if (!e -> data.let.statements) {
+ } else if (e -> data.let.statements -> op ==
let_statement) {
- r = r -> data.let.statements;
+ e = e -> data.let.statements;
goto next_let;
} else if (ns) {
ns -> outer = scope;
execute_statements
(packet, lease, in_options, out_options,
- ns, r -> data.let.statements);
+ ns, e -> data.let.statements);
}
if (ns)
binding_scope_dereference (&ns, MDL);
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.62 2000/02/02 17:10:38 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.63 2000/02/05 18:04:47 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
(struct expression **)0, expr_none))
return 0;
- if (!is_boolean_expression (*expr)) {
+ if (!is_boolean_expression (*expr) &&
+ (*expr) -> op != expr_variable_reference &&
+ (*expr) -> op != expr_funcall) {
parse_warn (cfile, "Expecting a boolean expression.");
*lose = 1;
expression_dereference (expr, MDL);
(struct expression **)0, expr_none))
return 0;
- if (!is_data_expression (*expr)) {
+ if (!is_data_expression (*expr) &&
+ (*expr) -> op != expr_variable_reference &&
+ (*expr) -> op != expr_funcall) {
parse_warn (cfile, "Expecting a data expression.");
*lose = 1;
return 0;
(struct expression **)0, expr_none))
return 0;
- if (!is_numeric_expression (*expr)) {
+ if (!is_numeric_expression (*expr) &&
+ (*expr) -> op != expr_variable_reference &&
+ (*expr) -> op != expr_funcall) {
parse_warn (cfile, "Expecting a numeric expression.");
*lose = 1;
return 0;
(struct expression **)0, expr_none))
return 0;
- if (!is_dns_expression (*expr)) {
+ if (!is_dns_expression (*expr) &&
+ (*expr) -> op != expr_variable_reference &&
+ (*expr) -> op != expr_funcall) {
parse_warn (cfile, "Expecting a dns update subexpression.");
*lose = 1;
return 0;
const char *val;
struct collection *col;
struct option *option;
- struct expression *nexp;
+ struct expression *nexp, **ep;
int known;
enum expr_op opcode;
const char *s;
+ char *cptr;
struct executable_statement *stmt;
int i;
+ unsigned long u;
token = peek_token (&val, cfile);
}
if (!strcasecmp (val, "a"))
- i = T_A;
+ u = T_A;
else if (!strcasecmp (val, "ptr"))
- i = T_PTR;
+ u = T_PTR;
else if (!strcasecmp (val, "mx"))
- i = T_MX;
+ u = T_MX;
else if (!strcasecmp (val, "cname"))
- i = T_CNAME;
+ u = T_CNAME;
else if (!strcasecmp (val, "TXT"))
- i = T_TXT;
+ u = T_TXT;
else {
parse_warn (cfile, "unexpected rrtype: %s", val);
goto badnsupdate;
}
+ s = (opcode == expr_ns_add
+ ? "old-dns-update"
+ : "old-dns-delete");
+ cptr = dmalloc (strlen (s) + 1, MDL);
+ if (!cptr)
+ log_fatal ("can't allocate name for %s", s);
+ strcpy (cptr, s);
if (!expression_allocate (expr, MDL))
log_fatal ("can't allocate expression");
-#if 0
(*expr) -> op = expr_funcall;
- (*expr) -> data.funcall.context = context_boolean;
- (*expr) -> data.funcall.name =
+ (*expr) -> data.funcall.name = cptr;
- 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))
+ /* Fake up a function call. */
+ ep = &(*expr) -> data.funcall.arglist;
+ if (!expression_allocate (ep, MDL))
+ log_fatal ("can't allocate expression");
+ (*ep) -> op = expr_arg;
+ if (!make_const_int (&(*ep) -> data.arg.val, u))
log_fatal ("can't allocate rrtype value.");
token = next_token (&val, cfile);
if (token != COMMA)
goto nocomma;
-
- 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,
+ ep = &((*ep) -> data.arg.next);
+ if (!expression_allocate (ep, MDL))
+ log_fatal ("can't allocate expression");
+ (*ep) -> op = expr_arg;
+ if (!(parse_data_expression (&(*ep) -> data.arg.val,
cfile, lose)))
goto nodata;
if (token != COMMA)
goto nocomma;
- 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,
+ ep = &((*ep) -> data.arg.next);
+ if (!expression_allocate (ep, MDL))
+ log_fatal ("can't allocate expression");
+ (*ep) -> op = expr_arg;
+ if (!(parse_data_expression (&(*ep) -> data.arg.val,
cfile, lose)))
goto nodata;
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
- (&stmt -> data.let.expr, cfile, lose))) {
+ ep = &((*ep) -> data.arg.next);
+ if (!expression_allocate (ep, MDL))
+ log_fatal ("can't allocate expression");
+ (*ep) -> op = expr_arg;
+ if (!(parse_numeric_expression (&(*ep) -> data.arg.val,
+ cfile, lose))) {
parse_warn (cfile,
"expecting numeric expression.");
goto badnsupdate;
}
}
-#endif
+
token = next_token (&val, cfile);
if (token != RPAREN)
goto norparen;
if (token != NAME && token != NUMBER_OR_NAME)
return 0;
+ token = next_token (&val, cfile);
+
+ /* Save the name of the variable being referenced. */
+ cptr = dmalloc (strlen (val) + 1, MDL);
+ if (!cptr)
+ log_fatal ("can't allocate variable name");
+ strcpy (cptr, val);
+
+ /* Simple variable reference, as far as we can tell. */
+ token = peek_token (&val, cfile);
+ if (token != LPAREN) {
+ if (!expression_allocate (expr, MDL))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_variable_reference;
+ (*expr) -> data.variable = cptr;
+ break;
+ }
+
token = next_token (&val, cfile);
if (!expression_allocate (expr, MDL))
log_fatal ("can't allocate expression");
- (*expr) -> op = expr_variable_reference;
- (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
- if (!(*expr)->data.variable)
- log_fatal ("can't allocate variable name");
- strcpy ((*expr) -> data.variable, val);
+ (*expr) -> op = expr_funcall;
+ (*expr) -> data.funcall.name = cptr;
+
+ /* Now parse the argument list. */
+ ep = &(*expr) -> data.funcall.arglist;
+ do {
+ if (!expression_allocate (ep, MDL))
+ log_fatal ("can't allocate expression");
+ (*ep) -> op = expr_arg;
+ if (!parse_expression (&(*ep) -> data.arg.val,
+ cfile, lose, context_any,
+ (struct expression **)0,
+ expr_none)) {
+ if (!*lose) {
+ parse_warn (cfile,
+ "expecting expression.");
+ *lose = 1;
+ }
+ skip_to_semi (cfile);
+ expression_dereference (expr, MDL);
+ return 0;
+ }
+ ep = &((*ep) -> data.arg.next);
+ token = next_token (&val, cfile);
+ } while (token == COMMA);
+ if (token != RPAREN) {
+ parse_warn (cfile, "Right parenthesis expected.");
+ skip_to_semi (cfile);
+ *lose = 1;
+ expression_dereference (expr, MDL);
+ return 0;
+ }
break;
}
return 1;