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

Collapse All | Expand All

(-)PROTOCOL (+14 lines)
Lines 331-334 link(oldpath, newpath) and will respond Link Here
331
This extension is advertised in the SSH_FXP_VERSION hello with version
331
This extension is advertised in the SSH_FXP_VERSION hello with version
332
"1".
332
"1".
333
333
334
10. sftp: Extension request "fsync@openssh.com"
335
336
This request asks the server to call fsync(2) on an open file handle.
337
338
	uint32		id
339
	string		"hardlink@openssh.com"
340
	string		handle
341
342
One receiving this request, a server will call fsync(handle_fd) and will
343
respond with a SSH_FXP_STATUS message.
344
345
This extension is advertised in the SSH_FXP_VERSION hello with version
346
"1".
347
334
$OpenBSD: PROTOCOL,v 1.20 2013/01/08 18:49:04 markus Exp $
348
$OpenBSD: PROTOCOL,v 1.20 2013/01/08 18:49:04 markus Exp $
(-)sftp-client.c (-12 / +61 lines)
Lines 69-74 struct sftp_conn { Link Here
69
#define SFTP_EXT_STATVFS	0x00000002
69
#define SFTP_EXT_STATVFS	0x00000002
70
#define SFTP_EXT_FSTATVFS	0x00000004
70
#define SFTP_EXT_FSTATVFS	0x00000004
71
#define SFTP_EXT_HARDLINK	0x00000008
71
#define SFTP_EXT_HARDLINK	0x00000008
72
#define SFTP_EXT_FSYNC		0x00000010
72
	u_int exts;
73
	u_int exts;
73
	u_int64_t limit_kbps;
74
	u_int64_t limit_kbps;
74
	struct bwlimit bwlimit_in, bwlimit_out;
75
	struct bwlimit bwlimit_in, bwlimit_out;
Lines 381-386 do_init(int fd_in, int fd_out, u_int tra Link Here
381
		    strcmp(value, "1") == 0) {
382
		    strcmp(value, "1") == 0) {
382
			ret->exts |= SFTP_EXT_HARDLINK;
383
			ret->exts |= SFTP_EXT_HARDLINK;
383
			known = 1;
384
			known = 1;
385
 		} else if (strcmp(name, "fsync@openssh.com") == 0 &&
386
 		    strcmp(value, "1") == 0) {
387
 			ret->exts |= SFTP_EXT_FSYNC;
388
 			known = 1;
384
		}
389
		}
385
		if (known) {
390
		if (known) {
386
			debug2("Server supports extension \"%s\" revision %s",
391
			debug2("Server supports extension \"%s\" revision %s",
Lines 862-867 do_symlink(struct sftp_conn *conn, char Link Here
862
	return(status);
867
	return(status);
863
}
868
}
864
869
870
int
871
do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len)
872
{
873
	Buffer msg;
874
	u_int status, id;
875
876
	/* Silently return if the extension is not supported */
877
	if ((conn->exts & SFTP_EXT_FSYNC) == 0)
878
		return -1;
879
880
	buffer_init(&msg);
881
882
	/* Send fsync request */
883
	id = conn->msg_id++;
884
885
	buffer_put_char(&msg, SSH2_FXP_EXTENDED);
886
	buffer_put_int(&msg, id);
887
	buffer_put_cstring(&msg, "fsync@openssh.com");
888
	buffer_put_string(&msg, handle, handle_len);
889
	send_msg(conn, &msg);
890
	debug3("Sent message fsync@openssh.com I:%u", id);
891
	buffer_free(&msg);
892
893
	status = get_status(conn, id);
894
	if (status != SSH2_FX_OK)
895
		error("Couldn't sync file: %s", fx2txt(status));
896
897
	return status;
898
}
899
865
#ifdef notyet
900
#ifdef notyet
866
char *
901
char *
867
do_readlink(struct sftp_conn *conn, char *path)
902
do_readlink(struct sftp_conn *conn, char *path)
Lines 984-990 send_read_request(struct sftp_conn *conn Link Here
984
1019
985
int
1020
int
986
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
1021
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
987
    Attrib *a, int preserve_flag, int resume_flag)
1022
    Attrib *a, int preserve_flag, int resume_flag, int fsync_flag)
988
{
1023
{
989
	Attrib junk;
1024
	Attrib junk;
990
	Buffer msg;
1025
	Buffer msg;
Lines 1240-1245 do_download(struct sftp_conn *conn, char Link Here
1240
				error("Can't set times on \"%s\": %s",
1275
				error("Can't set times on \"%s\": %s",
1241
				    local_path, strerror(errno));
1276
				    local_path, strerror(errno));
1242
		}
1277
		}
1278
		if (fsync_flag) {
1279
			debug("syncing \"%s\"", local_path);
1280
			if (fsync(local_fd) == -1)
1281
				error("Couldn't sync file \"%s\": %s",
1282
				    local_path, strerror(errno));
1283
		}
1243
	}
1284
	}
