]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Change "execute" from numeric expression to executable statement, so
authorEvan Hunt <each@isc.org>
Sun, 28 Jan 2007 23:00:19 +0000 (23:00 +0000)
committerEvan Hunt <each@isc.org>
Sun, 28 Jan 2007 23:00:19 +0000 (23:00 +0000)
it will not be necessary to use eval(execute(...)) [rt16620]

common/dhcp-eval.5
common/execute.c
common/parse.c
common/print.c
common/tree.c
includes/statement.h
includes/tree.h

index 4aeb88376acabaa56a49fd56e98c810eb4c99abc..f2b30f3bdb1e1338b945c9fe73b98b33ff65ecec 100644 (file)
@@ -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
+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
-Execute is synchronous, and the program will block until the external
-command being run has finished. Please note that lengthy program
+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
index a5fc03a487f84ceed56e9898b0f26b9c9c012a58..efe31ff022c0c6ada167afab970088a92ef7c2e9 100644 (file)
@@ -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;
            }
        }
index 5c7bf71f230bd1943b19c34a0d000074e4f08964..486d0cd2cf1658166862a0ea123a26e17632ae91 100644 (file)
@@ -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);
index 4438fbe541f66693c6f1482a121fb6aaf0b66221..f068ecdfc8d50183f52f0c321c4dcccb62fe222a 100644 (file)
@@ -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 "
index 9965bf44a6399de5e8223ff1928d2c32deb18067..f3d8d3e3dff85abfb082d42bc7af25a2e1733141 100644 (file)
@@ -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:
index 44fe8a8489593bcca836a40f5b036aa666862501..27c758f470e45a538837d24d4c444460a24c496f 100644 (file)
@@ -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;
 };
 
index 1a3988228586da8f0eb1dcd537a6498647cf14a9..e70a612309f5d229c4c796aa2205afc3349e9b6c 100644 (file)
@@ -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;