From: ben Date: Wed, 15 Jan 2003 23:30:21 +0000 (+0000) Subject: Add the ability to close sessions. This adds *_free() functions to most X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/fabd1805a8f429ca83b4271aabd1206ac3537ebb Add the ability to close sessions. This adds *_free() functions to most areas of the code. Not all back-ends have been tested, but Telnet and SSH behave reasonably. Incidentally, almost all of this patch was written through Mac PuTTY, admittedly over a Telnet connection. git-svn-id: svn://svn.tartarus.org/sgt/putty@2615 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/ldisc.c b/ldisc.c index c77b5c8f..7b3976ef 100644 --- a/ldisc.c +++ b/ldisc.c @@ -87,6 +87,19 @@ void *ldisc_create(Config *mycfg, Terminal *term, return ldisc; } +void ldisc_free(void *handle) +{ + Ldisc ldisc = (Ldisc) handle; + + if (ldisc->term) + ldisc->term->ldisc = NULL; + if (ldisc->back) + ldisc->back->provide_ldisc(ldisc->backhandle, NULL); + if (ldisc->buf) + sfree(ldisc->buf); + sfree(ldisc); +} + void ldisc_send(void *handle, char *buf, int len, int interactive) { Ldisc ldisc = (Ldisc) handle; diff --git a/logging.c b/logging.c index b8091bfd..652eb9df 100644 --- a/logging.c +++ b/logging.c @@ -170,6 +170,14 @@ void *log_init(void *frontend, Config *cfg) return ctx; } +void log_free(void *handle) +{ + struct LogContext *ctx = (struct LogContext *)handle; + + logfclose(ctx); + sfree(ctx); +} + void log_reconfig(void *handle, Config *cfg) { struct LogContext *ctx = (struct LogContext *)handle; diff --git a/mac/mac.c b/mac/mac.c index ace079ca..52258c36 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.31 2003/01/15 22:37:58 ben Exp $ */ +/* $Id: mac.c,v 1.32 2003/01/15 23:30:21 ben Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -541,18 +541,15 @@ static void mac_closewindow(WindowPtr window) { CloseDeskAcc(((WindowPeek)window)->windowKind); break; case wTerminal: - /* FIXME: end session and stuff */ + mac_closeterm(window); break; case wAbout: windows.about = NULL; - CloseWindow(window); + DisposeDialog(window); break; case wLicence: windows.licence = NULL; - CloseWindow(window); - break; - default: - CloseWindow(window); + DisposeWindow(window); break; } } diff --git a/mac/mac.h b/mac/mac.h index 01a55a96..99e2df88 100644 --- a/mac/mac.h +++ b/mac/mac.h @@ -95,6 +95,7 @@ extern void mac_clickterm(WindowPtr, EventRecord *); extern void mac_growterm(WindowPtr, EventRecord *); extern void mac_keyterm(WindowPtr, EventRecord *); extern void mac_menuterm(WindowPtr, short, short); +extern void mac_closeterm(WindowPtr); /* from macstore.c */ extern OSErr get_putty_dir(Boolean makeit, short *pVRefNum, long *pDirID); extern OSErr get_session_dir(Boolean makeit, short *pVRefNum, long *pDirID); diff --git a/mac/macterm.c b/mac/macterm.c index 4e844bdc..02232a57 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.49 2003/01/14 19:42:00 ben Exp $ */ +/* $Id: macterm.c,v 1.50 2003/01/15 23:30:21 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -190,7 +190,7 @@ void mac_startsession(Session *s) ShowWindow(s->window); s->next = sesslist; - s->prev = s->next->prev; + s->prev = &sesslist; if (s->next != NULL) s->next->prev = &s->next; sesslist = s; @@ -917,6 +917,25 @@ static pascal void mac_growtermdraghook(void) SetPort(portsave); } +void mac_closeterm(WindowPtr window) +{ + Session *s = (Session *)GetWRefCon(window); + + /* XXX warn on close */ + HideWindow(s->window); + *s->prev = s->next; + s->next->prev = s->prev; + ldisc_free(s->ldisc); + s->back->free(s->backhandle); + log_free(s->logctx); + if (s->uni_to_font != NULL) + DisposeUnicodeToTextInfo(&s->uni_to_font); + term_free(s->term); + DisposeWindow(s->window); + DisposePalette(s->palette); + sfree(s); +} + void mac_activateterm(WindowPtr window, Boolean active) { Session *s; diff --git a/putty.h b/putty.h index 516760ae..39d94541 100644 --- a/putty.h +++ b/putty.h @@ -189,6 +189,7 @@ enum { struct backend_tag { char *(*init) (void *frontend_handle, void **backend_handle, Config *cfg, char *host, int port, char **realhost, int nodelay); + void (*free) (void *handle); /* back->reconfig() passes in a replacement configuration. */ void (*reconfig) (void *handle, Config *cfg); /* back->send() returns the current amount of buffered data. */ @@ -496,6 +497,7 @@ int platform_default_i(const char *name, int def); */ Terminal *term_init(Config *, struct unicode_data *, void *); +void term_free(Terminal *); void term_size(Terminal *, int, int, int); void term_out(Terminal *); void term_paint(Terminal *, Context, int, int, int, int, int); @@ -525,6 +527,7 @@ void term_provide_logctx(Terminal *term, void *logctx); * Exports from logging.c. */ void *log_init(void *frontend, Config *cfg); +void log_free(void *logctx); void log_reconfig(void *logctx, Config *cfg); void logfopen(void *logctx); void logfclose(void *logctx); @@ -574,6 +577,7 @@ extern Backend ssh_backend; * Exports from ldisc.c. */ void *ldisc_create(Config *, Terminal *, Backend *, void *, void *); +void ldisc_free(void *); void ldisc_send(void *handle, char *buf, int len, int interactive); /* diff --git a/raw.c b/raw.c index 94ff43f1..a22314f8 100644 --- a/raw.c +++ b/raw.c @@ -123,6 +123,15 @@ static char *raw_init(void *frontend_handle, void **backend_handle, return NULL; } +static void raw_free(void *handle) +{ + Raw raw = (Raw) handle; + + if (raw->s) + sk_close(raw->s); + sfree(raw); +} + /* * Stub routine (we don't have any need to reconfigure this backend). */ @@ -214,6 +223,7 @@ static int raw_exitcode(void *handle) Backend raw_backend = { raw_init, + raw_free, raw_reconfig, raw_send, raw_sendbuffer, diff --git a/rlogin.c b/rlogin.c index ff2af317..89a2bfe1 100644 --- a/rlogin.c +++ b/rlogin.c @@ -177,6 +177,15 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle, return NULL; } +static void rlogin_free(void *handle) +{ + Rlogin rlogin = (Rlogin) handle; + + if (rlogin->s) + sk_close(rlogin->s); + sfree(rlogin); +} + /* * Stub routine (we don't have any need to reconfigure this backend). */ @@ -282,6 +291,7 @@ static int rlogin_exitcode(void *handle) Backend rlogin_backend = { rlogin_init, + rlogin_free, rlogin_reconfig, rlogin_send, rlogin_sendbuffer, diff --git a/ssh.c b/ssh.c index 1b2e7e12..1d9b1ed1 100644 --- a/ssh.c +++ b/ssh.c @@ -4031,6 +4031,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) SHA_Final(&ssh->exhash, s->exchange_hash); dh_cleanup(ssh->kex_ctx); + ssh->kex_ctx = NULL; #if 0 debug(("Exchange hash is:\n")); @@ -5948,6 +5949,9 @@ static char *ssh_init(void *frontend_handle, void **backend_handle, ssh->term_width = ssh->cfg.width; ssh->term_height = ssh->cfg.height; + ssh->channels = NULL; + ssh->rportfwds = NULL; + ssh->send_ok = 0; ssh->editing = 0; ssh->echoing = 0; @@ -5964,6 +5968,65 @@ static char *ssh_init(void *frontend_handle, void **backend_handle, return NULL; } +static void ssh_free(void *handle) +{ + Ssh ssh = (Ssh) handle; + struct ssh_channel *c; + struct ssh_rportfwd *pf; + + if (ssh->v1_cipher_ctx) + ssh->cipher->free_context(ssh->v1_cipher_ctx); + if (ssh->cs_cipher_ctx) + ssh->cscipher->free_context(ssh->cs_cipher_ctx); + if (ssh->sc_cipher_ctx) + ssh->sccipher->free_context(ssh->sc_cipher_ctx); + if (ssh->cs_mac_ctx) + ssh->csmac->free_context(ssh->cs_mac_ctx); + if (ssh->sc_mac_ctx) + ssh->scmac->free_context(ssh->sc_mac_ctx); + if (ssh->cs_comp_ctx) + ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx); + if (ssh->sc_comp_ctx) + ssh->sccomp->compress_cleanup(ssh->sc_comp_ctx); + if (ssh->kex_ctx) + dh_cleanup(ssh->kex_ctx); + sfree(ssh->savedhost); + + if (ssh->channels) { + while ((c = delpos234(ssh->channels, 0)) != NULL) { + switch (c->type) { + case CHAN_X11: + if (c->u.x11.s != NULL) + x11_close(c->u.x11.s); + break; + case CHAN_SOCKDATA: + if (c->u.pfd.s != NULL) + pfd_close(c->u.pfd.s); + break; + } + sfree(c); + } + freetree234(ssh->channels); + } + + if (ssh->rportfwds) { + while ((pf = delpos234(ssh->rportfwds, 0)) != NULL) + sfree(pf); + freetree234(ssh->rportfwds); + } + sfree(ssh->deferred_send_data); + if (ssh->x11auth) + x11_free_auth(ssh->x11auth); + sfree(ssh->do_ssh_init_state); + sfree(ssh->do_ssh1_login_state); + sfree(ssh->do_ssh2_transport_state); + sfree(ssh->do_ssh2_authconn_state); + + if (ssh->s) + sk_close(ssh->s); + sfree(ssh); +} + /* * Reconfigure the SSH backend. * @@ -6236,6 +6299,7 @@ extern int ssh_fallback_cmd(void *handle) Backend ssh_backend = { ssh_init, + ssh_free, ssh_reconfig, ssh_send, ssh_sendbuffer, diff --git a/ssh.h b/ssh.h index 29c3c40a..c819c552 100644 --- a/ssh.h +++ b/ssh.h @@ -272,6 +272,7 @@ extern char *x11_init(Socket *, char *, void *, void *, const char *, int, extern void x11_close(Socket); extern int x11_send(Socket, char *, int); extern void *x11_invent_auth(char *, int, char *, int, int); +extern void x11_free_auth(void *); extern void x11_unthrottle(Socket s); extern void x11_override_throttle(Socket s, int enable); extern int x11_get_screen_number(char *display); diff --git a/telnet.c b/telnet.c index 91d0cab4..f2d31ef2 100644 --- a/telnet.c +++ b/telnet.c @@ -740,6 +740,15 @@ static char *telnet_init(void *frontend_handle, void **backend_handle, return NULL; } +static void telnet_free(void *handle) +{ + Telnet telnet = (Telnet) handle; + + sfree(telnet->sb_buf); + if (telnet->s) + sk_close(telnet->s); + sfree(telnet); +} /* * Reconfigure the Telnet backend. There's no immediate action * necessary, in this backend: we just save the fresh config for @@ -974,6 +983,7 @@ static int telnet_exitcode(void *handle) Backend telnet_backend = { telnet_init, + telnet_free, telnet_reconfig, telnet_send, telnet_sendbuffer, diff --git a/terminal.c b/terminal.c index 9ad33d61..005bee55 100644 --- a/terminal.c +++ b/terminal.c @@ -391,6 +391,34 @@ Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata, return term; } +void term_free(Terminal *term) +{ + unsigned long *line; + struct beeptime *beep; + + while ((line = delpos234(term->scrollback, 0)) != NULL) + sfree(line); + freetree234(term->scrollback); + while ((line = delpos234(term->screen, 0)) != NULL) + sfree(line); + freetree234(term->screen); + while ((line = delpos234(term->alt_screen, 0)) != NULL) + sfree(line); + freetree234(term->alt_screen); + sfree(term->disptext); + while (term->beephead) { + beep = term->beephead; + term->beephead = beep->next; + sfree(beep); + } + bufchain_clear(&term->inbuf); + if(term->print_job) + printer_finish_job(term->print_job); + bufchain_clear(&term->printer_buf); + sfree(term->paste_buffer); + sfree(term); +} + /* * Set up the terminal for a given size. */ diff --git a/testback.c b/testback.c index 70f22951..333c316b 100644 --- a/testback.c +++ b/testback.c @@ -1,4 +1,4 @@ -/* $Id: testback.c,v 1.5 2003/01/12 16:11:27 ben Exp $ */ +/* $Id: testback.c,v 1.6 2003/01/15 23:30:21 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999 Ben Harris @@ -35,6 +35,8 @@ static char *null_init(void *, void **, Config *, char *, int, char **, int); static char *loop_init(void *, void **, Config *, char *, int, char **, int); +static void null_free(void *); +static void loop_free(void *); static void null_reconfig(void *, Config *); static int null_send(void *, char *, int); static int loop_send(void *, char *, int); @@ -50,13 +52,13 @@ static void null_provide_logctx(void *, void *); static void null_unthrottle(void *, int); Backend null_backend = { - null_init, null_reconfig, null_send, null_sendbuffer, null_size, + null_init, null_free, null_reconfig, null_send, null_sendbuffer, null_size, null_special, null_socket, null_exitcode, null_sendok, null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle, 0 }; Backend loop_backend = { - loop_init, null_reconfig, loop_send, null_sendbuffer, null_size, + loop_init, loop_free, null_reconfig, loop_send, null_sendbuffer, null_size, null_special, null_socket, null_exitcode, null_sendok, null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle, 0 }; @@ -82,6 +84,17 @@ static char *loop_init(void *frontend_handle, void **backend_handle, return NULL; } +static void null_free(void *handle) +{ + +} + +static void loop_free(void *handle) +{ + + sfree(handle); +} + static void null_reconfig(void *handle, Config *cfg) { } diff --git a/x11fwd.c b/x11fwd.c index 52e678b3..54674866 100644 --- a/x11fwd.c +++ b/x11fwd.c @@ -112,6 +112,12 @@ void *x11_invent_auth(char *proto, int protomaxlen, return auth; } +void x11_free_auth(void *auth) +{ + + sfree(auth); +} + /* * Fetch the real auth data for a given display string, and store * it in an X11Auth structure. Returns NULL on success, or an error