Add the ability to close sessions. This adds *_free() functions to most
authorben <ben@cda61777-01e9-0310-a592-d414129be87e>
Wed, 15 Jan 2003 23:30:21 +0000 (23:30 +0000)
committerben <ben@cda61777-01e9-0310-a592-d414129be87e>
Wed, 15 Jan 2003 23:30:21 +0000 (23:30 +0000)
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

14 files changed:
ldisc.c
logging.c
mac/mac.c
mac/mac.h
mac/macterm.c
putty.h
raw.c
rlogin.c
ssh.c
ssh.h
telnet.c
terminal.c
testback.c
x11fwd.c

diff --git a/ldisc.c b/ldisc.c
index c77b5c8..7b3976e 100644 (file)
--- 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;
index b8091bf..652eb9d 100644 (file)
--- 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;
index ace079c..52258c3 100644 (file)
--- 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;
     }
 }
index 01a55a9..99e2df8 100644 (file)
--- 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);
index 4e844bd..02232a5 100644 (file)
@@ -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 516760a..39d9454 100644 (file)
--- 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 94ff43f..a22314f 100644 (file)
--- 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,
index ff2af31..89a2bfe 100644 (file)
--- 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 1b2e7e1..1d9b1ed 100644 (file)
--- 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 29c3c40..c819c55 100644 (file)
--- 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);
index 91d0cab..f2d31ef 100644 (file)
--- 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,
index 9ad33d6..005bee5 100644 (file)
@@ -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.
  */
index 70f2295..333c316 100644 (file)
@@ -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) {
 
 }
index 52e678b..5467486 100644 (file)
--- 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