Palmer Dabbelt
2014-Sep-22 22:33 UTC
Allow the TERM env variable to be overwritten by .ssh/config
This is pretty much the same request as an old mailing list thread http://marc.info/?l=openssh-unix-dev&m=134073696320230&w=2 for almost exactly the same reason: some machines don't have new-enough terminal info databases to support newer TERM strings ("rxvt-unicode-256color" in my case). As such, I'd like to be able to override the TERM that is forwarded to some machines from my .ssh/config. The solutions proposed in that post don't work well for me because I like having a shared .bashrc and don't want to go making it super long just to have a big list of hosts that don't support "*-256color". Following is a git-formatted patch to implement this feature. It's based against the 6.6-p1 tarballs as I'm not really sure what else to base it against. Hopefully that's OK?
Palmer Dabbelt
2014-Sep-22 22:33 UTC
[PATCH] Allow the TERM env variable to be overwritten by .ssh/config
I run urxvt, but I have some hosts that have an older terminal info database that don't support the "rxvt-unicode-256color" string that my terminal exports. Many applications just fail to open when faced with an unknown TERM string, which is a huge pain. This patch allows me to specify what TERM should be for each host in my .ssh/config. This allows me to override TERM differently on each host depending on their level of support for my TERM variable (either rxvt-unicode, rxvt, or xterm). There are a number of posts referencing this lack of feature on the Internet along with some workarounds, but I think this is cleaner. --- readconf.c | 8 +++++++- readconf.h | 2 ++ ssh.c | 11 +++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/readconf.c b/readconf.c index dc884c9..db85a25 100644 --- a/readconf.c +++ b/readconf.c @@ -129,7 +129,7 @@ typedef enum { oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, - oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, + oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oTerm, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, @@ -196,6 +196,7 @@ static struct { { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, { "proxycommand", oProxyCommand }, + { "term", oTerm }, { "port", oPort }, { "cipher", oCipher }, { "ciphers", oCiphers }, @@ -994,6 +995,10 @@ parse_command: *charptr = xstrdup(s + len); return 0; + case oTerm: + charptr = &options->term; + goto parse_string; + case oPort: intptr = &options->port; parse_int: @@ -1568,6 +1573,7 @@ initialize_options(Options * options) options->canonicalize_max_dots = -1; options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; + options->term = NULL; } /* diff --git a/readconf.h b/readconf.h index 75e3f8f..883bfed 100644 --- a/readconf.h +++ b/readconf.h @@ -104,6 +104,8 @@ typedef struct { int identity_file_userprovided[SSH_MAX_IDENTITY_FILES]; Key *identity_keys[SSH_MAX_IDENTITY_FILES]; + char *term; /* TERM to send to the server, or NULL if getenv("TERM") is used */ + /* Local TCP/IP forward requests. */ int num_local_forwards; Forward *local_forwards; diff --git a/ssh.c b/ssh.c index 1e6cb90..c19ed46 100644 --- a/ssh.c +++ b/ssh.c @@ -1439,7 +1439,10 @@ ssh_session(void) /* Store TERM in the packet. There is no limit on the length of the string. */ - cp = getenv("TERM"); + cp = options.term; + fprintf(stderr, "stored term: '%s'\n", cp); + if (!cp) + cp = getenv("TERM"); if (!cp) cp = ""; packet_put_cstring(cp); @@ -1568,6 +1571,7 @@ ssh_session2_setup(int id, int success, void *arg) { extern char **environ; const char *display; + char *term; int interactive = tty_flag; if (!success) @@ -1601,7 +1605,10 @@ ssh_session2_setup(int id, int success, void *arg) packet_set_interactive(interactive, options.ip_qos_interactive, options.ip_qos_bulk); - client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), + term = options.term; + if (!term) + term = getenv("TERM"); + client_session2_setup(id, tty_flag, subsystem_flag, term, NULL, fileno(stdin), &command, environ); } -- 1.8.5.5
Carson Gaspar
2014-Sep-22 23:22 UTC
Allow the TERM env variable to be overwritten by .ssh/config
On 9/22/2014 3:33 PM, Palmer Dabbelt wrote:> This is pretty much the same request as an old mailing list thread > > http://marc.info/?l=openssh-unix-dev&m=134073696320230&w=2[*snip*]> The solutions proposed in that post don't work well for me because I > like having a shared .bashrc and don't want to go making it super long > just to have a big list of hosts that don't support "*-256color".I don't like your patch as-is. If ssh needs something like this, it should be generic to any env var, not TERM specific. And then one could argue that a shell wrapper function could do the same thing (but wouldn't have identical destination parsing rules and would need config to live elsewhere, so there is some value in having such functionality in ssh itself). Put something like this in your shell startup on the destination hosts to avoid maintaining a host list anywhere or patching ssh: # Optionally wrap in "if test -t 1" to only bother on a TTY local TRYTERMLIST='' case "$TERM" in 'rxvt-unicode-256color') TRYTERMLIST='rxvt-unicode-256color rxvt-256color xterm' ;; esac if test -n "$TRYTERMLIST" && test -x "$(type -P infocmp)"; then local T for T in $TRYTERMLIST; do if infocmp "$T" >/dev/null 2>&1; then export TERM="$T" break fi done fi Or, given that you appear to have a shared/dist'd home directory, just copy the correct terminfo file(s) into your home dir and set TERMINFO. -- Carson
Iain Morgan
2014-Sep-23 02:06 UTC
Allow the TERM env variable to be overwritten by .ssh/config
On Mon, Sep 22, 2014 at 15:33:29 -0700, Palmer Dabbelt wrote:> This is pretty much the same request as an old mailing list thread > > http://marc.info/?l=openssh-unix-dev&m=134073696320230&w=2 > > for almost exactly the same reason: some machines don't have > new-enough terminal info databases to support newer TERM strings > ("rxvt-unicode-256color" in my case). As such, I'd like to be able to > override the TERM that is forwarded to some machines from my > .ssh/config. > > The solutions proposed in that post don't work well for me because I > like having a shared .bashrc and don't want to go making it super long > just to have a big list of hosts that don't support "*-256color". >Perhaps you could use tput to test for terminal capabilities rather than keeping a list of hosts. I've had to deal with a somewhat different issue; preferring to suppress color support. I used to use "tput colors" to test for the number of colors supported, and re-define TERM as needed. More recently, I taken to simply overriding the terminfo definitions for those terminal types that I use by creating a ~/.terminfo directory or ~/.terminfo.db database. -- Iain Morgan