From 7ffe62d9019a3e1749bd90f23c4bab15657d6cd7 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 22 Dec 2008 13:12:36 +0000
Subject: [PATCH] - Given a recent enough libssh2, libcurl can now seek/resume
 with SFTP even   on file indexes beyond 2 or 4GB.

---
 CHANGES       |  2 ++
 RELEASE-NOTES |  1 +
 lib/ssh.c     | 16 +++++++++++++---
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/CHANGES b/CHANGES
index bd74340897..37553ee0c4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,8 @@
                                   Changelog
 
 Daniel Stenberg (22 Dec 2008)
+- Given a recent enough libssh2, libcurl can now seek/resume with SFTP even
+  on file indexes beyond 2 or 4GB.
 
 - Anthony Bryan provided a set of patches that cleaned up manual language,
   corrected spellings and more.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index fff8f41a83..5783b5eaec 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -37,6 +37,7 @@ This release includes the following bugfixes:
  o curl_multi_timeout() no longer returns timeout 0 when there's nothing to do
    yet
  o the multi_socket API and HTTP pipelining now work a lot better when combined
+ o SFTP seek/resume beyond 32bit file sizes
 
 This release includes the following known bugs:
 
diff --git a/lib/ssh.c b/lib/ssh.c
index c1aa48fd9f..339c2db2a7 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -431,6 +431,16 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
   return CURLE_OK;
 }
 
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK2
+#define SFTP_SEEK(x,y) libssh2_sftp_seek2(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, y)
+#endif
+
 /*
  * ssh_statemach_act() runs the SSH statemachine "one round" and returns.  The
  * data the pointer 'block' points to will be set to TRUE if the libssh2
@@ -1343,7 +1353,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         Curl_pgrsSetUploadSize(data, data->set.infilesize);
       }
 
-      libssh2_sftp_seek(sshc->sftp_handle, data->state.resume_from);
+      SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
     }
     if(data->set.infilesize>0) {
       data->req.size = data->set.infilesize;
@@ -1716,7 +1726,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           size = to - from + 1;
         }
 
-        libssh2_sftp_seek(conn->proto.sshc.sftp_handle, from);
+        SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
       }
       data->req.size = size;
       data->req.maxdownload = size;
@@ -1750,7 +1760,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       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);
+      SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
     }
   }
   /* Setup the actual download */
-- 
GitLab