diff options
-rw-r--r-- | README | 16 | ||||
-rw-r--r-- | sshexec.1 | 20 | ||||
-rw-r--r-- | sshexec.c | 42 |
3 files changed, 71 insertions, 7 deletions
@@ -3,8 +3,9 @@ NAME SYNOPSIS sshexec [{ [ssh=ssh-command] [dir=directory] [cd=(strict|lax)] - [[fd]{>,>>,>|,<,<>}[&]=file] }] [ssh-option] ... - destination command [argument] ... + [[fd]{>,>>,>|,<,<>}[&]=file] [asis=asis-marker + [nasis=asis-count]] }] [ssh-option] ... destination + command [argument] ... DESCRIPTION The sshexec utility is a wrapper for SSH that makes it easy to @@ -103,6 +104,17 @@ OPTIONS Close the file descriptor fd. (Default fd is 0 (standard input).) + asis=asis-marker + Any argument equal to asis-marker will be skipped over + and instead the next argument (regardless of whether + it to is equal to asis-marker) will be interpreted as + raw shell code string that shall be inserted without + escaping. + + masis=asis-count + If specified, asis-marker shall only have it's specified + affect up to asis-count times. + OPERANDS The following operands are supported: @@ -10,6 +10,8 @@ sshexec - run a command through ssh(1) with normal command syntax .RI [\fBdir=\fP directory ] .RB [ cd= ( strict | lax )] .RB [[\fIfd\fP]{ > , >> , >| , < , <> }[ & ] = \fIfile\fP] +.RB [ asis= \fIasis-marker\fP +.RB [ nasis= \fIasis-count\fP]] .BR } ] .RI [ ssh-option ]\ ...\, .I destination @@ -206,6 +208,24 @@ Close the file descriptor (Default .I fd is 0 (standard input).) +.TP +.BI asis= asis-marker +Any +.I argument +equal to +.I asis-marker +will be skipped over and instead the next argument +(regardless of whether it to is equal to +.IR asis-marker ) +will be interpreted as raw shell code string that +shall be inserted without escaping. +.TP +.BI masis= asis-count +If specified, +.I asis-marker +shall only have it's specified affect up to +.I asis-count +times. .SH OPERANDS The following operands are supported: @@ -19,7 +19,8 @@ static void usage(void) { exitf("usage: %s [{ %s }] [ssh-option] ... destination command [argument] ...\n", - argv0, "[ssh=command] [dir=directory] [cd=(strict|lax)] [[fd]{>,>>,>|,<>}[&]=file]"); + argv0, "[ssh=command] [dir=directory] [cd=(strict|lax)] [[fd]{>,>>,>|,<>}[&]=file] " + "[asis=asis-marker [nasis=asis-count]]"); } @@ -130,6 +131,8 @@ main(int argc_unused, char *argv[]) const char *dir = NULL; const char *ssh = NULL; const char *cd = NULL; + const char *asis = NULL; + const char *nasis_str = NULL; struct redirection *redirections = NULL; size_t nredirections = 0; char *destination; @@ -142,6 +145,8 @@ main(int argc_unused, char *argv[]) const char **args; size_t i; int strict_cd; + unsigned long long int nasis = ULLONG_MAX; + int next_asis; (void) argc_unused; @@ -160,7 +165,8 @@ main(int argc_unused, char *argv[]) for (; *argv && strcmp(*argv, "}"); argv++) { STORE_OPT(&ssh, "ssh") STORE_OPT(&dir, "dir") - STORE_OPT(&cd, "cd") + STORE_OPT(&asis, "asis") + STORE_OPT(&nasis_str, "nasis") p = *argv; while (isdigit(*p)) @@ -212,6 +218,16 @@ main(int argc_unused, char *argv[]) else usage(); + if (nasis_str) { + char *end; + if (!asis || !isdigit(*nasis_str)) + usage(); + errno = 0; + nasis = strtoull(nasis_str, &end, 10); + if ((!nasis && errno) || *end) + usage(); + } + opts = argv; nopts = 0; while (*argv) { @@ -275,11 +291,27 @@ dest_dir_checked: build_command_escape(dir); build_command_asis(strict_cd ? " && " : " ; "); } - build_command_asis("exec env --"); + if (asis) + build_command_asis("( env --"); + else + build_command_asis("exec env --"); + next_asis = 0; for (; *argv; argv++) { - build_command_asis(" "); - build_command_escape(*argv); + if (asis && nasis && !strcmp(*argv, asis)) { + nasis -= 1U; + next_asis = 1; + } else { + build_command_asis(" "); + if (next_asis) { + next_asis = 0; + build_command_asis(*argv); + } else { + build_command_escape(*argv); + } + } } + if (asis) + build_command_asis(" )"); for (i = 0; i < nredirections; i++) { build_command_asis(" "); build_command_asis(redirections[i].asis); |