diff --git a/Recipe b/Recipe index eabdf3fa..581d030c 100644 --- a/Recipe +++ b/Recipe @@ -347,7 +347,7 @@ psftp : [U] psftp uxsftp uxcons UXSSH BE_SSH SFTP wildcard UXMISC uxnogtk pageant : [X] uxpgnt uxagentc aqsync pageant sshrsa sshpubk sshdes sshbn + sshmd5 version tree234 misc sshaes sshsha sshdss sshsh256 sshsh512 + sshecc CONF uxsignal nocproxy nogss be_none x11fwd ux_x11 uxcons - + gtkask gtkmisc nullplug UXMISC + + gtkask gtkmisc nullplug logging UXMISC ptermapp : [XT] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore + uxsignal CHARSET uxpterm version time xpmpterm xpmptcfg diff --git a/be_misc.c b/be_misc.c index 55853411..1e8026ea 100644 --- a/be_misc.c +++ b/be_misc.c @@ -8,7 +8,8 @@ #include "putty.h" #include "network.h" -void backend_socket_log(Frontend *frontend, int type, SockAddr *addr, int port, +void backend_socket_log(Frontend *frontend, LogContext *logctx, + int type, SockAddr *addr, int port, const char *error_msg, int error_code, Conf *conf, int session_started) { @@ -53,7 +54,7 @@ void backend_socket_log(Frontend *frontend, int type, SockAddr *addr, int port, } if (msg) { - logevent(frontend, msg); + logevent(logctx, msg); sfree(msg); } } diff --git a/cmdgen.c b/cmdgen.c index fe083a0c..7e98ef24 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -116,9 +116,6 @@ void nonfatal(const char *p, ...) /* * Stubs to let everything else link sensibly. */ -void log_eventlog(LogContext *logctx, const char *event) -{ -} char *x_get_default(const char *key) { return NULL; diff --git a/defs.h b/defs.h index 0d98b70c..f524378e 100644 --- a/defs.h +++ b/defs.h @@ -49,7 +49,9 @@ typedef struct Backend Backend; typedef struct BackendVtable BackendVtable; typedef struct Ldisc_tag Ldisc; -typedef struct LogContext_tag LogContext; +typedef struct LogContext LogContext; +typedef struct LogPolicy LogPolicy; +typedef struct LogPolicyVtable LogPolicyVtable; typedef struct Frontend Frontend; diff --git a/fuzzterm.c b/fuzzterm.c index fb68482c..d6152661 100644 --- a/fuzzterm.c +++ b/fuzzterm.c @@ -137,11 +137,6 @@ int dlg_coloursel_results(union control *ctrl, void *dlg, int *r, int *g, int *b) { return 0; } void dlg_refresh(union control *ctrl, void *dlg) { } -/* miscellany */ -void logevent(Frontend *frontend, const char *msg) { } -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx) { return 0; } - const char *const appname = "FuZZterm"; const int ngsslibs = 0; const char *const gsslibnames[0] = { }; diff --git a/logging.c b/logging.c index f07982ac..eb1aeec2 100644 --- a/logging.c +++ b/logging.c @@ -12,12 +12,12 @@ #include "putty.h" /* log session to file stuff ... */ -struct LogContext_tag { +struct LogContext { FILE *lgfp; enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state; bufchain queue; Filename *currlogfilename; - Frontend *frontend; + LogPolicy *lp; Conf *conf; int logtype; /* cached out of conf */ }; @@ -48,9 +48,8 @@ static void logwrite(LogContext *ctx, void *data, int len) if (fwrite(data, 1, len, ctx->lgfp) < (size_t)len) { logfclose(ctx); ctx->state = L_ERROR; - /* Log state is L_ERROR so this won't cause a loop */ - logevent(ctx->frontend, - "Disabled writing session log due to error while writing"); + lp_eventlog(ctx->lp, "Disabled writing session log " + "due to error while writing"); } } /* else L_ERROR, so ignore the write */ } @@ -121,23 +120,14 @@ static void logfopen_callback(void *vctx, int mode) ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" : "unknown"), filename_to_str(ctx->currlogfilename)); - logevent(ctx->frontend, event); + lp_eventlog(ctx->lp, event); if (shout) { /* * If we failed to open the log file due to filesystem error * (as opposed to user action such as clicking Cancel in the - * askappend box), we should log it more prominently. We do - * this by sending it to the same place that stderr output - * from the main session goes (so, either a console tool's - * actual stderr, or a terminal window). - * - * Of course this is one case in which that policy won't cause - * it to turn up embarrassingly in a log file of real server - * output, because the whole point is that we haven't managed - * to open any such log file :-) + * askappend box), we should log it more prominently. */ - from_backend(ctx->frontend, 1, event, strlen(event)); - from_backend(ctx->frontend, 1, "\r\n", 2); + lp_logging_error(ctx->lp, event); } sfree(event); @@ -188,8 +178,8 @@ void logfopen(LogContext *ctx) if (logxfovr != LGXF_ASK) { mode = ((logxfovr == LGXF_OVR) ? 2 : 1); } else - mode = askappend(ctx->frontend, ctx->currlogfilename, - logfopen_callback, ctx); + mode = lp_askappend(ctx->lp, ctx->currlogfilename, + logfopen_callback, ctx); } else mode = 2; /* create == overwrite */ @@ -223,16 +213,32 @@ void logtraffic(LogContext *ctx, unsigned char c, int logmode) * Log an Event Log entry. Used in SSH packet logging mode, to copy * the Event Log entries into the same log file as the packet data. */ -void log_eventlog(LogContext *ctx, const char *event) +void logevent(LogContext *ctx, const char *event) { - /* If we don't have a context yet (eg winnet.c init) then skip entirely */ if (!ctx) - return; - if (ctx->logtype != LGTYP_PACKETS && - ctx->logtype != LGTYP_SSHRAW) - return; - logprintf(ctx, "Event Log: %s\r\n", event); - logflush(ctx); + return; + if (ctx->logtype == LGTYP_PACKETS || ctx->logtype == LGTYP_SSHRAW) { + logprintf(ctx, "Event Log: %s\r\n", event); + logflush(ctx); + } + lp_eventlog(ctx->lp, event); +} + +void logevent_and_free(LogContext *ctx, char *event) +{ + logevent(ctx, event); + sfree(event); +} + +void logeventf(LogContext *ctx, const char *fmt, ...) +{ + va_list ap; + char *buf; + + va_start(ap, fmt); + buf = dupvprintf(fmt, ap); + va_end(ap); + logevent_and_free(ctx, buf); } /* @@ -359,12 +365,12 @@ void log_packet(LogContext *ctx, int direction, int type, logflush(ctx); } -LogContext *log_init(Frontend *frontend, Conf *conf) +LogContext *log_init(LogPolicy *lp, Conf *conf) { LogContext *ctx = snew(LogContext); ctx->lgfp = NULL; ctx->state = L_CLOSED; - ctx->frontend = frontend; + ctx->lp = lp; ctx->conf = conf_copy(conf); ctx->logtype = conf_get_int(ctx->conf, CONF_logtype); ctx->currlogfilename = NULL; diff --git a/misc.c b/misc.c index f24a6e36..0b9e6c25 100644 --- a/misc.c +++ b/misc.c @@ -337,12 +337,6 @@ void burnstr(char *string) /* sfree(str), only clear it first */ } } -void logevent_and_free(Frontend *frontend, char *s) -{ - logevent(frontend, s); - sfree(s); -} - int toint(unsigned u) { /* diff --git a/misc.h b/misc.h index 0977050b..968c3d5d 100644 --- a/misc.h +++ b/misc.h @@ -31,13 +31,6 @@ char *dupprintf(const char *fmt, ...) char *dupvprintf(const char *fmt, va_list ap); void burnstr(char *string); -/* - * Pass a dynamically allocated string to logevent and immediately - * free it. Intended for use by wrapper macros which pass the return - * value of dupprintf straight to this. - */ -void logevent_and_free(Frontend *frontend, char *msg); - struct strbuf { char *s; unsigned char *u; diff --git a/network.h b/network.h index f7152054..9a1b2383 100644 --- a/network.h +++ b/network.h @@ -106,8 +106,7 @@ Socket *new_connection(SockAddr *addr, const char *hostname, Socket *new_listener(const char *srcaddr, int port, Plug *plug, int local_host_only, Conf *conf, int addressfamily); SockAddr *name_lookup(const char *host, int port, char **canonicalname, - Conf *conf, int addressfamily, - Frontend *frontend_for_logging, + Conf *conf, int addressfamily, LogContext *logctx, const char *lookup_reason_for_logging); int proxy_for_destination (SockAddr *addr, const char *hostname, int port, Conf *conf); @@ -236,7 +235,8 @@ extern Plug *const nullplug; /* * Exports from be_misc.c. */ -void backend_socket_log(Frontend *frontend, int type, SockAddr *addr, int port, +void backend_socket_log(Frontend *frontend, LogContext *logctx, + int type, SockAddr *addr, int port, const char *error_msg, int error_code, Conf *conf, int session_started); void log_proxy_stderr(Plug *plug, bufchain *buf, const void *vdata, int len); diff --git a/portfwd.c b/portfwd.c index 8ae9e80c..5d8250ca 100644 --- a/portfwd.c +++ b/portfwd.c @@ -10,18 +10,6 @@ #include "ssh.h" #include "sshchan.h" -static void logeventf(Frontend *frontend, const char *fmt, ...) -{ - va_list ap; - char *buf; - - va_start(ap, fmt); - buf = dupvprintf(fmt, ap); - va_end(ap); - logevent(frontend, buf); - sfree(buf); -} - /* * Enumeration of values that live in the 'socks_state' field of * struct PortForwarding. @@ -641,7 +629,7 @@ static void pfd_open_failure(Channel *chan, const char *errtext) assert(chan->vt == &PortForwarding_channelvt); PortForwarding *pf = container_of(chan, PortForwarding, chan); - logeventf(pf->cl->frontend, + logeventf(pf->cl->logctx, "Forwarded connection refused by server%s%s", errtext ? ": " : "", errtext ? errtext : ""); } @@ -803,7 +791,7 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) sserv = 1; sport = net_service_lookup(sports); if (!sport) { - logeventf(mgr->cl->frontend, "Service lookup failed for source" + logeventf(mgr->cl->logctx, "Service lookup failed for source" " port \"%s\"", sports); } } @@ -829,7 +817,7 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) dserv = 1; dport = net_service_lookup(dports); if (!dport) { - logeventf(mgr->cl->frontend, + logeventf(mgr->cl->logctx, "Service lookup failed for destination" " port \"%s\"", dports); } @@ -899,7 +887,7 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) message = msg2; } - logeventf(mgr->cl->frontend, "Cancelling %s", message); + logeventf(mgr->cl->logctx, "Cancelling %s", message); sfree(message); /* pfr->remote or pfr->local may be NULL if setting up a @@ -959,7 +947,7 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) mgr->cl, conf, &pfr->local, pfr->addressfamily); - logeventf(mgr->cl->frontend, + logeventf(mgr->cl->logctx, "Local %sport %s forwarding to %s%s%s", pfr->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " : pfr->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "", @@ -972,7 +960,7 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) mgr->cl, conf, &pfr->local, pfr->addressfamily); - logeventf(mgr->cl->frontend, + logeventf(mgr->cl->logctx, "Local %sport %s SOCKS dynamic forwarding%s%s", pfr->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " : pfr->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "", @@ -997,12 +985,12 @@ void portfwdmgr_config(PortFwdManager *mgr, Conf *conf) pfr->addressfamily, sportdesc, pfr, NULL); if (!pfr->remote) { - logeventf(mgr->cl->frontend, + logeventf(mgr->cl->logctx, "Duplicate remote port forwarding to %s:%d", pfr->daddr, pfr->dport); pfr_free(pfr); } else { - logeventf(mgr->cl->frontend, "Requesting remote port %s" + logeventf(mgr->cl->logctx, "Requesting remote port %s" " forward to %s", sportdesc, dportdesc); } } diff --git a/proxy.c b/proxy.c index ee97472c..14f72e2b 100644 --- a/proxy.c +++ b/proxy.c @@ -367,29 +367,23 @@ static char *dns_log_msg(const char *host, int addressfamily, } SockAddr *name_lookup(const char *host, int port, char **canonicalname, - Conf *conf, int addressfamily, Frontend *frontend, + Conf *conf, int addressfamily, LogContext *logctx, const char *reason) { - char *logmsg; if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && do_proxy_dns(conf) && proxy_for_destination(NULL, host, port, conf)) { - if (frontend) { - logmsg = dupprintf("Leaving host lookup to proxy of \"%s\"" - " (for %s)", host, reason); - logevent(frontend, logmsg); - sfree(logmsg); - } + if (logctx) + logeventf(logctx, "Leaving host lookup to proxy of \"%s\"" + " (for %s)", host, reason); *canonicalname = dupstr(host); return sk_nonamelookup(host); } else { - if (frontend) { - logmsg = dns_log_msg(host, addressfamily, reason); - logevent(frontend, logmsg); - sfree(logmsg); - } + if (logctx) + logevent_and_free( + logctx, dns_log_msg(host, addressfamily, reason)); return sk_namelookup(host, canonicalname, addressfamily); } diff --git a/pscp.c b/pscp.c index d1efe426..1b9e7c34 100644 --- a/pscp.c +++ b/pscp.c @@ -509,19 +509,17 @@ static void do_cmd(char *host, char *user, char *cmd) } conf_set_int(conf, CONF_nopty, TRUE); - logctx = log_init(NULL, conf); - console_provide_logctx(logctx); + logctx = log_init(default_logpolicy, conf); platform_psftp_pre_conn_setup(); - err = backend_init(&ssh_backend, NULL, &backend, conf, + err = backend_init(&ssh_backend, NULL, &backend, logctx, conf, conf_get_str(conf, CONF_host), conf_get_int(conf, CONF_port), &realhost, 0, conf_get_int(conf, CONF_tcp_keepalives)); if (err != NULL) bump("ssh_init: %s", err); - backend_provide_logctx(backend, logctx); ssh_scp_init(); if (verbose && realhost != NULL && errs == 0) tell_user(stderr, "Connected to %s", realhost); @@ -2382,7 +2380,6 @@ int psftp_main(int argc, char *argv[]) random_save_seed(); cmdline_cleanup(); - console_provide_logctx(NULL); backend_free(backend); backend = NULL; sk_cleanup(); diff --git a/psftp.c b/psftp.c index 557264be..4caabe76 100644 --- a/psftp.c +++ b/psftp.c @@ -2816,12 +2816,11 @@ static int psftp_connect(char *userhost, char *user, int portnumber) "exec sftp-server"); conf_set_int(conf, CONF_ssh_subsys2, FALSE); - logctx = log_init(NULL, conf); - console_provide_logctx(logctx); + logctx = log_init(default_logpolicy, conf); platform_psftp_pre_conn_setup(); - err = backend_init(&ssh_backend, NULL, &backend, conf, + err = backend_init(&ssh_backend, NULL, &backend, logctx, conf, conf_get_str(conf, CONF_host), conf_get_int(conf, CONF_port), &realhost, 0, @@ -2830,7 +2829,6 @@ static int psftp_connect(char *userhost, char *user, int portnumber) fprintf(stderr, "ssh_init: %s\n", err); return 1; } - backend_provide_logctx(backend, logctx); while (!backend_sendok(backend)) { if (backend_exitcode(backend) >= 0) return 1; @@ -2972,7 +2970,6 @@ int psftp_main(int argc, char *argv[]) do_sftp_cleanup(); random_save_seed(); cmdline_cleanup(); - console_provide_logctx(NULL); sk_cleanup(); return ret; diff --git a/putty.h b/putty.h index 242bfa67..f1d78473 100644 --- a/putty.h +++ b/putty.h @@ -480,7 +480,8 @@ struct Backend { }; struct BackendVtable { const char *(*init) (Frontend *frontend, Backend **backend_out, - Conf *conf, const char *host, int port, + LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, int nodelay, int keepalive); void (*free) (Backend *be); @@ -501,7 +502,6 @@ struct BackendVtable { int (*sendok) (Backend *be); int (*ldisc_option_state) (Backend *be, int); void (*provide_ldisc) (Backend *be, Ldisc *ldisc); - void (*provide_logctx) (Backend *be, LogContext *logctx); /* Tells the back end that the front end buffer is clearing. */ void (*unthrottle) (Backend *be, int bufsize); int (*cfg_info) (Backend *be); @@ -515,8 +515,8 @@ struct BackendVtable { int default_port; }; -#define backend_init(vt, fe, out, conf, host, port, rhost, nd, ka) \ - ((vt)->init(fe, out, conf, host, port, rhost, nd, ka)) +#define backend_init(vt, fe, out, logctx, conf, host, port, rhost, nd, ka) \ + ((vt)->init(fe, out, logctx, conf, host, port, rhost, nd, ka)) #define backend_free(be) ((be)->vt->free(be)) #define backend_reconfig(be, conf) ((be)->vt->reconfig(be, conf)) #define backend_send(be, buf, len) ((be)->vt->send(be, buf, len)) @@ -530,8 +530,6 @@ struct BackendVtable { #define backend_ldisc_option_state(be, opt) \ ((be)->vt->ldisc_option_state(be, opt)) #define backend_provide_ldisc(be, ldisc) ((be)->vt->provide_ldisc(be, ldisc)) -#define backend_provide_logctx(be, logctx) \ - ((be)->vt->provide_logctx(be, logctx)) #define backend_unthrottle(be, bufsize) ((be)->vt->unthrottle(be, bufsize)) #define backend_cfg_info(be) ((be)->vt->cfg_info(be)) @@ -1170,14 +1168,64 @@ int format_arrow_key(char *buf, Terminal *term, int xkey, int ctrl); /* * Exports from logging.c. */ -LogContext *log_init(Frontend *frontend, Conf *conf); +struct LogPolicyVtable { + /* + * Pass Event Log entries on from LogContext to the front end, + * which might write them to standard error or save them for a GUI + * list box or other things. + */ + void (*eventlog)(LogPolicy *lp, const char *event); + + /* + * Ask what to do about the specified output log file already + * existing. Can return four values: + * + * - 2 means overwrite the log file + * - 1 means append to the log file + * - 0 means cancel logging for this session + * - -1 means please wait, and callback() will be called with one + * of those options. + */ + int (*askappend)(LogPolicy *lp, Filename *filename, + void (*callback)(void *ctx, int result), void *ctx); + + /* + * Emergency logging when the log file itself can't be opened, + * which typically means we want to shout about it more loudly + * than a mere Event Log entry. + * + * One reasonable option is to send it to the same place that + * stderr output from the main session goes (so, either a console + * tool's actual stderr, or a terminal window). In many cases this + * is unlikely to cause this error message to turn up + * embarrassingly in a log file of real server output, because the + * whole point is that we haven't managed to open any such log + * file :-) + */ + void (*logging_error)(LogPolicy *lp, const char *event); +}; +struct LogPolicy { + const LogPolicyVtable *vt; +}; +#define lp_eventlog(lp, event) ((lp)->vt->eventlog(lp, event)) +#define lp_askappend(lp, fn, cb, ctx) ((lp)->vt->askappend(lp, fn, cb, ctx)) +#define lp_logging_error(lp, event) ((lp)->vt->logging_error(lp, event)) + +LogContext *log_init(LogPolicy *lp, Conf *conf); void log_free(LogContext *logctx); void log_reconfig(LogContext *logctx, Conf *conf); void logfopen(LogContext *logctx); void logfclose(LogContext *logctx); void logtraffic(LogContext *logctx, unsigned char c, int logmode); void logflush(LogContext *logctx); -void log_eventlog(LogContext *logctx, const char *string); +void logevent(LogContext *logctx, const char *event); +void logeventf(LogContext *logctx, const char *fmt, ...); +/* + * Pass a dynamically allocated string to logevent and immediately + * free it. Intended for use by wrapper macros which pass the return + * value of dupprintf straight to this. + */ +void logevent_and_free(LogContext *logctx, char *event); enum { PKT_INCOMING, PKT_OUTGOING }; enum { PKTLOG_EMIT, PKTLOG_BLANK, PKTLOG_OMIT }; struct logblank_t { @@ -1191,6 +1239,10 @@ void log_packet(LogContext *logctx, int direction, int type, const unsigned long *sequence, unsigned downstream_id, const char *additional_log_text); +/* This is defined by applications that have an obvious logging + * destination like standard error or the GUI. */ +extern LogPolicy default_logpolicy[1]; + /* * Exports from testback.c */ @@ -1352,7 +1404,6 @@ int wc_unescape(char *output, const char *wildcard); /* * Exports from frontend (windlg.c etc) */ -void logevent(Frontend *frontend, const char *); void pgp_fingerprints(void); /* * verify_ssh_host_key() can return one of three values: @@ -1386,16 +1437,6 @@ int askalg(Frontend *frontend, const char *algtype, const char *algname, void (*callback)(void *ctx, int result), void *ctx); int askhk(Frontend *frontend, const char *algname, const char *betteralgs, void (*callback)(void *ctx, int result), void *ctx); -/* - * askappend can return four values: - * - * - 2 means overwrite the log file - * - 1 means append to the log file - * - 0 means cancel logging for this session - * - -1 means please wait. - */ -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx); /* * Exports from console frontends (wincons.c, uxcons.c) @@ -1403,7 +1444,6 @@ int askappend(Frontend *frontend, Filename *filename, */ extern int console_batch_mode; int console_get_userpass_input(prompts_t *p); -void console_provide_logctx(LogContext *logctx); int is_interactive(void); /* diff --git a/raw.c b/raw.c index e5db12f9..09cdb1d3 100644 --- a/raw.c +++ b/raw.c @@ -16,6 +16,7 @@ struct Raw { int closed_on_socket_error; int bufsize; Frontend *frontend; + LogContext *logctx; int sent_console_eof, sent_socket_eof, session_started; Conf *conf; @@ -36,7 +37,7 @@ static void raw_log(Plug *plug, int type, SockAddr *addr, int port, const char *error_msg, int error_code) { Raw *raw = container_of(plug, Raw, plug); - backend_socket_log(raw->frontend, type, addr, port, + backend_socket_log(raw->frontend, raw->logctx, type, addr, port, error_msg, error_code, raw->conf, raw->session_started); } @@ -68,7 +69,7 @@ static void raw_closing(Plug *plug, const char *error_msg, int error_code, raw->closed_on_socket_error = TRUE; notify_remote_exit(raw->frontend); } - logevent(raw->frontend, error_msg); + logevent(raw->logctx, error_msg); connection_fatal(raw->frontend, "%s", error_msg); } else { /* Otherwise, the remote side closed the connection normally. */ @@ -119,7 +120,7 @@ static const PlugVtable Raw_plugvt = { * freed by the caller. */ static const char *raw_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, + LogContext *logctx, Conf *conf, const char *host, int port, char **realhost, int nodelay, int keepalive) { @@ -141,13 +142,14 @@ static const char *raw_init(Frontend *frontend, Backend **backend_handle, raw->conf = conf_copy(conf); raw->frontend = frontend; + raw->logctx = logctx; addressfamily = conf_get_int(conf, CONF_addressfamily); /* * Try to find host. */ addr = name_lookup(host, port, realhost, conf, addressfamily, - raw->frontend, "main connection"); + raw->logctx, "main connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); return err; @@ -282,11 +284,6 @@ static void raw_provide_ldisc(Backend *be, Ldisc *ldisc) /* This is a stub. */ } -static void raw_provide_logctx(Backend *be, LogContext *logctx) -{ - /* This is a stub. */ -} - static int raw_exitcode(Backend *be) { Raw *raw = container_of(be, Raw, backend); @@ -321,7 +318,6 @@ const struct BackendVtable raw_backend = { raw_sendok, raw_ldisc, raw_provide_ldisc, - raw_provide_logctx, raw_unthrottle, raw_cfg_info, NULL /* test_for_upstream */, diff --git a/rlogin.c b/rlogin.c index e982552b..34232c83 100644 --- a/rlogin.c +++ b/rlogin.c @@ -20,6 +20,7 @@ struct Rlogin { int cansize; int term_width, term_height; Frontend *frontend; + LogContext *logctx; Conf *conf; @@ -40,7 +41,7 @@ static void rlogin_log(Plug *plug, int type, SockAddr *addr, int port, const char *error_msg, int error_code) { Rlogin *rlogin = container_of(plug, Rlogin, plug); - backend_socket_log(rlogin->frontend, type, addr, port, + backend_socket_log(rlogin->frontend, rlogin->logctx, type, addr, port, error_msg, error_code, rlogin->conf, !rlogin->firstbyte); } @@ -65,7 +66,7 @@ static void rlogin_closing(Plug *plug, const char *error_msg, int error_code, } if (error_msg) { /* A socket error has occurred. */ - logevent(rlogin->frontend, error_msg); + logevent(rlogin->logctx, error_msg); connection_fatal(rlogin->frontend, "%s", error_msg); } /* Otherwise, the remote side closed the connection normally. */ } @@ -150,7 +151,7 @@ static const PlugVtable Rlogin_plugvt = { * freed by the caller. */ static const char *rlogin_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, + LogContext *logctx, Conf *conf, const char *host, int port, char **realhost, int nodelay, int keepalive) { @@ -167,6 +168,7 @@ static const char *rlogin_init(Frontend *frontend, Backend **backend_handle, rlogin->s = NULL; rlogin->closed_on_socket_error = FALSE; rlogin->frontend = frontend; + rlogin->logctx = logctx; rlogin->term_width = conf_get_int(conf, CONF_width); rlogin->term_height = conf_get_int(conf, CONF_height); rlogin->firstbyte = 1; @@ -180,7 +182,7 @@ static const char *rlogin_init(Frontend *frontend, Backend **backend_handle, * Try to find host. */ addr = name_lookup(host, port, realhost, conf, addressfamily, - rlogin->frontend, "rlogin connection"); + rlogin->logctx, "rlogin connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); return err; @@ -373,11 +375,6 @@ static void rlogin_provide_ldisc(Backend *be, Ldisc *ldisc) /* This is a stub. */ } -static void rlogin_provide_logctx(Backend *be, LogContext *logctx) -{ - /* This is a stub. */ -} - static int rlogin_exitcode(Backend *be) { Rlogin *rlogin = container_of(be, Rlogin, backend); @@ -412,7 +409,6 @@ const struct BackendVtable rlogin_backend = { rlogin_sendok, rlogin_ldisc, rlogin_provide_ldisc, - rlogin_provide_logctx, rlogin_unthrottle, rlogin_cfg_info, NULL /* test_for_upstream */, diff --git a/ssh.c b/ssh.c index 0119d236..69927b65 100644 --- a/ssh.c +++ b/ssh.c @@ -114,15 +114,15 @@ struct Ssh { #define ssh_logevent(params) ( \ - logevent_and_free((ssh)->frontend, dupprintf params)) + logevent_and_free((ssh)->logctx, dupprintf params)) static void ssh_shutdown(Ssh *ssh); static void ssh_throttle_all(Ssh *ssh, int enable, int bufsize); static void ssh_bpp_output_raw_data_callback(void *vctx); -Frontend *ssh_get_frontend(Ssh *ssh) +LogContext *ssh_get_logctx(Ssh *ssh) { - return ssh->frontend; + return ssh->logctx; } static void ssh_connect_bpp(Ssh *ssh) @@ -179,7 +179,7 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv, int is_simple = (conf_get_int(ssh->conf, CONF_ssh_simple) && !ssh->connshare); - ssh->bpp = ssh2_bpp_new(ssh->frontend, &ssh->stats); + ssh->bpp = ssh2_bpp_new(ssh->logctx, &ssh->stats); ssh_connect_bpp(ssh); #ifndef NO_GSSAPI @@ -254,7 +254,7 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv, } else { - ssh->bpp = ssh1_bpp_new(ssh->frontend); + ssh->bpp = ssh1_bpp_new(ssh->logctx); ssh_connect_bpp(ssh); connection_layer = ssh1_connection_new(ssh, ssh->conf, &ssh->cl); @@ -267,7 +267,7 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv, } } else { - ssh->bpp = ssh2_bare_bpp_new(ssh->frontend); + ssh->bpp = ssh2_bare_bpp_new(ssh->logctx); ssh_connect_bpp(ssh); connection_layer = ssh2_connection_new( @@ -407,7 +407,7 @@ void ssh_remote_error(Ssh *ssh, const char *fmt, ...) * closed its end (or is about to). */ ssh_shutdown(ssh); - logevent(ssh->frontend, msg); + logevent(ssh->logctx, msg); connection_fatal(ssh->frontend, "%s", msg); sfree(msg); } @@ -426,7 +426,7 @@ void ssh_remote_eof(Ssh *ssh, const char *fmt, ...) * closed its end. */ ssh_shutdown(ssh); - logevent(ssh->frontend, msg); + logevent(ssh->logctx, msg); sfree(msg); notify_remote_exit(ssh->frontend); } else { @@ -447,7 +447,7 @@ void ssh_proto_error(Ssh *ssh, const char *fmt, ...) SSH2_DISCONNECT_PROTOCOL_ERROR); ssh_initiate_connection_close(ssh); - logevent(ssh->frontend, msg); + logevent(ssh->logctx, msg); connection_fatal(ssh->frontend, "%s", msg); sfree(msg); } @@ -462,7 +462,7 @@ void ssh_sw_abort(Ssh *ssh, const char *fmt, ...) ssh_initiate_connection_close(ssh); - logevent(ssh->frontend, msg); + logevent(ssh->logctx, msg); connection_fatal(ssh->frontend, "%s", msg); sfree(msg); @@ -486,7 +486,7 @@ void ssh_user_close(Ssh *ssh, const char *fmt, ...) ssh_initiate_connection_close(ssh); - logevent(ssh->frontend, msg); + logevent(ssh->logctx, msg); sfree(msg); notify_remote_exit(ssh->frontend); @@ -508,7 +508,7 @@ static void ssh_socket_log(Plug *plug, int type, SockAddr *addr, int port, */ if (!ssh->attempting_connshare) - backend_socket_log(ssh->frontend, type, addr, port, + backend_socket_log(ssh->frontend, ssh->logctx, type, addr, port, error_msg, error_code, ssh->conf, ssh->session_started); } @@ -645,7 +645,7 @@ static const char *connect_to_host(Ssh *ssh, const char *host, int port, ssh->connshare = NULL; ssh->attempting_connshare = TRUE; /* affects socket logging behaviour */ ssh->s = ssh_connection_sharing_init( - ssh->savedhost, ssh->savedport, ssh->conf, ssh->frontend, + ssh->savedhost, ssh->savedport, ssh->conf, ssh->logctx, &ssh->plug, &ssh->connshare); if (ssh->connshare) ssh_connshare_provide_connlayer(ssh->connshare, &ssh->cl_dummy); @@ -677,7 +677,7 @@ static const char *connect_to_host(Ssh *ssh, const char *host, int port, */ addressfamily = conf_get_int(ssh->conf, CONF_addressfamily); addr = name_lookup(host, port, realhost, ssh->conf, addressfamily, - ssh->frontend, "SSH connection"); + ssh->logctx, "SSH connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); return err; @@ -715,7 +715,7 @@ static const char *connect_to_host(Ssh *ssh, const char *host, int port, */ ssh->version_receiver.got_ssh_version = ssh_got_ssh_version; ssh->bpp = ssh_verstring_new( - ssh->conf, ssh->frontend, ssh->bare_connection, + ssh->conf, ssh->logctx, ssh->bare_connection, ssh->version == 1 ? "1.5" : "2.0", &ssh->version_receiver); ssh_connect_bpp(ssh); queue_idempotent_callback(&ssh->bpp->ic_in_raw); @@ -789,7 +789,7 @@ static void ssh_cache_conf_values(Ssh *ssh) * Returns an error message, or NULL on success. */ static const char *ssh_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, + LogContext *logctx, Conf *conf, const char *host, int port, char **realhost, int nodelay, int keepalive) { @@ -814,7 +814,7 @@ static const char *ssh_init(Frontend *frontend, Backend **backend_handle, *backend_handle = &ssh->backend; ssh->frontend = frontend; - ssh->cl_dummy.frontend = frontend; + ssh->cl_dummy.logctx = ssh->logctx = logctx; random_ref(); /* do this now - may be needed by sharing setup code */ ssh->need_random_unref = TRUE; @@ -1045,12 +1045,6 @@ static void ssh_provide_ldisc(Backend *be, Ldisc *ldisc) ssh->ldisc = ldisc; } -static void ssh_provide_logctx(Backend *be, LogContext *logctx) -{ - Ssh *ssh = container_of(be, Ssh, backend); - ssh->logctx = logctx; -} - void ssh_got_exitcode(Ssh *ssh, int exitcode) { ssh->exitcode = exitcode; @@ -1111,7 +1105,6 @@ const struct BackendVtable ssh_backend = { ssh_sendok, ssh_ldisc, ssh_provide_ldisc, - ssh_provide_logctx, ssh_unthrottle, ssh_cfg_info, ssh_test_for_upstream, diff --git a/ssh.h b/ssh.h index 3e14aa4c..ea0d6c75 100644 --- a/ssh.h +++ b/ssh.h @@ -163,8 +163,8 @@ int ssh2_censor_packet( PktOut *ssh_new_packet(void); void ssh_free_pktout(PktOut *pkt); -extern Socket *ssh_connection_sharing_init( - const char *host, int port, Conf *conf, Frontend *frontend, +Socket *ssh_connection_sharing_init( + const char *host, int port, Conf *conf, LogContext *logctx, Plug *sshplug, ssh_sharing_state **state); void ssh_connshare_provide_connlayer(ssh_sharing_state *sharestate, ConnectionLayer *cl); @@ -266,7 +266,7 @@ struct ConnectionLayerVtable { }; struct ConnectionLayer { - Frontend *frontend; + LogContext *logctx; const struct ConnectionLayerVtable *vt; }; @@ -309,7 +309,7 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret, char *hostname, int port, SshChannel *c, int addressfamily); -Frontend *ssh_get_frontend(Ssh *ssh); +LogContext *ssh_get_logctx(Ssh *ssh); /* Communications back to ssh.c from connection layers */ void ssh_throttle_conn(Ssh *ssh, int adjust); diff --git a/ssh1bpp.c b/ssh1bpp.c index 33482a2c..9ec22ce1 100644 --- a/ssh1bpp.c +++ b/ssh1bpp.c @@ -43,12 +43,12 @@ static const struct BinaryPacketProtocolVtable ssh1_bpp_vtable = { ssh1_bpp_queue_disconnect, }; -BinaryPacketProtocol *ssh1_bpp_new(Frontend *frontend) +BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx) { struct ssh1_bpp_state *s = snew(struct ssh1_bpp_state); memset(s, 0, sizeof(*s)); s->bpp.vt = &ssh1_bpp_vtable; - s->bpp.frontend = frontend; + s->bpp.logctx = logctx; ssh_bpp_common_setup(&s->bpp); return &s->bpp; } @@ -68,9 +68,6 @@ static void ssh1_bpp_free(BinaryPacketProtocol *bpp) sfree(s); } -#define bpp_logevent(printf_args) \ - logevent_and_free(s->bpp.frontend, dupprintf printf_args) - void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp, const struct ssh1_cipheralg *cipher, const void *session_key) diff --git a/ssh1connection.c b/ssh1connection.c index 07105176..e89e87f4 100644 --- a/ssh1connection.c +++ b/ssh1connection.c @@ -260,11 +260,11 @@ PacketProtocolLayer *ssh1_connection_new( s->x11authtree = newtree234(x11_authcmp); - /* Need to get the frontend for s->cl now, because we won't be + /* Need to get the log context for s->cl now, because we won't be * helpfully notified when a copy is written into s->ppl by our * owner. */ s->cl.vt = &ssh1_connlayer_vtable; - s->cl.frontend = ssh_get_frontend(ssh); + s->cl.logctx = ssh_get_logctx(ssh); s->portfwdmgr = portfwdmgr_new(&s->cl); s->rportfwds = newtree234(ssh1_rportfwd_cmp); diff --git a/ssh2bpp-bare.c b/ssh2bpp-bare.c index e7c8f8ca..7d3cfed9 100644 --- a/ssh2bpp-bare.c +++ b/ssh2bpp-bare.c @@ -33,12 +33,12 @@ static const struct BinaryPacketProtocolVtable ssh2_bare_bpp_vtable = { ssh2_bpp_queue_disconnect, /* in sshcommon.c */ }; -BinaryPacketProtocol *ssh2_bare_bpp_new(Frontend *frontend) +BinaryPacketProtocol *ssh2_bare_bpp_new(LogContext *logctx) { struct ssh2_bare_bpp_state *s = snew(struct ssh2_bare_bpp_state); memset(s, 0, sizeof(*s)); s->bpp.vt = &ssh2_bare_bpp_vtable; - s->bpp.frontend = frontend; + s->bpp.logctx = logctx; ssh_bpp_common_setup(&s->bpp); return &s->bpp; } diff --git a/ssh2bpp.c b/ssh2bpp.c index c837194a..5b088676 100644 --- a/ssh2bpp.c +++ b/ssh2bpp.c @@ -54,12 +54,12 @@ static const struct BinaryPacketProtocolVtable ssh2_bpp_vtable = { }; BinaryPacketProtocol *ssh2_bpp_new( - Frontend *frontend, struct DataTransferStats *stats) + LogContext *logctx, struct DataTransferStats *stats) { struct ssh2_bpp_state *s = snew(struct ssh2_bpp_state); memset(s, 0, sizeof(*s)); s->bpp.vt = &ssh2_bpp_vtable; - s->bpp.frontend = frontend; + s->bpp.logctx = logctx; s->stats = stats; ssh_bpp_common_setup(&s->bpp); return &s->bpp; @@ -85,9 +85,6 @@ static void ssh2_bpp_free(BinaryPacketProtocol *bpp) sfree(s); } -#define bpp_logevent(printf_args) \ - logevent_and_free(s->bpp.frontend, dupprintf printf_args) - void ssh2_bpp_new_outgoing_crypto( BinaryPacketProtocol *bpp, const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv, diff --git a/ssh2connection.c b/ssh2connection.c index e51d221f..16996d43 100644 --- a/ssh2connection.c +++ b/ssh2connection.c @@ -388,11 +388,11 @@ PacketProtocolLayer *ssh2_connection_new( s->x11authtree = newtree234(x11_authcmp); - /* Need to get the frontend for s->cl now, because we won't be + /* Need to get the log context for s->cl now, because we won't be * helpfully notified when a copy is written into s->ppl by our * owner. */ s->cl.vt = &ssh2_connlayer_vtable; - s->cl.frontend = ssh_get_frontend(ssh); + s->cl.logctx = ssh_get_logctx(ssh); s->portfwdmgr = portfwdmgr_new(&s->cl); s->rportfwds = newtree234(ssh2_rportfwd_cmp); diff --git a/sshbpp.h b/sshbpp.h index e5de4dbc..dc1b995d 100644 --- a/sshbpp.h +++ b/sshbpp.h @@ -23,7 +23,6 @@ struct BinaryPacketProtocol { PacketLogSettings *pls; LogContext *logctx; Ssh *ssh; - Frontend *frontend; /* ic_in_raw is filled in by the BPP (probably by calling * ssh_bpp_common_setup). The BPP's owner triggers it when data is @@ -53,7 +52,7 @@ struct BinaryPacketProtocol { * does centralised parts of the freeing too. */ void ssh_bpp_free(BinaryPacketProtocol *bpp); -BinaryPacketProtocol *ssh1_bpp_new(Frontend *frontend); +BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx); void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp, const struct ssh1_cipheralg *cipher, const void *session_key); @@ -72,6 +71,13 @@ void ssh2_bpp_queue_disconnect(BinaryPacketProtocol *bpp, const char *msg, int category); int ssh2_bpp_check_unimplemented(BinaryPacketProtocol *bpp, PktIn *pktin); +/* Convenience macro for BPPs to send formatted strings to the Event + * Log. Assumes a function parameter called 'bpp' is in scope, and + * takes a double pair of parens because it passes a whole argument + * list to dupprintf. */ +#define bpp_logevent(params) ( \ + logevent_and_free((bpp)->logctx, dupprintf params)) + /* * Structure that tracks how much data is sent and received, for * purposes of triggering an SSH-2 rekey when either one gets over a @@ -98,7 +104,7 @@ struct DataTransferStats { ((stats)->direction.remaining -= (size), FALSE)) BinaryPacketProtocol *ssh2_bpp_new( - Frontend *frontend, struct DataTransferStats *stats); + LogContext *logctx, struct DataTransferStats *stats); void ssh2_bpp_new_outgoing_crypto( BinaryPacketProtocol *bpp, const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv, @@ -121,7 +127,7 @@ void ssh2_bpp_new_incoming_crypto( */ int ssh2_bpp_rekey_inadvisable(BinaryPacketProtocol *bpp); -BinaryPacketProtocol *ssh2_bare_bpp_new(Frontend *frontend); +BinaryPacketProtocol *ssh2_bare_bpp_new(LogContext *logctx); /* * The initial code to handle the SSH version exchange is also @@ -134,7 +140,7 @@ struct ssh_version_receiver { int major_version); }; BinaryPacketProtocol *ssh_verstring_new( - Conf *conf, Frontend *frontend, int bare_connection_mode, + Conf *conf, LogContext *logctx, int bare_connection_mode, const char *protoversion, struct ssh_version_receiver *rcv); const char *ssh_verstring_get_remote(BinaryPacketProtocol *); const char *ssh_verstring_get_local(BinaryPacketProtocol *); diff --git a/sshcommon.c b/sshcommon.c index 7679c5bd..16cf9310 100644 --- a/sshcommon.c +++ b/sshcommon.c @@ -638,12 +638,6 @@ const char *ssh2_pkt_type(Pkt_KCtx pkt_kctx, Pkt_ACtx pkt_actx, int type) * PacketProtocolLayer. */ -void ssh_logevent_and_free(void *frontend, char *message) -{ - logevent(frontend, message); - sfree(message); -} - void ssh_ppl_replace(PacketProtocolLayer *old, PacketProtocolLayer *new) { new->bpp = old->bpp; diff --git a/sshppl.h b/sshppl.h index f139263d..f637b0e0 100644 --- a/sshppl.h +++ b/sshppl.h @@ -53,7 +53,8 @@ struct PacketProtocolLayer { bufchain *user_input; /* Logging and error-reporting facilities. */ - void *frontend; /* for logevent, dialog boxes etc */ + LogContext *logctx; + void *frontend; /* for dialog boxes etc */ Ssh *ssh; /* for session termination + assorted connection-layer ops */ /* Known bugs in the remote implementation. */ @@ -122,7 +123,7 @@ void ssh2_userauth_set_transport_layer(PacketProtocolLayer *userauth, * scope, and takes a double pair of parens because it passes a whole * argument list to dupprintf. */ #define ppl_logevent(params) ( \ - logevent_and_free((ppl)->frontend, dupprintf params)) + logevent_and_free((ppl)->logctx, dupprintf params)) /* Convenience macro for protocol layers to send formatted strings to * the terminal. Also expects 'ppl' to be in scope and takes double diff --git a/sshshare.c b/sshshare.c index 688f73b2..b3e5b65d 100644 --- a/sshshare.c +++ b/sshshare.c @@ -703,18 +703,6 @@ static void share_remove_forwarding(struct ssh_sharing_connstate *cs, sfree(fwd); } -static void logeventf(Frontend *frontend, const char *fmt, ...) -{ - va_list ap; - char *buf; - - va_start(ap, fmt); - buf = dupvprintf(fmt, ap); - va_end(ap); - logevent(frontend, buf); - sfree(buf); -} - static void log_downstream(struct ssh_sharing_connstate *cs, const char *logfmt, ...) { @@ -724,7 +712,7 @@ static void log_downstream(struct ssh_sharing_connstate *cs, va_start(ap, logfmt); buf = dupvprintf(logfmt, ap); va_end(ap); - logeventf(cs->parent->cl->frontend, + logeventf(cs->parent->cl->logctx, "Connection sharing downstream #%u: %s", cs->id, buf); sfree(buf); } @@ -738,7 +726,7 @@ static void log_general(struct ssh_sharing_state *sharestate, va_start(ap, logfmt); buf = dupvprintf(logfmt, ap); va_end(ap); - logeventf(sharestate->cl->frontend, "Connection sharing: %s", buf); + logeventf(sharestate->cl->logctx, "Connection sharing: %s", buf); sfree(buf); } @@ -2080,7 +2068,7 @@ void ssh_connshare_provide_connlayer(ssh_sharing_state *sharestate, * upstream) we return NULL. */ Socket *ssh_connection_sharing_init( - const char *host, int port, Conf *conf, Frontend *frontend, + const char *host, int port, Conf *conf, LogContext *logctx, Plug *sshplug, ssh_sharing_state **state) { int result, can_upstream, can_downstream; @@ -2133,16 +2121,16 @@ Socket *ssh_connection_sharing_init( /* For this result, if 'logtext' is not NULL then it is an * error message indicating a reason why connection sharing * couldn't be set up _at all_ */ - logeventf(frontend, + logeventf(logctx, "Could not set up connection sharing: %s", logtext); } else { /* Failing that, ds_err and us_err indicate why we * couldn't be a downstream and an upstream respectively */ if (ds_err) - logeventf(frontend, "Could not set up connection sharing" + logeventf(logctx, "Could not set up connection sharing" " as downstream: %s", ds_err); if (us_err) - logeventf(frontend, "Could not set up connection sharing" + logeventf(logctx, "Could not set up connection sharing" " as upstream: %s", us_err); } @@ -2160,8 +2148,7 @@ Socket *ssh_connection_sharing_init( */ /* 'logtext' is a local endpoint address */ - logeventf(frontend, - "Using existing shared connection at %s", logtext); + logeventf(logctx, "Using existing shared connection at %s", logtext); *state = NULL; sfree(sharestate); @@ -2177,7 +2164,7 @@ Socket *ssh_connection_sharing_init( */ /* 'logtext' is a local endpoint address */ - logeventf(frontend, "Sharing this connection at %s", logtext); + logeventf(logctx, "Sharing this connection at %s", logtext); *state = sharestate; sharestate->listensock = sock; diff --git a/sshverstring.c b/sshverstring.c index 68cee61c..c9412a2f 100644 --- a/sshverstring.c +++ b/sshverstring.c @@ -58,7 +58,7 @@ static int ssh_version_includes_v1(const char *ver); static int ssh_version_includes_v2(const char *ver); BinaryPacketProtocol *ssh_verstring_new( - Conf *conf, Frontend *frontend, int bare_connection_mode, + Conf *conf, LogContext *logctx, int bare_connection_mode, const char *protoversion, struct ssh_version_receiver *rcv) { struct ssh_verstring_state *s = snew(struct ssh_verstring_state); @@ -87,7 +87,7 @@ BinaryPacketProtocol *ssh_verstring_new( assert(s->prefix_wanted.len <= PREFIX_MAXLEN); s->conf = conf_copy(conf); - s->bpp.frontend = frontend; + s->bpp.logctx = logctx; s->our_protoversion = dupstr(protoversion); s->receiver = rcv; @@ -145,11 +145,9 @@ static int ssh_version_includes_v2(const char *ver) return ssh_versioncmp(ver, "1.99") >= 0; } -#define bpp_logevent(printf_args) \ - logevent_and_free(s->bpp.frontend, dupprintf printf_args) - static void ssh_verstring_send(struct ssh_verstring_state *s) { + BinaryPacketProtocol *bpp = &s->bpp; /* for bpp_logevent */ char *p; int sv_pos; @@ -421,6 +419,7 @@ static void ssh_verstring_handle_output(BinaryPacketProtocol *bpp) */ static void ssh_detect_bugs(struct ssh_verstring_state *s) { + BinaryPacketProtocol *bpp = &s->bpp; /* for bpp_logevent */ const char *imp = s->softwareversion; s->remote_bugs = 0; diff --git a/telnet.c b/telnet.c index fcaab876..76d8a943 100644 --- a/telnet.c +++ b/telnet.c @@ -174,6 +174,7 @@ struct Telnet { int closed_on_socket_error; Frontend *frontend; + LogContext *logctx; Ldisc *ldisc; int term_width, term_height; @@ -214,18 +215,15 @@ static void c_write(Telnet *telnet, const void *buf, int len) static void log_option(Telnet *telnet, const char *sender, int cmd, int option) { - char *buf; /* * The strange-looking "" below is there to avoid a * trigraph - a double question mark followed by > maps to a * closing brace character! */ - buf = dupprintf("%s:\t%s %s", sender, - (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" : - cmd == DO ? "DO" : cmd == DONT ? "DONT" : ""), - telopt(option)); - logevent(telnet->frontend, buf); - sfree(buf); + logeventf(telnet->logctx, "%s:\t%s %s", sender, + (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" : + cmd == DO ? "DO" : cmd == DONT ? "DONT" : ""), + telopt(option)); } static void send_opt(Telnet *telnet, int cmd, int option) @@ -366,7 +364,6 @@ static void process_subneg(Telnet *telnet) switch (telnet->sb_opt) { case TELOPT_TSPEED: if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) { - char *logbuf; char *termspeed = conf_get_str(telnet->conf, CONF_termspeed); b = snewn(20 + strlen(termspeed), unsigned char); b[0] = IAC; @@ -378,17 +375,14 @@ static void process_subneg(Telnet *telnet) b[n] = IAC; b[n + 1] = SE; telnet->bufsize = sk_write(telnet->s, b, n + 2); - logevent(telnet->frontend, "server:\tSB TSPEED SEND"); - logbuf = dupprintf("client:\tSB TSPEED IS %s", termspeed); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logevent(telnet->logctx, "server:\tSB TSPEED SEND"); + logeventf(telnet->logctx, "client:\tSB TSPEED IS %s", termspeed); sfree(b); } else - logevent(telnet->frontend, "server:\tSB TSPEED "); + logevent(telnet->logctx, "server:\tSB TSPEED "); break; case TELOPT_TTYPE: if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) { - char *logbuf; char *termtype = conf_get_str(telnet->conf, CONF_termtype); b = snewn(20 + strlen(termtype), unsigned char); b[0] = IAC; @@ -403,24 +397,20 @@ static void process_subneg(Telnet *telnet) b[n + 5] = SE; telnet->bufsize = sk_write(telnet->s, b, n + 6); b[n + 4] = 0; - logevent(telnet->frontend, "server:\tSB TTYPE SEND"); - logbuf = dupprintf("client:\tSB TTYPE IS %s", b + 4); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logevent(telnet->logctx, "server:\tSB TTYPE SEND"); + logeventf(telnet->logctx, "client:\tSB TTYPE IS %s", b + 4); sfree(b); } else - logevent(telnet->frontend, "server:\tSB TTYPE \r\n"); + logevent(telnet->logctx, "server:\tSB TTYPE \r\n"); break; case TELOPT_OLD_ENVIRON: case TELOPT_NEW_ENVIRON: p = telnet->sb_buf; q = p + telnet->sb_len; if (p < q && *p == TELQUAL_SEND) { - char *logbuf; p++; - logbuf = dupprintf("server:\tSB %s SEND", telopt(telnet->sb_opt)); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logeventf(telnet->logctx, "server:\tSB %s SEND", + telopt(telnet->sb_opt)); if (telnet->sb_opt == TELOPT_OLD_ENVIRON) { if (conf_get_int(telnet->conf, CONF_rfc_environ)) { value = RFC_VALUE; @@ -493,29 +483,20 @@ static void process_subneg(Telnet *telnet) b[n++] = SE; telnet->bufsize = sk_write(telnet->s, b, n); if (n == 6) { - logbuf = dupprintf("client:\tSB %s IS ", - telopt(telnet->sb_opt)); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logeventf(telnet->logctx, "client:\tSB %s IS ", + telopt(telnet->sb_opt)); } else { - logbuf = dupprintf("client:\tSB %s IS:", - telopt(telnet->sb_opt)); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logeventf(telnet->logctx, "client:\tSB %s IS:", + telopt(telnet->sb_opt)); for (eval = conf_get_str_strs(telnet->conf, CONF_environmt, NULL, &ekey); eval != NULL; eval = conf_get_str_strs(telnet->conf, CONF_environmt, ekey, &ekey)) { - logbuf = dupprintf("\t%s=%s", ekey, eval); - logevent(telnet->frontend, logbuf); - sfree(logbuf); - } - if (user) { - logbuf = dupprintf("\tUSER=%s", user); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logeventf(telnet->logctx, "\t%s=%s", ekey, eval); } + if (user) + logeventf(telnet->logctx, "\tUSER=%s", user); } sfree(b); sfree(user); @@ -646,7 +627,7 @@ static void telnet_log(Plug *plug, int type, SockAddr *addr, int port, const char *error_msg, int error_code) { Telnet *telnet = container_of(plug, Telnet, plug); - backend_socket_log(telnet->frontend, type, addr, port, + backend_socket_log(telnet->frontend, telnet->logctx, type, addr, port, error_msg, error_code, telnet->conf, telnet->session_started); } @@ -670,7 +651,7 @@ static void telnet_closing(Plug *plug, const char *error_msg, int error_code, notify_remote_exit(telnet->frontend); } if (error_msg) { - logevent(telnet->frontend, error_msg); + logevent(telnet->logctx, error_msg); connection_fatal(telnet->frontend, "%s", error_msg); } /* Otherwise, the remote side closed the connection normally. */ @@ -707,7 +688,8 @@ static const PlugVtable Telnet_plugvt = { * freed by the caller. */ static const char *telnet_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, const char *host, int port, + LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, int nodelay, int keepalive) { SockAddr *addr; @@ -728,6 +710,7 @@ static const char *telnet_init(Frontend *frontend, Backend **backend_handle, telnet->sb_buf = NULL; telnet->sb_size = 0; telnet->frontend = frontend; + telnet->logctx = logctx; telnet->term_width = conf_get_int(telnet->conf, CONF_width); telnet->term_height = conf_get_int(telnet->conf, CONF_height); telnet->state = TOP_LEVEL; @@ -741,7 +724,7 @@ static const char *telnet_init(Frontend *frontend, Backend **backend_handle, */ addressfamily = conf_get_int(telnet->conf, CONF_addressfamily); addr = name_lookup(host, port, realhost, telnet->conf, addressfamily, - telnet->frontend, "Telnet connection"); + telnet->logctx, "Telnet connection"); if ((err = sk_addr_error(addr)) != NULL) { sk_addr_free(addr); return err; @@ -884,7 +867,6 @@ static void telnet_size(Backend *be, int width, int height) Telnet *telnet = container_of(be, Telnet, backend); unsigned char b[24]; int n; - char *logbuf; telnet->term_width = width; telnet->term_height = height; @@ -906,10 +888,8 @@ static void telnet_size(Backend *be, int width, int height) b[n++] = IAC; b[n++] = SE; telnet->bufsize = sk_write(telnet->s, b, n); - logbuf = dupprintf("client:\tSB NAWS %d,%d", - telnet->term_width, telnet->term_height); - logevent(telnet->frontend, logbuf); - sfree(logbuf); + logeventf(telnet->logctx, "client:\tSB NAWS %d,%d", + telnet->term_width, telnet->term_height); } /* @@ -1054,11 +1034,6 @@ static void telnet_provide_ldisc(Backend *be, Ldisc *ldisc) telnet->ldisc = ldisc; } -static void telnet_provide_logctx(Backend *be, LogContext *logctx) -{ - /* This is a stub. */ -} - static int telnet_exitcode(Backend *be) { Telnet *telnet = container_of(be, Telnet, backend); @@ -1093,7 +1068,6 @@ const struct BackendVtable telnet_backend = { telnet_sendok, telnet_ldisc, telnet_provide_ldisc, - telnet_provide_logctx, telnet_unthrottle, telnet_cfg_info, NULL /* test_for_upstream */, diff --git a/testback.c b/testback.c index 16f6476e..6a89bfc5 100644 --- a/testback.c +++ b/testback.c @@ -50,21 +50,20 @@ static int null_exitcode(Backend *); static int null_sendok(Backend *); static int null_ldisc(Backend *, int); static void null_provide_ldisc(Backend *, Ldisc *); -static void null_provide_logctx(Backend *, LogContext *); static void null_unthrottle(Backend *, int); static int null_cfg_info(Backend *); const struct BackendVtable null_backend = { null_init, null_free, null_reconfig, null_send, null_sendbuffer, null_size, null_special, null_get_specials, null_connected, null_exitcode, null_sendok, - null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle, + null_ldisc, null_provide_ldisc, null_unthrottle, null_cfg_info, NULL /* test_for_upstream */, "null", -1, 0 }; const struct BackendVtable loop_backend = { loop_init, loop_free, null_reconfig, loop_send, null_sendbuffer, null_size, null_special, null_get_specials, null_connected, null_exitcode, null_sendok, - null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle, + null_ldisc, null_provide_ldisc, null_unthrottle, null_cfg_info, NULL /* test_for_upstream */, "loop", -1, 0 }; diff --git a/testbn.c b/testbn.c index 0abe4690..0bc555ee 100644 --- a/testbn.c +++ b/testbn.c @@ -32,7 +32,6 @@ int random_byte(void) return 0; } -void logevent(Frontend *frontend, const char *msg) { assert(0); } void queue_idempotent_callback(IdempotentCallback *ic) { assert(0); } #define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' ) diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index ccabe1e3..e9d2d6c4 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -4048,8 +4048,8 @@ void logevent_dlg(eventlog_stuff *es, const char *string) } } -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx) +int gtkdlg_askappend(Frontend *frontend, Filename *filename, + void (*callback)(void *ctx, int result), void *ctx) { static const char msgtemplate[] = "The session log file \"%.*s\" already exists. " diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 6ec5d639..9ff65c81 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -180,6 +180,8 @@ struct Frontend { #ifdef OSX_META_KEY_CONFIG int system_mod_mask; #endif + + LogPolicy logpolicy; }; static void cache_conf_values(Frontend *inst) @@ -336,13 +338,38 @@ int get_userpass_input(prompts_t *p, bufchain *input) return ret; } -void logevent(Frontend *inst, const char *string) +static void gtk_eventlog(LogPolicy *lp, const char *string) { - log_eventlog(inst->logctx, string); - + Frontend *inst = container_of(lp, Frontend, logpolicy); logevent_dlg(inst->eventlogstuff, string); } +static int gtk_askappend(LogPolicy *lp, Filename *filename, + void (*callback)(void *ctx, int result), void *ctx) +{ + Frontend *inst = container_of(lp, Frontend, logpolicy); + + int gtkdlg_askappend(Frontend *frontend, Filename *filename, + void (*callback)(void *ctx, int result), void *ctx); + return gtkdlg_askappend(inst, filename, callback, ctx); +} + +static void gtk_logging_error(LogPolicy *lp, const char *event) +{ + Frontend *inst = container_of(lp, Frontend, logpolicy); + + /* Send 'can't open log file' errors to the terminal window. + * (Marked as stderr, although terminal.c won't care.) */ + from_backend(inst, 1, event, strlen(event)); + from_backend(inst, 1, "\r\n", 2); +} + +static const LogPolicyVtable gtk_logpolicy_vt = { + gtk_eventlog, + gtk_askappend, + gtk_logging_error, +}; + int font_dimension(Frontend *inst, int which) /* 0 for width, 1 for height */ { if (which) @@ -4806,7 +4833,7 @@ void restart_session_menuitem(GtkMenuItem *item, gpointer data) Frontend *inst = (Frontend *)data; if (!inst->backend) { - logevent(inst, "----- Session restarted -----"); + logevent(inst->logctx, "----- Session restarted -----"); term_pwron(inst->term, FALSE); start_backend(inst); inst->exited = FALSE; @@ -5011,7 +5038,7 @@ static void start_backend(Frontend *inst) vt = select_backend(inst->conf); error = backend_init(vt, (void *)inst, &inst->backend, - inst->conf, + inst->logctx, inst->conf, conf_get_str(inst->conf, CONF_host), conf_get_int(inst->conf, CONF_port), &realhost, @@ -5037,8 +5064,6 @@ static void start_backend(Frontend *inst) } sfree(realhost); - backend_provide_logctx(inst->backend, inst->logctx); - term_provide_backend(inst->term, inst->backend); inst->ldisc = ldisc_create(inst->conf, inst->term, inst->backend, inst); @@ -5096,6 +5121,8 @@ void new_session_window(Conf *conf, const char *geometry_string) #endif inst->drawing_area_setup_needed = TRUE; + inst->logpolicy.vt = >k_logpolicy_vt; + #ifndef NOT_X_WINDOWS inst->disp = get_x11_display(); if (geometry_string) { @@ -5414,7 +5441,7 @@ void new_session_window(Conf *conf, const char *geometry_string) inst->term = term_init(inst->conf, &inst->ucsdata, inst); setup_clipboards(inst, inst->term, inst->conf); - inst->logctx = log_init(inst, inst->conf); + inst->logctx = log_init(&inst->logpolicy, inst->conf); term_provide_logctx(inst->term, inst->logctx); term_size(inst->term, inst->height, inst->width, diff --git a/unix/uxcons.c b/unix/uxcons.c index c476cbf8..4bcd293c 100644 --- a/unix/uxcons.c +++ b/unix/uxcons.c @@ -23,8 +23,6 @@ int console_batch_mode = FALSE; -static void *console_logctx = NULL; - static struct termios orig_termios_stderr; static int stderr_is_a_tty; @@ -327,8 +325,9 @@ int askhk(Frontend *frontend, const char *algname, const char *betteralgs, * Ask whether to wipe a session log file before writing to it. * Returns 2 for wipe, 1 for append, 0 for cancel (don't log). */ -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx) +static int console_askappend(LogPolicy *lp, Filename *filename, + void (*callback)(void *ctx, int result), + void *ctx) { static const char msgtemplate[] = "The session log file \"%.*s\" already exists.\n" @@ -405,22 +404,24 @@ void old_keyfile_warning(void) postmsg(&cf); } -void console_provide_logctx(LogContext *logctx) +static void console_logging_error(LogPolicy *lp, const char *string) { - console_logctx = logctx; + /* Errors setting up logging are considered important, so they're + * displayed to standard error even when not in verbose mode */ + struct termios cf; + premsg(&cf); + fprintf(stderr, "%s\n", string); + fflush(stderr); + postmsg(&cf); } -void logevent(Frontend *frontend, const char *string) + +static void console_eventlog(LogPolicy *lp, const char *string) { - struct termios cf; - if (flags & FLAG_VERBOSE) { - premsg(&cf); - fprintf(stderr, "%s\n", string); - fflush(stderr); - postmsg(&cf); - } - if (console_logctx) - log_eventlog(console_logctx, string); + /* Ordinary Event Log entries are displayed in the same way as + * logging errors, but only in verbose mode */ + if (flags & FLAG_VERBOSE) + console_logging_error(lp, string); } /* @@ -573,3 +574,10 @@ int is_interactive(void) char *platform_get_x_display(void) { return dupstr(getenv("DISPLAY")); } + +static const LogPolicyVtable default_logpolicy_vt = { + console_eventlog, + console_askappend, + console_logging_error, +}; +LogPolicy default_logpolicy[1] = {{ &default_logpolicy_vt }}; diff --git a/unix/uxpgnt.c b/unix/uxpgnt.c index 90a624a8..a3f2356e 100644 --- a/unix/uxpgnt.c +++ b/unix/uxpgnt.c @@ -92,7 +92,6 @@ int platform_default_i(const char *name, int def) { return def; } FontSpec *platform_default_fontspec(const char *name) { return fontspec_new(""); } Filename *platform_default_filename(const char *name) { return filename_from_str(""); } char *x_get_default(const char *key) { return NULL; } -void log_eventlog(LogContext *logctx, const char *event) {} int from_backend(Frontend *fe, int is_stderr, const void *data, int datalen) { assert(!"only here to satisfy notional call from backend_socket_log"); } diff --git a/unix/uxplink.c b/unix/uxplink.c index b1a2ef5d..c26fd43f 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -822,8 +822,7 @@ int main(int argc, char **argv) /* * Start up the connection. */ - logctx = log_init(NULL, conf); - console_provide_logctx(logctx); + logctx = log_init(default_logpolicy, conf); { const char *error; char *realhost; @@ -835,7 +834,7 @@ int main(int argc, char **argv) __AFL_INIT(); #endif - error = backend_init(backvt, NULL, &backend, conf, + error = backend_init(backvt, NULL, &backend, logctx, conf, conf_get_str(conf, CONF_host), conf_get_int(conf, CONF_port), &realhost, nodelay, @@ -844,7 +843,6 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to open connection:\n%s\n", error); return 1; } - backend_provide_logctx(backend, logctx); ldisc_create(conf, NULL, backend, NULL); sfree(realhost); } diff --git a/unix/uxpty.c b/unix/uxpty.c index e0951808..31f6b880 100644 --- a/unix/uxpty.c +++ b/unix/uxpty.c @@ -737,7 +737,8 @@ static void pty_uxsel_setup(Pty *pty) * freed by the caller. */ static const char *pty_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, const char *host, int port, + LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, int nodelay, int keepalive) { int slavefd; @@ -1219,12 +1220,6 @@ static void pty_provide_ldisc(Backend *be, Ldisc *ldisc) /* This is a stub. */ } -static void pty_provide_logctx(Backend *be, LogContext *logctx) -{ - /* Pty *pty = container_of(be, Pty, backend); */ - /* This is a stub. */ -} - static int pty_exitcode(Backend *be) { Pty *pty = container_of(be, Pty, backend); @@ -1254,7 +1249,6 @@ const struct BackendVtable pty_backend = { pty_sendok, pty_ldisc, pty_provide_ldisc, - pty_provide_logctx, pty_unthrottle, pty_cfg_info, NULL /* test_for_upstream */, diff --git a/unix/uxser.c b/unix/uxser.c index 0b53d859..6c837625 100644 --- a/unix/uxser.c +++ b/unix/uxser.c @@ -20,6 +20,7 @@ typedef struct Serial Serial; struct Serial { Frontend *frontend; + LogContext *logctx; int fd; int finished; int inbufsize; @@ -67,7 +68,6 @@ static const char *serial_configure(Serial *serial, Conf *conf) struct termios options; int bflag, bval, speed, flow, parity; const char *str; - char *msg; if (serial->fd < 0) return "Unable to reconfigure already-closed serial connection"; @@ -181,9 +181,7 @@ static const char *serial_configure(Serial *serial, Conf *conf) #undef SETBAUD cfsetispeed(&options, bflag); cfsetospeed(&options, bflag); - msg = dupprintf("Configuring baud rate %d", bval); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring baud rate %d", bval); options.c_cflag &= ~CSIZE; switch (conf_get_int(conf, CONF_serdatabits)) { @@ -193,20 +191,16 @@ static const char *serial_configure(Serial *serial, Conf *conf) case 8: options.c_cflag |= CS8; break; default: return "Invalid number of data bits (need 5, 6, 7 or 8)"; } - msg = dupprintf("Configuring %d data bits", - conf_get_int(conf, CONF_serdatabits)); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %d data bits", + conf_get_int(conf, CONF_serdatabits)); if (conf_get_int(conf, CONF_serstopbits) >= 4) { options.c_cflag |= CSTOPB; } else { options.c_cflag &= ~CSTOPB; } - msg = dupprintf("Configuring %d stop bits", - (options.c_cflag & CSTOPB ? 2 : 1)); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %d stop bits", + (options.c_cflag & CSTOPB ? 2 : 1)); options.c_iflag &= ~(IXON|IXOFF); #ifdef CRTSCTS @@ -229,9 +223,7 @@ static const char *serial_configure(Serial *serial, Conf *conf) str = "RTS/CTS"; } else str = "no"; - msg = dupprintf("Configuring %s flow control", str); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %s flow control", str); /* Parity */ parity = conf_get_int(conf, CONF_serparity); @@ -247,9 +239,7 @@ static const char *serial_configure(Serial *serial, Conf *conf) options.c_cflag &= ~PARENB; str = "no"; } - msg = dupprintf("Configuring %s parity", str); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %s parity", str); options.c_cflag |= CLOCAL | CREAD; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); @@ -290,7 +280,7 @@ static const char *serial_configure(Serial *serial, Conf *conf) * freed by the caller. */ static const char *serial_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, + LogContext *logctx, Conf *conf, const char *host, int port, char **realhost, int nodelay, int keepalive) { @@ -303,16 +293,13 @@ static const char *serial_init(Frontend *frontend, Backend **backend_handle, *backend_handle = &serial->backend; serial->frontend = frontend; + serial->logctx = logctx; serial->finished = FALSE; serial->inbufsize = 0; bufchain_init(&serial->output_data); line = conf_get_str(conf, CONF_serline); - { - char *msg = dupprintf("Opening serial device %s", line); - logevent(serial->frontend, msg); - sfree(msg); - } + logeventf(serial->logctx, "Opening serial device %s", line); serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (serial->fd < 0) @@ -503,7 +490,7 @@ static void serial_special(Backend *be, SessionSpecialCode code, int arg) if (serial->fd >= 0 && code == SS_BRK) { tcsendbreak(serial->fd, 0); - logevent(serial->frontend, "Sending serial break at user request"); + logevent(serial->logctx, "Sending serial break at user request"); } return; @@ -552,11 +539,6 @@ static void serial_provide_ldisc(Backend *be, Ldisc *ldisc) /* This is a stub. */ } -static void serial_provide_logctx(Backend *be, LogContext *logctx) -{ - /* This is a stub. */ -} - static int serial_exitcode(Backend *be) { Serial *serial = container_of(be, Serial, backend); @@ -589,7 +571,6 @@ const struct BackendVtable serial_backend = { serial_sendok, serial_ldisc, serial_provide_ldisc, - serial_provide_logctx, serial_unthrottle, serial_cfg_info, NULL /* test_for_upstream */, diff --git a/windows/wincons.c b/windows/wincons.c index 7fb3e90b..e2296e23 100644 --- a/windows/wincons.c +++ b/windows/wincons.c @@ -13,8 +13,6 @@ int console_batch_mode = FALSE; -static void *console_logctx = NULL; - /* * Clean up and exit. */ @@ -247,8 +245,9 @@ int askhk(Frontend *frontend, const char *algname, const char *betteralgs, * Ask whether to wipe a session log file before writing to it. * Returns 2 for wipe, 1 for append, 0 for cancel (don't log). */ -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx) +static int console_askappend(LogPolicy *lp, Filename *filename, + void (*callback)(void *ctx, int result), + void *ctx) { HANDLE hin; DWORD savemode, i; @@ -335,18 +334,20 @@ void pgp_fingerprints(void) " " PGP_PREV_MASTER_KEY_FP "\n", stdout); } -void console_provide_logctx(LogContext *logctx) +static void console_logging_error(LogPolicy *lp, const char *string) { - console_logctx = logctx; + /* Ordinary Event Log entries are displayed in the same way as + * logging errors, but only in verbose mode */ + fprintf(stderr, "%s\n", string); + fflush(stderr); } -void logevent(Frontend *frontend, const char *string) +static void console_eventlog(LogPolicy *lp, const char *string) { - if (flags & FLAG_VERBOSE) { - fprintf(stderr, "%s\n", string); - fflush(stderr); - } - log_eventlog(console_logctx, string); + /* Ordinary Event Log entries are displayed in the same way as + * logging errors, but only in verbose mode */ + if (flags & FLAG_VERBOSE) + console_logging_error(lp, string); } static void console_data_untrusted(HANDLE hout, const char *data, int len) @@ -486,3 +487,10 @@ void frontend_keypress(Frontend *frontend) */ return; } + +static const LogPolicyVtable default_logpolicy_vt = { + console_eventlog, + console_askappend, + console_logging_error, +}; +LogPolicy default_logpolicy[1] = {{ &default_logpolicy_vt }}; diff --git a/windows/windlg.c b/windows/windlg.c index 05ddfdd2..d0843754 100644 --- a/windows/windlg.c +++ b/windows/windlg.c @@ -761,14 +761,12 @@ int do_reconfig(HWND hwnd, int protcfginfo) return ret; } -void logevent(Frontend *frontend, const char *string) +static void win_gui_eventlog(LogPolicy *lp, const char *string) { char timebuf[40]; char **location; struct tm tm; - log_eventlog(logctx, string); - tm=ltime(); strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", &tm); @@ -798,6 +796,14 @@ void logevent(Frontend *frontend, const char *string) } } +static void win_gui_logging_error(LogPolicy *lp, const char *event) +{ + /* Send 'can't open log file' errors to the terminal window. + * (Marked as stderr, although terminal.c won't care.) */ + from_backend(NULL, 1, event, strlen(event)); + from_backend(NULL, 1, "\r\n", 2); +} + void showeventlog(HWND hwnd) { if (!logbox) { @@ -953,8 +959,9 @@ int askhk(Frontend *frontend, const char *algname, const char *betteralgs, * Ask whether to wipe a session log file before writing to it. * Returns 2 for wipe, 1 for append, 0 for cancel (don't log). */ -int askappend(Frontend *frontend, Filename *filename, - void (*callback)(void *ctx, int result), void *ctx) +static int win_gui_askappend(LogPolicy *lp, Filename *filename, + void (*callback)(void *ctx, int result), + void *ctx) { static const char msgtemplate[] = "The session log file \"%.*s\" already exists.\n" @@ -986,6 +993,13 @@ int askappend(Frontend *frontend, Filename *filename, return 0; } +static const LogPolicyVtable default_logpolicy_vt = { + win_gui_eventlog, + win_gui_askappend, + win_gui_logging_error, +}; +LogPolicy default_logpolicy[1] = {{ &default_logpolicy_vt }}; + /* * Warn about the obsolescent key file format. * diff --git a/windows/window.c b/windows/window.c index 7bef7ee6..1c5cfc64 100644 --- a/windows/window.c +++ b/windows/window.c @@ -266,13 +266,12 @@ static void start_backend(void) cleanup_exit(1); } - error = backend_init(vt, NULL, &backend, conf, + error = backend_init(vt, NULL, &backend, logctx, conf, conf_get_str(conf, CONF_host), conf_get_int(conf, CONF_port), &realhost, conf_get_int(conf, CONF_tcp_nodelay), conf_get_int(conf, CONF_tcp_keepalives)); - backend_provide_logctx(backend, logctx); if (error) { char *str = dupprintf("%s Error", appname); sprintf(msg, "Unable to open connection to\n" @@ -635,7 +634,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) */ term = term_init(conf, &ucsdata, NULL); setup_clipboards(term, conf); - logctx = log_init(NULL, conf); + logctx = log_init(default_logpolicy, conf); term_provide_logctx(term, logctx); term_size(term, conf_get_int(conf, CONF_height), conf_get_int(conf, CONF_width), @@ -743,7 +742,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } if (restricted_acl) { - logevent(NULL, "Running with restricted process ACL"); + lp_eventlog(default_logpolicy, "Running with restricted process ACL"); } start_backend(); @@ -2162,7 +2161,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; case IDM_RESTART: if (!backend) { - logevent(NULL, "----- Session restarted -----"); + lp_eventlog(default_logpolicy, + "----- Session restarted -----"); term_pwron(term, FALSE); start_backend(); } diff --git a/windows/winnet.c b/windows/winnet.c index 458ee4ec..0ddb62d4 100644 --- a/windows/winnet.c +++ b/windows/winnet.c @@ -220,13 +220,6 @@ int sk_startup(int hi, int lo) return FALSE; } -#ifdef NET_SETUP_DIAGNOSTICS - { - char buf[80]; - sprintf(buf, "Using WinSock %d.%d", hi, lo); - logevent(NULL, buf); - } -#endif return TRUE; } @@ -252,9 +245,6 @@ void sk_init(void) #ifndef NO_IPV6 /* Check if we have getaddrinfo in Winsock */ if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) { -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "Native WinSock IPv6 support detected"); -#endif GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, getnameinfo); @@ -266,25 +256,15 @@ void sk_init(void) /* Fall back to wship6.dll for Windows 2000 */ wship6_module = load_system32_dll("wship6.dll"); if (wship6_module) { -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "WSH IPv6 support detected"); -#endif GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, getnameinfo); /* See comment above about type check */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror); } else { -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "No IPv6 support detected"); -#endif } } GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA); -#else -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "PuTTY was built without IPv6 support"); -#endif #endif GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect); @@ -559,9 +539,6 @@ SockAddr *sk_namelookup(const char *host, char **canonicalname, */ if (p_getaddrinfo) { struct addrinfo hints; -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "Using getaddrinfo() for resolving"); -#endif memset(&hints, 0, sizeof(hints)); hints.ai_family = hint_family; hints.ai_flags = AI_CANONNAME; @@ -576,9 +553,6 @@ SockAddr *sk_namelookup(const char *host, char **canonicalname, } else #endif { -#ifdef NET_SETUP_DIAGNOSTICS - logevent(NULL, "Using gethostbyname() for resolving"); -#endif /* * Otherwise use the IPv4-only gethostbyname... * (NOTE: we don't use gethostbyname as a fallback!) @@ -796,7 +770,7 @@ static int ipv4_is_local_addr(struct in_addr addr) &retbytes, NULL, NULL) == 0) n_local_interfaces = retbytes / sizeof(INTERFACE_INFO); else - logevent(NULL, "Unable to get list of local IP addresses"); + n_local_interfaces = -1; } if (n_local_interfaces > 0) { int i; diff --git a/windows/winpgen.c b/windows/winpgen.c index ecb28ac4..11b438dc 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -61,7 +61,6 @@ void nonfatal(const char *fmt, ...) } /* Stubs needed to link against misc.c */ -void logevent(Frontend *frontend, const char *msg) { assert(0); } void queue_idempotent_callback(IdempotentCallback *ic) { assert(0); } /* ---------------------------------------------------------------------- diff --git a/windows/winpgnt.c b/windows/winpgnt.c index 2fa53654..b5e9fcbb 100644 --- a/windows/winpgnt.c +++ b/windows/winpgnt.c @@ -114,7 +114,6 @@ static void unmungestr(char *in, char *out, int outlen) } /* Stubs needed to link against misc.c */ -void logevent(Frontend *frontend, const char *msg) { assert(0); } void queue_idempotent_callback(IdempotentCallback *ic) { assert(0); } static int has_security; diff --git a/windows/winplink.c b/windows/winplink.c index 255fb2fd..2d4b74fa 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -446,8 +446,7 @@ int main(int argc, char **argv) !conf_get_str_nthstrkey(conf, CONF_portfwd, 0)) conf_set_int(conf, CONF_ssh_simple, TRUE); - logctx = log_init(NULL, conf); - console_provide_logctx(logctx); + logctx = log_init(default_logpolicy, conf); if (just_test_share_exists) { if (!vt->test_for_upstream) { @@ -463,7 +462,7 @@ int main(int argc, char **argv) } if (restricted_acl) { - logevent(NULL, "Running with restricted process ACL"); + lp_eventlog(default_logpolicy, "Running with restricted process ACL"); } /* @@ -477,7 +476,7 @@ int main(int argc, char **argv) int nodelay = conf_get_int(conf, CONF_tcp_nodelay) && (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); - error = backend_init(vt, NULL, &backend, conf, + error = backend_init(vt, NULL, &backend, logctx, conf, conf_get_str(conf, CONF_host), conf_get_int(conf, CONF_port), &realhost, nodelay, @@ -486,7 +485,6 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to open connection:\n%s", error); return 1; } - backend_provide_logctx(backend, logctx); sfree(realhost); } diff --git a/windows/winser.c b/windows/winser.c index db53d24e..e1f40369 100644 --- a/windows/winser.c +++ b/windows/winser.c @@ -15,6 +15,7 @@ struct Serial { HANDLE port; struct handle *out, *in; Frontend *frontend; + LogContext *logctx; int bufsize; long clearbreak_time; int break_in_progress; @@ -61,7 +62,7 @@ static int serial_gotdata(struct handle *h, void *data, int len) notify_remote_exit(serial->frontend); - logevent(serial->frontend, error_msg); + logevent(serial->logctx, error_msg); connection_fatal(serial->frontend, "%s", error_msg); @@ -81,7 +82,7 @@ static void serial_sentdata(struct handle *h, int new_backlog) notify_remote_exit(serial->frontend); - logevent(serial->frontend, error_msg); + logevent(serial->logctx, error_msg); connection_fatal(serial->frontend, "%s", error_msg); } else { @@ -101,7 +102,6 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) * device instead of a serial port. */ if (GetCommState(serport, &dcb)) { - char *msg; const char *str; /* @@ -124,14 +124,10 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) * Configurable parameters. */ dcb.BaudRate = conf_get_int(conf, CONF_serspeed); - msg = dupprintf("Configuring baud rate %lu", dcb.BaudRate); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring baud rate %lu", dcb.BaudRate); dcb.ByteSize = conf_get_int(conf, CONF_serdatabits); - msg = dupprintf("Configuring %u data bits", dcb.ByteSize); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %u data bits", dcb.ByteSize); switch (conf_get_int(conf, CONF_serstopbits)) { case 2: dcb.StopBits = ONESTOPBIT; str = "1"; break; @@ -139,9 +135,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) case 4: dcb.StopBits = TWOSTOPBITS; str = "2"; break; default: return "Invalid number of stop bits (need 1, 1.5 or 2)"; } - msg = dupprintf("Configuring %s data bits", str); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %s data bits", str); switch (conf_get_int(conf, CONF_serparity)) { case SER_PAR_NONE: dcb.Parity = NOPARITY; str = "no"; break; @@ -150,9 +144,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) case SER_PAR_MARK: dcb.Parity = MARKPARITY; str = "mark"; break; case SER_PAR_SPACE: dcb.Parity = SPACEPARITY; str = "space"; break; } - msg = dupprintf("Configuring %s parity", str); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %s parity", str); switch (conf_get_int(conf, CONF_serflow)) { case SER_FLOW_NONE: @@ -173,9 +165,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) str = "DSR/DTR"; break; } - msg = dupprintf("Configuring %s flow control", str); - logevent(serial->frontend, msg); - sfree(msg); + logeventf(serial->logctx, "Configuring %s flow control", str); if (!SetCommState(serport, &dcb)) return "Unable to configure serial port"; @@ -201,7 +191,8 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) * freed by the caller. */ static const char *serial_init(Frontend *frontend, Backend **backend_handle, - Conf *conf, const char *host, int port, + LogContext *logctx, Conf *conf, + const char *host, int port, char **realhost, int nodelay, int keepalive) { Serial *serial; @@ -218,13 +209,10 @@ static const char *serial_init(Frontend *frontend, Backend **backend_handle, *backend_handle = &serial->backend; serial->frontend = frontend; + serial->logctx = logctx; serline = conf_get_str(conf, CONF_serline); - { - char *msg = dupprintf("Opening serial device %s", serline); - logevent(serial->frontend, msg); - sfree(msg); - } + logeventf(serial->logctx, "Opening serial device %s", serline); { /* @@ -342,7 +330,7 @@ static void serbreak_timer(void *ctx, unsigned long now) if (now == serial->clearbreak_time && serial->port) { ClearCommBreak(serial->port); serial->break_in_progress = FALSE; - logevent(serial->frontend, "Finished serial break"); + logevent(serial->logctx, "Finished serial break"); } } @@ -354,7 +342,7 @@ static void serial_special(Backend *be, SessionSpecialCode code, int arg) Serial *serial = container_of(be, Serial, backend); if (serial->port && code == SS_BRK) { - logevent(serial->frontend, "Starting serial break at user request"); + logevent(serial->logctx, "Starting serial break at user request"); SetCommBreak(serial->port); /* * To send a serial break on Windows, we call SetCommBreak @@ -417,11 +405,6 @@ static void serial_provide_ldisc(Backend *be, Ldisc *ldisc) /* This is a stub. */ } -static void serial_provide_logctx(Backend *be, LogContext *logctx) -{ - /* This is a stub. */ -} - static int serial_exitcode(Backend *be) { Serial *serial = container_of(be, Serial, backend); @@ -454,7 +437,6 @@ const struct BackendVtable serial_backend = { serial_sendok, serial_ldisc, serial_provide_ldisc, - serial_provide_logctx, serial_unthrottle, serial_cfg_info, NULL /* test_for_upstream */, diff --git a/windows/winsftp.c b/windows/winsftp.c index 580e8d95..48235cd9 100644 --- a/windows/winsftp.c +++ b/windows/winsftp.c @@ -751,7 +751,7 @@ char *ssh_sftp_get_cmdline(const char *prompt, int no_fds_ok) void platform_psftp_pre_conn_setup(void) { if (restricted_acl) { - logevent(NULL, "Running with restricted process ACL"); + lp_eventlog(default_logpolicy, "Running with restricted process ACL"); } }