aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sshexec.145
-rw-r--r--sshexec.c22
2 files changed, 55 insertions, 12 deletions
diff --git a/sshexec.1 b/sshexec.1
index b17cc82..91922f6 100644
--- a/sshexec.1
+++ b/sshexec.1
@@ -10,7 +10,7 @@ sshexec - run a command through ssh(1) with normal command syntax
.RI [\fBdir=\fP directory ]
.RB [[\fIfd\fP]{ > , >> , >| , < , <> }[ & ] = \fIfile\fP]
.BR } ]
-[ssh-option] ...\,
+.RI [ ssh-option ]\ ...\,
.I destination
.I command
.RI [ argument ]\ ...\,
@@ -27,11 +27,19 @@ passes any argument after
to
.I ssh-command
.RB ( ssh
-if not specified), and only modifies
+if not specified), but it
+rewrites
.I command
-.RB [ argument ]\ ...\,
-and inserts extra arguments after
+and the
+.IR argument s
+to one argument that can be passed into
+.BR ssh (1)
+to describe each argument as separate arguments.
+It may also rewrite
.I destination
+to remove information that's not supported by
+.BR ssh (1)
+and inserts extra arguments after it
(it may also add a
.B --
argument immediately before
@@ -188,14 +196,29 @@ is 0 (standard input).)
The following operands are supported:
.TP
.I destination
-This operand is passed as is (without validation) to the
-.BR ssh (1)
-utility. The
-.BR ssh (1)
-utility will expect it the be either in the form
-.RI [ user\fP\fB@ ] hostname
+The destination to connect and log into. It shall be either in
+the form
+.RI [ user\fP\fB@ ] hostname [\fB:\fP directory ]
or in the form
-.BR ssh:// [\fIuser @ ]\fIhostname\fP[ : \fIport\fP].
+.BR ssh [ exec ] :// [\fIuser @ ]\fIhostname\fP[ : \fIport\fP][ / \fIdirectory\fP].
+
+.I user
+shall be the name of the remote user. If not specified,
+the name of the local user running the utility will be used.
+
+.I hostname
+shall be the address to the remote machine.
+
+.I port
+shall be the port or service name for the port to
+connect to on the remote machine.
+
+.I directory
+shall be directory to change the remote working directory.
+This is an alternative to (with the exact same behaviour)
+to the
+.B dir
+option and cannot be combined with it.
.TP
.IR command \ [ argument ]\ ...\,
Whereas the
diff --git a/sshexec.c b/sshexec.c
index a6db757..67868ee 100644
--- a/sshexec.c
+++ b/sshexec.c
@@ -131,7 +131,8 @@ main(int argc_unused, char *argv[])
const char *ssh = NULL;
struct redirection *redirections = NULL;
size_t nredirections = 0;
- const char *destination;
+ char *destination;
+ char *dest_dir_delim;
char **opts, *p;
size_t nopts;
enum optclass class;
@@ -240,6 +241,25 @@ main(int argc_unused, char *argv[])
else if (strchr(*argv, '='))
exitf("%s: the command argument must contain an \'=\'\n", argv0);
+ if (!strncmp(destination, "sshexec://", sizeof("sshexec://") - 1U)) {
+ memmove(&destination[sizeof("ssh") - 1U],
+ &destination[sizeof("sshexec") - 1U],
+ strlen(&destination[sizeof("sshexec") - 1U]) + 1U);
+ goto using_ssh_prefix;
+ } else if (!strncmp(destination, "ssh://", sizeof("ssh://") - 1U)) {
+ using_ssh_prefix:
+ dest_dir_delim = strchr(&destination[sizeof("ssh://")], '/');
+ } else {
+ dest_dir_delim = strchr(destination, ':');
+ }
+ if (dest_dir_delim) {
+ if (dir)
+ exitf("%s: directory specified both in 'dir' option and in destination operand\n", argv0);
+ *dest_dir_delim++ = '\0';
+ dir = dest_dir_delim;
+ }
+dest_dir_checked:
+
if (dir) {
build_command_asis("cd -- ");
build_command_escape(dir);