1244
	close(local_fd);
1285
	close(local_fd);
1245
	buffer_free(&msg);
1286
	buffer_free(&msg);
Lines 1250-1256 do_download(struct sftp_conn *conn, char Link Here
1250
1291
1251
static int
1292
static int
1252
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth,
1293
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth,
1253
    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag)
1294
    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
1295
    int fsync_flag)
1254
{
1296
{
1255
	int i, ret = 0;
1297
	int i, ret = 0;
1256
	SFTP_DIRENT **dir_entries;
1298
	SFTP_DIRENT **dir_entries;
Lines 1303-1313 download_dir_internal(struct sftp_conn * Link Here
1303
				continue;
1345
				continue;
1304
			if (download_dir_internal(conn, new_src, new_dst,
1346
			if (download_dir_internal(conn, new_src, new_dst,
1305
			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1347
			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1306
			    print_flag, resume_flag) == -1)
1348
			    print_flag, resume_flag, fsync_flag) == -1)
1307
				ret = -1;
1349
				ret = -1;
1308
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1350
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1309
			if (do_download(conn, new_src, new_dst,
1351
			if (do_download(conn, new_src, new_dst,
1310
			    &(dir_entries[i]->a), preserve_flag, resume_flag) == -1) {
1352
			    &(dir_entries[i]->a), preserve_flag,
1353
			    resume_flag, fsync_flag) == -1) {
1311
				error("Download of file %s to %s failed",
1354
				error("Download of file %s to %s failed",
1312
				    new_src, new_dst);
1355
				    new_src, new_dst);
1313
				ret = -1;
1356
				ret = -1;
Lines 1340-1346 download_dir_internal(struct sftp_conn * Link Here
1340
1383
1341
int
1384
int
1342
download_dir(struct sftp_conn *conn, char *src, char *dst,
1385
download_dir(struct sftp_conn *conn, char *src, char *dst,
1343
    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag)
1386
    Attrib *dirattrib, int preserve_flag, int print_flag,
1387
    int resume_flag, int fsync_flag)
1344
{
1388
{
1345
	char *src_canon;
1389
	char *src_canon;
1346
	int ret;
1390
	int ret;
Lines 1351-1364 download_dir(struct sftp_conn *conn, cha Link Here
1351
	}
1395
	}
1352
1396
1353
	ret = download_dir_internal(conn, src_canon, dst, 0,
1397
	ret = download_dir_internal(conn, src_canon, dst, 0,
1354
	    dirattrib, preserve_flag, print_flag, resume_flag);
1398
	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag);
1355
	free(src_canon);
1399
	free(src_canon);
1356
	return ret;
1400
	return ret;
1357
}
1401
}
1358
1402
1359
int
1403
int
1360
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1404
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1361
    int preserve_flag)
1405
    int preserve_flag, int fsync_flag)
1362
{
1406
{
1363
	int local_fd;
1407
	int local_fd;
1364
	int status = SSH2_FX_OK;
1408
	int status = SSH2_FX_OK;
Lines 1533-1538 do_upload(struct sftp_conn *conn, char * Link Here
1533
	if (preserve_flag)
1577
	if (preserve_flag)
1534
		do_fsetstat(conn, handle, handle_len, &a);
1578
		do_fsetstat(conn, handle, handle_len, &a);
1535
1579
1580
	if (fsync_flag)
1581
		(void)do_fsync(conn, handle, handle_len);
1582
1536
	if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
1583
	if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
1537
		status = -1;
1584
		status = -1;
1538
	free(handle);
1585
	free(handle);
Lines 1542-1548 do_upload(struct sftp_conn *conn, char * Link Here
1542
1589
1543
static int
1590
static int
1544
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth,
1591
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth,
1545
    int preserve_flag, int print_flag)
1592
    int preserve_flag, int print_flag, int fsync_flag)
1546
{
1593
{
1547
	int ret = 0, status;
1594
	int ret = 0, status;
1548
	DIR *dirp;
1595
	DIR *dirp;
Lines 1611-1621 upload_dir_internal(struct sftp_conn *co Link Here
1611
				continue;
1658
				continue;
1612
1659
1613
			if (upload_dir_internal(conn, new_src, new_dst,
1660
			if (upload_dir_internal(conn, new_src, new_dst,
1614
			    depth + 1, preserve_flag, print_flag) == -1)
1661
			    depth + 1, preserve_flag, print_flag,
1662
			    fsync_flag) == -1)
1615
				ret = -1;
1663
				ret = -1;
1616
		} else if (S_ISREG(sb.st_mode)) {
1664
		} else if (S_ISREG(sb.st_mode)) {
1617
			if (do_upload(conn, new_src, new_dst,
1665
			if (do_upload(conn, new_src, new_dst,
1618
			    preserve_flag) == -1) {
1666
			    preserve_flag, fsync_flag) == -1) {
1619
				error("Uploading of file %s to %s failed!",
1667
				error("Uploading of file %s to %s failed!",
1620
				    new_src, new_dst);
1668
				    new_src, new_dst);
1621
				ret = -1;
1669
				ret = -1;
Lines 1634-1640 upload_dir_internal(struct sftp_conn *co Link Here
1634
1682
1635
int
1683
int
1636
upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag,
1684
upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag,
1637
    int print_flag)
1685
    int print_flag, int fsync_flag)
1638
{
1686
{
1639
	char *dst_canon;
1687
	char *dst_canon;
1640
	int ret;
1688
	int ret;
Lines 1645-1651 upload_dir(struct sftp_conn *conn, char Link Here
1645
	}
1693
	}
1646
1694
1647
	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
1695
	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
1648
	    print_flag);
1696
	    print_flag, fsync_flag);
1697
1649
	free(dst_canon);
1698
	free(dst_canon);
1650
	return ret;
1699
	return ret;
1651
}
1700
}
(-)sftp-client.h (-4 / +8 lines)
Lines 100-128 int do_hardlink(struct sftp_conn *, char Link Here
100
/* Rename 'oldpath' to 'newpath' */
100
/* Rename 'oldpath' to 'newpath' */
101
int do_symlink(struct sftp_conn *, char *, char *);
101
int do_symlink(struct sftp_conn *, char *, char *);
102
102
103
/* Call fsync() on open file 'handle' */
104
int do_fsync(struct sftp_conn *conn, char *, u_int);
105
103
/*
106
/*
104
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
107
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
105
 * if 'pflag' is set
108
 * if 'pflag' is set
106
 */
109
 */
107
int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int);
110
int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int, int);
108
111
109
/*
112
/*
110
 * Recursively download 'remote_directory' to 'local_directory'. Preserve 
113
 * Recursively download 'remote_directory' to 'local_directory'. Preserve 
111
 * times if 'pflag' is set
114
 * times if 'pflag' is set
112
 */
115
 */
113
int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int, int);
116
int download_dir(struct sftp_conn *, char *, char *, Attrib *, int,
117
    int, int, int);
114
118
115
/*
119
/*
116
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
120
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
117
 * if 'pflag' is set
121
 * if 'pflag' is set
118
 */
122
 */
119
int do_upload(struct sftp_conn *, char *, char *, int);
123
int do_upload(struct sftp_conn *, char *, char *, int, int);
120
124
121
/*
125
/*
122
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
126
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
123
 * times if 'pflag' is set
127
 * times if 'pflag' is set
124
 */
128
 */
125
int upload_dir(struct sftp_conn *, char *, char *, int, int);
129
int upload_dir(struct sftp_conn *, char *, char *, int, int, int);
126
130
127
/* Concatenate paths, taking care of slashes. Caller must free result. */
131
/* Concatenate paths, taking care of slashes. Caller must free result. */
128
char *path_append(char *, char *);
132
char *path_append(char *, char *);
(-)sftp-server.c (+22 lines)
Lines 103-108 static void process_extended_posix_renam Link Here
103
static void process_extended_statvfs(u_int32_t id);
103
static void process_extended_statvfs(u_int32_t id);
104
static void process_extended_fstatvfs(u_int32_t id);
104
static void process_extended_fstatvfs(u_int32_t id);
105
static void process_extended_hardlink(u_int32_t id);
105
static void process_extended_hardlink(u_int32_t id);
106
static void process_extended_fsync(u_int32_t id);
106
static void process_extended(u_int32_t id);
107
static void process_extended(u_int32_t id);
107
108
108
struct sftp_handler {
109
struct sftp_handler {
Lines 143-148 struct sftp_handler extended_handlers[] Link Here
143
	{ "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
144
	{ "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
144
	{ "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
145
	{ "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
145
	{ "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
146
	{ "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
147
	{ "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 },
146
	{ NULL, NULL, 0, NULL, 0 }
148
	{ NULL, NULL, 0, NULL, 0 }
147
};
149
};
148
150
Lines 629-634 process_init(void) Link Here
629
	/* hardlink extension */
631
	/* hardlink extension */
630
	buffer_put_cstring(&msg, "hardlink@openssh.com");
632
	buffer_put_cstring(&msg, "hardlink@openssh.com");
631
	buffer_put_cstring(&msg, "1"); /* version */
633
	buffer_put_cstring(&msg, "1"); /* version */
634
	/* fsync extension */
635
	buffer_put_cstring(&msg, "fsync@openssh.com");
636
	buffer_put_cstring(&msg, "1"); /* version */
632
	send_msg(&msg);
637
	send_msg(&msg);
633
	buffer_free(&msg);
638
	buffer_free(&msg);
634
}
639
}
Lines 1252-1257 process_extended_hardlink(u_int32_t id) Link Here
1252
	send_status(id, status);
1257
	send_status(id, status);
1253
	free(oldpath);
1258
	free(oldpath);
1254
	free(newpath);
1259
	free(newpath);
1260
}
1261
1262
static void
1263
process_extended_fsync(u_int32_t id)
1264
{
1265
	int handle, fd, ret, status = SSH2_FX_OP_UNSUPPORTED;
1266
1267
	handle = get_handle();
1268
	debug3("request %u: fsync (handle %u)", id, handle);
1269
	verbose("fsync \"%s\"", handle_to_name(handle));
1270
	if ((fd = handle_to_fd(handle)) < 0)
1271
		status = SSH2_FX_NO_SUCH_FILE;
1272
	else if (handle_is_ok(handle, HANDLE_FILE)) {
1273
		ret = fsync(fd);
1274
		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
1275
	}
1276
	send_status(id, status);
1255
}
1277
}
1256
1278
1257
static void
1279
static void
(-)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 1246aCpqrv
34
.Op Fl 1246aCfpqrv
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 164-169 per-user configuration file for Link Here
164
.Xr ssh 1 .
164
.Xr ssh 1 .
165
This option is directly passed to
165
This option is directly passed to
166
.Xr ssh 1 .
166
.Xr ssh 1 .
167
.It Fl f
168
Requests that files be flushed to disk immediately after transfer.
169
When uploading files, this feature is only enabled if the server
170
implements the "fsync@openssh.com" extension.
167
.It Fl i Ar identity_file
171
.It Fl i Ar identity_file
168
Selects the file from which the identity (private key) for public key
172
Selects the file from which the identity (private key) for public key
169
authentication is read.
173
authentication is read.
Lines 348-354 extension. Link Here
348
Quit
352
Quit
349
.Nm sftp .
353
.Nm sftp .
350
.It Xo Ic get
354
.It Xo Ic get
351
.Op Fl aPpr
355
.Op Fl afPpr
352
.Ar remote-path
356
.Ar remote-path
353
.Op Ar local-path
357
.Op Ar local-path
354
.Xc
358
.Xc
Lines 376-381 the remote copy. Link Here
376
If the remote file contents differ from the partial local copy then the
380
If the remote file contents differ from the partial local copy then the
377
resultant file is likely to be corrupt.
381
resultant file is likely to be corrupt.
378
.Pp
382
.Pp
383
If the
384
.Fl f
385
flag is specified, then
386
.Xr fsync 2
387
will ba called after the file transfer has completed to flush the file
388
to disk.
389
.Pp
379
If either the
390
If either the
380
.Fl P
391
.Fl P
381
or
392
or
Lines 479-485 Create remote directory specified by Link Here
479
.It Ic progress
490
.It Ic progress
480
Toggle display of progress meter.
491
Toggle display of progress meter.
481
.It Xo Ic put
492
.It Xo Ic put
482
.Op Fl Ppr
493
.Op Fl fPpr
483
.Ar local-path
494
.Ar local-path
484
.Op Ar remote-path
495
.Op Ar remote-path
485
.Xc
496
.Xc
Lines 497-502 If it does and Link Here
497
is specified, then
508
is specified, then
498
.Ar remote-path
509
.Ar remote-path
499
must specify a directory.
510
must specify a directory.
511
.Pp
512
If the
513
.Fl f
514
flag is specified, then a request will be sent to the server to call
515
.Xr fsync 2
516
after the file has been transferred.
517
Note that this is only supported by servers that implement
518
the "fsync@openssh.com" extension.
500
.Pp
519
.Pp
501
If either the
520
If either the
502
.Fl P
521
.Fl P
(-)sftp.c (-19 / +34 lines)
Lines 75-80 int global_aflag = 0; Link Here
75
/* When this option is set, the file transfers will always preserve times */
75
/* When this option is set, the file transfers will always preserve times */
76
int global_pflag = 0;
76
int global_pflag = 0;
77
77
78
/* When this option is set, transfers will have fsync() called on each file */
79
int global_fflag = 0;
80
78
/* SIGINT received during command processing */
81
/* SIGINT received during command processing */
79
volatile sig_atomic_t interrupted = 0;
82
volatile sig_atomic_t interrupted = 0;
80
83
Lines 338-344 make_absolute(char *p, char *pwd) Link Here
338
341
339
static int
342
static int
340
parse_getput_flags(const char *cmd, char **argv, int argc,
343
parse_getput_flags(const char *cmd, char **argv, int argc,
341
    int *aflag, int *pflag, int *rflag)
344
    int *aflag, int *fflag, int *pflag, int *rflag)
342
{
345
{
343
	extern int opterr, optind, optopt, optreset;
346
	extern int opterr, optind, optopt, optreset;
344
	int ch;
347
	int ch;
Lines 346-357 parse_getput_flags(const char *cmd, char Link Here
346
	optind = optreset = 1;
349
	optind = optreset = 1;
347
	opterr = 0;
350
	opterr = 0;
348
351
349
	*aflag = *rflag = *pflag = 0;
352
	*aflag = *fflag = *rflag = *pflag = 0;
350
	while ((ch = getopt(argc, argv, "aPpRr")) != -1) {
353
	while ((ch = getopt(argc, argv, "afPpRr")) != -1) {
351
		switch (ch) {
354
		switch (ch) {
352
		case 'a':
355
		case 'a':
353
			*aflag = 1;
356
			*aflag = 1;
354
			break;
357
			break;
358
		case 'f':
359
			*fflag = 1;
360
			break;
355
		case 'p':
361
		case 'p':
356
		case 'P':
362
		case 'P':
357
			*pflag = 1;
363
			*pflag = 1;
Lines 553-559 pathname_is_dir(char *pathname) Link Here
553
559
554
static int
560
static int
555
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
561
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
556
    int pflag, int rflag, int resume)
562
    int pflag, int rflag, int resume, int fflag)
557
{
563
{
558
	char *abs_src = NULL;
564
	char *abs_src = NULL;
559
	char *abs_dst = NULL;
565
	char *abs_dst = NULL;
Lines 612-622 process_get(struct sftp_conn *conn, char Link Here
612
			printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
618
			printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
613
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
619
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
614
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
620
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
615
			    pflag || global_pflag, 1, resume) == -1)
621
			    pflag || global_pflag, 1, resume,
622
			    fflag || global_fflag) == -1)
616
				err = -1;
623
				err = -1;
617
		} else {
624
		} else {
618
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
625
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
619
			    pflag || global_pflag, resume) == -1)
626
			    pflag || global_pflag, resume,
627
			    fflag || global_fflag) == -1)
620
				err = -1;
628
				err = -1;
621
		}
629
		}
622
		free(abs_dst);
630
		free(abs_dst);
Lines 631-637 out: Link Here
631
639
632
static int
640
static int
633
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
641
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
634
    int pflag, int rflag)
642
    int pflag, int rflag, int fflag)
635
{
643
{
636
	char *tmp_dst = NULL;
644
	char *tmp_dst = NULL;
637
	char *abs_dst = NULL;
645
	char *abs_dst = NULL;
Lines 698-708 process_put(struct sftp_conn *conn, char Link Here
698
			printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
706
			printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
699
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
707
		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
700
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
708
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
701
			    pflag || global_pflag, 1) == -1)
709
			    pflag || global_pflag, 1,
710
			    fflag || global_fflag) == -1)
702
				err = -1;
711
				err = -1;
703
		} else {
712
		} else {
704
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
713
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
705
			    pflag || global_pflag) == -1)
