From a832773496d46caa5e328d36a15b4918f24a804e Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 26 Oct 2002 12:58:13 +0000 Subject: [PATCH] Yet more global-removal. The static variables in logging.c are now absent, and also (I think) all the frontend request functions (such as request_resize) take a context pointer, so that multiple windows can be handled sensibly. I wouldn't swear to this, but I _think_ that only leaves the Unicode stuff as the last stubborn holdout. git-svn-id: svn://svn.tartarus.org/sgt/putty@2147 cda61777-01e9-0310-a592-d414129be87e --- console.c | 15 +++-- logging.c | 93 +++++++++++++++++------------ pageant.c | 8 --- plink.c | 4 +- psftp.c | 4 +- putty.h | 81 +++++++++++++------------ puttygen.c | 8 --- raw.c | 12 +++- rlogin.c | 12 +++- scp.c | 4 +- sftp.c | 2 - ssh.c | 191 +++++++++++++++++++++++++++++++++-------------------------- ssh.h | 2 +- sshzlib.c | 1 + telnet.c | 38 +++++++----- terminal.c | 101 ++++++++++++++++++------------- terminal.h | 4 ++ unix/pterm.c | 184 ++++++++++++++++++++++++++++++++++++-------------------- unix/pty.c | 16 ++++- unix/unix.h | 4 +- windlg.c | 19 ++++-- window.c | 78 ++++++++++++------------ winnet.c | 8 ++- winstuff.h | 15 +++++ 24 files changed, 539 insertions(+), 365 deletions(-) diff --git a/console.c b/console.c index 85f99dc2..703e6837 100644 --- a/console.c +++ b/console.c @@ -36,7 +36,7 @@ void cleanup_exit(int code) exit(code); } -void verify_ssh_host_key(char *host, int port, char *keytype, +void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint) { int ret; @@ -142,7 +142,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, * below the configured 'warn' threshold). * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(char *ciphername, int cs) +void askcipher(void *frontend, char *ciphername, int cs) { HANDLE hin; DWORD savemode, i; @@ -192,7 +192,7 @@ void askcipher(char *ciphername, int cs) * 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(char *filename) +int askappend(void *frontend, char *filename) { HANDLE hin; DWORD savemode, i; @@ -240,6 +240,13 @@ int askappend(char *filename) /* * Warn about the obsolescent key file format. + * + * Uniquely among these functions, this one does _not_ expect a + * frontend handle. This means that if PuTTY is ported to a + * platform which requires frontend handles, this function will be + * an anomaly. Fortunately, the problem it addresses will not have + * been present on that platform, so it can plausibly be + * implemented as an empty function. */ void old_keyfile_warning(void) { @@ -257,7 +264,7 @@ void old_keyfile_warning(void) fputs(message, stderr); } -void logevent(char *string) +void logevent(void *frontend, char *string) { } diff --git a/logging.c b/logging.c index c843118d..6eaa3e9a 100644 --- a/logging.c +++ b/logging.c @@ -8,23 +8,27 @@ #include "putty.h" /* log session to file stuff ... */ -static FILE *lgfp = NULL; -static char currlogfilename[FILENAME_MAX]; +struct LogContext { + FILE *lgfp; + char currlogfilename[FILENAME_MAX]; + void *frontend; +}; static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm); /* * Log session traffic. */ -void logtraffic(unsigned char c, int logmode) +void logtraffic(void *handle, unsigned char c, int logmode) { + struct LogContext *ctx = (struct LogContext *)handle; if (cfg.logtype > 0) { if (cfg.logtype == logmode) { /* deferred open file from pgm start? */ - if (!lgfp) - logfopen(); - if (lgfp) - fputc(c, lgfp); + if (!ctx->lgfp) + logfopen(ctx); + if (ctx->lgfp) + fputc(c, ctx->lgfp); } } } @@ -32,30 +36,33 @@ void logtraffic(unsigned char c, int logmode) /* * Log an Event Log entry (used in SSH packet logging mode). */ -void log_eventlog(char *event) +void log_eventlog(void *handle, char *event) { + struct LogContext *ctx = (struct LogContext *)handle; if (cfg.logtype != LGTYP_PACKETS) return; - if (!lgfp) - logfopen(); - if (lgfp) - fprintf(lgfp, "Event Log: %s\n", event); + if (!ctx->lgfp) + logfopen(ctx); + if (ctx->lgfp) + fprintf(ctx->lgfp, "Event Log: %s\n", event); } /* * Log an SSH packet. */ -void log_packet(int direction, int type, char *texttype, void *data, int len) +void log_packet(void *handle, int direction, int type, + char *texttype, void *data, int len) { + struct LogContext *ctx = (struct LogContext *)handle; int i, j; char dumpdata[80], smalldata[5]; if (cfg.logtype != LGTYP_PACKETS) return; - if (!lgfp) - logfopen(); - if (lgfp) { - fprintf(lgfp, "%s packet type %d / 0x%02x (%s)\n", + if (!ctx->lgfp) + logfopen(ctx); + if (ctx->lgfp) { + fprintf(ctx->lgfp, "%s packet type %d / 0x%02x (%s)\n", direction == PKT_INCOMING ? "Incoming" : "Outgoing", type, type, texttype); for (i = 0; i < len; i += 16) { @@ -68,22 +75,23 @@ void log_packet(int direction, int type, char *texttype, void *data, int len) dumpdata[10+1+3*16+2+j] = (isprint(c) ? c : '.'); } strcpy(dumpdata + 10+1+3*16+2+j, "\n"); - fputs(dumpdata, lgfp); + fputs(dumpdata, ctx->lgfp); } - fflush(lgfp); + fflush(ctx->lgfp); } } /* open log file append/overwrite mode */ -void logfopen(void) +void logfopen(void *handle) { + struct LogContext *ctx = (struct LogContext *)handle; char buf[256]; time_t t; struct tm tm; char writemod[4]; /* Prevent repeat calls */ - if (lgfp) + if (ctx->lgfp) return; if (!cfg.logtype) @@ -94,29 +102,29 @@ void logfopen(void) tm = *localtime(&t); /* substitute special codes in file name */ - xlatlognam(currlogfilename,cfg.logfilename,cfg.host, &tm); + xlatlognam(ctx->currlogfilename, cfg.logfilename,cfg.host, &tm); - lgfp = fopen(currlogfilename, "r"); /* file already present? */ - if (lgfp) { + ctx->lgfp = fopen(ctx->currlogfilename, "r"); /* file already present? */ + if (ctx->lgfp) { int i; - fclose(lgfp); - i = askappend(currlogfilename); + fclose(ctx->lgfp); + i = askappend(ctx->frontend, ctx->currlogfilename); if (i == 1) writemod[0] = 'a'; /* set append mode */ else if (i == 0) { /* cancelled */ - lgfp = NULL; + ctx->lgfp = NULL; cfg.logtype = 0; /* disable logging */ return; } } - lgfp = fopen(currlogfilename, writemod); - if (lgfp) { /* enter into event log */ + ctx->lgfp = fopen(ctx->currlogfilename, writemod); + if (ctx->lgfp) { /* enter into event log */ /* --- write header line into log file */ - fputs("=~=~=~=~=~=~=~=~=~=~=~= PuTTY log ", lgfp); + fputs("=~=~=~=~=~=~=~=~=~=~=~= PuTTY log ", ctx->lgfp); strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm); - fputs(buf, lgfp); - fputs(" =~=~=~=~=~=~=~=~=~=~=~=\r\n", lgfp); + fputs(buf, ctx->lgfp); + fputs(" =~=~=~=~=~=~=~=~=~=~=~=\r\n", ctx->lgfp); sprintf(buf, "%s session log (%s mode) to file: ", (writemod[0] == 'a') ? "Appending" : "Writing new", @@ -124,20 +132,29 @@ void logfopen(void) cfg.logtype == LGTYP_DEBUG ? "raw" : cfg.logtype == LGTYP_PACKETS ? "SSH packets" : "")); /* Make sure we do not exceed the output buffer size */ - strncat(buf, currlogfilename, 128); + strncat(buf, ctx->currlogfilename, 128); buf[strlen(buf)] = '\0'; - logevent(buf); + logevent(ctx->frontend, buf); } } -void logfclose(void) +void logfclose(void *handle) { - if (lgfp) { - fclose(lgfp); - lgfp = NULL; + struct LogContext *ctx = (struct LogContext *)handle; + if (ctx->lgfp) { + fclose(ctx->lgfp); + ctx->lgfp = NULL; } } +void *log_init(void *frontend) +{ + struct LogContext *ctx = smalloc(sizeof(struct LogContext)); + ctx->lgfp = NULL; + ctx->frontend = frontend; + return ctx; +} + /* * translate format codes into time/date strings * and insert them into log file name diff --git a/pageant.c b/pageant.c index 71753c07..b8a4bd81 100644 --- a/pageant.c +++ b/pageant.c @@ -153,14 +153,6 @@ struct blob { }; static int cmpkeys_ssh2_asymm(void *av, void *bv); -/* - * This function is needed to link with the DES code. We need not - * have it do anything at all. - */ -void logevent(char *msg) -{ -} - #define GET_32BIT(cp) \ (((unsigned long)(unsigned char)(cp)[0] << 24) | \ ((unsigned long)(unsigned char)(cp)[1] << 16) | \ diff --git a/plink.c b/plink.c index 86b34151..528eee65 100644 --- a/plink.c +++ b/plink.c @@ -40,7 +40,7 @@ void modalfatalbox(char *p, ...) WSACleanup(); cleanup_exit(1); } -void connection_fatal(char *p, ...) +void connection_fatal(void *frontend, char *p, ...) { va_list ap; fprintf(stderr, "FATAL ERROR: "); @@ -538,6 +538,8 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to open connection:\n%s", error); return 1; } + logctx = log_init(NULL); + back->provide_logctx(backhandle, logctx); sfree(realhost); } connopen = 1; diff --git a/psftp.c b/psftp.c index 07045f26..e5857321 100644 --- a/psftp.c +++ b/psftp.c @@ -1472,7 +1472,7 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } -void connection_fatal(char *fmt, ...) +void connection_fatal(void *frontend, char *fmt, ...) { char str[0x100]; /* Make the size big enough */ va_list ap; @@ -1829,6 +1829,8 @@ static int psftp_connect(char *userhost, char *user, int portnumber) fprintf(stderr, "ssh_init: %s\n", err); return 1; } + logctx = log_init(NULL); + back->provide_logctx(backhandle, logctx); ssh_sftp_init(); if (verbose && realhost != NULL) printf("Connected to %s\n", realhost); diff --git a/putty.h b/putty.h index ba99aae6..116e2a3c 100644 --- a/putty.h +++ b/putty.h @@ -16,9 +16,12 @@ #endif #endif +#ifndef DONE_TYPEDEFS +#define DONE_TYPEDEFS typedef struct config_tag Config; typedef struct backend_tag Backend; typedef struct terminal_tag Terminal; +#endif #include "puttyps.h" #include "network.h" @@ -187,6 +190,7 @@ struct backend_tag { int (*sendok) (void *handle); int (*ldisc) (void *handle, int); void (*provide_ldisc) (void *handle, void *ldisc); + void (*provide_logctx) (void *handle, void *logctx); /* * back->unthrottle() tells the back end that the front end * buffer is clearing. @@ -388,43 +392,43 @@ struct RSAKey; /* be a little careful of scope */ /* * Exports from window.c. */ -void request_resize(int, int); +void request_resize(void *frontend, int, int); void do_text(Context, int, int, char *, int, unsigned long, int); void do_cursor(Context, int, int, char *, int, unsigned long, int); int CharWidth(Context ctx, int uc); -void set_title(char *); -void set_icon(char *); -void set_sbar(int, int, int); -Context get_ctx(void); +void set_title(void *frontend, char *); +void set_icon(void *frontend, char *); +void set_sbar(void *frontend, int, int, int); +Context get_ctx(void *frontend); void free_ctx(Context); -void palette_set(int, int, int, int); -void palette_reset(void); -void write_aclip(char *, int, int); -void write_clip(wchar_t *, int, int); -void get_clip(wchar_t **, int *); -void optimised_move(int, int, int); -void set_raw_mouse_mode(int); -Mouse_Button translate_button(Mouse_Button b); -void connection_fatal(char *, ...); +void palette_set(void *frontend, int, int, int, int); +void palette_reset(void *frontend); +void write_aclip(void *frontend, char *, int, int); +void write_clip(void *frontend, wchar_t *, int, int); +void get_clip(void *frontend, wchar_t **, int *); +void optimised_move(void *frontend, int, int, int); +void set_raw_mouse_mode(void *frontend, int); +Mouse_Button translate_button(void *frontend, Mouse_Button b); +void connection_fatal(void *frontend, char *, ...); void fatalbox(char *, ...); void modalfatalbox(char *, ...); -void beep(int); -void begin_session(void); -void sys_cursor(int x, int y); -void request_paste(void); +void beep(void *frontend, int); +void begin_session(void *frontend); +void sys_cursor(void *frontend, int x, int y); +void request_paste(void *frontend); void frontend_keypress(void *frontend); void ldisc_update(void *frontend, int echo, int edit); #define OPTIMISE_IS_SCROLL 1 -void set_iconic(int iconic); -void move_window(int x, int y); -void set_zorder(int top); -void refresh_window(void); -void set_zoomed(int zoomed); -int is_iconic(void); -void get_window_pos(int *x, int *y); -void get_window_pixels(int *x, int *y); -char *get_window_title(int icon); +void set_iconic(void *frontend, int iconic); +void move_window(void *frontend, int x, int y); +void set_zorder(void *frontend, int top); +void refresh_window(void *frontend); +void set_zoomed(void *frontend, int zoomed); +int is_iconic(void *frontend); +void get_window_pos(void *frontend, int *x, int *y); +void get_window_pixels(void *frontend, int *x, int *y); +char *get_window_title(void *frontend, int icon); void cleanup_exit(int); @@ -451,7 +455,7 @@ void registry_cleanup(void); * Exports from terminal.c. */ -Terminal *term_init(void); +Terminal *term_init(void *frontend); void term_size(Terminal *, int, int, int); void term_out(Terminal *); void term_paint(Terminal *, Context, int, int, int, int); @@ -475,16 +479,19 @@ int from_backend(void *, int is_stderr, char *data, int len); void term_provide_resize_fn(Terminal *term, void (*resize_fn)(void *, int, int), void *resize_ctx); +void term_provide_logctx(Terminal *term, void *logctx); /* * Exports from logging.c. */ -void logfopen(); -void logfclose(); -void logtraffic(unsigned char c, int logmode); +void *log_init(void *frontend); +void logfopen(void *logctx); +void logfclose(void *logctx); +void logtraffic(void *logctx, unsigned char c, int logmode); +void log_eventlog(void *logctx, char *string); enum { PKT_INCOMING, PKT_OUTGOING }; -void log_eventlog(char *string); -void log_packet(int direction, int type, char *texttype, void *data, int len); +void log_packet(void *logctx, int direction, int type, + char *texttype, void *data, int len); /* * Exports from raw.c. @@ -591,11 +598,11 @@ int wc_unescape(char *output, const char *wildcard); /* * Exports from windlg.c */ -void logevent(char *); -void verify_ssh_host_key(char *host, int port, char *keytype, +void logevent(void *frontend, char *); +void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint); -void askcipher(char *ciphername, int cs); -int askappend(char *filename); +void askcipher(void *frontend, char *ciphername, int cs); +int askappend(void *frontend, char *filename); /* * Exports from console.c (that aren't equivalents to things in diff --git a/puttygen.c b/puttygen.c index 4be822ac..956cdaf4 100644 --- a/puttygen.c +++ b/puttygen.c @@ -222,14 +222,6 @@ static int prompt_keyfile(HWND hwnd, char *dlgtitle, } /* - * This function is needed to link with the DES code. We need not - * have it do anything at all. - */ -void logevent(char *msg) -{ -} - -/* * Dialog-box function for the Licence box. */ static int CALLBACK LicenceProc(HWND hwnd, UINT msg, diff --git a/raw.c b/raw.c index e269a7d2..049b8518 100644 --- a/raw.c +++ b/raw.c @@ -41,7 +41,7 @@ static int raw_closing(Plug plug, char *error_msg, int error_code, } if (error_msg) { /* A socket error has occurred. */ - logevent(error_msg); + logevent(raw->frontend, error_msg); connection_fatal("%s", error_msg); } /* Otherwise, the remote side closed the connection normally. */ return 0; @@ -93,7 +93,7 @@ static char *raw_init(void *frontend_handle, void **backend_handle, { char buf[200]; sprintf(buf, "Looking up host \"%.170s\"", host); - logevent(buf); + logevent(raw->frontend, buf); } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) @@ -109,7 +109,7 @@ static char *raw_init(void *frontend_handle, void **backend_handle, char buf[200], addrbuf[100]; sk_getaddr(addr, addrbuf, 100); sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); - logevent(buf); + logevent(raw->frontend, buf); } raw->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) raw); if ((err = sk_socket_error(raw->s))) @@ -191,6 +191,11 @@ static void raw_provide_ldisc(void *handle, void *ldisc) /* This is a stub. */ } +static void raw_provide_logctx(void *handle, void *logctx) +{ + /* This is a stub. */ +} + static int raw_exitcode(void *handle) { /* Exit codes are a meaningless concept in the Raw protocol */ @@ -208,6 +213,7 @@ Backend raw_backend = { raw_sendok, raw_ldisc, raw_provide_ldisc, + raw_provide_logctx, raw_unthrottle, 1 }; diff --git a/rlogin.c b/rlogin.c index 61f4afb8..7b556048 100644 --- a/rlogin.c +++ b/rlogin.c @@ -42,7 +42,7 @@ static int rlogin_closing(Plug plug, char *error_msg, int error_code, } if (error_msg) { /* A socket error has occurred. */ - logevent(error_msg); + logevent(rlogin->frontend, error_msg); connection_fatal("%s", error_msg); } /* Otherwise, the remote side closed the connection normally. */ return 0; @@ -124,7 +124,7 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle, { char buf[200]; sprintf(buf, "Looking up host \"%.170s\"", host); - logevent(buf); + logevent(rlogin->frontend, buf); } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) @@ -140,7 +140,7 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle, char buf[200], addrbuf[100]; sk_getaddr(addr, addrbuf, 100); sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); - logevent(buf); + logevent(rlogin->frontend, buf); } rlogin->s = new_connection(addr, *realhost, port, 1, 0, nodelay, (Plug) rlogin); @@ -255,6 +255,11 @@ static void rlogin_provide_ldisc(void *handle, void *ldisc) /* This is a stub. */ } +static void rlogin_provide_logctx(void *handle, void *logctx) +{ + /* This is a stub. */ +} + static int rlogin_exitcode(void *handle) { Rlogin rlogin = (Rlogin) handle; @@ -273,6 +278,7 @@ Backend rlogin_backend = { rlogin_sendok, rlogin_ldisc, rlogin_provide_ldisc, + rlogin_provide_logctx, rlogin_unthrottle, 1 }; diff --git a/scp.c b/scp.c index 0d100f08..069f7ef9 100644 --- a/scp.c +++ b/scp.c @@ -260,7 +260,7 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } -void connection_fatal(char *fmt, ...) +void connection_fatal(void *frontend, char *fmt, ...) { char str[0x100]; /* Make the size big enough */ va_list ap; @@ -571,6 +571,8 @@ static void do_cmd(char *host, char *user, char *cmd) err = back->init(NULL, &backhandle, cfg.host, cfg.port, &realhost, 0); if (err != NULL) bump("ssh_init: %s", err); + logctx = log_init(NULL); + back->provide_logctx(backhandle, logctx); ssh_scp_init(); if (verbose && realhost != NULL) tell_user(stderr, "Connected to %s\n", realhost); diff --git a/sftp.c b/sftp.c index e1f60173..6d78c2c2 100644 --- a/sftp.c +++ b/sftp.c @@ -942,8 +942,6 @@ struct fxp_name *fxp_dup_name(struct fxp_name *name) */ void fxp_free_name(struct fxp_name *name) { - int i; - sfree(name->filename); sfree(name->longname); sfree(name); diff --git a/ssh.c b/ssh.c index d713ccf0..0cfba57e 100644 --- a/ssh.c +++ b/ssh.c @@ -15,26 +15,6 @@ #define TRUE 1 #endif -#define logevent(s) { logevent(s); \ - if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \ - { fprintf(stderr, "%s\n", s); fflush(stderr); } } - -/* logevent, only printf-formatted. */ -void logeventf(char *fmt, ...) -{ - va_list ap; - char stuff[200]; - - va_start(ap, fmt); - vsprintf(stuff, fmt, ap); - va_end(ap); - logevent(stuff); -} - -#define bombout(msg) ( ssh->state = SSH_STATE_CLOSED, \ - (ssh->s ? sk_close(ssh->s), ssh->s = NULL : 0), \ - logeventf msg, connection_fatal msg ) - #define SSH1_MSG_DISCONNECT 1 /* 0x1 */ #define SSH1_SMSG_PUBLIC_KEY 2 /* 0x2 */ #define SSH1_CMSG_SESSION_KEY 3 /* 0x3 */ @@ -557,6 +537,7 @@ struct ssh_tag { Socket s; void *ldisc; + void *logctx; unsigned char session_key[32]; int v1_compressing; @@ -658,6 +639,26 @@ struct ssh_tag { int (*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen); }; +#define logevent(s) { logevent(ssh->frontend, s); \ + if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \ + { fprintf(stderr, "%s\n", s); fflush(stderr); } } + +/* logevent, only printf-formatted. */ +void logeventf(Ssh ssh, char *fmt, ...) +{ + va_list ap; + char stuff[200]; + + va_start(ap, fmt); + vsprintf(stuff, fmt, ap); + va_end(ap); + logevent(stuff); +} + +#define bombout(msg) ( ssh->state = SSH_STATE_CLOSED, \ + (ssh->s ? sk_close(ssh->s), ssh->s = NULL : 0), \ + logeventf msg, connection_fatal msg ) + static int ssh_channelcmp(void *av, void *bv) { struct ssh_channel *a = (struct ssh_channel *) av; @@ -823,7 +824,7 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) if (ssh->cipher && detect_attack(ssh->crcda_ctx, ssh->pktin.data, st->biglen, NULL)) { - bombout(("Network attack (CRC compensation) detected!")); + bombout((ssh,"Network attack (CRC compensation) detected!")); crReturn(0); } @@ -833,7 +834,7 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) st->realcrc = crc32(ssh->pktin.data, st->biglen - 4); st->gotcrc = GET_32BIT(ssh->pktin.data + st->biglen - 4); if (st->gotcrc != st->realcrc) { - bombout(("Incorrect CRC received on packet")); + bombout((ssh,"Incorrect CRC received on packet")); crReturn(0); } @@ -860,8 +861,11 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) ssh->pktin.type = ssh->pktin.body[-1]; - log_packet(PKT_INCOMING, ssh->pktin.type, ssh1_pkt_type(ssh->pktin.type), - ssh->pktin.body, ssh->pktin.length); + if (ssh->logctx) + log_packet(ssh->logctx, + PKT_INCOMING, ssh->pktin.type, + ssh1_pkt_type(ssh->pktin.type), + ssh->pktin.body, ssh->pktin.length); if (ssh->pktin.type == SSH1_SMSG_STDOUT_DATA || ssh->pktin.type == SSH1_SMSG_STDERR_DATA || @@ -870,7 +874,7 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) ssh->pktin.type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) { long stringlen = GET_32BIT(ssh->pktin.body); if (stringlen + 4 != ssh->pktin.length) { - bombout(("Received data packet with bogus string length")); + bombout((ssh,"Received data packet with bogus string length")); crReturn(0); } } @@ -903,7 +907,7 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) memcpy(buf + nowlen, ssh->pktin.body + 4, msglen); buf[nowlen + msglen] = '\0'; /* logevent(buf); (this is now done within the bombout macro) */ - bombout(("Server sent disconnect message:\n\"%s\"", buf+nowlen)); + bombout((ssh,"Server sent disconnect message:\n\"%s\"", buf+nowlen)); crReturn(0); } @@ -957,7 +961,7 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) * do us any more damage. */ if (st->len < 0 || st->pad < 0 || st->len + st->pad < 0) { - bombout(("Incoming packet was garbled on decryption")); + bombout((ssh,"Incoming packet was garbled on decryption")); crReturn(0); } @@ -1005,7 +1009,7 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) if (ssh->scmac && !ssh->scmac->verify(ssh->sc_mac_ctx, ssh->pktin.data, st->len + 4, st->incoming_sequence)) { - bombout(("Incorrect MAC received on packet")); + bombout((ssh,"Incorrect MAC received on packet")); crReturn(0); } st->incoming_sequence++; /* whether or not we MACed */ @@ -1034,9 +1038,10 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) ssh->pktin.savedpos = 6; ssh->pktin.type = ssh->pktin.data[5]; - log_packet(PKT_INCOMING, ssh->pktin.type, - ssh2_pkt_type(ssh->pkt_ctx, ssh->pktin.type), - ssh->pktin.data+6, ssh->pktin.length-6); + if (ssh->logctx) + log_packet(ssh->logctx, PKT_INCOMING, ssh->pktin.type, + ssh2_pkt_type(ssh->pkt_ctx, ssh->pktin.type), + ssh->pktin.data+6, ssh->pktin.length-6); switch (ssh->pktin.type) { /* @@ -1064,7 +1069,7 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) memcpy(buf + nowlen, ssh->pktin.data + 14, msglen); buf[nowlen + msglen] = '\0'; logevent(buf); - bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"", + bombout((ssh,"Server sent disconnect message\ntype %d (%s):\n\"%s\"", reason, (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ? ssh2_disconnect_reasons[reason] : "unknown", @@ -1177,8 +1182,10 @@ static int s_wrpkt_prepare(Ssh ssh) ssh->pktout.body[-1] = ssh->pktout.type; - log_packet(PKT_OUTGOING, ssh->pktout.type, ssh1_pkt_type(ssh->pktout.type), - ssh->pktout.body, ssh->pktout.length); + if (ssh->logctx) + log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.type, + ssh1_pkt_type(ssh->pktout.type), + ssh->pktout.body, ssh->pktout.length); if (ssh->v1_compressing) { unsigned char *compblk; @@ -1459,9 +1466,10 @@ static int ssh2_pkt_construct(Ssh ssh) { int cipherblk, maclen, padding, i; - log_packet(PKT_OUTGOING, ssh->pktout.data[5], - ssh2_pkt_type(ssh->pkt_ctx, ssh->pktout.data[5]), - ssh->pktout.data + 6, ssh->pktout.length - 6); + if (ssh->logctx) + log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.data[5], + ssh2_pkt_type(ssh->pkt_ctx, ssh->pktout.data[5]), + ssh->pktout.data + 6, ssh->pktout.length - 6); /* * Compress packet payload. @@ -1626,7 +1634,7 @@ static Bignum ssh2_pkt_getmp(Ssh ssh) if (!p) return NULL; if (p[0] & 0x80) { - bombout(("internal error: Can't handle negative mpints")); + bombout((ssh,"internal error: Can't handle negative mpints")); return NULL; } b = bignum_from_bytes(p, length); @@ -1878,11 +1886,11 @@ static int do_ssh_init(Ssh ssh, unsigned char c) s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0; if (cfg.sshprot == 0 && !s->proto1) { - bombout(("SSH protocol version 1 required by user but not provided by server")); + bombout((ssh,"SSH protocol version 1 required by user but not provided by server")); crReturn(0); } if (cfg.sshprot == 3 && !s->proto2) { - bombout(("SSH protocol version 2 required by user but not provided by server")); + bombout((ssh,"SSH protocol version 2 required by user but not provided by server")); crReturn(0); } @@ -1989,7 +1997,7 @@ static int ssh_closing(Plug plug, char *error_msg, int error_code, if (error_msg) { /* A socket error has occurred. */ logevent(error_msg); - connection_fatal(error_msg); + connection_fatal(ssh->frontend, error_msg); } else { /* Otherwise, the remote side closed the connection normally. */ } @@ -2238,7 +2246,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) crWaitUntil(ispkt); if (ssh->pktin.type != SSH1_SMSG_PUBLIC_KEY) { - bombout(("Public key packet not received")); + bombout((ssh,"Public key packet not received")); crReturn(0); } @@ -2299,7 +2307,8 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) fatalbox("Out of memory"); rsastr_fmt(keystr, &hostkey); rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey); - verify_ssh_host_key(ssh->savedhost, ssh->savedport, "rsa", keystr, + verify_ssh_host_key(ssh->frontend, + ssh->savedhost, ssh->savedport, "rsa", keystr, fingerprint); sfree(keystr); } @@ -2347,17 +2356,17 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) } if (!cipher_chosen) { if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0) - bombout(("Server violates SSH 1 protocol by not " + bombout((ssh,"Server violates SSH 1 protocol by not " "supporting 3DES encryption")); else /* shouldn't happen */ - bombout(("No supported ciphers found")); + bombout((ssh,"No supported ciphers found")); crReturn(0); } /* Warn about chosen cipher if necessary. */ if (warn) - askcipher(cipher_string, 0); + askcipher(ssh->frontend, cipher_string, 0); } switch (s->cipher_type) { @@ -2400,7 +2409,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) crWaitUntil(ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS) { - bombout(("Encryption not successfully enabled")); + bombout((ssh,"Encryption not successfully enabled")); crReturn(0); } @@ -2694,7 +2703,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) PKT_STR, "No more passwords available to try", PKT_END); logevent("Unable to authenticate"); - connection_fatal("Unable to authenticate"); + connection_fatal(ssh->frontend, "Unable to authenticate"); ssh->state = SSH_STATE_CLOSED; crReturn(1); } @@ -2750,7 +2759,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) continue; /* go and try password */ } if (ssh->pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) { - bombout(("Bizarre response to offer of public key")); + bombout((ssh,"Bizarre response to offer of public key")); crReturn(0); } @@ -2786,7 +2795,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) " our public key.\r\n"); continue; /* go and try password */ } else if (ssh->pktin.type != SSH1_SMSG_SUCCESS) { - bombout(("Bizarre response to RSA authentication response")); + bombout((ssh,"Bizarre response to RSA authentication response")); crReturn(0); } @@ -2919,7 +2928,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) c_write_str(ssh, "Access denied\r\n"); logevent("Authentication refused"); } else if (ssh->pktin.type != SSH1_SMSG_SUCCESS) { - bombout(("Strange packet received, type %d", ssh->pktin.type)); + bombout((ssh,"Strange packet received, type %d", ssh->pktin.type)); crReturn(0); } } @@ -3019,7 +3028,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (!ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS && ssh->pktin.type != SSH1_SMSG_FAILURE) { - bombout(("Protocol confusion")); + bombout((ssh,"Protocol confusion")); crReturnV; } else if (ssh->pktin.type == SSH1_SMSG_FAILURE) { logevent("Agent forwarding refused"); @@ -3047,7 +3056,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (!ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS && ssh->pktin.type != SSH1_SMSG_FAILURE) { - bombout(("Protocol confusion")); + bombout((ssh,"Protocol confusion")); crReturnV; } else if (ssh->pktin.type == SSH1_SMSG_FAILURE) { logevent("X11 forwarding refused"); @@ -3156,7 +3165,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (!ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS && ssh->pktin.type != SSH1_SMSG_FAILURE) { - bombout(("Protocol confusion")); + bombout((ssh,"Protocol confusion")); crReturnV; } else if (ssh->pktin.type == SSH1_SMSG_FAILURE) { c_write_str(ssh, "Server refused port" @@ -3181,7 +3190,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (!ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS && ssh->pktin.type != SSH1_SMSG_FAILURE) { - bombout(("Protocol confusion")); + bombout((ssh,"Protocol confusion")); crReturnV; } else if (ssh->pktin.type == SSH1_SMSG_FAILURE) { c_write_str(ssh, "Server refused to allocate pty\r\n"); @@ -3199,7 +3208,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (!ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS && ssh->pktin.type != SSH1_SMSG_FAILURE) { - bombout(("Protocol confusion")); + bombout((ssh,"Protocol confusion")); crReturnV; } else if (ssh->pktin.type == SSH1_SMSG_FAILURE) { c_write_str(ssh, "Server refused to compress\r\n"); @@ -3450,7 +3459,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) sfree(c); } } else { - bombout(("Received CHANNEL_CLOSE%s for %s channel %d\n", + bombout((ssh,"Received CHANNEL_CLOSE%s for %s channel %d\n", ssh->pktin.type == SSH1_MSG_CHANNEL_CLOSE ? "" : "_CONFIRMATION", c ? "half-open" : "nonexistent", i)); @@ -3552,7 +3561,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh->state = SSH_STATE_CLOSED; crReturnV; } else { - bombout(("Strange packet received: type %d", ssh->pktin.type)); + bombout((ssh,"Strange packet received: type %d", ssh->pktin.type)); crReturnV; } } else { @@ -3820,7 +3829,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) int i, j, len; if (ssh->pktin.type != SSH2_MSG_KEXINIT) { - bombout(("expected key exchange packet from server")); + bombout((ssh,"expected key exchange packet from server")); crReturn(0); } ssh->kex = NULL; @@ -3865,12 +3874,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) } if (s->cscipher_tobe) { if (s->warn) - askcipher(s->cscipher_tobe->name, 1); + askcipher(ssh->frontend, s->cscipher_tobe->name, 1); break; } } if (!s->cscipher_tobe) { - bombout(("Couldn't agree a client-to-server cipher (available: %s)", str)); + bombout((ssh,"Couldn't agree a client-to-server cipher (available: %s)", str)); crReturn(0); } @@ -3890,12 +3899,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) } if (s->sccipher_tobe) { if (s->warn) - askcipher(s->sccipher_tobe->name, 2); + askcipher(ssh->frontend, s->sccipher_tobe->name, 2); break; } } if (!s->sccipher_tobe) { - bombout(("Couldn't agree a server-to-client cipher (available: %s)", str)); + bombout((ssh,"Couldn't agree a server-to-client cipher (available: %s)", str)); crReturn(0); } @@ -3968,7 +3977,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) crWaitUntil(ispkt); if (ssh->pktin.type != SSH2_MSG_KEX_DH_GEX_GROUP) { - bombout(("expected key exchange group packet from server")); + bombout((ssh,"expected key exchange group packet from server")); crReturn(0); } s->p = ssh2_pkt_getmp(ssh); @@ -3994,7 +4003,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) crWaitUntil(ispkt); if (ssh->pktin.type != s->kex_reply_value) { - bombout(("expected key exchange reply packet from server")); + bombout((ssh,"expected key exchange reply packet from server")); crReturn(0); } ssh2_pkt_getstring(ssh, &s->hostkeydata, &s->hostkeylen); @@ -4025,7 +4034,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (!s->hkey || !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen, s->exchange_hash, 20)) { - bombout(("Server's host key did not match the signature supplied")); + bombout((ssh,"Server's host key did not match the signature supplied")); crReturn(0); } @@ -4035,7 +4044,8 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) */ s->keystr = ssh->hostkey->fmtkey(s->hkey); s->fingerprint = ssh->hostkey->fingerprint(s->hkey); - verify_ssh_host_key(ssh->savedhost, ssh->savedport, ssh->hostkey->keytype, + verify_ssh_host_key(ssh->frontend, + ssh->savedhost, ssh->savedport, ssh->hostkey->keytype, s->keystr, s->fingerprint); if (s->first_kex) { /* don't bother logging this in rekeys */ logevent("Host key fingerprint is:"); @@ -4056,7 +4066,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) */ crWaitUntil(ispkt); if (ssh->pktin.type != SSH2_MSG_NEWKEYS) { - bombout(("expected new-keys packet from server")); + bombout((ssh,"expected new-keys packet from server")); crReturn(0); } @@ -4281,7 +4291,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh2_pkt_send(ssh); crWaitUntilV(ispkt); if (ssh->pktin.type != SSH2_MSG_SERVICE_ACCEPT) { - bombout(("Server refused user authentication protocol")); + bombout((ssh,"Server refused user authentication protocol")); crReturnV; } @@ -4381,7 +4391,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) /* Load the pub half of cfg.keyfile so we notice if it's in Pageant */ if (*cfg.keyfile) { int keytype; - logeventf("Reading private key file \"%.150s\"", cfg.keyfile); + logeventf(ssh->frontend, + "Reading private key file \"%.150s\"", cfg.keyfile); keytype = key_type(cfg.keyfile); if (keytype == SSH_KEYTYPE_SSH2) { s->publickey_blob = @@ -4389,8 +4400,9 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) &s->publickey_bloblen); } else { char msgbuf[256]; - logeventf("Unable to use this key file (%s)", - key_type_to_str(keytype)); + logeventf(ssh->frontend, + "Unable to use this key file (%s)", + key_type_to_str(keytype)); sprintf(msgbuf, "Unable to use key file \"%.150s\" (%s)\r\n", cfg.keyfile, key_type_to_str(keytype)); c_write_str(ssh, msgbuf); @@ -4441,7 +4453,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (!s->gotit) s->curr_prompt = 0; } else if (ssh->pktin.type != SSH2_MSG_USERAUTH_FAILURE) { - bombout(("Strange packet received during authentication: type %d", + bombout((ssh,"Strange packet received during authentication: type %d", ssh->pktin.type)); crReturnV; } @@ -4830,7 +4842,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh2_pkt_addstring(ssh, "en"); /* language tag */ ssh2_pkt_send(ssh); logevent("Unable to authenticate"); - connection_fatal("Unable to authenticate"); + connection_fatal(ssh->frontend, + "Unable to authenticate"); ssh->state = SSH_STATE_CLOSED; crReturnV; } @@ -5038,12 +5051,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh2_pkt_send(ssh); crWaitUntilV(ispkt); if (ssh->pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) { - bombout(("Server refused to open a session")); + bombout((ssh,"Server refused to open a session")); crReturnV; /* FIXME: error data comes back in FAILURE packet */ } if (ssh2_pkt_getuint32(ssh) != ssh->mainchan->localid) { - bombout(("Server's channel confirmation cited wrong channel")); + bombout((ssh,"Server's channel confirmation cited wrong channel")); crReturnV; } ssh->mainchan->remoteid = ssh2_pkt_getuint32(ssh); @@ -5087,7 +5100,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { if (ssh->pktin.type != SSH2_MSG_CHANNEL_FAILURE) { - bombout(("Unexpected response to X11 forwarding request:" + bombout((ssh,"Unexpected response to X11 forwarding request:" " packet type %d", ssh->pktin.type)); crReturnV; } @@ -5215,7 +5228,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->pktin.type != SSH2_MSG_REQUEST_SUCCESS) { if (ssh->pktin.type != SSH2_MSG_REQUEST_FAILURE) { - bombout(("Unexpected response to port " + bombout((ssh,"Unexpected response to port " "forwarding request: packet type %d", ssh->pktin.type)); crReturnV; @@ -5255,7 +5268,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { if (ssh->pktin.type != SSH2_MSG_CHANNEL_FAILURE) { - bombout(("Unexpected response to agent forwarding request:" + bombout((ssh,"Unexpected response to agent forwarding request:" " packet type %d", ssh->pktin.type)); crReturnV; } @@ -5298,7 +5311,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { if (ssh->pktin.type != SSH2_MSG_CHANNEL_FAILURE) { - bombout(("Unexpected response to pty request:" + bombout((ssh,"Unexpected response to pty request:" " packet type %d", ssh->pktin.type)); crReturnV; } @@ -5356,7 +5369,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) } while (ssh->pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST); if (ssh->pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { if (ssh->pktin.type != SSH2_MSG_CHANNEL_FAILURE) { - bombout(("Unexpected response to shell/command request:" + bombout((ssh,"Unexpected response to shell/command request:" " packet type %d", ssh->pktin.type)); crReturnV; } @@ -5371,7 +5384,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh->fallback_cmd = TRUE; continue; } - bombout(("Server refused to start a shell/command")); + bombout((ssh,"Server refused to start a shell/command")); crReturnV; } else { logevent("Started a shell/command"); @@ -5508,7 +5521,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) c = find234(ssh->channels, &i, ssh_channelfind); if (!c || ((int)c->remoteid) == -1) { - bombout(("Received CHANNEL_CLOSE for %s channel %d\n", + bombout((ssh,"Received CHANNEL_CLOSE for %s channel %d\n", c ? "half-open" : "nonexistent", i)); } /* Do pre-close processing on the channel. */ @@ -5777,7 +5790,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh2_pkt_send(ssh); } } else { - bombout(("Strange packet received: type %d", ssh->pktin.type)); + bombout((ssh,"Strange packet received: type %d", ssh->pktin.type)); crReturnV; } } else { @@ -5851,7 +5864,7 @@ static char *ssh_init(void *frontend_handle, void **backend_handle, ssh->sccipher = NULL; ssh->sc_cipher_ctx = NULL; ssh->csmac = NULL; - ssh->sc_mac_ctx = NULL; + ssh->cs_mac_ctx = NULL; ssh->scmac = NULL; ssh->sc_mac_ctx = NULL; ssh->cscomp = NULL; @@ -5865,6 +5878,7 @@ static char *ssh_init(void *frontend_handle, void **backend_handle, ssh->size_needed = FALSE; ssh->eof_needed = FALSE; ssh->ldisc = NULL; + ssh->logctx = NULL; { static const struct Packet empty = { 0, 0, NULL, NULL, 0 }; ssh->pktin = ssh->pktout = empty; @@ -6148,6 +6162,12 @@ static void ssh_provide_ldisc(void *handle, void *ldisc) ssh->ldisc = ldisc; } +static void ssh_provide_logctx(void *handle, void *logctx) +{ + Ssh ssh = (Ssh) handle; + ssh->logctx = logctx; +} + static int ssh_return_exitcode(void *handle) { Ssh ssh = (Ssh) handle; @@ -6176,6 +6196,7 @@ Backend ssh_backend = { ssh_sendok, ssh_ldisc, ssh_provide_ldisc, + ssh_provide_logctx, ssh_unthrottle, 22 }; diff --git a/ssh.h b/ssh.h index 2d2d0df4..e3423ccf 100644 --- a/ssh.h +++ b/ssh.h @@ -248,7 +248,7 @@ int random_byte(void); void random_add_noise(void *noise, int length); void random_add_heavynoise(void *noise, int length); -void logevent(char *); +void logevent(void *, char *); /* Allocate and register a new channel for port forwarding */ void *new_sock_channel(void *handle, Socket s); diff --git a/sshzlib.c b/sshzlib.c index ae60bb10..58069b60 100644 --- a/sshzlib.c +++ b/sshzlib.c @@ -956,6 +956,7 @@ void *zlib_decompress_init(void) dctx->currlentable = dctx->currdisttable = dctx->lenlentable = NULL; dctx->bits = 0; dctx->nbits = 0; + dctx->winpos = 0; return dctx; } diff --git a/telnet.c b/telnet.c index 6fcde71f..1f1a89e3 100644 --- a/telnet.c +++ b/telnet.c @@ -224,14 +224,14 @@ static void c_write1(Telnet telnet, int c) sk_set_frozen(telnet->s, backlog > TELNET_MAX_BACKLOG); } -static void log_option(char *sender, int cmd, int option) +static void log_option(Telnet telnet, char *sender, int cmd, int option) { char buf[50]; sprintf(buf, "%s:\t%s %s", sender, (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" : cmd == DO ? "DO" : cmd == DONT ? "DONT" : ""), telopt(option)); - logevent(buf); + logevent(telnet->frontend, buf); } static void send_opt(Telnet telnet, int cmd, int option) @@ -242,7 +242,7 @@ static void send_opt(Telnet telnet, int cmd, int option) b[1] = cmd; b[2] = option; telnet->bufsize = sk_write(telnet->s, b, 3); - log_option("client", cmd, option); + log_option(telnet, "client", cmd, option); } static void deactivate_option(Telnet telnet, const struct Opt *o) @@ -314,7 +314,7 @@ static void proc_rec_opt(Telnet telnet, int cmd, int option) { const struct Opt *const *o; - log_option("server", cmd, option); + log_option(telnet, "server", cmd, option); for (o = opts; *o; o++) { if ((*o)->option == option && (*o)->ack == cmd) { switch (telnet->opt_states[(*o)->index]) { @@ -378,11 +378,11 @@ static void process_subneg(Telnet telnet) b[n] = IAC; b[n + 1] = SE; telnet->bufsize = sk_write(telnet->s, b, n + 2); - logevent("server:\tSB TSPEED SEND"); + logevent(telnet->frontend, "server:\tSB TSPEED SEND"); sprintf(logbuf, "client:\tSB TSPEED IS %s", cfg.termspeed); - logevent(logbuf); + logevent(telnet->frontend, logbuf); } else - logevent("server:\tSB TSPEED "); + logevent(telnet->frontend, "server:\tSB TSPEED "); break; case TELOPT_TTYPE: if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) { @@ -400,11 +400,11 @@ static void process_subneg(Telnet telnet) b[n + 5] = SE; telnet->bufsize = sk_write(telnet->s, b, n + 6); b[n + 4] = 0; - logevent("server:\tSB TTYPE SEND"); + logevent(telnet->frontend, "server:\tSB TTYPE SEND"); sprintf(logbuf, "client:\tSB TTYPE IS %s", b + 4); - logevent(logbuf); + logevent(telnet->frontend, logbuf); } else - logevent("server:\tSB TTYPE \r\n"); + logevent(telnet->frontend, "server:\tSB TTYPE \r\n"); break; case TELOPT_OLD_ENVIRON: case TELOPT_NEW_ENVIRON: @@ -414,7 +414,7 @@ static void process_subneg(Telnet telnet) char logbuf[50]; p++; sprintf(logbuf, "server:\tSB %s SEND", telopt(telnet->sb_opt)); - logevent(logbuf); + logevent(telnet->frontend, logbuf); if (telnet->sb_opt == TELOPT_OLD_ENVIRON) { if (cfg.rfc_environ) { value = RFC_VALUE; @@ -477,7 +477,7 @@ static void process_subneg(Telnet telnet) telnet->bufsize = sk_write(telnet->s, b, n); sprintf(logbuf, "client:\tSB %s IS %s", telopt(telnet->sb_opt), n == 6 ? "" : ""); - logevent(logbuf); + logevent(telnet->frontend, logbuf); } break; } @@ -605,7 +605,7 @@ static int telnet_closing(Plug plug, char *error_msg, int error_code, } if (error_msg) { /* A socket error has occurred. */ - logevent(error_msg); + logevent(telnet->frontend, error_msg); connection_fatal("%s", error_msg); } /* Otherwise, the remote side closed the connection normally. */ return 0; @@ -666,7 +666,7 @@ static char *telnet_init(void *frontend_handle, void **backend_handle, { char buf[200]; sprintf(buf, "Looking up host \"%.170s\"", host); - logevent(buf); + logevent(telnet->frontend, buf); } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) @@ -682,7 +682,7 @@ static char *telnet_init(void *frontend_handle, void **backend_handle, char buf[200], addrbuf[100]; sk_getaddr(addr, addrbuf, 100); sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); - logevent(buf); + logevent(telnet->frontend, buf); } telnet->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) telnet); @@ -788,7 +788,7 @@ static void telnet_size(void *handle, int width, int height) sprintf(logbuf, "client:\tSB NAWS %d,%d", ((unsigned char) b[3] << 8) + (unsigned char) b[4], ((unsigned char) b[5] << 8) + (unsigned char) b[6]); - logevent(logbuf); + logevent(telnet->frontend, logbuf); } /* @@ -916,6 +916,11 @@ static void telnet_provide_ldisc(void *handle, void *ldisc) telnet->ldisc = ldisc; } +static void telnet_provide_logctx(void *handle, void *logctx) +{ + /* This is a stub. */ +} + static int telnet_exitcode(void *handle) { Telnet telnet = (Telnet) handle; @@ -934,6 +939,7 @@ Backend telnet_backend = { telnet_sendok, telnet_ldisc, telnet_provide_ldisc, + telnet_provide_logctx, telnet_unthrottle, 23 }; diff --git a/terminal.c b/terminal.c index 0cbf9182..738c7540 100644 --- a/terminal.c +++ b/terminal.c @@ -188,7 +188,7 @@ static void power_on(Terminal *term) void term_update(Terminal *term) { Context ctx; - ctx = get_ctx(); + ctx = get_ctx(term->frontend); if (ctx) { int need_sbar_update = term->seen_disp_event; if (term->seen_disp_event && cfg.scroll_on_disp) { @@ -199,7 +199,7 @@ void term_update(Terminal *term) if (need_sbar_update) update_sbar(term); do_paint(term, ctx, TRUE); - sys_cursor(term->curs.x, term->curs.y - term->disptop); + sys_cursor(term->frontend, term->curs.x, term->curs.y - term->disptop); free_ctx(ctx); } } @@ -261,7 +261,7 @@ void term_reconfig(Terminal *term) swap_screen(term, 0, FALSE, FALSE); if (cfg.no_mouse_rep) { term->xterm_mouse = 0; - set_raw_mouse_mode(0); + set_raw_mouse_mode(term->frontend, 0); } if (cfg.no_remote_charset) { term->cset_attr[0] = term->cset_attr[1] = ATTR_ASCII; @@ -289,7 +289,7 @@ void term_clrsb(Terminal *term) /* * Initialise the terminal. */ -Terminal *term_init(void) +Terminal *term_init(void *frontend) { Terminal *term; @@ -298,6 +298,8 @@ Terminal *term_init(void) * that need it. */ term = smalloc(sizeof(Terminal)); + term->frontend = frontend; + term->logctx = NULL; term->compatibility_level = TM_PUTTY; strcpy(term->id_string, "\033[?6c"); term->last_blink = term->last_tblink = 0; @@ -558,7 +560,8 @@ static void update_sbar(Terminal *term) nscroll = count234(term->scrollback); - set_sbar(nscroll + term->rows, nscroll + term->disptop, term->rows); + set_sbar(term->frontend, nscroll + term->rows, + nscroll + term->disptop, term->rows); } /* @@ -873,7 +876,7 @@ static void toggle_mode(Terminal *term, int mode, int query, int state) case 3: /* 80/132 columns */ deselect(term); if (!cfg.no_remote_resize) - request_resize(state ? 132 : 80, term->rows); + request_resize(term->frontend, state ? 132 : 80, term->rows); term->reset_132 = state; break; case 5: /* reverse video */ @@ -932,11 +935,11 @@ static void toggle_mode(Terminal *term, int mode, int query, int state) break; case 1000: /* xterm mouse 1 */ term->xterm_mouse = state ? 1 : 0; - set_raw_mouse_mode(state); + set_raw_mouse_mode(term->frontend, state); break; case 1002: /* xterm mouse 2 */ term->xterm_mouse = state ? 2 : 0; - set_raw_mouse_mode(state); + set_raw_mouse_mode(term->frontend, state); break; case 1047: /* alternate screen */ compatibility(OTHER); @@ -994,14 +997,14 @@ static void do_osc(Terminal *term) case 0: case 1: if (!cfg.no_remote_wintitle) - set_icon(term->osc_string); + set_icon(term->frontend, term->osc_string); if (term->esc_args[0] == 1) break; /* fall through: parameter 0 means set both */ case 2: case 21: if (!cfg.no_remote_wintitle) - set_title(term->osc_string); + set_title(term->frontend, term->osc_string); break; } } @@ -1087,8 +1090,8 @@ void term_out(Terminal *term) * Optionally log the session traffic to a file. Useful for * debugging and possibly also useful for actual logging. */ - if (cfg.logtype == LGTYP_DEBUG) - logtraffic((unsigned char) c, LGTYP_DEBUG); + if (cfg.logtype == LGTYP_DEBUG && term->logctx) + logtraffic(term->logctx, (unsigned char) c, LGTYP_DEBUG); } else { c = unget; unget = -1; @@ -1374,7 +1377,7 @@ void term_out(Terminal *term) term->vbell_startpoint = ticks; term_update(term); } else - beep(cfg.beep); + beep(term->frontend, cfg.beep); } term->disptop = 0; } @@ -1415,7 +1418,8 @@ void term_out(Terminal *term) fix_cpos; term->seen_disp_event = TRUE; term->paste_hold = 0; - logtraffic((unsigned char) c, LGTYP_ASCII); + if (term->logctx) + logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII); break; case '\014': if (has_compat(SCOANSI)) { @@ -1439,7 +1443,8 @@ void term_out(Terminal *term) term->wrapnext = FALSE; term->seen_disp_event = 1; term->paste_hold = 0; - logtraffic((unsigned char) c, LGTYP_ASCII); + if (term->logctx) + logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII); break; case '\t': { @@ -1487,8 +1492,9 @@ void term_out(Terminal *term) incpos(cursplus); check_selection(term, term->curs, cursplus); } - if ((c & CSET_MASK) == ATTR_ASCII || (c & CSET_MASK) == 0) - logtraffic((unsigned char) c, LGTYP_ASCII); + if (((c & CSET_MASK) == ATTR_ASCII || (c & CSET_MASK) == 0) && + term->logctx) + logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII); { extern int wcwidth(wchar_t ucs); int width = 0; @@ -1632,7 +1638,7 @@ void term_out(Terminal *term) ldisc_send(term->ldisc, NULL, 0, 0); if (term->reset_132) { if (!cfg.no_remote_resize) - request_resize(80, term->rows); + request_resize(term->frontend, 80, term->rows); term->reset_132 = 0; } fix_cpos; @@ -2134,7 +2140,7 @@ void term_out(Terminal *term) term->esc_args[0] >= 24)) { compatibility(VT340TEXT); if (!cfg.no_remote_resize) - request_resize(term->cols, + request_resize(term->frontend, term->cols, def(term->esc_args[0], 24)); deselect(term); } else if (term->esc_nargs >= 1 && @@ -2146,15 +2152,16 @@ void term_out(Terminal *term) int x, y, len; char buf[80], *p; case 1: - set_iconic(FALSE); + set_iconic(term->frontend, FALSE); break; case 2: - set_iconic(TRUE); + set_iconic(term->frontend, TRUE); break; case 3: if (term->esc_nargs >= 3) { if (!cfg.no_remote_resize) - move_window(def(term->esc_args[1], 0), + move_window(term->frontend, + def(term->esc_args[1], 0), def(term->esc_args[2], 0)); } break; @@ -2165,42 +2172,46 @@ void term_out(Terminal *term) * manage it. */ break; case 5: - set_zorder(TRUE); /* move to top */ + /* move to top */ + set_zorder(term->frontend, TRUE); break; case 6: - set_zorder(FALSE); /* move to bottom */ + /* move to bottom */ + set_zorder(term->frontend, FALSE); break; case 7: - refresh_window(); + refresh_window(term->frontend); break; case 8: if (term->esc_nargs >= 3) { if (!cfg.no_remote_resize) - request_resize(def(term->esc_args[2], cfg.width), + request_resize(term->frontend, + def(term->esc_args[2], cfg.width), def(term->esc_args[1], cfg.height)); } break; case 9: if (term->esc_nargs >= 2) - set_zoomed(term->esc_args[1] ? + set_zoomed(term->frontend, + term->esc_args[1] ? TRUE : FALSE); break; case 11: if (term->ldisc) ldisc_send(term->ldisc, - is_iconic() ? "\033[1t" : - "\033[2t", 4, 0); + is_iconic(term->frontend) ? + "\033[1t" : "\033[2t", 4, 0); break; case 13: if (term->ldisc) { - get_window_pos(&x, &y); + get_window_pos(term->frontend, &x, &y); len = sprintf(buf, "\033[3;%d;%dt", x, y); ldisc_send(term->ldisc, buf, len, 0); } break; case 14: if (term->ldisc) { - get_window_pixels(&x, &y); + get_window_pixels(term->frontend, &x, &y); len = sprintf(buf, "\033[4;%d;%dt", x, y); ldisc_send(term->ldisc, buf, len, 0); } @@ -2231,7 +2242,7 @@ void term_out(Terminal *term) break; case 20: if (term->ldisc) { - p = get_window_title(TRUE); + p = get_window_title(term->frontend, TRUE); len = strlen(p); ldisc_send(term->ldisc, "\033]L", 3, 0); ldisc_send(term->ldisc, p, len, 0); @@ -2240,7 +2251,7 @@ void term_out(Terminal *term) break; case 21: if (term->ldisc) { - p = get_window_title(FALSE); + p = get_window_title(term->frontend,FALSE); len = strlen(p); ldisc_send(term->ldisc, "\033]l", 3, 0); ldisc_send(term->ldisc, p, len, 0); @@ -2275,7 +2286,7 @@ void term_out(Terminal *term) compatibility(VT420); if (term->esc_nargs == 1 && term->esc_args[0] > 0) { if (!cfg.no_remote_resize) - request_resize(term->cols, + request_resize(term->frontend, term->cols, def(term->esc_args[0], cfg.height)); deselect(term); @@ -2289,7 +2300,8 @@ void term_out(Terminal *term) compatibility(VT340TEXT); if (term->esc_nargs <= 1) { if (!cfg.no_remote_resize) - request_resize(def(term->esc_args[0], + request_resize(term->frontend, + def(term->esc_args[0], cfg.width), term->rows); deselect(term); } @@ -2441,7 +2453,7 @@ void term_out(Terminal *term) term->osc_strlen = 0; break; case 'R': /* Linux palette reset */ - palette_reset(); + palette_reset(term->frontend); term_invalidate(term); term->termstate = TOPLEVEL; break; @@ -2520,7 +2532,7 @@ void term_out(Terminal *term) } term->osc_string[term->osc_strlen++] = val; if (term->osc_strlen >= 7) { - palette_set(term->osc_string[0], + palette_set(term->frontend, term->osc_string[0], term->osc_string[1] * 16 + term->osc_string[2], term->osc_string[3] * 16 + term->osc_string[4], term->osc_string[5] * 16 + term->osc_string[6]); @@ -3286,7 +3298,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect) wblen++; *wbptr++ = 0; #endif - write_clip(workbuf, wblen, FALSE); /* transfer to clipboard */ + write_clip(term->frontend, workbuf, wblen, FALSE); /* transfer to clipbd */ if (buflen > 0) /* indicates we allocated this buffer */ sfree(workbuf); } @@ -3515,7 +3527,7 @@ void term_do_paste(Terminal *term) wchar_t *data; int len; - get_clip(&data, &len); + get_clip(term->frontend, &data, &len); if (data && len > 0) { wchar_t *p, *q; @@ -3558,7 +3570,7 @@ void term_do_paste(Terminal *term) term->paste_pos = term->paste_hold = term->paste_len = 0; } } - get_clip(NULL, NULL); + get_clip(term->frontend, NULL, NULL); } void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y, @@ -3651,7 +3663,7 @@ void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y, return; } - b = translate_button(b); + b = translate_button(term->frontend, b); /* * Set the selection type (rectangular or normal) at the start @@ -3762,7 +3774,7 @@ void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y, || a == MA_2CLK || a == MA_3CLK #endif )) { - request_paste(); + request_paste(term->frontend); } term_update(term); @@ -3871,3 +3883,8 @@ int from_backend(void *vterm, int is_stderr, char *data, int len) */ return 0; } + +void term_provide_logctx(Terminal *term, void *logctx) +{ + term->logctx = logctx; +} diff --git a/terminal.h b/terminal.h index 9628e07f..4f6b6e72 100644 --- a/terminal.h +++ b/terminal.h @@ -163,6 +163,10 @@ struct terminal_tag { void *resize_ctx; void *ldisc; + + void *frontend; + + void *logctx; }; #define in_utf(term) ((term)->utf || line_codepage==CP_UTF8) diff --git a/unix/pterm.c b/unix/pterm.c index 23461764..0d18a7c9 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -57,10 +57,14 @@ struct gui_data { Backend *back; void *backhandle; Terminal *term; + void *logctx; +}; + +struct draw_ctx { + GdkGC *gc; + struct gui_data *inst; }; -static struct gui_data the_inst; -static struct gui_data *inst = &the_inst; /* so we always write `inst->' */ static int send_raw_mouse; void ldisc_update(void *frontend, int echo, int edit) @@ -73,7 +77,7 @@ void ldisc_update(void *frontend, int echo, int edit) */ } -int askappend(char *filename) +int askappend(void *frontend, char *filename) { /* * Logging in an xterm-alike is liable to be something you only @@ -84,7 +88,7 @@ int askappend(char *filename) return 2; } -void logevent(char *string) +void logevent(void *frontend, char *string) { /* * This is not a very helpful function: events are logged @@ -93,8 +97,10 @@ void logevent(char *string) */ } -int font_dimension(int which) /* 0 for width, 1 for height */ +int font_dimension(void *frontend, int which)/* 0 for width, 1 for height */ { + struct gui_data *inst = (struct gui_data *)frontend; + if (which) return inst->font_height; else @@ -110,8 +116,10 @@ int font_dimension(int which) /* 0 for width, 1 for height */ * mouse or a means of faking it, and there is no need to switch * buttons around at all. */ -Mouse_Button translate_button(Mouse_Button button) +Mouse_Button translate_button(void *frontend, Mouse_Button button) { + /* struct gui_data *inst = (struct gui_data *)frontend; */ + if (button == MBT_LEFT) return MBT_SELECT; if (button == MBT_MIDDLE) @@ -125,12 +133,13 @@ Mouse_Button translate_button(Mouse_Button button) * Minimise or restore the window in response to a server-side * request. */ -void set_iconic(int iconic) +void set_iconic(void *frontend, int iconic) { /* * GTK 1.2 doesn't know how to do this. */ #if GTK_CHECK_VERSION(2,0,0) + struct gui_data *inst = (struct gui_data *)frontend; if (iconic) gtk_window_iconify(GTK_WINDOW(inst->window)); else @@ -141,8 +150,9 @@ void set_iconic(int iconic) /* * Move the window in response to a server-side request. */ -void move_window(int x, int y) +void move_window(void *frontend, int x, int y) { + struct gui_data *inst = (struct gui_data *)frontend; /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -159,8 +169,9 @@ void move_window(int x, int y) * Move the window to the top or bottom of the z-order in response * to a server-side request. */ -void set_zorder(int top) +void set_zorder(void *frontend, int top) { + struct gui_data *inst = (struct gui_data *)frontend; if (top) gdk_window_raise(inst->window->window); else @@ -170,8 +181,9 @@ void set_zorder(int top) /* * Refresh the window in response to a server-side request. */ -void refresh_window(void) +void refresh_window(void *frontend) { + struct gui_data *inst = (struct gui_data *)frontend; term_invalidate(inst->term); } @@ -179,12 +191,13 @@ void refresh_window(void) * Maximise or restore the window in response to a server-side * request. */ -void set_zoomed(int zoomed) +void set_zoomed(void *frontend, int zoomed) { /* * GTK 1.2 doesn't know how to do this. */ #if GTK_CHECK_VERSION(2,0,0) + struct gui_data *inst = (struct gui_data *)frontend; if (iconic) gtk_window_maximize(GTK_WINDOW(inst->window)); else @@ -195,16 +208,18 @@ void set_zoomed(int zoomed) /* * Report whether the window is iconic, for terminal reports. */ -int is_iconic(void) +int is_iconic(void *frontend) { + struct gui_data *inst = (struct gui_data *)frontend; return !gdk_window_is_viewable(inst->window->window); } /* * Report the window's position, for terminal reports. */ -void get_window_pos(int *x, int *y) +void get_window_pos(void *frontend, int *x, int *y) { + struct gui_data *inst = (struct gui_data *)frontend; /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -220,8 +235,9 @@ void get_window_pos(int *x, int *y) /* * Report the window's pixel size, for terminal reports. */ -void get_window_pixels(int *x, int *y) +void get_window_pixels(void *frontend, int *x, int *y) { + struct gui_data *inst = (struct gui_data *)frontend; /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -237,8 +253,9 @@ void get_window_pixels(int *x, int *y) /* * Return the window or icon title. */ -char *get_window_title(int icon) +char *get_window_title(void *frontend, int icon) { + struct gui_data *inst = (struct gui_data *)frontend; return icon ? inst->wintitle : inst->icontitle; } @@ -251,7 +268,7 @@ gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data) return FALSE; } -void show_mouseptr(int show) +static void show_mouseptr(struct gui_data *inst, int show) { if (!cfg.hide_mouseptr) show = 1; @@ -305,7 +322,7 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { - /* struct gui_data *inst = (struct gui_data *)data; */ + struct gui_data *inst = (struct gui_data *)data; /* * Pass the exposed rectangle to terminal.c, which will call us @@ -327,7 +344,7 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { - /* struct gui_data *inst = (struct gui_data *)data; */ + struct gui_data *inst = (struct gui_data *)data; char output[32]; int start, end; @@ -433,7 +450,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) * Neither does Shift-Ins. */ if (event->keyval == GDK_Insert && (event->state & GDK_SHIFT_MASK)) { - request_paste(); + request_paste(inst); return TRUE; } @@ -797,7 +814,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) #endif ldisc_send(inst->ldisc, output+start, end-start, 1); - show_mouseptr(0); + show_mouseptr(inst, 0); term_seen_key_event(inst->term); term_out(inst->term); } @@ -810,7 +827,7 @@ gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data) struct gui_data *inst = (struct gui_data *)data; int shift, ctrl, alt, x, y, button, act; - show_mouseptr(1); + show_mouseptr(inst, 1); if (event->button == 4 && event->type == GDK_BUTTON_PRESS) { term_scroll(inst->term, 0, -5); @@ -858,7 +875,7 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) struct gui_data *inst = (struct gui_data *)data; int shift, ctrl, alt, x, y, button; - show_mouseptr(1); + show_mouseptr(inst, 1); shift = event->state & GDK_SHIFT_MASK; ctrl = event->state & GDK_CONTROL_MASK; @@ -993,29 +1010,32 @@ void destroy(GtkWidget *widget, gpointer data) gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; inst->term->has_focus = event->in; term_out(inst->term); term_update(inst->term); - show_mouseptr(1); + show_mouseptr(inst, 1); return FALSE; } /* * set or clear the "raw mouse message" mode */ -void set_raw_mouse_mode(int activate) +void set_raw_mouse_mode(void *frontend, int activate) { + struct gui_data *inst = (struct gui_data *)frontend; activate = activate && !cfg.no_mouse_rep; send_raw_mouse = activate; if (send_raw_mouse) inst->currcursor = inst->rawcursor; else inst->currcursor = inst->textcursor; - show_mouseptr(inst->mouseptr_visible); + show_mouseptr(inst, inst->mouseptr_visible); } -void request_resize(int w, int h) +void request_resize(void *frontend, int w, int h) { + struct gui_data *inst = (struct gui_data *)frontend; int large_x, large_y; int offset_x, offset_y; int area_x, area_y; @@ -1041,7 +1061,7 @@ void request_resize(int w, int h) * bogus size request which guarantees to be bigger than the * current size of the drawing area. */ - get_window_pixels(&large_x, &large_y); + get_window_pixels(inst, &large_x, &large_y); large_x += 32; large_y += 32; @@ -1080,7 +1100,7 @@ void request_resize(int w, int h) #endif } -void real_palette_set(int n, int r, int g, int b) +static void real_palette_set(struct gui_data *inst, int n, int r, int g, int b) { gboolean success[1]; @@ -1095,7 +1115,7 @@ void real_palette_set(int n, int r, int g, int b) n, r, g, b); } -void set_window_background(void) +void set_window_background(struct gui_data *inst) { if (inst->area && inst->area->window) gdk_window_set_background(inst->area->window, &inst->cols[18]); @@ -1103,22 +1123,24 @@ void set_window_background(void) gdk_window_set_background(inst->window->window, &inst->cols[18]); } -void palette_set(int n, int r, int g, int b) +void palette_set(void *frontend, int n, int r, int g, int b) { + struct gui_data *inst = (struct gui_data *)frontend; static const int first[21] = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, 16, 17, 18, 20, 22 }; - real_palette_set(first[n], r, g, b); + real_palette_set(inst, first[n], r, g, b); if (first[n] >= 18) - real_palette_set(first[n] + 1, r, g, b); + real_palette_set(inst, first[n] + 1, r, g, b); if (first[n] == 18) - set_window_background(); + set_window_background(inst); } -void palette_reset(void) +void palette_reset(void *frontend) { + struct gui_data *inst = (struct gui_data *)frontend; /* This maps colour indices in cfg to those used in inst->cols. */ static const int ww[] = { 6, 7, 8, 9, 10, 11, 12, 13, @@ -1150,11 +1172,12 @@ void palette_reset(void) i, cfg.colours[i][0], cfg.colours[i][1], cfg.colours[i][2]); } - set_window_background(); + set_window_background(inst); } -void write_clip(wchar_t * data, int len, int must_deselect) +void write_clip(void *frontend, wchar_t * data, int len, int must_deselect) { + struct gui_data *inst = (struct gui_data *)frontend; if (inst->pasteout_data) sfree(inst->pasteout_data); inst->pasteout_data = smalloc(len); @@ -1174,6 +1197,7 @@ void write_clip(wchar_t * data, int len, int must_deselect) void selection_get(GtkWidget *widget, GtkSelectionData *seldata, guint info, guint time_stamp, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; gtk_selection_data_set(seldata, GDK_SELECTION_TYPE_STRING, 8, inst->pasteout_data, inst->pasteout_data_len); } @@ -1181,6 +1205,7 @@ void selection_get(GtkWidget *widget, GtkSelectionData *seldata, gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; term_deselect(inst->term); if (inst->pasteout_data) sfree(inst->pasteout_data); @@ -1189,8 +1214,9 @@ gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata, return TRUE; } -void request_paste(void) +void request_paste(void *frontend) { + struct gui_data *inst = (struct gui_data *)frontend; /* * In Unix, pasting is asynchronous: all we can do at the * moment is to call gtk_selection_convert(), and when the data @@ -1205,6 +1231,8 @@ gint idle_paste_func(gpointer data); /* forward ref */ void selection_received(GtkWidget *widget, GtkSelectionData *seldata, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; + if (seldata->length <= 0 || seldata->type != GDK_SELECTION_TYPE_STRING) return; /* Nothing happens. */ @@ -1236,30 +1264,35 @@ gint idle_paste_func(gpointer data) } -void get_clip(wchar_t ** p, int *len) +void get_clip(void *frontend, wchar_t ** p, int *len) { + struct gui_data *inst = (struct gui_data *)frontend; + if (p) { *p = inst->pastein_data; *len = inst->pastein_data_len; } } -void set_title(char *title) +void set_title(void *frontend, char *title) { + struct gui_data *inst = (struct gui_data *)frontend; strncpy(inst->wintitle, title, lenof(inst->wintitle)); inst->wintitle[lenof(inst->wintitle)-1] = '\0'; gtk_window_set_title(GTK_WINDOW(inst->window), inst->wintitle); } -void set_icon(char *title) +void set_icon(void *frontend, char *title) { + struct gui_data *inst = (struct gui_data *)frontend; strncpy(inst->icontitle, title, lenof(inst->icontitle)); inst->icontitle[lenof(inst->icontitle)-1] = '\0'; gdk_window_set_icon_name(inst->window->window, inst->icontitle); } -void set_sbar(int total, int start, int page) +void set_sbar(void *frontend, int total, int start, int page) { + struct gui_data *inst = (struct gui_data *)frontend; if (!cfg.scrollbar) return; inst->sbar_adjust->lower = 0; @@ -1275,20 +1308,22 @@ void set_sbar(int total, int start, int page) void scrollbar_moved(GtkAdjustment *adj, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; + if (!cfg.scrollbar) return; if (!inst->ignore_sbar) term_scroll(inst->term, 1, (int)adj->value); } -void sys_cursor(int x, int y) +void sys_cursor(void *frontend, int x, int y) { /* * This is meaningless under X. */ } -void beep(int mode) +void beep(void *frontend, int mode) { gdk_beep(); } @@ -1303,19 +1338,27 @@ int CharWidth(Context ctx, int uc) return 1; } -Context get_ctx(void) +Context get_ctx(void *frontend) { - GdkGC *gc; + struct gui_data *inst = (struct gui_data *)frontend; + struct draw_ctx *dctx; + if (!inst->area->window) return NULL; - gc = gdk_gc_new(inst->area->window); - return gc; + + dctx = smalloc(sizeof(*dctx)); + dctx->inst = inst; + dctx->gc = gdk_gc_new(inst->area->window); + return dctx; } void free_ctx(Context ctx) { - GdkGC *gc = (GdkGC *)ctx; + struct draw_ctx *dctx = (struct draw_ctx *)ctx; + /* struct gui_data *inst = dctx->inst; */ + GdkGC *gc = dctx->gc; gdk_gc_unref(gc); + sfree(dctx); } /* @@ -1327,8 +1370,11 @@ void free_ctx(Context ctx) void do_text_internal(Context ctx, int x, int y, char *text, int len, unsigned long attr, int lattr) { + struct draw_ctx *dctx = (struct draw_ctx *)ctx; + struct gui_data *inst = dctx->inst; + GdkGC *gc = dctx->gc; + int nfg, nbg, t, fontid, shadow; - GdkGC *gc = (GdkGC *)ctx; /* * NYI: @@ -1437,7 +1483,9 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len, void do_text(Context ctx, int x, int y, char *text, int len, unsigned long attr, int lattr) { - GdkGC *gc = (GdkGC *)ctx; + struct draw_ctx *dctx = (struct draw_ctx *)ctx; + struct gui_data *inst = dctx->inst; + GdkGC *gc = dctx->gc; do_text_internal(ctx, x, y, text, len, attr, lattr); @@ -1461,8 +1509,11 @@ void do_text(Context ctx, int x, int y, char *text, int len, void do_cursor(Context ctx, int x, int y, char *text, int len, unsigned long attr, int lattr) { + struct draw_ctx *dctx = (struct draw_ctx *)ctx; + struct gui_data *inst = dctx->inst; + GdkGC *gc = dctx->gc; + int passive; - GdkGC *gc = (GdkGC *)ctx; if (attr & TATTR_PASCURS) { attr &= ~TATTR_PASCURS; @@ -1551,7 +1602,7 @@ void do_cursor(Context ctx, int x, int y, char *text, int len, len*inst->font_width, inst->font_height); } -GdkCursor *make_mouse_ptr(int cursor_val) +GdkCursor *make_mouse_ptr(struct gui_data *inst, int cursor_val) { /* * Truly hideous hack: GTK doesn't allow us to set the mouse @@ -1654,7 +1705,7 @@ void modalfatalbox(char *p, ...) exit(1); } -char *get_x_display(void) +char *get_x_display(void *frontend) { return gdk_get_display(); } @@ -1827,6 +1878,7 @@ int main(int argc, char **argv) { extern int pty_master_fd; /* declared in pty.c */ extern void pty_pre_init(void); /* declared in pty.c */ + struct gui_data *inst; pty_pre_init(); @@ -1839,8 +1891,9 @@ int main(int argc, char **argv) exit(1); /* - * Initialise the whole instance structure to zeroes + * Create an instance structure and initialise to zeroes */ + inst = smalloc(sizeof(*inst)); memset(inst, 0, sizeof(*inst)); inst->fonts[0] = gdk_font_load(cfg.font); @@ -1868,14 +1921,14 @@ int main(int argc, char **argv) inst->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (cfg.wintitle[0]) - set_title(cfg.wintitle); + set_title(inst, cfg.wintitle); else - set_title("pterm"); + set_title(inst, "pterm"); /* * Set up the colour map. */ - palette_reset(); + palette_reset(inst); inst->area = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), @@ -1954,19 +2007,22 @@ int main(int argc, char **argv) gtk_widget_show(GTK_WIDGET(inst->hbox)); gtk_widget_show(inst->window); - set_window_background(); + set_window_background(inst); - inst->textcursor = make_mouse_ptr(GDK_XTERM); - inst->rawcursor = make_mouse_ptr(GDK_LEFT_PTR); - inst->blankcursor = make_mouse_ptr(-1); - make_mouse_ptr(-2); /* clean up cursor font */ + inst->textcursor = make_mouse_ptr(inst, GDK_XTERM); + inst->rawcursor = make_mouse_ptr(inst, GDK_LEFT_PTR); + inst->blankcursor = make_mouse_ptr(inst, -1); + make_mouse_ptr(inst, -2); /* clean up cursor font */ inst->currcursor = inst->textcursor; - show_mouseptr(1); + show_mouseptr(inst, 1); - inst->term = term_init(); + inst->term = term_init(inst); + inst->logctx = log_init(inst); + term_provide_logctx(inst->term, inst->logctx); inst->back = &pty_backend; inst->back->init((void *)inst->term, &inst->backhandle, NULL, 0, NULL, 0); + inst->back->provide_logctx(inst->backhandle, inst->logctx); term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle); diff --git a/unix/pty.c b/unix/pty.c index 67addceb..fd7a93c9 100644 --- a/unix/pty.c +++ b/unix/pty.c @@ -68,6 +68,7 @@ #endif int pty_master_fd; +static void *pty_frontend; static char pty_name[FILENAME_MAX]; static int pty_stamped_utmp = 0; static int pty_child_pid; @@ -388,6 +389,7 @@ static char *pty_init(void *frontend, void **backend_handle, int slavefd; pid_t pid, pgrp; + pty_frontend = frontend; *backend_handle = NULL; /* we can't sensibly use this, sadly */ pty_term_width = cfg.width; @@ -414,7 +416,7 @@ static char *pty_init(void *frontend, void **backend_handle, if (!cfg.stamp_utmp) close(pty_utmp_helper_pipe); /* just let the child process die */ else { - char *location = get_x_display(); + char *location = get_x_display(pty_frontend); int len = strlen(location)+1, pos = 0; /* +1 to include NUL */ while (pos < len) { int ret = write(pty_utmp_helper_pipe, location+pos, len - pos); @@ -554,8 +556,10 @@ static void pty_size(void *handle, int width, int height) size.ws_row = (unsigned short)pty_term_height; size.ws_col = (unsigned short)pty_term_width; - size.ws_xpixel = (unsigned short) pty_term_width * font_dimension(0); - size.ws_ypixel = (unsigned short) pty_term_height * font_dimension(1); + size.ws_xpixel = (unsigned short) pty_term_width * + font_dimension(pty_frontend, 0); + size.ws_ypixel = (unsigned short) pty_term_height * + font_dimension(pty_frontend, 1); ioctl(pty_master_fd, TIOCSWINSZ, (void *)&size); return; } @@ -594,6 +598,11 @@ static void pty_provide_ldisc(void *handle, void *ldisc) /* This is a stub. */ } +static void pty_provide_logctx(void *handle, void *logctx) +{ + /* This is a stub. */ +} + static int pty_exitcode(void *handle) { if (!pty_child_dead) @@ -613,6 +622,7 @@ Backend pty_backend = { pty_sendok, pty_ldisc, pty_provide_ldisc, + pty_provide_logctx, pty_unthrottle, 1 }; diff --git a/unix/unix.h b/unix/unix.h index 0355c942..7b0bb4be 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -31,8 +31,8 @@ unsigned long getticks(void); /* based on gettimeofday(2) */ #define BYTE unsigned char /* Things pty.c needs from pterm.c */ -char *get_x_display(void); -int font_dimension(int which); /* 0 for width, 1 for height */ +char *get_x_display(void *frontend); +int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */ /* Things uxstore.c needs from pterm.c */ char *app_name; /* for doing resource lookups */ diff --git a/windlg.c b/windlg.c index fe3a1ad6..5040a241 100644 --- a/windlg.c +++ b/windlg.c @@ -140,7 +140,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg, memcpy(p, sel_nl, sizeof(sel_nl)); p += sizeof(sel_nl); } - write_aclip(clipdata, size, TRUE); + write_aclip(NULL, clipdata, size, TRUE); sfree(clipdata); } sfree(selitems); @@ -3749,12 +3749,12 @@ int do_reconfig(HWND hwnd) return ret; } -void logevent(char *string) +void logevent(void *frontend, char *string) { char timebuf[40]; time_t t; - log_eventlog(string); + log_eventlog(logctx, string); if (nevents >= negsize) { negsize += 64; @@ -3793,7 +3793,7 @@ void showabout(HWND hwnd) DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc); } -void verify_ssh_host_key(char *host, int port, char *keytype, +void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint) { int ret; @@ -3869,7 +3869,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, * below the configured 'warn' threshold). * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(char *ciphername, int cs) +void askcipher(void *frontend, char *ciphername, int cs) { static const char mbtitle[] = "PuTTY Security Alert"; static const char msg[] = @@ -3898,7 +3898,7 @@ void askcipher(char *ciphername, int cs) * 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(char *filename) +int askappend(void *frontend, char *filename) { static const char mbtitle[] = "PuTTY Log to File"; static const char msgtemplate[] = @@ -3927,6 +3927,13 @@ int askappend(char *filename) /* * Warn about the obsolescent key file format. + * + * Uniquely among these functions, this one does _not_ expect a + * frontend handle. This means that if PuTTY is ported to a + * platform which requires frontend handles, this function will be + * an anomaly. Fortunately, the problem it addresses will not have + * been present on that platform, so it can plausibly be + * implemented as an empty function. */ void old_keyfile_warning(void) { diff --git a/window.c b/window.c index cda2d1d8..e5f22800 100644 --- a/window.c +++ b/window.c @@ -118,7 +118,6 @@ static int caret_x = -1, caret_y = -1; static void *ldisc; static Backend *back; static void *backhandle; -static Terminal *term; #define FONT_NORMAL 0 #define FONT_BOLD 1 @@ -499,7 +498,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) hwnd = NULL; - term = term_init(); + term = term_init(NULL); + logctx = log_init(NULL); + term_provide_logctx(term, logctx); cfgtopalette(); @@ -608,6 +609,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) error = back->init((void *)term, &backhandle, cfg.host, cfg.port, &realhost, cfg.tcp_nodelay); + back->provide_logctx(backhandle, logctx); if (error) { sprintf(msg, "Unable to open connection to\n" "%.800s\n" "%s", cfg.host, error); @@ -622,8 +624,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) title = msg; } sfree(realhost); - set_title(title); - set_icon(title); + set_title(NULL, title); + set_icon(NULL, title); } /* @@ -708,7 +710,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) /* * Open the initial log file if there is one. */ - logfopen(); + logfopen(logctx); /* * Finally show the window! @@ -866,7 +868,7 @@ char *do_select(SOCKET skt, int startup) /* * set or clear the "raw mouse message" mode */ -void set_raw_mouse_mode(int activate) +void set_raw_mouse_mode(void *frontend, int activate) { activate = activate && !cfg.no_mouse_rep; send_raw_mouse = activate; @@ -876,7 +878,7 @@ void set_raw_mouse_mode(int activate) /* * Print a message box and close the connection. */ -void connection_fatal(char *fmt, ...) +void connection_fatal(void *frontend, char *fmt, ...) { va_list ap; char stuff[200]; @@ -1257,7 +1259,7 @@ static void deinit_fonts(void) } } -void request_resize(int w, int h) +void request_resize(void *frontend, int w, int h) { int width, height; @@ -1554,7 +1556,7 @@ static void click(Mouse_Button b, int x, int y, int shift, int ctrl, int alt) * Translate a raw mouse button designation (LEFT, MIDDLE, RIGHT) * into a cooked one (SELECT, EXTEND, PASTE). */ -Mouse_Button translate_button(Mouse_Button button) +Mouse_Button translate_button(void *frontend, Mouse_Button button) { if (button == MBT_LEFT) return MBT_SELECT; @@ -1750,8 +1752,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if (strcmp(prev_cfg.logfilename, cfg.logfilename) || prev_cfg.logtype != cfg.logtype) { - logfclose(); /* reset logging */ - logfopen(); + logfclose(logctx); /* reset logging */ + logfopen(logctx); } sfree(logpal); @@ -1841,7 +1843,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, init_lvl = 2; } - set_title(cfg.wintitle); + set_title(NULL, cfg.wintitle); if (IsIconic(hwnd)) { SetWindowText(hwnd, cfg.win_name_always ? window_name : @@ -2391,7 +2393,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; case WM_PALETTECHANGED: if ((HWND) wParam != hwnd && pal != NULL) { - HDC hdc = get_ctx(); + HDC hdc = get_ctx(NULL); if (hdc) { if (RealizePalette(hdc) > 0) UpdateColors(hdc); @@ -2401,7 +2403,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; case WM_QUERYNEWPALETTE: if (pal != NULL) { - HDC hdc = get_ctx(); + HDC hdc = get_ctx(NULL); if (hdc) { if (RealizePalette(hdc) > 0) UpdateColors(hdc); @@ -2612,7 +2614,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * helper software tracks the system caret, so we should arrange to * have one.) */ -void sys_cursor(int x, int y) +void sys_cursor(void *frontend, int x, int y) { int cx, cy; @@ -3866,7 +3868,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return -1; } -void request_paste(void) +void request_paste(void *frontend) { /* * In Windows, pasting is synchronous: we can read the @@ -3876,7 +3878,7 @@ void request_paste(void) term_do_paste(term); } -void set_title(char *title) +void set_title(void *frontend, char *title) { sfree(window_name); window_name = smalloc(1 + strlen(title)); @@ -3885,7 +3887,7 @@ void set_title(char *title) SetWindowText(hwnd, title); } -void set_icon(char *title) +void set_icon(void *frontend, char *title) { sfree(icon_name); icon_name = smalloc(1 + strlen(title)); @@ -3894,7 +3896,7 @@ void set_icon(char *title) SetWindowText(hwnd, title); } -void set_sbar(int total, int start, int page) +void set_sbar(void *frontend, int total, int start, int page) { SCROLLINFO si; @@ -3911,7 +3913,7 @@ void set_sbar(int total, int start, int page) SetScrollInfo(hwnd, SB_VERT, &si, TRUE); } -Context get_ctx(void) +Context get_ctx(void *frontend) { HDC hdc; if (hwnd) { @@ -3942,7 +3944,7 @@ static void real_palette_set(int n, int r, int g, int b) colours[n] = RGB(r, g, b); } -void palette_set(int n, int r, int g, int b) +void palette_set(void *frontend, int n, int r, int g, int b) { static const int first[21] = { 0, 2, 4, 6, 8, 10, 12, 14, @@ -3953,14 +3955,14 @@ void palette_set(int n, int r, int g, int b) if (first[n] >= 18) real_palette_set(first[n] + 1, r, g, b); if (pal) { - HDC hdc = get_ctx(); + HDC hdc = get_ctx(frontend); UnrealizeObject(pal); RealizePalette(hdc); free_ctx(hdc); } } -void palette_reset(void) +void palette_reset(void *frontend) { int i; @@ -3981,13 +3983,13 @@ void palette_reset(void) if (pal) { HDC hdc; SetPaletteEntries(pal, 0, NCOLOURS, logpal->palPalEntry); - hdc = get_ctx(); + hdc = get_ctx(frontend); RealizePalette(hdc); free_ctx(hdc); } } -void write_aclip(char *data, int len, int must_deselect) +void write_aclip(void *frontend, char *data, int len, int must_deselect) { HGLOBAL clipdata; void *lock; @@ -4019,7 +4021,7 @@ void write_aclip(char *data, int len, int must_deselect) /* * Note: unlike write_aclip() this will not append a nul. */ -void write_clip(wchar_t * data, int len, int must_deselect) +void write_clip(void *frontend, wchar_t * data, int len, int must_deselect) { HGLOBAL clipdata, clipdata2, clipdata3; int len2; @@ -4182,7 +4184,7 @@ void write_clip(wchar_t * data, int len, int must_deselect) SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0); } -void get_clip(wchar_t ** p, int *len) +void get_clip(void *frontend, wchar_t ** p, int *len) { static HGLOBAL clipdata = NULL; static wchar_t *converted = 0; @@ -4229,7 +4231,7 @@ void get_clip(wchar_t ** p, int *len) * Move `lines' lines from position `from' to position `to' in the * window. */ -void optimised_move(int to, int from, int lines) +void optimised_move(void *frontend, int to, int from, int lines) { RECT r; int min, max; @@ -4315,7 +4317,7 @@ static void flash_window(int mode) /* * Beep. */ -void beep(int mode) +void beep(void *frontend, int mode) { if (mode == BELL_DEFAULT) { /* @@ -4356,7 +4358,7 @@ void beep(int mode) * Minimise or restore the window in response to a server-side * request. */ -void set_iconic(int iconic) +void set_iconic(void *frontend, int iconic) { if (IsIconic(hwnd)) { if (!iconic) @@ -4370,7 +4372,7 @@ void set_iconic(int iconic) /* * Move the window in response to a server-side request. */ -void move_window(int x, int y) +void move_window(void *frontend, int x, int y) { if (cfg.resize_action == RESIZE_DISABLED || cfg.resize_action == RESIZE_FONT || @@ -4384,7 +4386,7 @@ void move_window(int x, int y) * Move the window to the top or bottom of the z-order in response * to a server-side request. */ -void set_zorder(int top) +void set_zorder(void *frontend, int top) { if (cfg.alwaysontop) return; /* ignore */ @@ -4395,7 +4397,7 @@ void set_zorder(int top) /* * Refresh the window in response to a server-side request. */ -void refresh_window(void) +void refresh_window(void *frontend) { InvalidateRect(hwnd, NULL, TRUE); } @@ -4404,7 +4406,7 @@ void refresh_window(void) * Maximise or restore the window in response to a server-side * request. */ -void set_zoomed(int zoomed) +void set_zoomed(void *frontend, int zoomed) { if (IsZoomed(hwnd)) { if (!zoomed) @@ -4418,7 +4420,7 @@ void set_zoomed(int zoomed) /* * Report whether the window is iconic, for terminal reports. */ -int is_iconic(void) +int is_iconic(void *frontend) { return IsIconic(hwnd); } @@ -4426,7 +4428,7 @@ int is_iconic(void) /* * Report the window's position, for terminal reports. */ -void get_window_pos(int *x, int *y) +void get_window_pos(void *frontend, int *x, int *y) { RECT r; GetWindowRect(hwnd, &r); @@ -4437,7 +4439,7 @@ void get_window_pos(int *x, int *y) /* * Report the window's pixel size, for terminal reports. */ -void get_window_pixels(int *x, int *y) +void get_window_pixels(void *frontend, int *x, int *y) { RECT r; GetWindowRect(hwnd, &r); @@ -4448,7 +4450,7 @@ void get_window_pixels(int *x, int *y) /* * Return the window or icon title. */ -char *get_window_title(int icon) +char *get_window_title(void *frontend, int icon) { return icon ? icon_name : window_name; } diff --git a/winnet.c b/winnet.c index 7cadf86f..4ea29038 100644 --- a/winnet.c +++ b/winnet.c @@ -833,7 +833,9 @@ void try_send(Actual_Socket s) s->pending_error = err; return; } else { - logevent(winsock_error_string(err)); + /* We're inside the Windows frontend here, so we know + * that the frontend handle is unnecessary. */ + logevent(NULL, winsock_error_string(err)); fatalbox("%s", winsock_error_string(err)); } } else { @@ -972,7 +974,9 @@ int select_result(WPARAM wParam, LPARAM lParam) if (ret <= 0) { char *str = (ret == 0 ? "Internal networking trouble" : winsock_error_string(WSAGetLastError())); - logevent(str); + /* We're inside the Windows frontend here, so we know + * that the frontend handle is unnecessary. */ + logevent(NULL, str); fatalbox("%s", str); } else { return plug_receive(s->plug, 2, buf, ret); diff --git a/winstuff.h b/winstuff.h index 9dcfded7..90c03481 100644 --- a/winstuff.h +++ b/winstuff.h @@ -18,6 +18,13 @@ #endif #endif +#ifndef DONE_TYPEDEFS +#define DONE_TYPEDEFS +typedef struct config_tag Config; +typedef struct backend_tag Backend; +typedef struct terminal_tag Terminal; +#endif + #define PUTTY_REG_POS "Software\\SimonTatham\\PuTTY" #define PUTTY_REG_PARENT "Software\\SimonTatham" #define PUTTY_REG_PARENT_CHILD "PuTTY" @@ -50,6 +57,14 @@ GLOBAL char *help_path; GLOBAL int help_has_contents; /* + * The terminal and logging context are notionally local to the + * Windows front end, but they must be shared between window.c and + * windlg.c. + */ +GLOBAL Terminal *term; +GLOBAL void *logctx; + +/* * I've just looked in the windows standard headr files for WM_USER, there * are hundreds of flags defined using the form WM_USER+123 so I've * renumbered this NETEVENT value and the two in window.c -- 2.11.0