diff options
-rw-r--r-- | doc/jumper.8in | 19 | ||||
-rw-r--r-- | src/config.c | 30 | ||||
-rw-r--r-- | src/jumper.h | 1 | ||||
-rw-r--r-- | src/progman.c | 17 |
4 files changed, 45 insertions, 22 deletions
diff --git a/doc/jumper.8in b/doc/jumper.8in index 77c8cdc..1383c64 100644 --- a/doc/jumper.8in +++ b/doc/jumper.8in @@ -14,7 +14,7 @@ .\" You should have received a copy of the GNU General Public License .\" along with Jumper. If not, see <http://www.gnu.org/licenses/>. .so config.so -.TH JUMPER 8 "January 25, 2020" "JUMPER" +.TH JUMPER 8 "January 26, 2020" "JUMPER" .SH NAME jumper \- bring up network links on demand .SH SYNOPSIS @@ -479,6 +479,16 @@ Destination IP address. A list of additional options. Currently the following options are defined: .RS +7 .TP +.B nullin +Do not close standard input. Redirect it from +.B /dev/null +instead. Use this option with commands that require their standard +input to be open (e.g. +.BR "pppd nodetach" ). +.TP +.B shell +Run command as "/bin/sh -c '$command'". +.TP .B stdout Capture the standard output of the command and redirect it to the \fBsyslog\fR with the \fBLOG_INFO\fR priority. @@ -486,13 +496,6 @@ Capture the standard output of the command and redirect it to the .B stderr Capture the standard error of the command and redirect it to the \fBsyslog\fR with the \fBLOG_ERR\fR priority. -.TP -.B nullin -Do not close standard input. Redirect it from -.B /dev/null -instead. Use this option with commands that require their standard -input to be open (e.g. -.BR "pppd nodetach" ). .RE .TP \fBenviron\fR \fIENV\-SPEC\fR; diff --git a/src/config.c b/src/config.c index 53d757d..f42c408 100644 --- a/src/config.c +++ b/src/config.c @@ -269,18 +269,26 @@ cb_match_list(enum grecs_callback_command cmd, grecs_node_t *node, static void value_to_options(grecs_value_t *val, int *options) { - if (strcmp(val->v.string, "nowait") == 0) - *options |= OPT_NOWAIT; - else if (strcmp(val->v.string, "wait") == 0) - *options &= ~OPT_NOWAIT; - else if (strcmp(val->v.string, "stdout") == 0) - *options |= OPT_STDOUT; - else if (strcmp(val->v.string, "stderr") == 0) - *options |= OPT_STDERR; - else if (strcmp(val->v.string, "nullin") == 0) - *options |= OPT_NULLIN; - else +#define NEGATE 0x8000 + static struct transtab opttab[] = { + { "nowait", OPT_NOWAIT }, + { "wait", NEGATE | OPT_NOWAIT }, + { "stdout", OPT_STDOUT }, + { "stderr", OPT_STDERR }, + { "nullin", OPT_NULLIN }, + { "shell", OPT_SHELL }, + { NULL } + }; + int t; + + if (trans_strtotok(opttab, val->v.string, &t)) { grecs_error(&val->locus, 0, "unrecognized option"); + return; + } + if (t & NEGATE) + *options &= ~(t & ~NEGATE); + else + *options |= t; } static int diff --git a/src/jumper.h b/src/jumper.h index 448e8ef..c69d515 100644 --- a/src/jumper.h +++ b/src/jumper.h @@ -203,6 +203,7 @@ enum process_type { #define OPT_STDOUT 0x02 #define OPT_STDERR 0x04 #define OPT_NULLIN 0x08 +#define OPT_SHELL 0x10 const char *ipv4_to_string(uint32_t ip); int ipv4_match_p(ipv4_match_list_t *mp, uint32_t ip); diff --git a/src/progman.c b/src/progman.c index b9a0f5f..4474b38 100644 --- a/src/progman.c +++ b/src/progman.c @@ -479,13 +479,20 @@ progman_start(int type, listener_t *lp, struct grecs_locus *loc, fd_set fdset; struct wordsplit ws; - int flags = WRDSF_NOCMD | WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | - WRDSF_CESCAPES; + int flags = WRDSF_NOCMD; if (kve) { ws.ws_env = (const char **) kve; flags |= WRDSF_ENV | WRDSF_ENV_KV; } + + if (options & OPT_SHELL) { + ws.ws_offs = 2; + flags |= WRDSF_NOSPLIT | WRDSF_DOOFFS; + } else { + flags |= WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | + WRDSF_CESCAPES; + } if (wordsplit(prog, &ws, flags)) { diag(LOG_CRIT, "%s:%d: wordsplit: %s", @@ -493,6 +500,10 @@ progman_start(int type, listener_t *lp, struct grecs_locus *loc, wordsplit_strerror(&ws)); return -1; } + if (options & OPT_SHELL) { + ws.ws_wordv[0] = "/bin/sh"; + ws.ws_wordv[1] = "-c"; + } if (config.debug_level >= 1) { int i; @@ -501,7 +512,7 @@ progman_start(int type, listener_t *lp, struct grecs_locus *loc, size_t locsize = 0; grecs_txtacc_grow_string(acc, ws.ws_wordv[0]); - for (i = 1; i < ws.ws_wordc; i++) { + for (i = 1; i < ws.ws_wordc + ws.ws_offs; i++) { grecs_txtacc_grow_char(acc, ' '); grecs_txtacc_grow_string_escape(acc, ws.ws_wordv[i]); } |