📄 dhcp_xecute.patch
字号:
diff -urN dhcp-3.0.2.orig/common/conflex.c dhcp-3.0.2/common/conflex.c--- dhcp-3.0.2.orig/common/conflex.c 2004-11-24 10:39:15.000000000 -0700+++ dhcp-3.0.2/common/conflex.c 2005-02-24 12:32:12.000000000 -0700@@ -676,6 +676,8 @@ return EVAL; if (!strcasecmp (atom + 1, "ncapsulate")) return ENCAPSULATE;+ if (!strcasecmp (atom + 1, "xecute"))+ return EXECUTE; break; case 'f': if (!strcasecmp (atom + 1, "atal"))diff -urN dhcp-3.0.2.orig/common/dhcp-eval.5 dhcp-3.0.2/common/dhcp-eval.5--- dhcp-3.0.2.orig/common/dhcp-eval.5 2005-01-19 13:00:52.000000000 -0700+++ dhcp-3.0.2/common/dhcp-eval.5 2005-02-24 12:32:12.000000000 -0700@@ -409,7 +409,32 @@ 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+.PP+.B execute (\fIcommand-path\fB, \fIdata-expr1\fB ... \fIdata-exprN\fB)\fR+.PP+External command execution is possibly through execute expressions. Execute+takes a variable number of arguments, where the first is the command+name (full path or only the name of the executable) and following zero+or more are data-expressions which values will be passed as external+arguments. It returns the return code of the external command.+.PP+Execute is synchronous, and 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 the dhcpd) may result in+bad performance and timed out clients. Try keeping the execution times+short.+.PP+Passing user-supplied data might be dangerous. Check input buffers+and make sure the external command handles all kinds of "unusual"+characters (shell special characters in sh-scripts etc) correctly.+.PP+It is possible to use the execute expression 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.+.PP+The execute expression is only available if you have defined ENABLE_EXECUTE+in site.h before compilation.+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,diff -urN dhcp-3.0.2.orig/common/parse.c dhcp-3.0.2/common/parse.c--- dhcp-3.0.2.orig/common/parse.c 2004-09-30 14:38:31.000000000 -0600+++ dhcp-3.0.2/common/parse.c 2005-02-24 12:32:12.000000000 -0700@@ -3639,7 +3639,56 @@ return 0; } break;- + #ifdef ENABLE_EXECUTE+ case EXECUTE:+ token = next_token (&val, (unsigned *)0, cfile);+ + if (!expression_allocate (expr, MDL))+ log_fatal ("can't allocate expression.");+ + token = next_token (&val, (unsigned *)0, cfile);+ if (token != LPAREN) {+ parse_warn (cfile, "left parenthesis expected.");+ skip_to_semi (cfile);+ *lose = 1;+ return 0;+ }+ token = next_token (&val, (unsigned *)0, cfile);+ (*expr) -> data.funcall.name =+ dmalloc (strlen (val) + 1, MDL);+ if (!(*expr)->data.funcall.name)+ log_fatal ("can't allocate command name");+ strcpy ((*expr) -> data.funcall.name, val);+ token = next_token (&val, (unsigned *)0, cfile);+ ep = &((*expr) -> data.funcall.arglist);+ 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, (unsigned *)0, cfile);+ }+ (*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 case ENCODE_INT: token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile);diff -urN dhcp-3.0.2.orig/common/print.c dhcp-3.0.2/common/print.c--- dhcp-3.0.2.orig/common/print.c 2004-06-17 14:54:39.000000000 -0600+++ dhcp-3.0.2/common/print.c 2005-02-24 12:32:12.000000000 -0700@@ -459,6 +459,7 @@ { unsigned rv, left; const char *s;+ struct expression* next_arg; switch (expr -> op) { case expr_none:@@ -483,7 +484,8 @@ return rv; } break;-+ + case expr_equal: if (len > 6) { rv = 4;@@ -1024,6 +1026,29 @@ buf [rv++] = 0; return rv; }+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ rv = 11 + strlen (expr -> data.funcall.name);+ if (len > rv + 2) {+ sprintf (buf,+ "(execute \"%s\"",+ expr -> data.funcall.name);+ for(next_arg = expr -> data.funcall.arglist;+ next_arg;+ next_arg = next_arg -> data.arg.next) {+ if (len > rv + 3)+ buf [rv++] = ' ';+ rv += print_subexpression (next_arg ->+ data.arg.val,+ buf + rv,+ len - rv - 2);+ }+ buf [rv++] = ')';+ buf [rv] = 0;+ return rv;+ }+ break;+ #endif } return 0; }diff -urN dhcp-3.0.2.orig/common/tree.c dhcp-3.0.2/common/tree.c--- dhcp-3.0.2.orig/common/tree.c 2004-11-24 10:39:16.000000000 -0700+++ dhcp-3.0.2/common/tree.c 2005-02-24 12:32:12.000000000 -0700@@ -50,6 +50,113 @@ int resolver_inited = 0; #endif +#ifdef ENABLE_EXECUTE+static unsigned long execute (char** args)+{+pid_t p = fork();+if (p > 0) {+int status;+waitpid (p, &status, 0);+return WEXITSTATUS(status);+}+else if(p == 0) {+execvp (args[0], args);+log_error ("Unable to execute %s: %s", args[0],+strerror(errno));+_exit(127);+} else {+log_fatal ("unable to fork");+}+return 1; /* never reached */+}++#define CAPACITY_INCREMENT 8+static void append_to_ary (char*** ary_ptr, int* ary_size, int* ary_capacity,+char* new_element)+{+(*ary_size)++;+if (*ary_size > *ary_capacity) {+char** new_ary;+int new_ary_capacity = *ary_capacity + CAPACITY_INCREMENT;+new_ary = dmalloc(new_ary_capacity*sizeof(char *), MDL);+if (!new_ary)+log_fatal ("no memory for array.");+if (*ary_ptr != NULL) {+memcpy (new_ary, *ary_ptr,+(*ary_capacity)*sizeof(char *));+dfree (*ary_ptr, MDL);+}+*ary_ptr = new_ary;+*ary_capacity = new_ary_capacity;+}+(*ary_ptr)[*ary_size-1] = new_element;+}++static char* data_string_to_char_string (struct data_string* d)+{+char* str = dmalloc (d->len+1, MDL);+if (!str)+log_fatal ("no memory for string.");+/* FIXME: should one use d -> buffer -> data or d -> data? are+they equivalent? */+strncpy (str, d -> data, d -> len);+str[d->len] = '\0';+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;+append_to_ary (&arg_ary, &arg_ary_size, &arg_ary_capacity,+ expr -> data.funcall.name);+for(next_arg = expr -> data.funcall.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+append_to_ary (&arg_ary, &arg_ary_size, &arg_ary_capacity, NULL);+*result = execute (arg_ary);+for (i=1; i<arg_ary_size-1; i++)+dfree (arg_ary[i], MDL);+dfree(arg_ary, MDL);+return 1;+}+#endif+ + pair cons (car, cdr) caddr_t car; pair cdr;@@ -861,6 +968,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_const_int: case expr_lease_time: case expr_dns_transaction:@@ -1224,6 +1334,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_const_int: case expr_lease_time: case expr_dns_transaction:@@ -2087,6 +2200,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_const_int: case expr_lease_time: case expr_dns_transaction:@@ -2595,7 +2711,12 @@ #endif return 0; }-+#ifdef ENABLE_EXECUTE+ case expr_execute:+ return evaluate_execute (result, packet, lease,+ client_state, in_options,+ cfg_options, scope, expr);+#endif case expr_ns_add: case expr_ns_delete: case expr_ns_exists:@@ -3008,6 +3129,9 @@ return (expr -> op == expr_extract_int8 || expr -> op == expr_extract_int16 || expr -> op == expr_extract_int32 ||+ #ifdef ENABLE_EXECUTE+ expr -> op == expr_execute ||+ #endif expr -> op == expr_const_int || expr -> op == expr_lease_time || expr -> op == expr_dns_transaction ||@@ -3043,6 +3167,9 @@ expr -> op == expr_extract_int8 || expr -> op == expr_extract_int16 || expr -> op == expr_extract_int32 ||+ #ifdef ENABLE_EXECUTE+ expr -> op == expr_execute ||+ #endif expr -> op == expr_dns_transaction); } @@ -3069,6 +3196,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_encode_int8: case expr_encode_int16: case expr_encode_int32:@@ -3165,6 +3295,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_encode_int8: case expr_encode_int16: case expr_encode_int32:@@ -3225,6 +3358,8 @@ int firstp; { struct expression *e;+ struct expression* next_arg;+ const char *s; char obuf [65]; int scol;@@ -3696,7 +3831,27 @@ expr -> data.variable); col = token_print_indent (file, col, indent, "", "", ")"); break;-+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ col = token_print_indent (file, col, indent, "", "","execute");+ col = token_print_indent (file, col, indent, " ", "","(");+ scol = col;+ /* FIXME: use token_print_indent_concat() here? */+ col = token_print_indent (file, col, scol, "", "","\"");+ col = token_print_indent (file, col, scol, "", "",expr -> data.funcall.name);+ col = token_print_indent (file, col, scol, "", "","\"");+ for(next_arg = expr -> data.funcall.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, "", "",")");+ + break;+#endif default: log_fatal ("invalid expression type in print_expression: %d", expr -> op);@@ -3915,6 +4070,9 @@ case expr_extract_int8: case expr_extract_int16: case expr_extract_int32:+ #ifdef ENABLE_EXECUTE+ case expr_execute:+ #endif case expr_encode_int8: case expr_encode_int16: case expr_encode_int32:diff -urN dhcp-3.0.2.orig/includes/dhctoken.h dhcp-3.0.2/includes/dhctoken.h--- dhcp-3.0.2.orig/includes/dhctoken.h 2004-09-21 13:25:38.000000000 -0600+++ dhcp-3.0.2/includes/dhctoken.h 2005-02-24 12:33:21.000000000 -0700@@ -308,7 +308,8 @@ REFRESH = 612, DOMAIN_NAME = 613, DO_FORWARD_UPDATE = 614,- KNOWN_CLIENTS = 615+ KNOWN_CLIENTS = 615,+ EXECUTE = 616 }; #define is_identifier(x) ((x) >= FIRST_TOKEN && \diff -urN dhcp-3.0.2.orig/includes/site.h dhcp-3.0.2/includes/site.h--- dhcp-3.0.2.orig/includes/site.h 2002-03-12 11:33:39.000000000 -0700+++ dhcp-3.0.2/includes/site.h 2005-02-24 12:32:12.000000000 -0700@@ -167,6 +167,12 @@ /* #define DHCPD_LOG_FACILITY LOG_DAEMON */ +/* Define this if you want to be able to execute external commands+ during conditional evaluation. */++/* #define ENABLE_EXECUTE */++ /* Define this if you aren't debugging and you want to save memory (potentially a _lot_ of memory) by allocating leases in chunks rather than one at a time. */diff -urN dhcp-3.0.2.orig/includes/tree.h dhcp-3.0.2/includes/tree.h--- dhcp-3.0.2.orig/includes/tree.h 2004-06-10 11:59:31.000000000 -0600+++ dhcp-3.0.2/includes/tree.h 2005-02-24 12:32:12.000000000 -0700@@ -150,6 +150,9 @@ expr_hardware, expr_packet, expr_const_data,+ #ifdef ENABLE_EXECUTE+ expr_execute,+ #endif expr_extract_int8, expr_extract_int16, expr_extract_int32,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -