Factor out common pre-session-launch preparation.

A more or less identical piece of code to sanitise the CONF_host
string prior to session launch existed in Windows PuTTY and both
Windows and Unix Plink. It's long past time it was centralised.

While I'm here, I've added a couple of extra comments in the
centralised version, including one that - unfortunately - tries _but
fails_ to explain why a string of the form "host.name:1234" doesn't
get the suffix moved into CONF_port the way "user@host" moves the
prefix into CONF_username. Commit c1c1bc471 is the one I'm referring
to in the comment, and unfortunately it has an unexplained one-liner
log message from before I got into the habit of being usefully
verbose.
This commit is contained in:
Simon Tatham 2017-12-03 14:35:03 +00:00
Родитель cd3093bcfe
Коммит e3796cb779
6 изменённых файлов: 96 добавлений и 175 удалений

8
Recipe
Просмотреть файл

@ -235,12 +235,12 @@ TERMINAL = terminal wcwidth ldiscucs logging tree234 minibidi
# GUI front end and terminal emulator (putty, puttytel).
GUITERM = TERMINAL window windlg winctrls sizetip winprint winutils
+ wincfg sercfg winhelp winjump
+ wincfg sercfg winhelp winjump sessprep
# Same thing on Unix.
UXTERM = TERMINAL uxcfg sercfg uxucs uxprint timing callback miscucs
GTKTERM = UXTERM gtkwin gtkcfg gtkdlg gtkfont gtkcols gtkmisc xkeysym
+ x11misc gtkcomm
+ x11misc gtkcomm sessprep
GTKMAIN = gtkmain cmdline
# Non-SSH back ends (putty, puttytel, plink).
@ -298,7 +298,7 @@ U_BE_NOSSH = be_nos_s uxser nocproxy
putty : [G] GUITERM NONSSH WINSSH W_BE_ALL WINMISC winx11 putty.res LIBS
puttytel : [G] GUITERM NONSSH W_BE_NOSSH WINMISC puttytel.res nogss LIBS
plink : [C] winplink wincons NONSSH WINSSH W_BE_ALL logging WINMISC
+ winx11 plink.res winnojmp noterm LIBS
+ winx11 plink.res winnojmp sessprep noterm LIBS
pscp : [C] pscp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
+ pscp.res winnojmp LIBS
psftp : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
@ -325,7 +325,7 @@ puttytel : [X] GTKTERM uxmisc misc ldisc settings uxsel U_BE_NOSSH
+ nogss GTKMAIN
plink : [U] uxplink uxcons NONSSH UXSSH U_BE_ALL logging UXMISC uxsignal
+ ux_x11 noterm uxnogtk cmdline
+ ux_x11 noterm uxnogtk sessprep cmdline
PUTTYGEN_UNIX = sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand uxnoise sshsha misc sshrsa sshdss uxcons uxstore uxmisc

Просмотреть файл

@ -1176,6 +1176,11 @@ void pinger_free(Pinger);
int conf_launchable(Conf *conf);
char const *conf_dest(Conf *conf);
/*
* Exports from sessprep.c.
*/
void prepare_session(Conf *conf);
/*
* Exports from sercfg.c.
*/

84
sessprep.c Normal file
Просмотреть файл

@ -0,0 +1,84 @@
/*
* sessprep.c: centralise some preprocessing done on Conf objects
* before launching them.
*/
#include "putty.h"
void prepare_session(Conf *conf)
{
char *hostbuf = dupstr(conf_get_str(conf, CONF_host));
char *host = hostbuf;
char *p, *q;
/*
* Trim leading whitespace from the hostname.
*/
host += strspn(host, " \t");
/*
* See if host is of the form user@host, and separate out the
* username if so.
*/
if (host[0] != '\0') {
/*
* Use strrchr, in case the _username_ in turn is of the form
* user@host, which has been known.
*/
char *atsign = strrchr(host, '@');
if (atsign) {
*atsign = '\0';
conf_set_str(conf, CONF_username, host);
host = atsign + 1;
}
}
/*
* Trim a colon suffix off the hostname if it's there, and discard
* the text after it.
*
* The exact reason why we _ignore_ this text, rather than
* treating it as a port number, is unfortunately lost in the
* mists of history: the commit which originally introduced this
* change on 2001-05-06 was clear on _what_ it was doing but
* didn't bother to explain _why_. But I [SGT, 2017-12-03] suspect
* it has to do with priority order: what should a saved session
* do if its CONF_host contains 'server.example.com:123' and its
* CONF_port contains 456? If CONF_port contained the _default_
* port number then it might be a good guess that the colon suffix
* on the host name was intended to override that, but you don't
* really want to get into making heuristic judgments on that
* basis.
*
* (Then again, you could just as easily make the same argument
* about whether a 'user@' prefix on the host name should override
* CONF_username, which this code _does_ do. I don't have a good
* answer, sadly. Both these pieces of behaviour have been around
* for years and it would probably cause subtle breakage in all
* sorts of long-forgotten scripting to go changing things around
* now.)
*
* In order to protect unbracketed IPv6 address literals against
* this treatment, we do not make this change at all if there's
* _more_ than one (un-IPv6-bracketed) colon.
*/
p = host_strchr(host, ':');
if (p && p != host_strrchr(host, ':')) {
*p = '\0';
}
/*
* Remove any remaining whitespace.
*/
p = hostbuf;
q = host;
while (*q) {
if (*q != ' ' && *q != '\t')
*p++ = *q;
q++;
}
*p = '\0';
conf_set_str(conf, CONF_host, hostbuf);
sfree(hostbuf);
}

