View | Details | Raw Unified | Return to bug 1798 | Differences between
and this patch

Collapse All | Expand All

(-)sftp-client.c (-12 / +58 lines)
Lines 76-81 Link Here
76
#define SFTP_EXT_STATVFS	0x00000002
76
#define SFTP_EXT_STATVFS	0x00000002
77
#define SFTP_EXT_FSTATVFS	0x00000004
77
#define SFTP_EXT_FSTATVFS	0x00000004
78
#define SFTP_EXT_HARDLINK	0x00000008
78
#define SFTP_EXT_HARDLINK	0x00000008
79
#define SFTP_EXT_FSYNC		0x00000010
79
	u_int exts;
80
	u_int exts;
80
	u_int64_t limit_kbps;
81
	u_int64_t limit_kbps;
81
	struct bwlimit bwlimit_in, bwlimit_out;
82
	struct bwlimit bwlimit_in, bwlimit_out;
Lines 387-392 Link Here
387
		    strcmp(value, "1") == 0) {
388
		    strcmp(value, "1") == 0) {
388
			ret->exts |= SFTP_EXT_HARDLINK;
389
			ret->exts |= SFTP_EXT_HARDLINK;
389
			known = 1;
390
			known = 1;
391
 		} else if (strcmp(name, "fsync@openssh.com") == 0 &&
392
 		    strcmp(value, "1") == 0) {
393
 			ret->exts |= SFTP_EXT_FSYNC;
394
 			known = 1;
390
		}
395
		}
391
		if (known) {
396
		if (known) {
392
			debug2("Server supports extension \"%s\" revision %s",
397
			debug2("Server supports extension \"%s\" revision %s",
Lines 864-869 Link Here
864
	return(status);
869
	return(status);
865
}
870
}
866
871
872
int
873
do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len)
874
{
875
	Buffer msg;
876
	u_int status, id;
877
878
	/* Silently return if the extension is not supported */
879
	if ((conn->exts & SFTP_EXT_FSYNC) == 0)
880
		return -1;
881
882
	buffer_init(&msg);
883
884
	/* Send fsync request */
885
	id = conn->msg_id++;
886
887
	buffer_put_char(&msg, SSH2_FXP_EXTENDED);
888
	buffer_put_int(&msg, id);
889
	buffer_put_cstring(&msg, "fsync@openssh.com");
890
	buffer_put_string(&msg, handle, handle_len);
891
	send_msg(conn, &msg);
892
	debug3("Sent message fsync@openssh.com I:%u", id);
893
	buffer_free(&msg);
894
895
	status = get_status(conn, id);
896
	if (status != SSH2_FX_OK)
897
		error("Couldn't sync file: %s", fx2txt(status));
898
899
	return(status);
900
}
901
867
#ifdef notyet
902
#ifdef notyet
868
char *
903
char *
869
do_readlink(struct sftp_conn *conn, char *path)
904
do_readlink(struct sftp_conn *conn, char *path)
Lines 985-991 Link Here
985
1020
986
int
1021
int
987
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
1022
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
988
    Attrib *a, int pflag)
1023
    Attrib *a, int pflag, int fflag)
989
{
1024
{
990
	Attrib junk;
1025
	Attrib junk;
991
	Buffer msg;
1026
	Buffer msg;
Lines 1214-1219 Link Here
1214
				error("Can't set times on \"%s\": %s",
1249
				error("Can't set times on \"%s\": %s",
1215
				    local_path, strerror(errno));
1250
				    local_path, strerror(errno));
1216
		}
1251
		}
1252
		/* Flush file to disk if requested */
1253
		if (fflag) {
1254
			debug("syncing \"%s\"", local_path);
1255
			if (fsync(local_fd) == -1)
1256
				error("Couldn't sync file \"%s\": %s",
1257
				    local_path, strerror(errno));
1258
		}
1217
	}
1259
	}
1218
	close(local_fd);
1260
	close(local_fd);
1219
	buffer_free(&msg);
1261
	buffer_free(&msg);
Lines 1224-1230 Link Here
1224
1266
1225
static int
1267
static int
1226
download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
1268
download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
1227
    Attrib *dirattrib, int pflag, int printflag, int depth)
