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.

[originally from svn r2147]
This commit is contained in:
Simon Tatham 2002-10-26 12:58:13 +00:00
Родитель d17f035447
Коммит 4756c15fc9
24 изменённых файлов: 539 добавлений и 365 удалений

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

@ -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)
{
}

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

@ -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" : "<ukwn>"));
/* 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

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

@ -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) | \

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

@ -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;

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

@ -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);

81
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

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

@ -221,14 +221,6 @@ static int prompt_keyfile(HWND hwnd, char *dlgtitle,
return GetOpenFileName(&of);
}
/*
* 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.
*/

12
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
};

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

@ -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
};

4
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);

2
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);

191
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
};

2
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);

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

@ -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;
}

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

@ -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 <something weird>");
logevent(telnet->frontend, "server:\tSB TSPEED <something weird>");
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 <something weird>\r\n");
logevent(telnet->frontend, "server:\tSB TTYPE <something weird>\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 ? "<nothing>" : "<stuff>");
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
};

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

@ -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;
}

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

@ -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)

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

@ -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);

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

@ -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
};

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

@ -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 */

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

@ -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)
{

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

@ -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;
}

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

@ -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);

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

@ -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"
@ -49,6 +56,14 @@ GLOBAL HINSTANCE hinst;
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