diff options
author | Damien Miller <djm@mindrot.org> | 2013-10-17 11:48:52 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2013-10-17 11:48:52 +1100 |
commit | f29238e67471a7f1088a99c3c3dbafce76b790cf (patch) | |
tree | 39ea232a72df52b4adbc3affea0108d8b0f45b42 /sftp.c | |
parent | 51682faa599550a69d8120e5e2bdbdc0625ef4be (diff) |
- djm@cvs.openbsd.org 2013/10/17 00:30:13
[PROTOCOL sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c]
fsync@openssh.com protocol extension for sftp-server
client support to allow calling fsync() faster successful transfer
patch mostly by imorgan AT nas.nasa.gov; bz#1798
"fine" markus@ "grumble OK" deraadt@ "doesn't sound bad to me" millert@
Diffstat (limited to 'sftp.c')
-rw-r--r-- | sftp.c | 65 |
1 files changed, 40 insertions, 25 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.c,v 1.155 2013/08/31 00:13:54 djm Exp $ */ | 1 | /* $OpenBSD: sftp.c,v 1.156 2013/10/17 00:30:13 djm 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 | * |
@@ -94,6 +94,9 @@ int global_aflag = 0; | |||
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 */ |
95 | int global_pflag = 0; | 95 | int global_pflag = 0; |
96 | 96 | ||
97 | /* When this option is set, transfers will have fsync() called on each file */ | ||
98 | int global_fflag = 0; | ||
99 | |||
97 | /* SIGINT received during command processing */ | 100 | /* SIGINT received during command processing */ |
98 | volatile sig_atomic_t interrupted = 0; | 101 | volatile sig_atomic_t interrupted = 0; |
99 | 102 | ||
@@ -359,7 +362,7 @@ make_absolute(char *p, char *pwd) | |||
359 | 362 | ||
360 | static int | 363 | static int |
361 | parse_getput_flags(const char *cmd, char **argv, int argc, | 364 | parse_getput_flags(const char *cmd, char **argv, int argc, |
362 | int *aflag, int *pflag, int *rflag) | 365 | int *aflag, int *fflag, int *pflag, int *rflag) |
363 | { | 366 | { |
364 | extern int opterr, optind, optopt, optreset; | 367 | extern int opterr, optind, optopt, optreset; |
365 | int ch; | 368 | int ch; |
@@ -367,12 +370,15 @@ parse_getput_flags(const char *cmd, char **argv, int argc, | |||
367 | optind = optreset = 1; | 370 | optind = optreset = 1; |
368 | opterr = 0; | 371 | opterr = 0; |
369 | 372 | ||
370 | *aflag = *rflag = *pflag = 0; | 373 | *aflag = *fflag = *rflag = *pflag = 0; |
371 | while ((ch = getopt(argc, argv, "aPpRr")) != -1) { | 374 | while ((ch = getopt(argc, argv, "afPpRr")) != -1) { |
372 | switch (ch) { | 375 | switch (ch) { |
373 | case 'a': | 376 | case 'a': |
374 | *aflag = 1; | 377 | *aflag = 1; |
375 | break; | 378 | break; |
379 | case 'f': | ||
380 | *fflag = 1; | ||
381 | break; | ||
376 | case 'p': | 382 | case 'p': |
377 | case 'P': | 383 | case 'P': |
378 | *pflag = 1; | 384 | *pflag = 1; |
@@ -574,7 +580,7 @@ pathname_is_dir(char *pathname) | |||
574 | 580 | ||
575 | static int | 581 | static int |
576 | process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, | 582 | process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
577 | int pflag, int rflag, int resume) | 583 | int pflag, int rflag, int resume, int fflag) |
578 | { | 584 | { |
579 | char *abs_src = NULL; | 585 | char *abs_src = NULL; |
580 | char *abs_dst = NULL; | 586 | char *abs_dst = NULL; |
@@ -633,11 +639,13 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, | |||
633 | printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); | 639 | printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
634 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | 640 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
635 | if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, | 641 | if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, |
636 | pflag || global_pflag, 1, resume) == -1) | 642 | pflag || global_pflag, 1, resume, |
643 | fflag || global_fflag) == -1) | ||
637 | err = -1; | 644 | err = -1; |
638 | } else { | 645 | } else { |
639 | if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, | 646 | if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, |
640 | pflag || global_pflag, resume) == -1) | 647 | pflag || global_pflag, resume, |
648 | fflag || global_fflag) == -1) | ||
641 | err = -1; | 649 | err = -1; |
642 | } | 650 | } |
643 | free(abs_dst); | 651 | free(abs_dst); |
@@ -652,7 +660,7 @@ out: | |||
652 | 660 | ||
653 | static int | 661 | static int |
654 | process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, | 662 | process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
655 | int pflag, int rflag) | 663 | int pflag, int rflag, int fflag) |
656 | { | 664 | { |
657 | char *tmp_dst = NULL; | 665 | char *tmp_dst = NULL; |
658 | char *abs_dst = NULL; | 666 | char *abs_dst = NULL; |
@@ -719,11 +727,13 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, | |||
719 | printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); | 727 | printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); |
720 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | 728 | if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
721 | if (upload_dir(conn, g.gl_pathv[i], abs_dst, | 729 | if (upload_dir(conn, g.gl_pathv[i], abs_dst, |
722 | pflag || global_pflag, 1) == -1) | 730 | pflag || global_pflag, 1, |
731 | fflag || global_fflag) == -1) | ||
723 | err = -1; | 732 | err = -1; |
724 | } else { | 733 | } else { |
725 | if (do_upload(conn, g.gl_pathv[i], abs_dst, | 734 | if (do_upload(conn, g.gl_pathv[i], abs_dst, |
726 | pflag || global_pflag) == -1) | 735 | pflag || global_pflag, |
736 | fflag || global_fflag) == -1) | ||
727 | err = -1; | 737 | err = -1; |
728 | } | 738 | } |
729 | } | 739 | } |
@@ -1176,9 +1186,9 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, | |||
1176 | } | 1186 | } |
1177 | 1187 | ||
1178 | static int | 1188 | static int |
1179 | parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, | 1189 | parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag, |
1180 | int *pflag, int *rflag, int *sflag, unsigned long *n_arg, | 1190 | int *hflag, int *iflag, int *lflag, int *pflag, int *rflag, int *sflag, |
1181 | char **path1, char **path2) | 1191 | unsigned long *n_arg, char **path1, char **path2) |
1182 | { | 1192 | { |
1183 | const char *cmd, *cp = *cpp; | 1193 | const char *cmd, *cp = *cpp; |
1184 | char *cp2, **argv; | 1194 | char *cp2, **argv; |
@@ -1190,9 +1200,9 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, | |||
1190 | cp = cp + strspn(cp, WHITESPACE); | 1200 | cp = cp + strspn(cp, WHITESPACE); |
1191 | 1201 | ||
1192 | /* Check for leading '-' (disable error processing) */ | 1202 | /* Check for leading '-' (disable error processing) */ |
1193 | *iflag = 0; | 1203 | *ignore_errors = 0; |
1194 | if (*cp == '-') { | 1204 | if (*cp == '-') { |
1195 | *iflag = 1; | 1205 | *ignore_errors = 1; |
1196 | cp++; | 1206 | cp++; |
1197 | cp = cp + strspn(cp, WHITESPACE); | 1207 | cp = cp + strspn(cp, WHITESPACE); |
1198 | } | 1208 | } |
@@ -1222,7 +1232,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, | |||
1222 | } | 1232 | } |
1223 | 1233 | ||
1224 | /* Get arguments and parse flags */ | 1234 | /* Get arguments and parse flags */ |
1225 | *aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; | 1235 | *aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0; |
1236 | *rflag = *sflag = 0; | ||
1226 | *path1 = *path2 = NULL; | 1237 | *path1 = *path2 = NULL; |
1227 | optidx = 1; | 1238 | optidx = 1; |
1228 | switch (cmdnum) { | 1239 | switch (cmdnum) { |
@@ -1230,7 +1241,7 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, | |||
1230 | case I_REGET: | 1241 | case I_REGET: |
1231 | case I_PUT: | 1242 | case I_PUT: |
1232 | if ((optidx = parse_getput_flags(cmd, argv, argc, | 1243 | if ((optidx = parse_getput_flags(cmd, argv, argc, |
1233 | aflag, pflag, rflag)) == -1) | 1244 | aflag, fflag, pflag, rflag)) == -1) |
1234 | return -1; | 1245 | return -1; |
1235 | /* Get first pathname (mandatory) */ | 1246 | /* Get first pathname (mandatory) */ |
1236 | if (argc - optidx < 1) { | 1247 | if (argc - optidx < 1) { |
@@ -1371,8 +1382,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1371 | int err_abort) | 1382 | int err_abort) |
1372 | { | 1383 | { |
1373 | char *path1, *path2, *tmp; | 1384 | char *path1, *path2, *tmp; |
1374 | int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; | 1385 | int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, iflag = 0; |
1375 | int rflag = 0, sflag = 0; | 1386 | int lflag = 0, pflag = 0, rflag = 0, sflag = 0; |
1376 | int cmdnum, i; | 1387 | int cmdnum, i; |
1377 | unsigned long n_arg = 0; | 1388 | unsigned long n_arg = 0; |
1378 | Attrib a, *aa; | 1389 | Attrib a, *aa; |
@@ -1381,9 +1392,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1381 | glob_t g; | 1392 | glob_t g; |
1382 | 1393 | ||
1383 | path1 = path2 = NULL; | 1394 | path1 = path2 = NULL; |
1384 | cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, | 1395 | cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, |
1385 | &rflag, &sflag, &n_arg, &path1, &path2); | 1396 | &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); |
1386 | if (iflag != 0) | 1397 | if (ignore_errors != 0) |
1387 | err_abort = 0; | 1398 | err_abort = 0; |
1388 | 1399 | ||
1389 | memset(&g, 0, sizeof(g)); | 1400 | memset(&g, 0, sizeof(g)); |
@@ -1402,10 +1413,11 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1402 | /* FALLTHROUGH */ | 1413 | /* FALLTHROUGH */ |
1403 | case I_GET: | 1414 | case I_GET: |
1404 | err = process_get(conn, path1, path2, *pwd, pflag, | 1415 | err = process_get(conn, path1, path2, *pwd, pflag, |
1405 | rflag, aflag); | 1416 | rflag, aflag, fflag); |
1406 | break; | 1417 | break; |
1407 | case I_PUT: | 1418 | case I_PUT: |
1408 | err = process_put(conn, path1, path2, *pwd, pflag, rflag); | 1419 | err = process_put(conn, path1, path2, *pwd, pflag, |
1420 | rflag, fflag); | ||
1409 | break; | 1421 | break; |
1410 | case I_RENAME: | 1422 | case I_RENAME: |
1411 | path1 = make_absolute(path1, *pwd); | 1423 | path1 = make_absolute(path1, *pwd); |
@@ -2231,7 +2243,7 @@ main(int argc, char **argv) | |||
2231 | infile = stdin; | 2243 | infile = stdin; |
2232 | 2244 | ||
2233 | while ((ch = getopt(argc, argv, | 2245 | while ((ch = getopt(argc, argv, |
2234 | "1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { | 2246 | "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { |
2235 | switch (ch) { | 2247 | switch (ch) { |
2236 | /* Passed through to ssh(1) */ | 2248 | /* Passed through to ssh(1) */ |
2237 | case '4': | 2249 | case '4': |
@@ -2291,6 +2303,9 @@ main(int argc, char **argv) | |||
2291 | quiet = batchmode = 1; | 2303 | quiet = batchmode = 1; |
2292 | addargs(&args, "-obatchmode yes"); | 2304 | addargs(&args, "-obatchmode yes"); |
2293 | break; | 2305 | break; |
2306 | case 'f': | ||
2307 | global_fflag = 1; | ||
2308 | break; | ||
2294 | case 'p': | 2309 | case 'p': |
2295 | global_pflag = 1; | 2310 | global_pflag = 1; |
2296 | break; | 2311 | break; |