1269
    Attrib *dirattrib, int pflag, int fflag, int printflag, int depth)
1228
{
1270
{
1229
	int i, ret = 0;
1271
	int i, ret = 0;
1230
	SFTP_DIRENT **dir_entries;
1272
	SFTP_DIRENT **dir_entries;
Lines 1276-1287 Link Here
1276
			    strcmp(filename, "..") == 0)
1318
			    strcmp(filename, "..") == 0)
1277
				continue;
1319
				continue;
1278
			if (download_dir_internal(conn, new_src, new_dst,
1320
			if (download_dir_internal(conn, new_src, new_dst,
1279
			    &(dir_entries[i]->a), pflag, printflag,
1321
			    &(dir_entries[i]->a), pflag, fflag, printflag,
1280
			    depth + 1) == -1)
1322
			    depth + 1) == -1)
1281
				ret = -1;
1323
				ret = -1;
1282
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1324
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1283
			if (do_download(conn, new_src, new_dst,
1325
			if (do_download(conn, new_src, new_dst,
1284
			    &(dir_entries[i]->a), pflag) == -1) {
1326
			    &(dir_entries[i]->a), pflag, fflag) == -1) {
1285
				error("Download of file %s to %s failed",
1327
				error("Download of file %s to %s failed",
1286
				    new_src, new_dst);
1328
				    new_src, new_dst);
1287
				ret = -1;
1329
				ret = -1;
Lines 1314-1320 Link Here
1314
1356
1315
int
1357
int
1316
download_dir(struct sftp_conn *conn, char *src, char *dst,
1358
download_dir(struct sftp_conn *conn, char *src, char *dst,
1317
    Attrib *dirattrib, int pflag, int printflag)
1359
    Attrib *dirattrib, int pflag, int fflag, int printflag)
1318
{
1360
{
1319
	char *src_canon;
1361
	char *src_canon;
1320
	int ret;
1362
	int ret;
Lines 1325-1338 Link Here
1325
	}
1367
	}
1326
1368
1327
	ret = download_dir_internal(conn, src_canon, dst,
1369
	ret = download_dir_internal(conn, src_canon, dst,
1328
	    dirattrib, pflag, printflag, 0);
1370
	    dirattrib, pflag, fflag, printflag, 0);
1329
	xfree(src_canon);
1371
	xfree(src_canon);
1330
	return ret;
1372
	return ret;
1331
}
1373
}
1332
1374
1333
int
1375
int
1334
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1376
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1335
    int pflag)
1377
    int pflag, int fflag)
1336
{
1378
{
1337
	int local_fd;
1379
	int local_fd;
1338
	int status = SSH2_FX_OK;
1380
	int status = SSH2_FX_OK;
Lines 1506-1511 Link Here
1506
	if (pflag)
1548
	if (pflag)
1507
		do_fsetstat(conn, handle, handle_len, &a);
1549
		do_fsetstat(conn, handle, handle_len, &a);
1508
1550
1551
	if (fflag)
1552
		(void)do_fsync(conn, handle, handle_len);
1553
1509
	if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
1554
	if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
1510
		status = -1;
1555
		status = -1;
1511
	xfree(handle);
1556
	xfree(handle);
Lines 1515-1521 Link Here
1515
1560
1516
static int
1561
static int
1517
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
1562
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
1518
    int pflag, int printflag, int depth)
1563
    int pflag, int fflag, int printflag, int depth)
