*** lib/ssh.c.orig	2008-02-18 10:08:04.064523799 +0000
--- lib/ssh.c	2008-03-03 09:18:05.965133813 +0000
***************
*** 837,843 ****
        break;
      }
      else if(sshc->quote_item->data) {
!       fprintf(stderr, "data: %s\n", sshc->quote_item->data);
        /*
         * the arguments following the command must be separated from the
         * command with a space so we can check for it unconditionally
--- 837,843 ----
        break;
      }
      else if(sshc->quote_item->data) {
! /*      fprintf(stderr, "data: %s\n", sshc->quote_item->data);*/
        /*
         * the arguments following the command must be separated from the
         * command with a space so we can check for it unconditionally
***************
*** 1188,1197 ****
       *          If this is not done the destination file will be named the
       *          same name as the last directory in the path.
       */
!     sshc->sftp_handle =
!       libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
!                         LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
!                         data->set.new_file_perms);
      if(!sshc->sftp_handle) {
        if(libssh2_session_last_errno(sshc->ssh_session) ==
           LIBSSH2_ERROR_EAGAIN) {
--- 1188,1224 ----
       *          If this is not done the destination file will be named the
       *          same name as the last directory in the path.
       */
! 
!     if(data->state.resume_from != 0)
!     {
!       LIBSSH2_SFTP_ATTRIBUTES attrs;
!       if(data->state.resume_from< 0) {
!         rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
!         if(rc == LIBSSH2_ERROR_EAGAIN) {
!           break;
!         }
!         else if(rc) {
!           data->state.resume_from = 0;
!         }
!         else {
!           data->state.resume_from = attrs.filesize;
!         }
!       }
!     }
! 
! /* If we have restart position then open for append */ 
!     if(data->state.resume_from > 0) {
!       sshc->sftp_handle =
!         libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
!                           LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND,
!                           data->set.new_file_perms);
!     }
!     else {
!       sshc->sftp_handle =
!         libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
!                           LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
!                           data->set.new_file_perms);
!     }
      if(!sshc->sftp_handle) {
        if(libssh2_session_last_errno(sshc->ssh_session) ==
           LIBSSH2_ERROR_EAGAIN) {
***************
*** 1221,1226 ****
--- 1248,1304 ----
        }
      }
  
+     /* If we have restart point then we need to seek to the correct position. */
+     if(data->state.resume_from > 0){
+       /* Let's read off the proper amount of bytes from the input. */
+       if(conn->seek_func) {
+         curl_off_t readthisamountnow = data->state.resume_from;
+ 
+         if(conn->seek_func(conn->seek_client, 
+                            readthisamountnow, SEEK_SET) != 0) {
+           failf(data, "Could not seek stream");
+           return CURLE_FTP_COULDNT_USE_REST;
+         }
+       }
+       else {
+         curl_off_t passed=0;
+         curl_off_t readthisamountnow;
+         curl_off_t actuallyread;
+         do {
+           readthisamountnow = (data->state.resume_from - passed);
+ 
+           if(readthisamountnow > BUFSIZE)
+             readthisamountnow = BUFSIZE;
+ 
+           actuallyread = 
+             (curl_off_t) conn->fread_func(data->state.buffer, 
+                                           1, 
+                                           (size_t)readthisamountnow,
+                                           conn->fread_in);
+ 
+           passed += actuallyread;
+           if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
+             /* this checks for greater-than only to make sure that the
+                CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+             return CURLE_FTP_COULDNT_USE_REST;
+           }
+         } while(passed < data->state.resume_from);
+       }
+ 
+       /* now, decrease the size of the read */
+       if(data->set.infilesize>0) {
+         data->set.infilesize -= data->state.resume_from;
+         data->req.size = data->set.infilesize;
+         Curl_pgrsSetUploadSize(data, data->set.infilesize); 
+       }
+ 
+       libssh2_sftp_seek(sshc->sftp_handle, data->state.resume_from);
+     }
+     if(data->set.infilesize>0) {
+       data->req.size = data->set.infilesize;
+       Curl_pgrsSetUploadSize(data, data->set.infilesize); 
+     }
      /* upload data */
      result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL,
                                   FIRSTSOCKET, NULL);
***************
*** 1545,1555 ****
        data->req.maxdownload = attrs.filesize;
        Curl_pgrsSetDownloadSize(data, attrs.filesize);
      }
