mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-03 15:56:00 +00:00
Change "execute" from numeric expression to executable statement, so
it will not be necessary to use eval(execute(...)) [rt16620]
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
.\" $Id: dhcp-eval.5,v 1.23 2006/07/31 22:19:51 dhankins Exp $
|
||||
.\" $Id: dhcp-eval.5,v 1.24 2007/01/28 23:00:19 each Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 1996-2003 by Internet Software Consortium
|
||||
@@ -432,34 +432,31 @@ Rebind - DHCP client is in the REBINDING state - it has an IP address,
|
||||
and is trying to contact any server to renew it. The next message to
|
||||
be sent will be a DHCPREQUEST, which will be broadcast.
|
||||
.RE
|
||||
.SH REFERENCE: ACTION EXPRESSIONS
|
||||
.PP
|
||||
.B execute(\fIcommand-path\fB, \fIdata-expr1\fB ... \fIdata-exprN\fB);\fR
|
||||
.B log (\fIpriority\fB, \fIdata-expr\fB)\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
External command execution is made possible through \fBexecute();\fR
|
||||
expressions. These expressions take a variable number of arguments, where
|
||||
the first is the command name (full path or only the name of the executable)
|
||||
and is followed by zero or more are data-expressions whose values will be
|
||||
evaluated and passed as external arguments (assumed to be text strings
|
||||
suitable for use as a command-line argument). It returns the numeric return
|
||||
code of the external command, or one of the following special values:
|
||||
.TP 2
|
||||
.I \(bu
|
||||
125: Invalid arguments.
|
||||
.TP
|
||||
.I \(bu
|
||||
126: fork() failure
|
||||
.TP
|
||||
.I \(bu
|
||||
127: execvp() failure
|
||||
.TP
|
||||
.I \(bu
|
||||
-SIGNAL: Should the child exit due to a signal, rather than exiting normally
|
||||
with an exit status, the signal number multiplied by negative 1 will be
|
||||
returned.
|
||||
Logging statements may be used to send information to the standard logging
|
||||
channels. A logging statement includes an optional priority (\fBfatal\fR,
|
||||
\fBerror\fR, \fBinfo\fR, or \fBdebug\fR), and a data expression.
|
||||
.PP
|
||||
Execute is synchronous, and the program will block until the external
|
||||
command being run has finished. Please note that lengthy program
|
||||
Logging statements take only a single data expression argument, so if you
|
||||
want to output multiple data values, you will need to use the \fBconcat\fR
|
||||
operator to concatenate them.
|
||||
.RE
|
||||
.PP
|
||||
.B execute (\fIcommand-path\fB [, \fIdata-expr1\fB, ... \fIdata-exprN\fB]);\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
The \fBexecute\fR statement runs an external command. The first argument
|
||||
is a string literal containing the name or path of the command to run.
|
||||
The other arguments, if present, are either string literals or data-
|
||||
expressions which evaluate to text strings, to be passed as command-line
|
||||
arguments to the command.
|
||||
.PP
|
||||
\fBexecute\fR is synchronous; the program will block until the external
|
||||
command being run has finished. Please note that lengthy program
|
||||
execution (for example, in an "on commit" in dhcpd.conf) may result in
|
||||
bad performance and timeouts. Only external applications with very short
|
||||
execution times are suitable for use.
|
||||
@@ -470,21 +467,10 @@ Non-printable ASCII characters will be converted into dhcpd.conf language
|
||||
octal escapes ("\777"), make sure your external command handles them as
|
||||
such.
|
||||
.PP
|
||||
It is possible to use the execute expression in any context, not only
|
||||
It is possible to use the execute statement in any context, not only
|
||||
on events. If you put it in a regular scope in the configuration file
|
||||
you will execute that command every time a scope is evaluated.
|
||||
.RE
|
||||
.SH REFERENCE: LOGGING
|
||||
Logging statements may be used to send information to the standard logging
|
||||
channels. A logging statement includes an optional priority (\fBfatal\fR,
|
||||
\fBerror\fR, \fBinfo\fR, or \fBdebug\fR), and a data expression.
|
||||
.PP
|
||||
.B log (\fIpriority\fB, \fIdata-expr\fB)\fR
|
||||
.PP
|
||||
Logging statements take only a single data expression argument, so if you
|
||||
want to output multiple data values, you will need to use the \fBconcat\fR
|
||||
operator to concatenate them.
|
||||
.RE
|
||||
.SH REFERENCE: DYNAMIC DNS UPDATES
|
||||
.PP
|
||||
The DHCP client and server have the ability to dynamically update the
|
||||
|
111
common/execute.c
111
common/execute.c
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: execute.c,v 1.48 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: execute.c,v 1.49 2007/01/28 23:00:19 each Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -188,6 +188,86 @@ int execute_statements (result, packet, lease, client_state,
|
||||
#endif
|
||||
break;
|
||||
|
||||
case execute_statement: {
|
||||
#ifdef ENABLE_EXECUTE
|
||||
struct expression *expr;
|
||||
char **argv;
|
||||
int i, argc = r->data.execute.argc;
|
||||
pid_t p;
|
||||
|
||||
/* save room for the command and the NULL terminator */
|
||||
argv = dmalloc((argc + 2) * sizeof(*argv), MDL);
|
||||
if (!argv)
|
||||
break;
|
||||
|
||||
argv[0] = dmalloc(strlen(r->data.execute.command) + 1,
|
||||
MDL);
|
||||
if (argv[0]) {
|
||||
strcpy(argv[0], r->data.execute.command);
|
||||
} else {
|
||||
goto execute_out;
|
||||
}
|
||||
|
||||
log_debug("execute_statement argv[0] = %s", argv[0]);
|
||||
|
||||
for (i = 1, expr = r->data.execute.arglist; expr;
|
||||
expr = expr->data.arg.next, i++) {
|
||||
memset (&ds, 0, sizeof(ds));
|
||||
status = (evaluate_data_expression
|
||||
(&ds, packet,
|
||||
lease, client_state, in_options,
|
||||
out_options, scope,
|
||||
expr->data.arg.val, MDL));
|
||||
if (status) {
|
||||
argv[i] = dmalloc(ds.len + 1, MDL);
|
||||
if (argv[i]) {
|
||||
memcpy(argv[i], ds.data,
|
||||
ds.len);
|
||||
argv[i][ds.len] = 0;
|
||||
log_debug("execute_statement argv[%d] = %s", i, argv[i]);
|
||||
}
|
||||
data_string_forget (&ds, MDL);
|
||||
if (!argv[i]) {
|
||||
log_debug("execute_statement failed argv[%d]", i);
|
||||
goto execute_out;
|
||||
}
|
||||
} else {
|
||||
log_debug("execute: bad arg %d", i);
|
||||
goto execute_out;
|
||||
}
|
||||
}
|
||||
argv[i] = NULL;
|
||||
|
||||
if ((p = fork()) > 0) {
|
||||
int status;
|
||||
waitpid(p, &status, 0);
|
||||
|
||||
if (status) {
|
||||
log_error("execute: %s exit status %d",
|
||||
argv[0], status);
|
||||
}
|
||||
} else if (p == 0) {
|
||||
execvp(argv[0], argv);
|
||||
log_error("Unable to execute %s: %m", argv[0]);
|
||||
_exit(127);
|
||||
} else {
|
||||
log_error("execute: fork() failed");
|
||||
}
|
||||
|
||||
execute_out:
|
||||
for (i = 0; i <= argc; i++) {
|
||||
if(argv[i])
|
||||
dfree(argv[i], MDL);
|
||||
}
|
||||
|
||||
dfree(argv, MDL);
|
||||
#else /* !ENABLE_EXECUTE */
|
||||
log_fatal("Impossible case at %s:%d (ENABLE_EXECUTE "
|
||||
"is not defined).", MDL);
|
||||
#endif /* ENABLE_EXECUTE */
|
||||
break;
|
||||
}
|
||||
|
||||
case return_statement:
|
||||
status = evaluate_expression
|
||||
(result, packet,
|
||||
@@ -624,6 +704,14 @@ int executable_statement_dereference (ptr, file, line)
|
||||
dfree ((*ptr)->data.unset, file, line);
|
||||
break;
|
||||
|
||||
case execute_statement:
|
||||
if ((*ptr)->data.execute.command)
|
||||
dfree ((*ptr)->data.execute.command, file, line);
|
||||
if ((*ptr)->data.execute.arglist)
|
||||
expression_dereference (&(*ptr) -> data.execute.arglist,
|
||||
file, line);
|
||||
break;
|
||||
|
||||
case supersede_option_statement:
|
||||
case send_option_statement:
|
||||
case default_option_statement:
|
||||
@@ -650,6 +738,7 @@ void write_statements (file, statements, indent)
|
||||
int indent;
|
||||
{
|
||||
struct executable_statement *r, *x;
|
||||
struct expression *expr;
|
||||
int result;
|
||||
int status;
|
||||
const char *s, *t, *dot;
|
||||
@@ -882,6 +971,25 @@ void write_statements (file, statements, indent)
|
||||
"", "", ");");
|
||||
|
||||
break;
|
||||
|
||||
case execute_statement:
|
||||
#ifdef ENABLE_EXECUTE
|
||||
indent_spaces (file, indent);
|
||||
col = token_print_indent(file, col, indent + 4, "", "",
|
||||
"execute");
|
||||
col = token_print_indent(file, col, indent + 4, " ", "",
|
||||
"(");
|
||||
col = token_print_indent(file, col, indent + 4, "\"", "\"", r->data.execute.command);
|
||||
for (expr = r->data.execute.arglist; expr; expr = expr->data.arg.next) {
|
||||
col = token_print_indent(file, col, indent + 4, "", " ", ",");
|
||||
col = write_expression (file, expr->data.arg.val, col, indent + 4, 0);
|
||||
}
|
||||
col = token_print_indent(file, col, indent + 4, "", "", ");");
|
||||
#else /* !ENABLE_EXECUTE */
|
||||
log_fatal("Impossible case at %s:%d (ENABLE_EXECUTE "
|
||||
"is not defined).", MDL);
|
||||
#endif /* ENABLE_EXECUTE */
|
||||
break;
|
||||
|
||||
default:
|
||||
log_fatal ("bogus statement type %d\n", r -> op);
|
||||
@@ -1047,6 +1155,7 @@ int executable_statement_foreach (struct executable_statement *stmt,
|
||||
break;
|
||||
case log_statement:
|
||||
case return_statement:
|
||||
case execute_statement:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
140
common/parse.c
140
common/parse.c
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: parse.c,v 1.117 2006/08/04 10:59:33 shane Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: parse.c,v 1.118 2007/01/28 23:00:19 each Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -1806,10 +1806,12 @@ int parse_executable_statement (result, cfile, lose, case_context)
|
||||
{
|
||||
enum dhcp_token token;
|
||||
const char *val;
|
||||
unsigned len;
|
||||
struct executable_statement base;
|
||||
struct class *cta;
|
||||
struct option *option=NULL;
|
||||
struct option_cache *cache;
|
||||
struct expression **ep;
|
||||
int known;
|
||||
int flag;
|
||||
int i;
|
||||
@@ -2190,6 +2192,77 @@ int parse_executable_statement (result, cfile, lose, case_context)
|
||||
}
|
||||
break;
|
||||
|
||||
case EXECUTE:
|
||||
#ifdef ENABLE_EXECUTE
|
||||
token = next_token(&val, NULL, cfile);
|
||||
|
||||
if (!executable_statement_allocate (result, MDL))
|
||||
log_fatal ("no memory for execute statement.");
|
||||
(*result)->op = execute_statement;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
if (token != LPAREN) {
|
||||
parse_warn(cfile, "left parenthesis expected.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "Expecting a quoted string.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*result)->data.execute.command = dmalloc(len + 1, MDL);
|
||||
if ((*result)->data.execute.command == NULL)
|
||||
log_fatal("can't allocate command name");
|
||||
strcpy((*result)->data.execute.command, val);
|
||||
|
||||
ep = &(*result)->data.execute.arglist;
|
||||
(*result)->data.execute.argc = 0;
|
||||
|
||||
while((token = next_token(&val, NULL, cfile)) == COMMA) {
|
||||
if (!expression_allocate(ep, MDL))
|
||||
log_fatal ("can't allocate expression");
|
||||
|
||||
if (!parse_data_expression (&(*ep) -> data.arg.val,
|
||||
cfile, lose)) {
|
||||
if (!*lose) {
|
||||
parse_warn (cfile,
|
||||
"expecting expression.");
|
||||
*lose = 1;
|
||||
}
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
ep = &(*ep)->data.arg.next;
|
||||
(*result)->data.execute.argc++;
|
||||
}
|
||||
|
||||
if (token != RPAREN) {
|
||||
parse_warn(cfile, "right parenthesis expected.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!parse_semi (cfile)) {
|
||||
*lose = 1;
|
||||
executable_statement_dereference (result, MDL);
|
||||
}
|
||||
#else /* ! ENABLE_EXECUTE */
|
||||
parse_warn(cfile, "define ENABLE_EXECUTE in site.h to "
|
||||
"enable execute(); expressions.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
#endif /* ENABLE_EXECUTE */
|
||||
break;
|
||||
|
||||
case RETURN:
|
||||
token = next_token (&val, (unsigned *)0, cfile);
|
||||
|
||||
@@ -3684,71 +3757,6 @@ int parse_non_binary (expr, cfile, lose, context)
|
||||
goto norparen;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_EXECUTE
|
||||
case EXECUTE:
|
||||
token = next_token(&val, NULL, cfile);
|
||||
|
||||
if (!expression_allocate(expr, MDL))
|
||||
log_fatal("can't allocate expression.");
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
if (token != LPAREN) {
|
||||
parse_warn(cfile, "left parenthesis expected.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "Expecting a quoted string.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*expr)->data.execute.command = dmalloc(strlen(val) + 1, MDL);
|
||||
if ((*expr)->data.execute.command == NULL)
|
||||
log_fatal("can't allocate command name");
|
||||
|
||||
strcpy((*expr)->data.execute.command, val);
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
ep = &(*expr)->data.execute.arglist;
|
||||
i = 0;
|
||||
while (token == COMMA) {
|
||||
if (!expression_allocate(ep, MDL))
|
||||
log_fatal ("can't allocate expression");
|
||||
|
||||
if (!parse_data_expression(&(*ep)->data.arg.val,
|
||||
cfile, lose)) {
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
ep = &(*ep)->data.arg.next;
|
||||
token = next_token(&val, NULL, cfile);
|
||||
i++;
|
||||
}
|
||||
(*expr)->data.execute.argc = i;
|
||||
(*expr)->op = expr_execute;
|
||||
if (token != RPAREN) {
|
||||
parse_warn(cfile, "right parenthesis expected.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case EXECUTE:
|
||||
parse_warn(cfile, "define ENABLE_EXECUTE in site.h to "
|
||||
"enable execute(); expressions.");
|
||||
skip_to_semi(cfile);
|
||||
*lose = 1;
|
||||
return 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* NOT EXISTS is special cased above... */
|
||||
not_exists:
|
||||
token = peek_token (&val, (unsigned *)0, cfile);
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: print.c,v 1.61 2006/07/31 22:19:51 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: print.c,v 1.62 2007/01/28 23:00:19 each Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -1034,6 +1034,7 @@ static unsigned print_subexpression (expr, buf, len)
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
|
||||
case expr_function:
|
||||
rv = 9;
|
||||
if (len > rv + 1) {
|
||||
@@ -1051,37 +1052,6 @@ static unsigned print_subexpression (expr, buf, len)
|
||||
buf [rv] = 0;
|
||||
return rv;
|
||||
}
|
||||
case expr_execute:
|
||||
#ifdef ENABLE_EXECUTE
|
||||
rv = 11 + strlen(expr->data.execute.command);
|
||||
if (len > rv + 2) {
|
||||
sprintf(buf, "(execute \"%s\"",
|
||||
expr->data.execute.command);
|
||||
for(next_arg = expr->data.execute.arglist;
|
||||
next_arg;
|
||||
next_arg = next_arg->data.arg.next) {
|
||||
if (len <= rv + 3)
|
||||
return 0;
|
||||
|
||||
buf[rv++] = ' ';
|
||||
rv += print_subexpression(next_arg->
|
||||
data.arg.val,
|
||||
buf + rv,
|
||||
len - rv - 2);
|
||||
}
|
||||
|
||||
if (len <= rv + 2)
|
||||
return 0;
|
||||
|
||||
buf[rv++] = ')';
|
||||
buf[rv] = 0;
|
||||
return rv;
|
||||
}
|
||||
#else
|
||||
log_fatal("Impossible case at %s:%d (ENABLE_EXECUTE is not "
|
||||
"defined.", MDL);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
log_fatal("Impossible case at %s:%d (undefined expression "
|
||||
|
137
common/tree.c
137
common/tree.c
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: tree.c,v 1.110 2006/11/06 18:13:31 shane Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: tree.c,v 1.111 2007/01/28 23:00:19 each Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -51,35 +51,6 @@ struct __res_state resolver_state;
|
||||
int resolver_inited = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_EXECUTE
|
||||
static unsigned long
|
||||
execute(char **args)
|
||||
{
|
||||
pid_t p;
|
||||
|
||||
if (args == NULL || args[0] == NULL)
|
||||
return 125;
|
||||
|
||||
p = fork();
|
||||
|
||||
if (p > 0) {
|
||||
int status;
|
||||
waitpid(p, &status, 0);
|
||||
|
||||
if (WIFEXITED(status))
|
||||
return WEXITSTATUS(status);
|
||||
else
|
||||
return -WTERMSIG(status);
|
||||
} else if (p == 0) {
|
||||
execvp(args[0], args);
|
||||
log_error("Unable to execute %s: %m", args[0]);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
return 126;
|
||||
}
|
||||
|
||||
static void
|
||||
append_to_ary(char **ary_ptr, int *ary_size, int ary_capacity,
|
||||
char *new_element)
|
||||
@@ -135,66 +106,6 @@ data_string_to_char_string(struct data_string *d)
|
||||
return str;
|
||||
}
|
||||
|
||||
static int
|
||||
evaluate_execute(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 status;
|
||||
int cmd_status;
|
||||
int i;
|
||||
struct data_string ds;
|
||||
struct expression *next_arg;
|
||||
char **arg_ary = NULL;
|
||||
int arg_ary_size = 0;
|
||||
int arg_ary_capacity = 0;
|
||||
|
||||
/* Need 1 bucket for the command, and 1 for the trailing NULL
|
||||
* terminator.
|
||||
*/
|
||||
i = expr->data.execute.argc + 2;
|
||||
arg_ary = dmalloc(i * sizeof(char *), MDL);
|
||||
/* Leave one bucket free for the NULL terminator. */
|
||||
arg_ary_capacity = i - 1;
|
||||
|
||||
if (arg_ary == NULL)
|
||||
return 0;
|
||||
|
||||
append_to_ary(arg_ary, &arg_ary_size, arg_ary_capacity,
|
||||
expr->data.execute.command);
|
||||
|
||||
for(next_arg = expr->data.execute.arglist;
|
||||
next_arg;
|
||||
next_arg = next_arg->data.arg.next) {
|
||||
memset(&ds, 0, sizeof ds);
|
||||
status = (evaluate_data_expression
|
||||
(&ds, packet, lease, client_state, in_options,
|
||||
cfg_options, scope, next_arg->data.arg.val, MDL));
|
||||
if (!status) {
|
||||
if (arg_ary) {
|
||||
for (i=1; i < arg_ary_size; i++)
|
||||
dfree(arg_ary[i], MDL);
|
||||
dfree(arg_ary, MDL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
append_to_ary(arg_ary, &arg_ary_size, arg_ary_capacity,
|
||||
data_string_to_char_string(&ds));
|
||||
data_string_forget(&ds, MDL);
|
||||
}
|
||||
# if defined (DEBUG_EXPRESSIONS)
|
||||
log_debug("exec: execute");
|
||||
# endif
|
||||
*result = execute(arg_ary);
|
||||
for (i=1; i < arg_ary_size; i++)
|
||||
dfree(arg_ary[i], MDL);
|
||||
dfree(arg_ary, MDL);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pair cons (car, cdr)
|
||||
caddr_t car;
|
||||
pair cdr;
|
||||
@@ -1008,7 +919,6 @@ int evaluate_dns_expression (result, packet, lease, client_state, in_options,
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_const_int:
|
||||
case expr_lease_time:
|
||||
case expr_dns_transaction:
|
||||
@@ -1374,7 +1284,6 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_const_int:
|
||||
case expr_lease_time:
|
||||
case expr_dns_transaction:
|
||||
@@ -2311,7 +2220,6 @@ int evaluate_data_expression (result, packet, lease, client_state,
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_const_int:
|
||||
case expr_lease_time:
|
||||
case expr_dns_transaction:
|
||||
@@ -2823,20 +2731,6 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
case expr_execute:
|
||||
#if defined (ENABLE_EXECUTE)
|
||||
status = evaluate_execute(result, packet, lease,
|
||||
client_state, in_options,
|
||||
cfg_options, scope, expr);
|
||||
# if defined (DEBUG_EXPRESSIONS)
|
||||
log_debug("num: execute() -> %d", status);
|
||||
# endif
|
||||
return status;
|
||||
#else
|
||||
log_fatal("Impossible case at %s:%d (ENABLE_EXECUTE "
|
||||
"is not defined).", MDL);
|
||||
#endif
|
||||
break;
|
||||
case expr_ns_add:
|
||||
case expr_ns_delete:
|
||||
case expr_ns_exists:
|
||||
@@ -3266,7 +3160,6 @@ int is_numeric_expression (expr)
|
||||
return (expr -> op == expr_extract_int8 ||
|
||||
expr -> op == expr_extract_int16 ||
|
||||
expr -> op == expr_extract_int32 ||
|
||||
expr -> op == expr_execute ||
|
||||
expr -> op == expr_const_int ||
|
||||
expr -> op == expr_lease_time ||
|
||||
expr -> op == expr_dns_transaction ||
|
||||
@@ -3302,7 +3195,6 @@ int is_compound_expression (expr)
|
||||
expr -> op == expr_extract_int8 ||
|
||||
expr -> op == expr_extract_int16 ||
|
||||
expr -> op == expr_extract_int32 ||
|
||||
expr -> op == expr_execute ||
|
||||
expr -> op == expr_dns_transaction);
|
||||
}
|
||||
|
||||
@@ -3331,7 +3223,6 @@ static int op_val (op)
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_encode_int8:
|
||||
case expr_encode_int16:
|
||||
case expr_encode_int32:
|
||||
@@ -3430,7 +3321,6 @@ enum expression_context op_context (op)
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_encode_int8:
|
||||
case expr_encode_int16:
|
||||
case expr_encode_int32:
|
||||
@@ -3978,30 +3868,6 @@ int write_expression (file, expr, col, indent, firstp)
|
||||
expr -> data.variable);
|
||||
col = token_print_indent (file, col, indent, "", "", ")");
|
||||
break;
|
||||
case expr_execute:
|
||||
#if defined(ENABLE_EXECUTE)
|
||||
col = token_print_indent(file, col, indent, "", "",
|
||||
"execute");
|
||||
col = token_print_indent(file, col, indent, " ", "",
|
||||
"(");
|
||||
scol = col;
|
||||
col = token_print_indent_concat(file, col, scol, "", "", "\"",
|
||||
expr->data.execute.command,
|
||||
"\"", NULL);
|
||||
for(next_arg = expr->data.execute.arglist;
|
||||
next_arg;
|
||||
next_arg = next_arg->data.arg.next) {
|
||||
col = token_print_indent(file, col, scol, "", " ",
|
||||
",");
|
||||
col = write_expression(file, next_arg->data.arg.val,
|
||||
col, scol, 0);
|
||||
}
|
||||
col = token_print_indent(file, col, indent, "", "", ")");
|
||||
#else
|
||||
log_fatal("Impossible case at %s:%d (ENABLE_EXECUTE is not "
|
||||
"defined.", MDL);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
log_fatal ("invalid expression type in print_expression: %d",
|
||||
@@ -4227,7 +4093,6 @@ int data_subexpression_length (int *rv,
|
||||
case expr_extract_int8:
|
||||
case expr_extract_int16:
|
||||
case expr_extract_int32:
|
||||
case expr_execute:
|
||||
case expr_encode_int8:
|
||||
case expr_encode_int16:
|
||||
case expr_encode_int32:
|
||||
|
@@ -56,7 +56,8 @@ struct executable_statement {
|
||||
let_statement,
|
||||
define_statement,
|
||||
log_statement,
|
||||
return_statement
|
||||
return_statement,
|
||||
execute_statement
|
||||
} op;
|
||||
union {
|
||||
struct {
|
||||
@@ -99,6 +100,11 @@ struct executable_statement {
|
||||
} priority;
|
||||
struct expression *expr;
|
||||
} log;
|
||||
struct {
|
||||
char *command;
|
||||
struct expression *arglist;
|
||||
int argc;
|
||||
} execute;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
@@ -153,7 +153,6 @@ enum expr_op {
|
||||
expr_extract_int8,
|
||||
expr_extract_int16,
|
||||
expr_extract_int32,
|
||||
expr_execute,
|
||||
expr_encode_int8,
|
||||
expr_encode_int16,
|
||||
expr_encode_int32,
|
||||
@@ -275,11 +274,6 @@ struct expression {
|
||||
char *name;
|
||||
struct expression *arglist;
|
||||
} funcall;
|
||||
struct {
|
||||
char *command;
|
||||
struct expression *arglist;
|
||||
int argc;
|
||||
} execute;
|
||||
struct fundef *func;
|
||||
} data;
|
||||
int flags;
|
||||
|
Reference in New Issue
Block a user