- logan@cvs.openbsd.org 2014/04/21 14:36:16
[sftp-client.c sftp-client.h sftp.c]
Implement sftp upload resume support.
OK from djm@, with input from guenther@, mlarkin@ and
okan@
diff --git a/sftp.c b/sftp.c
index ad1f8c8..e74bed5 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.158 2013/11/20 20:54:10 deraadt Exp $ */
+/* $OpenBSD: sftp.c,v 1.159 2014/04/21 14:36:16 logan Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -88,7 +88,7 @@
/* When this option is set, we always recursively download/upload directories */
int global_rflag = 0;
-/* When this option is set, we resume download if possible */
+/* When this option is set, we resume download or upload if possible */
int global_aflag = 0;
/* When this option is set, the file transfers will always preserve times */
@@ -159,6 +159,7 @@
I_VERSION,
I_PROGRESS,
I_REGET,
+ I_REPUT
};
struct CMD {
@@ -201,6 +202,7 @@
{ "quit", I_QUIT, NOARGS },
{ "reget", I_REGET, REMOTE },
{ "rename", I_RENAME, REMOTE },
+ { "reput", I_REPUT, LOCAL },
{ "rm", I_RM, REMOTE },
{ "rmdir", I_RMDIR, REMOTE },
{ "symlink", I_SYMLINK, REMOTE },
@@ -250,6 +252,7 @@
"exit Quit sftp\n"
"get [-Ppr] remote [local] Download file\n"
"reget remote [local] Resume download file\n"
+ "reput [local] remote Resume upload file\n"
"help Display this help text\n"
"lcd path Change local directory to 'path'\n"
"lls [ls-options [path]] Display local directory listing\n"
@@ -660,7 +663,7 @@
static int
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
- int pflag, int rflag, int fflag)
+ int pflag, int rflag, int resume, int fflag)
{
char *tmp_dst = NULL;
char *abs_dst = NULL;
@@ -723,16 +726,20 @@
}
free(tmp);
- if (!quiet)
+ resume |= global_aflag;
+ if (!quiet && resume)
+ printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
+ abs_dst);
+ else if (!quiet && !resume)
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
- pflag || global_pflag, 1,
+ pflag || global_pflag, 1, resume,
fflag || global_fflag) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
- pflag || global_pflag,
+ pflag || global_pflag, resume,
fflag || global_fflag) == -1)
err = -1;
}
@@ -1186,8 +1193,9 @@
}
static int
-parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag,
- int *hflag, int *iflag, int *lflag, int *pflag, int *rflag, int *sflag,
+parse_args(const char **cpp, int *ignore_errors, int *aflag,
+ int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
+ int *rflag, int *sflag,
unsigned long *n_arg, char **path1, char **path2)
{
const char *cmd, *cp = *cpp;
@@ -1239,6 +1247,7 @@
switch (cmdnum) {
case I_GET:
case I_REGET:
+ case I_REPUT:
case I_PUT:
if ((optidx = parse_getput_flags(cmd, argv, argc,
aflag, fflag, pflag, rflag)) == -1)
@@ -1256,11 +1265,6 @@
/* Destination is not globbed */
undo_glob_escape(*path2);
}
- if (*aflag && cmdnum == I_PUT) {
- /* XXX implement resume for uploads */
- error("Resume is not supported for uploads");
- return -1;
- }
break;
case I_LINK:
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
@@ -1382,7 +1386,8 @@
int err_abort)
{
char *path1, *path2, *tmp;
- int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, iflag = 0;
+ int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
+ iflag = 0;
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
@@ -1415,9 +1420,12 @@
err = process_get(conn, path1, path2, *pwd, pflag,
rflag, aflag, fflag);
break;
+ case I_REPUT:
+ aflag = 1;
+ /* FALLTHROUGH */
case I_PUT:
err = process_put(conn, path1, path2, *pwd, pflag,
- rflag, fflag);
+ rflag, aflag, fflag);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);