1519
{
1564
{
1520
	int ret = 0, status;
1565
	int ret = 0, status;
1521
	DIR *dirp;
1566
	DIR *dirp;
Lines 1584-1593 Link Here
1584
				continue;
1629
				continue;
1585
1630
1586
			if (upload_dir_internal(conn, new_src, new_dst,
1631
			if (upload_dir_internal(conn, new_src, new_dst,
1587
			    pflag, printflag, depth + 1) == -1)
1632
			    pflag, fflag, printflag, depth + 1) == -1)
1588
				ret = -1;
1633
				ret = -1;
1589
		} else if (S_ISREG(sb.st_mode)) {
1634
		} else if (S_ISREG(sb.st_mode)) {
1590
			if (do_upload(conn, new_src, new_dst, pflag) == -1) {
1635
			if (do_upload(conn, new_src, new_dst, pflag,
1636
			    fflag) == -1) {
1591
				error("Uploading of file %s to %s failed!",
1637
				error("Uploading of file %s to %s failed!",
1592
				    new_src, new_dst);
1638
				    new_src, new_dst);
1593
				ret = -1;
1639
				ret = -1;
Lines 1606-1612 Link Here
1606
1652
1607
int
1653
int
1608
upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
1654
upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
1609
    int pflag)
1655
    int pflag, int fflag)
1610
{
1656
{
1611
	char *dst_canon;
1657
	char *dst_canon;
1612
	int ret;
1658
	int ret;
Lines 1616-1622 Link Here
1616
		return -1;
1662
		return -1;
1617
	}
1663
	}
1618
1664
1619
	ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0);
1665
	ret = upload_dir_internal(conn, src, dst_canon, pflag, fflag, printflag, 0);
1620
	xfree(dst_canon);
1666
	xfree(dst_canon);
1621
	return ret;
1667
	return ret;
1622
}
1668
}
(-)sftp-client.h (-4 / +4 lines)
Lines 106-130 Link Here
106
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
106
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
107
 * if 'pflag' is set
107
 * if 'pflag' is set
108
 */
108
 */
109
int do_download(struct sftp_conn *, char *, char *, Attrib *, int);
109
int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int);
110
110
111
/*
111
/*
112
 * Recursively download 'remote_directory' to 'local_directory'. Preserve 
112
 * Recursively download 'remote_directory' to 'local_directory'. Preserve 
113
 * times if 'pflag' is set
113
 * times if 'pflag' is set
114
 */
114
 */
115
int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int);
115
int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int, int);
116
116
117
/*
117
/*
118
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
118
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
119
 * if 'pflag' is set
119
 * if 'pflag' is set
120
 */
120
 */
121
int do_upload(struct sftp_conn *, char *, char *, int);
121
int do_upload(struct sftp_conn *, char *, char *, int, int);
122
122
123
/*
123
/*
124
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
124
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
125
 * times if 'pflag' is set
125
 * times if 'pflag' is set
126
 */
126
 */
127
int upload_dir(struct sftp_conn *, char *, char *, int, int);
127
int upload_dir(struct sftp_conn *, char *, char *, int, int, int);
128
128
129
/* Concatenate paths, taking care of slashes. Caller must free result. */
129
/* Concatenate paths, taking care of slashes. Caller must free result. */
130
char *path_append(char *, char *);
130
char *path_append(char *, char *);
(-)sftp-server.c (+25 lines)
Lines 538-543 Link Here
538
	/* hardlink extension */
538
	/* hardlink extension */
539
	buffer_put_cstring(&msg, "hardlink@openssh.com");
539
	buffer_put_cstring(&msg, "hardlink@openssh.com");
540
	buffer_put_cstring(&msg, "1"); /* version */
540
	buffer_put_cstring(&msg, "1"); /* version */
541
	/* fsync extension */
542
	buffer_put_cstring(&msg, "fsync@openssh.com");
543
	buffer_put_cstring(&msg, "1"); /* version */
541
	send_msg(&msg);
544
	send_msg(&msg);
542
	buffer_free(&msg);
545
	buffer_free(&msg);