Просмотреть файл

@ -823,63 +823,7 @@ int main(int argc, char **argv)
usage();
}
/*
* Muck about with the hostname in various ways.
*/
{
char *hostbuf = dupstr(conf_get_str(conf, CONF_host));
char *host = hostbuf;
char *p, *q;
/*
* Trim leading whitespace.
*/
host += strspn(host, " \t");
/*
* See if host is of the form user@host, and separate out
* the username if so.
*/
if (host[0] != '\0') {
char *atsign = strrchr(host, '@');
if (atsign) {
*atsign = '\0';
conf_set_str(conf, CONF_username, host);
host = atsign + 1;
}
}
/*
* Trim a colon suffix off the hostname if it's there. In
* order to protect unbracketed IPv6 address literals
* against this treatment, we do not do this if there's
* _more_ than one colon.
*/
{
char *c = host_strchr(host, ':');
if (c) {
char *d = host_strchr(c+1, ':');
if (!d)
*c = '\0';
}
}
/*
* Remove any remaining whitespace.
*/
p = hostbuf;
q = host;
while (*q) {
if (*q != ' ' && *q != '\t')
*p++ = *q;
q++;
}
*p = '\0';
conf_set_str(conf, CONF_host, hostbuf);
sfree(hostbuf);
}
prepare_session(conf);
/*
* Perform command-line overrides on session configuration.

Просмотреть файл

@ -606,63 +606,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
cleanup_exit(0);
}
/*
* Muck about with the hostname in various ways.
*/
{
char *hostbuf = dupstr(conf_get_str(conf, CONF_host));
char *host = hostbuf;
char *p, *q;
/*
* Trim leading whitespace.
*/
host += strspn(host, " \t");
/*
* See if host is of the form user@host, and separate
* out the username if so.
*/
if (host[0] != '\0') {
char *atsign = strrchr(host, '@');
if (atsign) {
*atsign = '\0';
conf_set_str(conf, CONF_username, host);
host = atsign + 1;
}
}
/*
* Trim a colon suffix off the hostname if it's there. In
* order to protect unbracketed IPv6 address literals
* against this treatment, we do not do this if there's
* _more_ than one colon.
*/
{
char *c = host_strchr(host, ':');
if (c) {
char *d = host_strchr(c+1, ':');
if (!d)
*c = '\0';
}
}
/*
* Remove any remaining whitespace.
*/
p = hostbuf;
q = host;
while (*q) {
if (*q != ' ' && *q != '\t')
*p++ = *q;
q++;
}
*p = '\0';
conf_set_str(conf, CONF_host, hostbuf);
sfree(hostbuf);
}
prepare_session(conf);
}
if (!prev) {

Просмотреть файл

@ -498,63 +498,7 @@ int main(int argc, char **argv)
usage();
}
/*
* Muck about with the hostname in various ways.
*/
{
char *hostbuf = dupstr(conf_get_str(conf, CONF_host));
char *host = hostbuf;
char *p, *q;
/*
* Trim leading whitespace.
*/
host += strspn(host, " \t");
/*
* See if host is of the form user@host, and separate out
* the username if so.
*/
if (host[0] != '\0') {
char *atsign = strrchr(host, '@');
if (atsign) {
*atsign = '\0';
conf_set_str(conf, CONF_username, host);
host = atsign + 1;
}
}
/*
* Trim a colon suffix off the hostname if it's there. In
* order to protect unbracketed IPv6 address literals
* against this treatment, we do not do this if there's
* _more_ than one colon.
*/
{
char *c = host_strchr(host, ':');
if (c) {
char *d = host_strchr(c+1, ':');
if (!d)
*c = '\0';
}
}
/*
* Remove any remaining whitespace.
*/
p = hostbuf;
q = host;
while (*q) {
if (*q != ' ' && *q != '\t')
*p++ = *q;
q++;
}
*p = '\0';
conf_set_str(conf, CONF_host, hostbuf);
sfree(hostbuf);
}
prepare_session(conf);
/*
* Perform command-line overrides on session configuration.