=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sftp.c,v retrieving revision 1.155 retrieving revision 1.156 diff -u -r1.155 -r1.156 --- src/usr.bin/ssh/sftp.c 2013/08/31 00:13:54 1.155 +++ src/usr.bin/ssh/sftp.c 2013/10/17 00:30:13 1.156 @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.155 2013/08/31 00:13:54 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.156 2013/10/17 00:30:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -75,6 +75,9 @@ /* When this option is set, the file transfers will always preserve times */ int global_pflag = 0; +/* When this option is set, transfers will have fsync() called on each file */ +int global_fflag = 0; + /* SIGINT received during command processing */ volatile sig_atomic_t interrupted = 0; @@ -338,7 +341,7 @@ static int parse_getput_flags(const char *cmd, char **argv, int argc, - int *aflag, int *pflag, int *rflag) + int *aflag, int *fflag, int *pflag, int *rflag) { extern int opterr, optind, optopt, optreset; int ch; @@ -346,12 +349,15 @@ optind = optreset = 1; opterr = 0; - *aflag = *rflag = *pflag = 0; - while ((ch = getopt(argc, argv, "aPpRr")) != -1) { + *aflag = *fflag = *rflag = *pflag = 0; + while ((ch = getopt(argc, argv, "afPpRr")) != -1) { switch (ch) { case 'a': *aflag = 1; break; + case 'f': + *fflag = 1; + break; case 'p': case 'P': *pflag = 1; @@ -553,7 +559,7 @@ static int process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, - int pflag, int rflag, int resume) + int pflag, int rflag, int resume, int fflag) { char *abs_src = NULL; char *abs_dst = NULL; @@ -612,11 +618,13 @@ printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, 1, resume) == -1) + pflag || global_pflag, 1, resume, + fflag || global_fflag) == -1) err = -1; } else { if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, resume) == -1) + pflag || global_pflag, resume, + fflag || global_fflag) == -1) err = -1; } free(abs_dst); @@ -631,7 +639,7 @@ static int process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, - int pflag, int rflag) + int pflag, int rflag, int fflag) { char *tmp_dst = NULL; char *abs_dst = NULL; @@ -698,11 +706,13 @@ 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) == -1) + pflag || global_pflag, 1, + fflag || global_fflag) == -1) err = -1; } else { if (do_upload(conn, g.gl_pathv[i], abs_dst, - pflag || global_pflag) == -1) + pflag || global_pflag, + fflag || global_fflag) == -1) err = -1; } } @@ -1155,9 +1165,9 @@ } static int -parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag, - int *pflag, int *rflag, int *sflag, unsigned long *n_arg, - char **path1, char **path2) +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; char *cp2, **argv; @@ -1169,9 +1179,9 @@ cp = cp + strspn(cp, WHITESPACE); /* Check for leading '-' (disable error processing) */ - *iflag = 0; + *ignore_errors = 0; if (*cp == '-') { - *iflag = 1; + *ignore_errors = 1; cp++; cp = cp + strspn(cp, WHITESPACE); } @@ -1201,7 +1211,8 @@ } /* Get arguments and parse flags */ - *aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0; + *aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0; + *rflag = *sflag = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { @@ -1209,7 +1220,7 @@ case I_REGET: case I_PUT: if ((optidx = parse_getput_flags(cmd, argv, argc, - aflag, pflag, rflag)) == -1) + aflag, fflag, pflag, rflag)) == -1) return -1; /* Get first pathname (mandatory) */ if (argc - optidx < 1) { @@ -1350,8 +1361,8 @@ int err_abort) { char *path1, *path2, *tmp; - int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0; - int rflag = 0, sflag = 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; Attrib a, *aa; @@ -1360,9 +1371,9 @@ glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag, - &rflag, &sflag, &n_arg, &path1, &path2); - if (iflag != 0) + cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, + &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); + if (ignore_errors != 0) err_abort = 0; memset(&g, 0, sizeof(g)); @@ -1381,10 +1392,11 @@ /* FALLTHROUGH */ case I_GET: err = process_get(conn, path1, path2, *pwd, pflag, - rflag, aflag); + rflag, aflag, fflag); break; case I_PUT: - err = process_put(conn, path1, path2, *pwd, pflag, rflag); + err = process_put(conn, path1, path2, *pwd, pflag, + rflag, fflag); break; case I_RENAME: path1 = make_absolute(path1, *pwd); @@ -2189,7 +2201,7 @@ infile = stdin; while ((ch = getopt(argc, argv, - "1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { + "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': @@ -2248,6 +2260,9 @@ showprogress = 0; quiet = batchmode = 1; addargs(&args, "-obatchmode yes"); + break; + case 'f': + global_fflag = 1; break; case 'p': global_pflag = 1;