543
}
546
}
Lines 1247-1252 Link Here
1247
}
1250
}
1248
1251
1249
static void
1252
static void
1253
process_extended_fsync(u_int32_t id)
1254
{
1255
	int handle, fd, ret, status = SSH2_FX_NO_SUCH_FILE;
1256
1257
	handle = get_handle();
1258
	debug3("request %u: fsync \"%s\" (handle %u)",
1259
		id, handle_to_name(handle), handle);
1260
	if (readonly)
1261
		status = SSH2_FX_PERMISSION_DENIED;
1262
	else if ((fd = handle_to_fd(handle)) < 0)
1263
		status = SSH2_FX_NO_SUCH_FILE;
1264
	else if (handle_is_ok(handle, HANDLE_FILE)) {
1265
		ret = fsync(fd);
1266
		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
1267
	}
1268
	send_status(id, status);
1269
}
1270
1271
1272
static void
1250
process_extended(void)
1273
process_extended(void)
1251
{
1274
{
1252
	u_int32_t id;
1275
	u_int32_t id;
Lines 1262-1267 Link Here
1262
		process_extended_fstatvfs(id);
1285
		process_extended_fstatvfs(id);
1263
	else if (strcmp(request, "hardlink@openssh.com") == 0)
1286
	else if (strcmp(request, "hardlink@openssh.com") == 0)
1264
		process_extended_hardlink(id);
1287
		process_extended_hardlink(id);
1288
	else if (strcmp(request, "fsync@openssh.com") == 0)
1289
		process_extended_fsync(id);
1265
	else
1290
	else
1266
		send_status(id, SSH2_FX_OP_UNSUPPORTED);	/* MUST */
1291
		send_status(id, SSH2_FX_OP_UNSUPPORTED);	/* MUST */
1267
	xfree(request);
1292
	xfree(request);
(-)sftp.1 (-3 / +22 lines)
Lines 31-37 Link Here
31
.Sh SYNOPSIS
31
.Sh SYNOPSIS
32
.Nm sftp
32
.Nm sftp
33
.Bk -words
33
.Bk -words
34
.Op Fl 1246Cpqrv
34
.Op Fl 1246Cfpqrv
35
.Op Fl B Ar buffer_size
35
.Op Fl B Ar buffer_size
36
.Op Fl b Ar batchfile
36
.Op Fl b Ar batchfile
37
.Op Fl c Ar cipher
37
.Op Fl c Ar cipher
Lines 155-160 Link Here
155
.Xr ssh 1 .
155
.Xr ssh 1 .
156
This option is directly passed to
156
This option is directly passed to
157
.Xr ssh 1 .
157
.Xr ssh 1 .
158
.It Fl f
159
Requests that files be flushed to disk immediately after transfer.
160
When uploading files, this feature is only enabled if the server
161
implements the "fsync@openssh.com" extension.
158
.It Fl i Ar identity_file
162
.It Fl i Ar identity_file
159
Selects the file from which the identity (private key) for public key
163
Selects the file from which the identity (private key) for public key
160
authentication is read.
164
authentication is read.
Lines 337-343 Link Here
337
Quit
341
Quit
338
.Nm sftp .
342
.Nm sftp .
339
.It Xo Ic get
343
.It Xo Ic get
340
.Op Fl Ppr
344
.Op Fl fPpr
341
.Ar remote-path
345
.Ar remote-path
342
.Op Ar local-path
346
.Op Ar local-path
343
.Xc
347
.Xc
Lines 357-362 Link Here
357
.Ar local-path
361
.Ar local-path
358
must specify a directory.
362
must specify a directory.
359
.Pp
363
.Pp
364
If the
365
.Fl f
366
flag is specified, then
367
.Xr fsync 2
368
will ba called after the file transfer has completed to flush the file
369
to disk.
370
.Pp
360
If either the
371
If either the
361
.Fl P
372
.Fl P
362
or
373
or
Lines 460-466 Link Here
460
.It Ic progress
471
.It Ic progress
461
Toggle display of progress meter.
472
Toggle display of progress meter.
462
.It Xo Ic put
473
.It Xo Ic put
463
.Op Fl Ppr
474
.Op Fl fPpr
464
.Ar local-path
475
.Ar local-path
465
.Op Ar remote-path
476
.Op Ar remote-path
466
.Xc
477
.Xc
Lines 478-483 Link Here
478
is specified, then
489
is specified, then
479
.Ar remote-path
490
.Ar remote-path
480
must specify a directory.
491
must specify a directory.
492
.Pp
493
If the
494
.Fl f
495
flag is specified, then a request will be sent to the server to call
496
.Xr fsync 2
497
after the file has been transferred.
498
Note that this is only supported by servers that implement the "fsync@openssh.com"
499
extension.
481
.Pp
500
.Pp
482
If ether the
501
If ether the
483
.Fl P
502
.Fl P
(-)sftp.c (-16 / +29 lines)
Lines 89-94 Link Here
89
/* When this option is set, the file transfers will always preserve times */
89
/* When this option is set, the file transfers will always preserve times */
90
int global_pflag = 0;
90
int global_pflag = 0;
91
91
92
/* When this is set, call fsync() after each file */
93
int global_fflag = 0;
94
92
/* SIGINT received during command processing */
95
/* SIGINT received during command processing */
93
volatile sig_atomic_t interrupted = 0;
96
volatile sig_atomic_t interrupted = 0;
94
97
Lines 349-355 Link Here
349
352
350
static int
353
static int
351
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
354
parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
352
    int *rflag)
355
    int *rflag, int *fflag)
