32 #include <sys/types.h> 36 in_options, out_options, scope, statements,
62 while (r && !(result && *result)) {
66 case statements_statement:
67 #if defined (DEBUG_EXPRESSIONS) 75 #if defined (DEBUG_EXPRESSIONS) 76 log_debug (
"exec: statements returns %d", status);
93 #if defined (DEBUG_EXPRESSIONS) 105 #if defined (DEBUG_EXPRESSIONS) 111 if (r->
data.
on.statements)
117 #if defined (DEBUG_EXPRESSIONS) 123 if (r->
data.
on.statements)
131 case switch_statement:
132 #if defined (DEBUG_EXPRESSIONS) 137 in_options, out_options, scope,
140 #if defined (DEBUG_EXPRESSIONS) 141 log_debug (
"exec: switch: case %lx", (
unsigned long)e);
146 in_options, out_options, scope, e,
158 case default_statement:
165 out_options, scope, r->
data.
ie.expr));
167 #if defined (DEBUG_EXPRESSIONS) 169 ? (rc ?
"true" :
"false")
177 in_options, out_options, scope,
187 #if defined (DEBUG_EXPRESSIONS) 189 (status ?
"succeeded" :
"failed"));
195 case execute_statement: {
196 #ifdef ENABLE_EXECUTE 203 argv =
dmalloc((argc + 2) *
sizeof(*argv),
MDL);
215 log_debug(
"execute_statement argv[0] = %s", argv[0]);
219 memset (&ds, 0,
sizeof(ds));
228 memcpy(argv[i], ds.
data,
231 log_debug(
"execute_statement argv[%d] = %s", i, argv[i]);
235 log_debug(
"execute_statement failed argv[%d]", i);
245 if ((p = fork()) > 0) {
247 waitpid(p, &status, 0);
254 execvp(argv[0], argv);
255 log_error(
"Unable to execute %s: %m", argv[0]);
262 for (i = 0; i <= argc; i++) {
269 log_fatal(
"Impossible case at %s:%d (ENABLE_EXECUTE " 270 "is not defined).",
MDL);
275 case return_statement:
279 out_options, scope, r ->
data.retval,
MDL);
280 #if defined (DEBUG_EXPRESSIONS) 282 (status ?
"succeeded" :
"failed"));
289 #if defined (DEBUG_EXPRESSIONS) 292 :
"<unnamed class>"));
297 case break_statement:
298 #if defined (DEBUG_EXPRESSIONS) 303 case supersede_option_statement:
304 case send_option_statement:
305 #if defined (DEBUG_EXPRESSIONS) 307 (r->
op == supersede_option_statement
308 ?
"supersede" :
"send"),
311 goto option_statement;
313 case default_option_statement:
314 #if defined (DEBUG_EXPRESSIONS) 318 goto option_statement;
320 case append_option_statement:
321 #if defined (DEBUG_EXPRESSIONS) 325 goto option_statement;
327 case prepend_option_statement:
328 #if defined (DEBUG_EXPRESSIONS) 339 case define_statement:
348 log_error(
"set %s: can't allocate scope",
354 #if defined (DEBUG_EXPRESSIONS) 381 if (r->
op == set_statement) {
385 in_options, out_options,
405 #if defined (DEBUG_EXPRESSIONS) 407 (
binding && status ?
"" :
" (failed)"));
413 case unset_statement:
414 if (!scope || !*scope)
424 #if defined (DEBUG_EXPRESSIONS) 426 (status ?
"found" :
"not found"));
433 #if defined (DEBUG_EXPRESSIONS) 451 (e->data.let.name + 1),
469 in_options, out_options,
470 scope, e->data.set.expr,
MDL));
475 #if defined (DEBUG_EXPRESSIONS) 476 log_debug(
"exec: let %s%s", e->data.let.name,
477 (
binding && status ?
"" :
"failed"));
481 if (!e->data.let.statements) {
482 }
else if (e->data.let.statements->op ==
484 e = e->data.let.statements;
492 in_options, out_options,
493 &ns, e->data.let.statements,
on_star);
500 memset (&ds, 0,
sizeof ds);
506 #if defined (DEBUG_EXPRESSIONS) 511 switch (r->
data.
log.priority) {
512 case log_priority_fatal:
516 case log_priority_error:
520 case log_priority_debug:
524 case log_priority_info:
534 case vendor_opt_statement:
539 in_options, out_options, scope);
574 struct group *limiting_group;
606 for (limit = limiting_group; limit; limit = limit ->
next) {
614 in_options, out_options, scope,
630 #if defined (POINTER_DEBUG) 639 if ((*ptr) ->
refcnt > 0) {
644 if ((*ptr) ->
refcnt < 0) {
646 #if defined (DEBUG_RC_HISTORY) 647 dump_rc_history (*ptr);
649 #if defined (POINTER_DEBUG) 659 switch ((*ptr) ->
op) {
661 if ((*ptr) ->
data.statements)
667 if ((*ptr) ->
data.on.statements)
673 if ((*ptr) ->
data.s_switch.statements)
676 if ((*ptr) ->
data.s_switch.expr)
682 if ((*ptr) ->
data.s_switch.expr)
688 if ((*ptr) ->
data.ie.expr)
691 if ((*ptr) ->
data.ie.tc)
694 if ((*ptr) ->
data.ie.fc)
700 if ((*ptr) ->
data.eval)
706 if ((*ptr) ->
data.eval)
712 if ((*ptr)->data.set.name)
714 if ((*ptr)->data.set.expr)
720 if ((*ptr)->data.unset)
725 if ((*ptr)->data.execute.command)
727 if ((*ptr)->data.execute.arglist)
737 if ((*ptr) ->
data.option)
757 #if defined ENABLE_EXECUTE 761 const char *s, *t, *dot;
775 fprintf (
file,
"on ");
778 fprintf (
file,
"%sexpiry", s);
782 fprintf (
file,
"%scommit", s);
786 fprintf (
file,
"%srelease", s);
789 if (r ->
data.on.statements) {
790 fprintf (
file,
" {");
792 r ->
data.on.statements,
803 fprintf (
file,
"switch (");
805 r ->
data.s_switch.expr,
810 col,
indent,
" ",
"",
"{");
819 fprintf (
file,
"case ");
821 r ->
data.s_switch.expr,
829 fprintf (
file,
"default: ");
834 fprintf (
file,
"if ");
842 if (x ->
data.ie.fc &&
846 fprintf (
file,
"} elsif ");
854 if (x ->
data.ie.fc) {
856 fprintf (
file,
"} else {");
866 fprintf (
file,
"eval ");
874 fprintf (
file,
"return;");
884 fprintf (
file,
"break;");
890 goto option_statement;
894 goto option_statement;
898 goto option_statement;
918 fprintf (
file,
"%s %s%s%s = ", s, t, dot,
920 col = (
indent + strlen (s) + strlen (t) +
921 strlen (dot) + strlen (r ->
data.option ->
938 fprintf (
file,
"set ");
940 "",
"", r ->
data.set.name);
951 fprintf (
file,
"unset ");
953 "",
"", r ->
data.set.name);
960 fprintf (
file,
"log ");
963 switch (r ->
data.log.priority) {
994 #ifdef ENABLE_EXECUTE 1013 log_fatal(
"Impossible case at %s:%d (ENABLE_EXECUTE " 1014 "is not defined).",
MDL);
1020 fprintf (
file,
"parse-vendor-option;");
1049 memset (&ds, 0,
sizeof ds);
1050 memset (&cd, 0,
sizeof cd);
1054 out_options, scope, expr,
1057 for (s = stmt; s; s = s -> next) {
1058 if (s -> op == case_statement) {
1061 in_options, out_options,
1063 if (sub && cd.
len == ds.
len &&
1081 in_options, out_options,
1085 for (s = stmt; s; s = s->
next) {
1086 if (s -> op == case_statement) {
1089 in_options, out_options,
1091 if (sub && n == c) {
1103 for (s = stmt; s; s = s->
next)
1104 if (s->
op == default_statement)
1114 int (*callback) (
struct 1117 void *vp,
int condp)
1122 for (foo = stmt; foo; foo = foo->
next) {
1123 if ((*callback) (foo, vp, condp) != 0)
1159 (foo->
data.
on.statements, callback, vp, 1)))
1177 (foo->
data.
let.statements, callback, vp, 0)))
#define rc_register(file, line, reference, addr, refcnt, d, f)
struct executable_statement::@7::@13 execute
int executable_statement_reference(struct executable_statement **ptr, struct executable_statement *bp, const char *file, int line)
int fundef_reference(struct fundef **ptr, struct fundef *src, const char *file, int line)
void set_option(struct universe *universe, struct option_state *options, struct option_cache *option, enum statement_op op)
struct universe * universe
int token_indent_data_string(FILE *file, int col, int indent, const char *prefix, const char *suffix, struct data_string *data)
int binding_value_dereference(struct binding_value **v, const char *file, int line)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
struct expression::expr_union::@25 arg
struct binding_scope * outer
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
enum executable_statement::statement_op op
struct executable_statement * on_release
void parse_vendor_option(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope)
Parse a vendor option (option 43)
struct universe dhcp_universe
void data_string_forget(struct data_string *data, const char *file, int line)
int evaluate_numeric_expression(unsigned long *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
int find_matching_case(struct executable_statement **ep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct expression *expr, struct executable_statement *stmt)
enum binding_value::@15 type
int log_error(const char *,...) __attribute__((__format__(__printf__
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
int evaluate_expression(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr, const char *file, int line)
struct executable_statement * next
void indent_spaces(FILE *file, int indent)
void expression_dereference(struct expression **eptr, const char *file, int line)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
struct executable_statement::@7::@11 set
int binding_value_allocate(struct binding_value **cptr, const char *file, int line)
struct executable_statement * statements
struct executable_statement::@7::@12 log
union expression::expr_union data
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
void classify(struct packet *packet, struct class *class)
struct option_cache * option
int binding_scope_allocate(struct binding_scope **ptr, const char *file, int line)
struct executable_statement::@7::@10 s_switch
void dfree(void *, const char *, int)
struct executable_statement::@7::@11 let
int int log_info(const char *,...) __attribute__((__format__(__printf__
void write_statements(FILE *file, struct executable_statement *statements, int indent)
int evaluate_data_expression(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr, const char *file, int line)
void * dmalloc(size_t, const char *, int)
struct executable_statement::@7::@9 on
int executable_statement_foreach(struct executable_statement *stmt, int(*callback)(struct executable_statement *, void *, int), void *vp, int condp)
union executable_statement::@7 data
union binding_value::value value
struct binding * bindings
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
int token_print_indent_concat(FILE *file, int col, int indent, const char *prefix, const char *suffix,...)
struct executable_statement::@7::@8 ie
int is_data_expression(struct expression *expr)
struct binding_value * value
struct executable_statement * statements
int evaluate_boolean_expression(int *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
int token_print_indent(FILE *file, int col, int indent, const char *prefix, const char *suffix, const char *buf)
struct expression * c_case
struct executable_statement * on_expiry
int write_expression(FILE *file, struct expression *expr, int col, int indent, int firstp)
struct binding * find_binding(struct binding_scope *scope, const char *name)
struct executable_statement * on_commit
const unsigned char * data