From 738b37b03276b198554afeab72c52f9c1a799142 Mon Sep 17 00:00:00 2001 From: "Lev A. Melnikovsky" <43612263+melnikovsky@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:04:19 +0200 Subject: [PATCH] vfs/shell: add MC_SSH_COMMAND and MC_SSH environment variable support MC_SSH_COMMAND, if set, is invoked via 'sh -c' so that it can contain options and arguments. MC's generated flags (compression, port, login name, hostname, remote command) are passed as positional parameters and are available as "$@" inside the command string, mirroring the GIT_SSH_COMMAND convention. MC_SSH, if set, replaces the 'ssh' binary with a plain executable path and no shell interpretation, analogous to GIT_SSH. MC_SSH_COMMAND takes precedence over MC_SSH. Examples: MC_SSH_COMMAND='ssh -i ~/.ssh/mykey' mc MC_SSH_COMMAND='ssh -o ProxyJump=bastion -o StrictHostKeyChecking=no' mc MC_SSH=/usr/local/bin/myssh mc Both variables are ignored for rsh connections (port == SHELL_FLAG_RSH). --- src/vfs/shell/shell.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/vfs/shell/shell.c b/src/vfs/shell/shell.c index 7fbcd4d565..1001184896 100644 --- a/src/vfs/shell/shell.c +++ b/src/vfs/shell/shell.c @@ -515,11 +515,38 @@ static void shell_open_archive_pipeopen (struct vfs_s_super *super) { char gbuf[10]; - const char *argv[10]; // All of 10 is used now + const char *argv[14]; // increased for optional sh -c prefix const char *xsh = (super->path_element->port == SHELL_FLAG_RSH ? "rsh" : "ssh"); + const char *mc_ssh_cmd; + gboolean use_shell_cmd; int i = 0; - argv[i++] = xsh; + mc_ssh_cmd = g_getenv ("MC_SSH_COMMAND"); + use_shell_cmd = + (mc_ssh_cmd != NULL && *mc_ssh_cmd != '\0' && super->path_element->port != SHELL_FLAG_RSH); + + /* MC_SSH: plain executable override, lower priority than MC_SSH_COMMAND. + * Ignored for rsh connections, mirroring the GIT_SSH convention. */ + if (!use_shell_cmd && super->path_element->port != SHELL_FLAG_RSH) + { + const char *mc_ssh = g_getenv ("MC_SSH"); + + if (mc_ssh != NULL && *mc_ssh != '\0') + xsh = mc_ssh; + } + + if (use_shell_cmd) + { + /* Invoke as: sh -c "$MC_SSH_COMMAND" ssh [MC-generated-args...] + * MC's flags (-C, -p, -l, host, remote-cmd) arrive as $@ inside the + * shell command, mirroring the GIT_SSH_COMMAND convention. */ + argv[i++] = "sh"; + argv[i++] = "-c"; + argv[i++] = mc_ssh_cmd; + argv[i++] = "ssh"; // $0 inside the shell script + } + else + argv[i++] = xsh; if (super->path_element->port == SHELL_FLAG_COMPRESSED) argv[i++] = "-C"; @@ -552,7 +579,7 @@ shell_open_archive_pipeopen (struct vfs_s_super *super) argv[i++] = "echo SHELL:; /bin/sh"; argv[i++] = NULL; - shell_pipeopen (super, xsh, argv); + shell_pipeopen (super, use_shell_cmd ? "sh" : xsh, argv); } /* --------------------------------------------------------------------------------------------- */