353
{
356
{
354
	extern int opterr, optind, optopt, optreset;
357
	extern int opterr, optind, optopt, optreset;
355
	int ch;
358
	int ch;
Lines 358-364 Link Here
358
	opterr = 0;
361
	opterr = 0;
359
362
360
	*rflag = *pflag = 0;
363
	*rflag = *pflag = 0;
361
	while ((ch = getopt(argc, argv, "PpRr")) != -1) {
364
	*fflag = global_fflag;
365
	while ((ch = getopt(argc, argv, "FfPpRr")) != -1) {
362
		switch (ch) {
366
		switch (ch) {
363
		case 'p':
367
		case 'p':
364
		case 'P':
368
		case 'P':
Lines 368-373 Link Here
368
		case 'R':
372
		case 'R':
369
			*rflag = 1;
373
			*rflag = 1;
370
			break;
374
			break;
375
		case 'f':
376
		case 'F':
377
			*fflag = 1;
378
			break;
371
		default:
379
		default:
372
			error("%s: Invalid flag -%c", cmd, optopt);
380
			error("%s: Invalid flag -%c", cmd, optopt);
373
			return -1;
381
			return -1;
Lines 517-523 Link Here
517
525
518
static int
526
static int
519
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
527
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
520
    int pflag, int rflag)
528
    int pflag, int rflag, int fflag)
521
{
529
{
522
	char *abs_src = NULL;
530
	char *abs_src = NULL;
523
	char *abs_dst = NULL;
531
	char *abs_dst = NULL;
Lines 572-582 Link Here
572
		printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
580
		printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
573
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
581
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
574
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, 
582
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, 
575
			    pflag || global_pflag, 1) == -1)
583
			    pflag || global_pflag, fflag, 1) == -1)
576
				err = -1;
584
				err = -1;
577
		} else {
585
		} else {
578
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
586
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
579
			    pflag || global_pflag) == -1)
587
			    pflag || global_pflag, fflag) == -1)
580
				err = -1;
588
				err = -1;
581
		}
589
		}
582
		xfree(abs_dst);
590
		xfree(abs_dst);
Lines 591-597 Link Here
591
599
592
static int
600
static int
593
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
601
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
594
    int pflag, int rflag)
602
    int pflag, int rflag, int fflag)
595
{
603
{
596
	char *tmp_dst = NULL;
604
	char *tmp_dst = NULL;
597
	char *abs_dst = NULL;
605
	char *abs_dst = NULL;
Lines 657-667 Link Here
657
		printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
665
		printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
658
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
666
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
659
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
667
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
660
			    pflag || global_pflag, 1) == -1)
668
			    pflag || global_pflag, fflag, 1) == -1)
661
				err = -1;
669
				err = -1;
662
		} else {
670
		} else {
663
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
671
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
664
			    pflag || global_pflag) == -1)
672
			    pflag || global_pflag, fflag) == -1)
665
				err = -1;
673
				err = -1;
666
		}
674
		}
667
	}
675
	}
Lines 1113-1119 Link Here
1113
1121
1114
static int
1122
static int
1115
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1123
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1116
    int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2)
1124
    int *hflag, int *sflag, int *fflag, unsigned long *n_arg, char **path1, char **path2)