714
			    pflag || global_pflag,
715
			    fflag || global_fflag) == -1)
706
				err = -1;
716
				err = -1;
707
		}
717
		}
708
	}
718
	}
Lines 1155-1162 makeargv(const char *arg, int *argcp, in Link Here
1155
}
1165
}
1156
1166
1157
static int
1167
static int
1158
parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag,
1168
parse_args(const char **cpp, int *aflag, int *fflag, int *hflag, int *iflag,
1159
    int *pflag, int *rflag, int *sflag, unsigned long *n_arg,
1169
    int *lflag, int *pflag, int *rflag, int *sflag, unsigned long *n_arg,
1160
    char **path1, char **path2)
1170
    char **path1, char **path2)
1161
{
1171
{
1162
	const char *cmd, *cp = *cpp;
1172
	const char *cmd, *cp = *cpp;
Lines 1201-1207 parse_args(const char **cpp, int *aflag, Link Here
1201
	}
1211
	}
1202
1212
1203
	/* Get arguments and parse flags */
1213
	/* Get arguments and parse flags */
1204
	*aflag = *lflag = *pflag = *rflag = *hflag = *n_arg = 0;
1214
	*aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0;
1215
	*rflag = *sflag = 0;
1205
	*path1 = *path2 = NULL;
1216
	*path1 = *path2 = NULL;
1206
	optidx = 1;
1217
	optidx = 1;
1207
	switch (cmdnum) {
1218
	switch (cmdnum) {
Lines 1209-1215 parse_args(const char **cpp, int *aflag, Link Here
1209
	case I_REGET:
1220
	case I_REGET:
1210
	case I_PUT:
1221
	case I_PUT:
1211
		if ((optidx = parse_getput_flags(cmd, argv, argc,
1222
		if ((optidx = parse_getput_flags(cmd, argv, argc,
1212
		    aflag, pflag, rflag)) == -1)
1223
		    aflag, fflag, pflag, rflag)) == -1)
1213
			return -1;
1224
			return -1;
1214
		/* Get first pathname (mandatory) */
1225
		/* Get first pathname (mandatory) */
1215
		if (argc - optidx < 1) {
1226
		if (argc - optidx < 1) {
Lines 1350-1356 parse_dispatch_command(struct sftp_conn Link Here
1350
    int err_abort)
1361
    int err_abort)
1351
{
1362
{
1352
	char *path1, *path2, *tmp;
1363
	char *path1, *path2, *tmp;
1353
	int aflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0;
1364
	int aflag = 0, fflag = 0, hflag = 0, iflag = 0, lflag = 0, pflag = 0;
1354
	int rflag = 0, sflag = 0;
1365
	int rflag = 0, sflag = 0;
1355
	int cmdnum, i;
1366
	int cmdnum, i;
1356
	unsigned long n_arg = 0;
1367
	unsigned long n_arg = 0;
Lines 1360-1367 parse_dispatch_command(struct sftp_conn Link Here
1360
	glob_t g;
1371
	glob_t g;
1361
1372
1362
	path1 = path2 = NULL;
1373
	path1 = path2 = NULL;
1363
	cmdnum = parse_args(&cmd, &aflag, &hflag, &iflag, &lflag, &pflag,
1374
	cmdnum = parse_args(&cmd, &aflag, &fflag, &hflag, &iflag, &lflag,
1364
	    &rflag, &sflag, &n_arg, &path1, &path2);
1375
	    &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
1365
	if (iflag != 0)
1376
	if (iflag != 0)
1366
		err_abort = 0;
1377
		err_abort = 0;
1367
1378
Lines 1381-1390 parse_dispatch_command(struct sftp_conn Link Here
1381
		/* FALLTHROUGH */
1392
		/* FALLTHROUGH */
1382
	case I_GET:
1393
	case I_GET:
1383
		err = process_get(conn, path1, path2, *pwd, pflag,
1394
		err = process_get(conn, path1, path2, *pwd, pflag,
1384
		    rflag, aflag);
1395
		    rflag, aflag, fflag);
1385
		break;
1396
		break;
1386
	case I_PUT:
1397
	case I_PUT:
1387
		err = process_put(conn, path1, path2, *pwd, pflag, rflag);
1398
		err = process_put(conn, path1, path2, *pwd, pflag,
1399
		    rflag, fflag);
1388
		break;
1400
		break;
1389
	case I_RENAME:
1401
	case I_RENAME:
1390
		path1 = make_absolute(path1, *pwd);
1402
		path1 = make_absolute(path1, *pwd);
Lines 2189-2195 main(int argc, char **argv) Link Here
2189
	infile = stdin;
2201
	infile = stdin;
2190
2202
2191
	while ((ch = getopt(argc, argv,
2203
	while ((ch = getopt(argc, argv,
2192
	    "1246ahpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
2204
	    "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
2193
		switch (ch) {
2205
		switch (ch) {
2194
		/* Passed through to ssh(1) */
2206
		/* Passed through to ssh(1) */
2195
		case '4':
2207
		case '4':
Lines 2248-2253 main(int argc, char **argv) Link Here
2248
			showprogress = 0;
2260
			showprogress = 0;
2249
			quiet = batchmode = 1;
2261
			quiet = batchmode = 1;
2250
			addargs(&args, "-obatchmode yes");
2262
			addargs(&args, "-obatchmode yes");
2263
			break;
2264
		case 'f':
2265
			global_fflag = 1;
2251
			break;
2266
			break;
2252
		case 'p':
2267
		case 'p':
2253
			global_pflag = 1;
2268
			global_pflag = 1;

Return to bug 1798