diff --git a/putty.h b/putty.h index 662e6db1..8fa76aa1 100644 --- a/putty.h +++ b/putty.h @@ -495,10 +495,10 @@ struct Backend { const BackendVtable *vt; }; struct BackendVtable { - const char *(*init) (const BackendVtable *vt, Seat *seat, - Backend **backend_out, LogContext *logctx, Conf *conf, - const char *host, int port, - char **realhost, bool nodelay, bool keepalive); + char *(*init) (const BackendVtable *vt, Seat *seat, + Backend **backend_out, LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, + bool nodelay, bool keepalive); void (*free) (Backend *be); /* Pass in a replacement configuration. */ @@ -540,7 +540,7 @@ struct BackendVtable { unsigned serial_parity_mask, serial_flow_mask; }; -static inline const char *backend_init( +static inline char *backend_init( const BackendVtable *vt, Seat *seat, Backend **out, LogContext *logctx, Conf *conf, const char *host, int port, char **rhost, bool nd, bool ka) { return vt->init(vt, seat, out, logctx, conf, host, port, rhost, nd, ka); } diff --git a/raw.c b/raw.c index 6058793b..15f8d85e 100644 --- a/raw.c +++ b/raw.c @@ -119,10 +119,10 @@ static const PlugVtable Raw_plugvt = { * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *raw_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *raw_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { SockAddr *addr; const char *err; @@ -155,7 +155,7 @@ static const char *raw_init(const BackendVtable *vt, Seat *seat, raw->logctx, "main connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); - return err; + return dupstr(err); } if (port < 0) @@ -167,7 +167,7 @@ static const char *raw_init(const BackendVtable *vt, Seat *seat, raw->s = new_connection(addr, *realhost, port, false, true, nodelay, keepalive, &raw->plug, conf); if ((err = sk_socket_error(raw->s)) != NULL) - return err; + return dupstr(err); loghost = conf_get_str(conf, CONF_loghost); if (*loghost) { diff --git a/rlogin.c b/rlogin.c index cc95a3db..8c3d12d0 100644 --- a/rlogin.c +++ b/rlogin.c @@ -153,10 +153,10 @@ static const PlugVtable Rlogin_plugvt = { * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *rlogin_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *rlogin_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { SockAddr *addr; const char *err; @@ -188,7 +188,7 @@ static const char *rlogin_init(const BackendVtable *vt, Seat *seat, rlogin->logctx, "rlogin connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); - return err; + return dupstr(err); } if (port < 0) @@ -200,7 +200,7 @@ static const char *rlogin_init(const BackendVtable *vt, Seat *seat, rlogin->s = new_connection(addr, *realhost, port, true, false, nodelay, keepalive, &rlogin->plug, conf); if ((err = sk_socket_error(rlogin->s)) != NULL) - return err; + return dupstr(err); loghost = conf_get_str(conf, CONF_loghost); if (*loghost) { diff --git a/ssh.c b/ssh.c index 46451142..421315e4 100644 --- a/ssh.c +++ b/ssh.c @@ -704,7 +704,7 @@ static const PlugVtable Ssh_plugvt = { * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *connect_to_host( +static char *connect_to_host( Ssh *ssh, const char *host, int port, char **realhost, bool nodelay, bool keepalive) { @@ -765,7 +765,7 @@ static const char *connect_to_host( ssh->logctx, "SSH connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); - return err; + return dupstr(err); } ssh->fullhostname = dupstr(*realhost); /* save in case of GSSAPI */ @@ -775,7 +775,7 @@ static const char *connect_to_host( if ((err = sk_socket_error(ssh->s)) != NULL) { ssh->s = NULL; seat_notify_remote_exit(ssh->seat); - return err; + return dupstr(err); } } @@ -870,12 +870,11 @@ bool ssh_is_bare(Ssh *ssh) * * Returns an error message, or NULL on success. */ -static const char *ssh_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *ssh_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { - const char *p; Ssh *ssh; ssh = snew(Ssh); @@ -906,15 +905,16 @@ static const char *ssh_init(const BackendVtable *vt, Seat *seat, random_ref(); /* do this now - may be needed by sharing setup code */ ssh->need_random_unref = true; - p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive); - if (p != NULL) { + char *conn_err = connect_to_host( + ssh, host, port, realhost, nodelay, keepalive); + if (conn_err) { /* Call random_unref now instead of waiting until the caller * frees this useless Ssh object, in case the caller is * impatient and just exits without bothering, in which case * the random seed won't be re-saved. */ ssh->need_random_unref = false; random_unref(); - return p; + return conn_err; } return NULL; diff --git a/supdup.c b/supdup.c index 87d72fd3..f210ebe3 100644 --- a/supdup.c +++ b/supdup.c @@ -635,11 +635,11 @@ static void supdup_send_config(Supdup *supdup) * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *supdup_init(const BackendVtable *x, Seat *seat, - Backend **backend_handle, - LogContext *logctx, Conf *conf, - const char *host, int port, char **realhost, - bool nodelay, bool keepalive) +static char *supdup_init(const BackendVtable *x, Seat *seat, + Backend **backend_handle, + LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, + bool nodelay, bool keepalive) { static const PlugVtable fn_table = { .log = supdup_log, @@ -696,7 +696,7 @@ static const char *supdup_init(const BackendVtable *x, Seat *seat, addr = name_lookup(host, port, realhost, supdup->conf, addressfamily, NULL, ""); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); - return err; + return dupstr(err); } if (port < 0) @@ -708,7 +708,7 @@ static const char *supdup_init(const BackendVtable *x, Seat *seat, supdup->s = new_connection(addr, *realhost, port, false, true, nodelay, keepalive, &supdup->plug, supdup->conf); if ((err = sk_socket_error(supdup->s)) != NULL) - return err; + return dupstr(err); supdup->pinger = pinger_new(supdup->conf, &supdup->backend); diff --git a/telnet.c b/telnet.c index 7a94e675..3a60e646 100644 --- a/telnet.c +++ b/telnet.c @@ -678,10 +678,10 @@ static const PlugVtable Telnet_plugvt = { * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *telnet_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *telnet_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { SockAddr *addr; const char *err; @@ -720,7 +720,7 @@ static const char *telnet_init(const BackendVtable *vt, Seat *seat, telnet->logctx, "Telnet connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); - return err; + return dupstr(err); } if (port < 0) @@ -732,7 +732,7 @@ static const char *telnet_init(const BackendVtable *vt, Seat *seat, telnet->s = new_connection(addr, *realhost, port, false, true, nodelay, keepalive, &telnet->plug, telnet->conf); if ((err = sk_socket_error(telnet->s)) != NULL) - return err; + return dupstr(err); telnet->pinger = pinger_new(telnet->conf, &telnet->backend); diff --git a/testback.c b/testback.c index 32e2e70a..173786ed 100644 --- a/testback.c +++ b/testback.c @@ -32,12 +32,10 @@ #include "putty.h" -static const char *null_init(const BackendVtable *, Seat *, Backend **, - LogContext *, Conf *, const char *, int, char **, - bool, bool); -static const char *loop_init(const BackendVtable *, Seat *, Backend **, - LogContext *, Conf *, const char *, int, char **, - bool, bool); +static char *null_init(const BackendVtable *, Seat *, Backend **, LogContext *, + Conf *, const char *, int, char **, bool, bool); +static char *loop_init(const BackendVtable *, Seat *, Backend **, LogContext *, + Conf *, const char *, int, char **, bool, bool); static void null_free(Backend *); static void loop_free(Backend *); static void null_reconfig(Backend *, Conf *); @@ -104,10 +102,10 @@ struct loop_state { Backend backend; }; -static const char *null_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) { +static char *null_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { /* No local authentication phase in this protocol */ seat_set_trust_status(seat, false); @@ -115,10 +113,10 @@ static const char *null_init(const BackendVtable *vt, Seat *seat, return NULL; } -static const char *loop_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) { +static char *loop_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { struct loop_state *st = snew(struct loop_state); /* No local authentication phase in this protocol */ diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 7ac2f2ef..865dffa0 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -5088,8 +5088,7 @@ static void gtk_seat_update_specials_menu(Seat *seat) static void start_backend(GtkFrontend *inst) { const struct BackendVtable *vt; - char *realhost; - const char *error; + char *error, *realhost; char *s; vt = select_backend(inst->conf); @@ -5107,6 +5106,7 @@ static void start_backend(GtkFrontend *inst) seat_connection_fatal(&inst->seat, "Unable to open connection to %s:\n%s", conf_dest(inst->conf), error); + sfree(error); inst->exited = true; return; } diff --git a/unix/uxplink.c b/unix/uxplink.c index f5691294..a23e4384 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -914,8 +914,7 @@ int main(int argc, char **argv) */ logctx = log_init(console_cli_logpolicy, conf); { - const char *error; - char *realhost; + char *error, *realhost; /* nodelay is only useful if stdin is a terminal device */ bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && isatty(0); @@ -931,6 +930,7 @@ int main(int argc, char **argv) conf_get_bool(conf, CONF_tcp_keepalives)); if (error) { fprintf(stderr, "Unable to open connection:\n%s\n", error); + sfree(error); return 1; } ldisc_create(conf, NULL, backend, plink_seat); diff --git a/unix/uxpty.c b/unix/uxpty.c index e2a11444..346fdb55 100644 --- a/unix/uxpty.c +++ b/unix/uxpty.c @@ -1270,10 +1270,10 @@ Backend *pty_backend_create( * it gets the argv array from the global variable pty_argv, expecting * that it will have been invoked by pterm. */ -static const char *pty_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *pty_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { const char *cmd = NULL; struct ssh_ttymodes modes; diff --git a/unix/uxser.c b/unix/uxser.c index 89e79c6b..d9d28bce 100644 --- a/unix/uxser.c +++ b/unix/uxser.c @@ -63,14 +63,15 @@ static void serial_select_result(int fd, int event); static void serial_uxsel_setup(Serial *serial); static void serial_try_write(Serial *serial); -static const char *serial_configure(Serial *serial, Conf *conf) +static char *serial_configure(Serial *serial, Conf *conf) { struct termios options; int bflag, bval, speed, flow, parity; const char *str; if (serial->fd < 0) - return "Unable to reconfigure already-closed serial connection"; + return dupstr("Unable to reconfigure already-closed " + "serial connection"); tcgetattr(serial->fd, &options); @@ -189,7 +190,8 @@ static const char *serial_configure(Serial *serial, Conf *conf) case 6: options.c_cflag |= CS6; break; case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; - default: return "Invalid number of data bits (need 5, 6, 7 or 8)"; + default: return dupstr("Invalid number of data bits " + "(need 5, 6, 7 or 8)"); } logeventf(serial->logctx, "Configuring %d data bits", conf_get_int(conf, CONF_serdatabits)); @@ -266,7 +268,7 @@ static const char *serial_configure(Serial *serial, Conf *conf) options.c_cc[VTIME] = 0; if (tcsetattr(serial->fd, TCSANOW, &options) < 0) - return "Unable to configure serial port"; + return dupstr("Unable to configure serial port"); return NULL; } @@ -279,13 +281,13 @@ static const char *serial_configure(Serial *serial, Conf *conf) * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *serial_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *serial_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { Serial *serial; - const char *err; + char *err; char *line; /* No local authentication phase in this protocol */ @@ -306,7 +308,7 @@ static const char *serial_init(const BackendVtable *vt, Seat *seat, serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (serial->fd < 0) - return "Unable to open serial port"; + return dupstr("Unable to open serial port"); cloexec(serial->fd); diff --git a/windows/window.c b/windows/window.c index 2dbfd8c3..0ccf700f 100644 --- a/windows/window.c +++ b/windows/window.c @@ -368,9 +368,8 @@ static WinGuiSeat wgs = { .seat.vt = &win_seat_vt, static void start_backend(void) { const struct BackendVtable *vt; - const char *error; const char *title; - char *realhost; + char *error, *realhost; int i; /* @@ -397,6 +396,7 @@ static void start_backend(void) char *str = dupprintf("%s Error", appname); char *msg = dupprintf("Unable to open connection to\n%s\n%s", conf_dest(conf), error); + sfree(error); MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK); sfree(str); sfree(msg); diff --git a/windows/winplink.c b/windows/winplink.c index 3172508f..83f988ad 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -492,8 +492,7 @@ int main(int argc, char **argv) */ winselcli_setup(); /* ensure event object exists */ { - const char *error; - char *realhost; + char *error, *realhost; /* nodelay is only useful if stdin is a character device (console) */ bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); @@ -505,6 +504,7 @@ int main(int argc, char **argv) conf_get_bool(conf, CONF_tcp_keepalives)); if (error) { fprintf(stderr, "Unable to open connection:\n%s", error); + sfree(error); return 1; } sfree(realhost); diff --git a/windows/winser.c b/windows/winser.c index 7f3a3821..2a132f83 100644 --- a/windows/winser.c +++ b/windows/winser.c @@ -91,7 +91,7 @@ static void serial_sentdata(struct handle *h, size_t new_backlog, int err) } } -static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) +static char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) { DCB dcb; COMMTIMEOUTS timeouts; @@ -134,7 +134,8 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) case 2: dcb.StopBits = ONESTOPBIT; str = "1 stop bit"; break; case 3: dcb.StopBits = ONE5STOPBITS; str = "1.5 stop bits"; break; case 4: dcb.StopBits = TWOSTOPBITS; str = "2 stop bits"; break; - default: return "Invalid number of stop bits (need 1, 1.5 or 2)"; + default: return dupstr("Invalid number of stop bits " + "(need 1, 1.5 or 2)"); } logeventf(serial->logctx, "Configuring %s", str); @@ -169,7 +170,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) logeventf(serial->logctx, "Configuring %s flow control", str); if (!SetCommState(serport, &dcb)) - return "Unable to configure serial port"; + return dupstr("Unable to configure serial port"); timeouts.ReadIntervalTimeout = 1; timeouts.ReadTotalTimeoutMultiplier = 0; @@ -177,7 +178,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(serport, &timeouts)) - return "Unable to configure serial timeouts"; + return dupstr("Unable to configure serial timeouts"); } return NULL; @@ -191,14 +192,14 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ -static const char *serial_init(const BackendVtable *vt, Seat *seat, - Backend **backend_handle, LogContext *logctx, - Conf *conf, const char *host, int port, - char **realhost, bool nodelay, bool keepalive) +static char *serial_init(const BackendVtable *vt, Seat *seat, + Backend **backend_handle, LogContext *logctx, + Conf *conf, const char *host, int port, + char **realhost, bool nodelay, bool keepalive) { Serial *serial; HANDLE serport; - const char *err; + char *err; char *serline; /* No local authentication phase in this protocol */ @@ -250,7 +251,7 @@ static const char *serial_init(const BackendVtable *vt, Seat *seat, } if (serport == INVALID_HANDLE_VALUE) - return "Unable to open serial port"; + return dupstr("Unable to open serial port"); err = serial_configure(serial, serport, conf); if (err)