1117
{
1125
{
1118
	const char *cmd, *cp = *cpp;
1126
	const char *cmd, *cp = *cpp;
1119
	char *cp2, **argv;
1127
	char *cp2, **argv;
Lines 1164-1170 Link Here
1164
	case I_GET:
1172
	case I_GET:
1165
	case I_PUT:
1173
	case I_PUT:
1166
		if ((optidx = parse_getput_flags(cmd, argv, argc,
1174
		if ((optidx = parse_getput_flags(cmd, argv, argc,
1167
		    pflag, rflag)) == -1)
1175
		    pflag, rflag, fflag)) == -1)
1168
			return -1;
1176
			return -1;
1169
		/* Get first pathname (mandatory) */
1177
		/* Get first pathname (mandatory) */
1170
		if (argc - optidx < 1) {
1178
		if (argc - optidx < 1) {
Lines 1287-1293 Link Here
1287
    int err_abort)
1295
    int err_abort)
1288
{
1296
{
1289
	char *path1, *path2, *tmp;
1297
	char *path1, *path2, *tmp;
1290
	int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0;
1298
	int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0, fflag = 0;
1291
	int cmdnum, i;
1299
	int cmdnum, i;
1292
	unsigned long n_arg = 0;
1300
	unsigned long n_arg = 0;
1293
	Attrib a, *aa;
1301
	Attrib a, *aa;
Lines 1297-1303 Link Here
1297
1305
1298
	path1 = path2 = NULL;
1306
	path1 = path2 = NULL;
1299
	cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag,
1307
	cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag,
1300
	    &sflag, &n_arg, &path1, &path2);
1308
	    &sflag, &fflag, &n_arg, &path1, &path2);
1301
1309
1302
	if (iflag != 0)
1310
	if (iflag != 0)
1303
		err_abort = 0;
1311
		err_abort = 0;
Lines 1314-1323 Link Here
1314
		err = -1;
1322
		err = -1;
1315
		break;
1323
		break;
1316
	case I_GET:
1324
	case I_GET:
1317
		err = process_get(conn, path1, path2, *pwd, pflag, rflag);
1325
		err = process_get(conn, path1, path2, *pwd, pflag,
1326
			rflag, fflag);
1318
		break;
1327
		break;
1319
	case I_PUT:
1328
	case I_PUT:
1320
		err = process_put(conn, path1, path2, *pwd, pflag, rflag);
1329
		err = process_put(conn, path1, path2, *pwd, pflag,
1330
			rflag, fflag);
1321
		break;
1331
		break;
1322
	case I_RENAME:
1332
	case I_RENAME:
1323
		path1 = make_absolute(path1, *pwd);
1333
		path1 = make_absolute(path1, *pwd);
Lines 2066-2072 Link Here
2066
	extern char *__progname;
2076
	extern char *__progname;
2067
2077
2068
	fprintf(stderr,
2078
	fprintf(stderr,
2069
	    "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2079
	    "usage: %s [-1246Cfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2070
	    "          [-D sftp_server_path] [-F ssh_config] "
2080
	    "          [-D sftp_server_path] [-F ssh_config] "
2071
	    "[-i identity_file] [-l limit]\n"
2081
	    "[-i identity_file] [-l limit]\n"
2072
	    "          [-o ssh_option] [-P port] [-R num_requests] "
2082
	    "          [-o ssh_option] [-P port] [-R num_requests] "
Lines 2113-2119 Link Here
2113
	infile = stdin;
2123
	infile = stdin;
2114
2124
2115
	while ((ch = getopt(argc, argv,
2125
	while ((ch = getopt(argc, argv,
2116
	    "1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
2126
	    "1246fhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
2117
		switch (ch) {
2127
		switch (ch) {
2118
		/* Passed through to ssh(1) */
2128
		/* Passed through to ssh(1) */
2119
		case '4':
2129
		case '4':
Lines 2167-2172 Link Here
2167
			showprogress = 0;
2177
			showprogress = 0;
2168
			batchmode = 1;
2178
			batchmode = 1;
2169
			addargs(&args, "-obatchmode yes");
2179
			addargs(&args, "-obatchmode yes");
2180
			break;
2181
		case 'f':
2182
			global_fflag = 1;
2170
			break;
2183
			break;
2171
		case 'p':
2184
		case 'p':
2172
			global_pflag = 1;
2185
			global_pflag = 1;

Return to bug 1798