[Bug 2021] sftp resume support (using size and offset)
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Wed Jun 19 20:04:48 EST 2013
https://bugzilla.mindrot.org/show_bug.cgi?id=2021
--- Comment #13 from Loganaden Velvindron <loganaden at gmail.com> ---
(In reply to Damien Miller from comment #11)
> Comment on attachment 2199 [details]
> Resume diff with copyright
>
> >Index: sftp-client.c
> >===================================================================
> >RCS file: /cvs/openssh/sftp-client.c,v
> >retrieving revision 1.108
> >diff -u -p -r1.108 sftp-client.c
> >--- sftp-client.c 2 Jul 2012 12:15:39 -0000 1.108
> >+++ sftp-client.c 11 Dec 2012 19:00:53 -0000
> >@@ -15,6 +15,24 @@
> > * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> > */
> >
> >+/*
> >+ * Copyright (c) 2012 Loganaden Velvindron
> >+ *
> >+ * Permission to use, copy, modify, and distribute this software for any
> >+ * purpose with or without fee is hereby granted, provided that the above
> >+ * copyright notice and this permission notice appear in all copies.
> >+ *
> >+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> >+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> >+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> >+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> >+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> >+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> >+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> >+ *
> >+ * Sponsored by AfriNIC.
> >+ */
>
> Normally we wouldn't add a whole copyright notice for a change of a
> few dozen lines. I'm happy to credit AfriNIC in the commit message.
The diff I uploaded the last time was incomplete. The complete diff is
a bit long. In Any case, I'm fine with it :-)
>
> >@@ -1050,11 +1069,36 @@ do_download(struct sftp_conn *conn, char
> > return(-1);
> > }
> >
> >- local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC,
> >- mode | S_IWRITE);
> >+ if (resume) {
> >+ if (stat(local_path, &st) == -1) {
> >+ offset = 0;
> >+ highwater = 0;
> >+ local_fd = open(local_path, O_WRONLY | O_CREAT,
> >+ mode | S_IWRITE);
> >+ }
>
> I thing it would be safer and clearer to do:
>
> local_fd = open(local_path, O_WRONLY | O_CREAT | S_IWRITE | mode |
> resume ? 0 : O_TRUNC)
> fstat(local_fd, &st)
> offset = highwater = st.st_size
> // test bigger, etc.
Yep, agreed as well.
>
>
> >@@ -1139,6 +1183,12 @@ do_download(struct sftp_conn *conn, char
> > write_error = 1;
> > max_req = 0;
> > }
> >+ else if (req->offset <= highwater)
> >+ highwater = req->offset + len;
> >+ else if (req->offset > highwater) {
> >+ ftruncate(local_fd, 0);
> >+ printf("reordered blocks detected");
>
> This will spam the user for every block transferred and break the
> download of a file that would have otherwise downloaded fine (by
> truncating it). I think it would be better to just leave highwater
> at 0 for this case and do a debug() call on the first run through
> the loop.
That makes sense.
>
> >+ }
> > progress_counter += len;
> > xfree(data);
> >
> >@@ -1187,6 +1237,11 @@ do_download(struct sftp_conn *conn, char
> > /* Sanity check */
> > if (TAILQ_FIRST(&requests) != NULL)
> > fatal("Transfer complete, but requests still in queue");
> >+ /* Truncate at highest contiguous point to avoid holes on interrupt */
> >+ if (read_error || write_error || interrupted) {
> >+ debug("truncating at %llu", highwater);
> >+ ftruncate(local_fd, highwater);
>
> Here you should check if highwater == 0 to detect reordered blocks
> and warn the user: logit("server reordered requests: %s download
> cannot be resumed", local_path) or something similar.
Added as you requested.
>
> >@@ -1233,6 +1288,7 @@ download_dir_internal(struct sftp_conn *
> > SFTP_DIRENT **dir_entries;
> > char *filename, *new_src, *new_dst;
> > mode_t mode = 0777;
> >+ int resume = 0;
> >
> > if (depth >= MAX_DIR_DEPTH) {
> > error("Maximum directory depth exceeded: %d levels", depth);
> >@@ -1284,7 +1340,7 @@ download_dir_internal(struct sftp_conn *
> > ret = -1;
> > } else if (S_ISREG(dir_entries[i]->a.perm) ) {
> > if (do_download(conn, new_src, new_dst,
> >- &(dir_entries[i]->a), pflag) == -1) {
> >+ &(dir_entries[i]->a), pflag, resume) == -1) {
>
> why use a variable here and not just 0?
do_download() needs to later pass on the resume value. It can be 1 as
well.
--
You are receiving this mail because:
You are watching the assignee of the bug.
You are watching someone on the CC list of the bug.
More information about the openssh-bugs
mailing list