summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-05-15 13:46:25 +1000
committerDamien Miller <djm@mindrot.org>2014-05-15 13:46:25 +1000
commitd8accc0aa72656ba63d50937165c5ae49db1dcd6 (patch)
tree95e22a55fc9c75952f3fdc684cd96b8c0538871d /sftp.c
parent16cd3928a87d20c77b13592a74b60b08621d3ce6 (diff)
- 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@
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/sftp.c b/sftp.c
index ad1f8c84d..e74bed5e0 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.158 2013/11/20 20:54:10 deraadt Exp $ */ 1/* $OpenBSD: sftp.c,v 1.159 2014/04/21 14:36:16 logan Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -88,7 +88,7 @@ int showprogress = 1;
88/* When this option is set, we always recursively download/upload directories */ 88/* When this option is set, we always recursively download/upload directories */
89int global_rflag = 0; 89int global_rflag = 0;
90 90
91/* When this option is set, we resume download if possible */ 91/* When this option is set, we resume download or upload if possible */
92int global_aflag = 0; 92int global_aflag = 0;
93 93
94/* When this option is set, the file transfers will always preserve times */ 94/* When this option is set, the file transfers will always preserve times */
@@ -159,6 +159,7 @@ enum sftp_command {
159 I_VERSION, 159 I_VERSION,
160 I_PROGRESS, 160 I_PROGRESS,
161 I_REGET, 161 I_REGET,
162 I_REPUT
162}; 163};
163 164
164struct CMD { 165struct CMD {
@@ -201,6 +202,7 @@ static const struct CMD cmds[] = {
201 { "quit", I_QUIT, NOARGS }, 202 { "quit", I_QUIT, NOARGS },
202 { "reget", I_REGET, REMOTE }, 203 { "reget", I_REGET, REMOTE },
203 { "rename", I_RENAME, REMOTE }, 204 { "rename", I_RENAME, REMOTE },
205 { "reput", I_REPUT, LOCAL },
204 { "rm", I_RM, REMOTE }, 206 { "rm", I_RM, REMOTE },
205 { "rmdir", I_RMDIR, REMOTE }, 207 { "rmdir", I_RMDIR, REMOTE },
206 { "symlink", I_SYMLINK, REMOTE }, 208 { "symlink", I_SYMLINK, REMOTE },
@@ -250,6 +252,7 @@ help(void)
250 "exit Quit sftp\n" 252 "exit Quit sftp\n"
251 "get [-Ppr] remote [local] Download file\n" 253 "get [-Ppr] remote [local] Download file\n"
252 "reget remote [local] Resume download file\n" 254 "reget remote [local] Resume download file\n"
255 "reput [local] remote Resume upload file\n"
253 "help Display this help text\n" 256 "help Display this help text\n"
254 "lcd path Change local directory to 'path'\n" 257 "lcd path Change local directory to 'path'\n"
255 "lls [ls-options [path]] Display local directory listing\n" 258 "lls [ls-options [path]] Display local directory listing\n"
@@ -660,7 +663,7 @@ out:
660 663
661static int 664static int
662process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, 665process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
663 int pflag, int rflag, int fflag) 666 int pflag, int rflag, int resume, int fflag)
664{ 667{
665 char *tmp_dst = NULL; 668 char *tmp_dst = NULL;
666 char *abs_dst = NULL; 669 char *abs_dst = NULL;
@@ -723,16 +726,20 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
723 } 726 }
724 free(tmp); 727 free(tmp);
725 728
726 if (!quiet) 729 resume |= global_aflag;
730 if (!quiet && resume)
731 printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
732 abs_dst);
733 else if (!quiet && !resume)
727 printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); 734 printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
728 if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { 735 if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
729 if (upload_dir(conn, g.gl_pathv[i], abs_dst, 736 if (upload_dir(conn, g.gl_pathv[i], abs_dst,
730 pflag || global_pflag, 1, 737 pflag || global_pflag, 1, resume,
731 fflag || global_fflag) == -1) 738 fflag || global_fflag) == -1)
732 err = -1; 739 err = -1;
733 } else { 740 } else {
734 if (do_upload(conn, g.gl_pathv[i], abs_dst, 741 if (do_upload(conn, g.gl_pathv[i], abs_dst,
735 pflag || global_pflag, 742 pflag || global_pflag, resume,
736 fflag || global_fflag) == -1) 743 fflag || global_fflag) == -1)
737 err = -1; 744 err = -1;
738 } 745 }
@@ -1186,8 +1193,9 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
1186} 1193}
1187 1194
1188static int 1195static int
1189parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag, 1196parse_args(const char **cpp, int *ignore_errors, int *aflag,
1190 int *hflag, int *iflag, int *lflag, int *pflag, int *rflag, int *sflag, 1197 int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
1198 int *rflag, int *sflag,
1191 unsigned long *n_arg, char **path1, char **path2) 1199 unsigned long *n_arg, char **path1, char **path2)
1192{ 1200{
1193 const char *cmd, *cp = *cpp; 1201 const char *cmd, *cp = *cpp;
@@ -1239,6 +1247,7 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag,
1239 switch (cmdnum) { 1247 switch (cmdnum) {
1240 case I_GET: 1248 case I_GET:
1241 case I_REGET: 1249 case I_REGET:
1250 case I_REPUT:
1242 case I_PUT: 1251 case I_PUT:
1243 if ((optidx = parse_getput_flags(cmd, argv, argc, 1252 if ((optidx = parse_getput_flags(cmd, argv, argc,
1244 aflag, fflag, pflag, rflag)) == -1) 1253 aflag, fflag, pflag, rflag)) == -1)
@@ -1256,11 +1265,6 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag,
1256 /* Destination is not globbed */ 1265 /* Destination is not globbed */
1257 undo_glob_escape(*path2); 1266 undo_glob_escape(*path2);
1258 } 1267 }
1259 if (*aflag && cmdnum == I_PUT) {
1260 /* XXX implement resume for uploads */
1261 error("Resume is not supported for uploads");
1262 return -1;
1263 }
1264 break; 1268 break;
1265 case I_LINK: 1269 case I_LINK:
1266 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) 1270 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
@@ -1382,7 +1386,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1382 int err_abort) 1386 int err_abort)
1383{ 1387{
1384 char *path1, *path2, *tmp; 1388 char *path1, *path2, *tmp;
1385 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, iflag = 0; 1389 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
1390 iflag = 0;
1386 int lflag = 0, pflag = 0, rflag = 0, sflag = 0; 1391 int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
1387 int cmdnum, i; 1392 int cmdnum, i;
1388 unsigned long n_arg = 0; 1393 unsigned long n_arg = 0;
@@ -1415,9 +1420,12 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1415 err = process_get(conn, path1, path2, *pwd, pflag, 1420 err = process_get(conn, path1, path2, *pwd, pflag,
1416 rflag, aflag, fflag); 1421 rflag, aflag, fflag);
1417 break; 1422 break;
1423 case I_REPUT:
1424 aflag = 1;
1425 /* FALLTHROUGH */
1418 case I_PUT: 1426 case I_PUT:
1419 err = process_put(conn, path1, path2, *pwd, pflag, 1427 err = process_put(conn, path1, path2, *pwd, pflag,
1420 rflag, fflag); 1428 rflag, aflag, fflag);
1421 break; 1429 break;
1422 case I_RENAME: 1430 case I_RENAME:
1423 path1 = make_absolute(path1, *pwd); 1431 path1 = make_absolute(path1, *pwd);