#ifndef lint
static char copyright[] =
-"$Id: execute.c,v 1.34 2000/07/06 10:04:03 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: execute.c,v 1.35 2000/07/06 22:42:22 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
struct binding_scope *scope;
struct executable_statement *statements;
{
- struct executable_statement *r, *e;
+ struct executable_statement *r, *e, *next;
int result;
int status;
unsigned long num;
if (!statements)
return 1;
- for (r = statements; r; r = r -> next) {
+ r = (struct executable_statement *)0;
+ next = (struct executable_statement *)0;
+ e = (struct executable_statement *)0;
+ executable_statement_reference (&r, statements, MDL);
+ while (r) {
+ if (r -> next)
+ executable_statement_reference (&next, r -> next, MDL);
switch (r -> op) {
case statements_statement:
#if defined (DEBUG_EXPRESSIONS)
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: switch");
#endif
- e = find_matching_case (packet, lease,
- in_options, out_options, scope,
- r -> data.s_switch.expr,
- r -> data.s_switch.statements);
+ status = (find_matching_case
+ (&e, packet, lease,
+ in_options, out_options, scope,
+ r -> data.s_switch.expr,
+ r -> data.s_switch.statements));
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: switch: case %lx", (unsigned long)e);
#endif
- if (e && !execute_statements (packet, lease,
- in_options, out_options,
- scope, e))
- return 0;
+ if (status) {
+ if (!(execute_statements
+ (packet, lease,
+ in_options, out_options, scope, e))) {
+ executable_statement_dereference
+ (&e, MDL);
+ return 0;
+ }
+ executable_statement_dereference (&e, MDL);
+ }
break;
/* These have no effect when executed. */
default:
log_fatal ("bogus statement type %d", r -> op);
}
+ executable_statement_dereference (&r, MDL);
+ if (next) {
+ executable_statement_reference (&r, next, MDL);
+ executable_statement_dereference (&next, MDL);
+ }
}
return 1;
return that (the default statement can precede all the case statements).
Otherwise, return the null statement. */
-struct executable_statement *find_matching_case (packet, lease, in_options,
- out_options, scope,
- expr, stmt)
- struct packet *packet;
- struct lease *lease;
- struct option_state *in_options;
- struct option_state *out_options;
- struct binding_scope *scope;
- struct expression *expr;
- struct executable_statement *stmt;
+int find_matching_case (struct executable_statement **ep,
+ struct packet *packet, struct lease *lease,
+ struct option_state *in_options,
+ struct option_state *out_options,
+ struct binding_scope *scope,
+ struct expression *expr,
+ struct executable_statement *stmt)
{
int status, sub;
struct executable_statement *s;
{
data_string_forget (&cd, MDL);
data_string_forget (&ds, MDL);
- return s -> next;
+ executable_statement_reference
+ (ep, s -> next, MDL);
+ return 1;
}
data_string_forget (&cd, MDL);
}
sub = (evaluate_numeric_expression
(&c, packet, lease, in_options,
out_options, scope, s -> data.c_case));
- if (sub && n == c)
- return s -> next;
+ if (sub && n == c) {
+ executable_statement_reference
+ (ep, s -> next, MDL);
+ return 1;
+ }
}
}
}
for (s = stmt; s; s = s -> next)
if (s -> op == default_statement)
break;
- if (s)
- return s -> next;
- return (struct executable_statement *)0;
+ if (s) {
+ executable_statement_reference (ep, s -> next, MDL);
+ return 1;
+ }
+ return 0;
}