summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-17 11:48:52 +1100
committerDamien Miller <djm@mindrot.org>2013-10-17 11:48:52 +1100
commitf29238e67471a7f1088a99c3c3dbafce76b790cf (patch)
tree39ea232a72df52b4adbc3affea0108d8b0f45b42 /sftp.c
parent51682faa599550a69d8120e5e2bdbdc0625ef4be (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.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/sftp.c b/sftp.c
index f7b488ae5..c316e1ed4 100644
--- a/sftp.c
+++ b/sftp.c
@@ -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 */
95int global_pflag = 0; 95int global_pflag = 0;
96 96
97/* When this option is set, transfers will have fsync() called on each file */
98int global_fflag = 0;
99
97/* SIGINT received during command processing */ 100/* SIGINT received during command processing */
98volatile sig_atomic_t interrupted = 0; 101volatile sig_atomic_t interrupted = 0;
99 102
@@ -359,7 +362,7 @@ make_absolute(char *p, char *pwd)
359 362
360static int 363static int
361parse_getput_flags(const char *cmd, char **argv, int argc, 364parse_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
575static int 581static int
576process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, 582process_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
653static int 661static int
654process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, 662process_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
1178static int 1188static int
1179parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, 1189parse_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;