-   }
  
    /* Setup the actual download */
!   result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
                                 FALSE, NULL, -1, NULL);
    if(result) {
      state(conn, SSH_SFTP_CLOSE);
      sshc->actualcode = result;
--- 1623,1671 ----
        data->req.maxdownload = attrs.filesize;
        Curl_pgrsSetDownloadSize(data, attrs.filesize);
      }
  
+     /* We can resume if we can seek to the resume position */
+     if(data->state.resume_from) {
+       if(data->state.resume_from< 0) {
+         /* We're supposed to download the last abs(from) bytes */
+         if(attrs.filesize < -data->state.resume_from) {
+           failf(data, "Offset (%" 
+                 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
+                 data->state.resume_from, attrs.filesize);
+           return CURLE_BAD_DOWNLOAD_RESUME;
+         }
+         /* download from where? */
+         data->state.resume_from = attrs.filesize - data->state.resume_from;
+       }
+       else {
+         if(attrs.filesize < data->state.resume_from) {
+           failf(data, "Offset (%" FORMAT_OFF_T 
+                 ") was beyond file size (%" FORMAT_OFF_T ")",
+                 data->state.resume_from, attrs.filesize);
+           return CURLE_BAD_DOWNLOAD_RESUME;
+         }
+       }
+       /* Does a completed file need to be seeked and started or closed ? *
+       /* Now store the number of bytes we are expected to download */
+       data->req.size = attrs.filesize - data->state.resume_from;
+       data->req.maxdownload = attrs.filesize - data->state.resume_from;
+       Curl_pgrsSetDownloadSize(data, 
+                                attrs.filesize - data->state.resume_from);
+       libssh2_sftp_seek(sshc->sftp_handle, data->state.resume_from);
+     }
+   }
    /* Setup the actual download */
!   if(data->req.size == 0) {
!     /* no data to transfer */
!     result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
!     infof(data, "File already completely downloaded\n");
!     state(conn, SSH_STOP);
!     break;
!   }
!   else {
!     result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
                                 FALSE, NULL, -1, NULL);
+   }
    if(result) {
      state(conn, SSH_SFTP_CLOSE);
      sshc->actualcode = result;
***************
*** 1905,1911 ****
      failf(data, "Failure initialising ssh session");
      return CURLE_FAILED_INIT;
    }
! 
  #ifdef CURL_LIBSSH2_DEBUG
    libssh2_trace(ssh->ssh_session, LIBSSH2_TRACE_CONN|LIBSSH2_TRACE_TRANS|
                  LIBSSH2_TRACE_KEX|LIBSSH2_TRACE_AUTH|LIBSSH2_TRACE_SCP|
--- 2021,2036 ----
      failf(data, "Failure initialising ssh session");
      return CURLE_FAILED_INIT;
    }
! /*
!   libssh2_session_method_pref(ssh->ssh_session,
!                                 LIBSSH2_METHOD_COMP_CS,
!                                 "zlib");
! */
! /*
!   libssh2_session_method_pref(ssh->ssh_session,
!                                 LIBSSH2_METHOD_COMP_SC,
!                                 "zlib");
! */
  #ifdef CURL_LIBSSH2_DEBUG
    libssh2_trace(ssh->ssh_session, LIBSSH2_TRACE_CONN|LIBSSH2_TRACE_TRANS|
                  LIBSSH2_TRACE_KEX|LIBSSH2_TRACE_AUTH|LIBSSH2_TRACE_SCP|

