Index: lib/ssh.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ssh.c,v
retrieving revision 1.101
diff -u -r1.101 ssh.c
--- lib/ssh.c	21 May 2008 21:08:31 -0000	1.101
+++ lib/ssh.c	24 May 2008 20:07:26 -0000
@@ -2152,23 +2152,25 @@
   Curl_safefree(conn->data->state.proto.ssh);
   conn->data->state.proto.ssh = NULL;
 
-  state(conn, SSH_SESSION_DISCONNECT);
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
 
-  result = ssh_easy_statemach(conn);
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = ssh_easy_statemach(conn);
+  }
 
   return result;
 }
 
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
-                         bool premature)
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
 {
   CURLcode result = CURLE_OK;
   bool done = FALSE;
-  (void)premature; /* not used */
-  (void)status; /* unused */
 
   if(status == CURLE_OK) {
-    state(conn, SSH_SCP_DONE);
     /* run the state-machine */
     if(conn->data->state.used_interface == Curl_if_multi) {
       result = ssh_multi_statemach(conn, &done);
@@ -2179,12 +2181,33 @@
     }
   }
   else {
+    struct ssh_conn *sshc = &conn->proto.sshc;
     result = status;
     done = TRUE;
+
+    /* free possible leftovers */
+    if(sshc->homedir) {
+      free(sshc->homedir);
+      sshc->homedir=NULL;
+    }
+    if(sshc->sftp_session) {
+      (void)libssh2_sftp_shutdown(sshc->sftp_session);
+      sshc->sftp_session=NULL;
+    }
+    if(sshc->ssh_channel) {
+      (void)libssh2_channel_free(sshc->ssh_channel);
+      sshc->ssh_channel = NULL;
+    }
+    if(sshc->ssh_session) {
+      fprintf(stderr, "free ssh2 session!\n");
+      (void)libssh2_session_free(sshc->ssh_session);
+      sshc->ssh_session = NULL;
+    }
   }
 
   if(done) {
     struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
+
     Curl_safefree(sftp_scp->path);
     sftp_scp->path = NULL;
     Curl_pgrsDone(conn);
@@ -2194,6 +2217,19 @@
 
 }
 
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void)premature; /* not used */
+
+  if(status == CURLE_OK)
+    state(conn, SSH_SCP_DONE);
+
+  return ssh_done(conn, status);
+
+}
+
 /* return number of received (decrypted) bytes */
 ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
                       const void *mem, size_t len)
@@ -2295,8 +2331,11 @@
   Curl_safefree(conn->data->state.proto.ssh);
   conn->data->state.proto.ssh = NULL;
 
-  state(conn, SSH_SFTP_SHUTDOWN);
-  result = ssh_easy_statemach(conn);
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = ssh_easy_statemach(conn);
+  }
 
   DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
 
@@ -2307,12 +2346,8 @@
 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
                                bool premature)
 {
-  CURLcode result = CURLE_OK;
-  bool done = FALSE;
   struct ssh_conn *sshc = &conn->proto.sshc;
 
-  (void)status; /* unused */
-
   if(status == CURLE_OK) {
     /* Before we shut down, see if there are any post-quote commands to send: */
     if(!status && !premature && conn->data->set.postquote) {
@@ -2321,25 +2356,8 @@
     }
     else
       state(conn, SSH_SFTP_CLOSE);
-
-    /* run the state-machine */
-    if(conn->data->state.used_interface == Curl_if_multi)
-      result = ssh_multi_statemach(conn, &done);
-    else {
-      result = ssh_easy_statemach(conn);
-      done = TRUE;
-    }
-  }
-  else {
-    result = status;
-    done = TRUE;
   }
-
-  if(done) {
-    Curl_pgrsDone(conn);
-  }
-
-  return result;
+  return ssh_done(conn, status);
 }
 
 /* return number of sent bytes */
