View | Details | Raw Unified | Return to bug 3431
Collapse All | Expand All

(-)a/scp.c (-4 / +4 lines)
Lines 1278-1288 source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) Link Here
1278
1278
1279
	if (src_is_dir && iamrecursive) {
1279
	if (src_is_dir && iamrecursive) {
1280
		if (upload_dir(conn, src, abs_dst, pflag,
1280
		if (upload_dir(conn, src, abs_dst, pflag,
1281
		    SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {
1281
		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
1282
			error("failed to upload directory %s to %s", src, targ);
1282
			error("failed to upload directory %s to %s", src, targ);
1283
			errs = 1;
1283
			errs = 1;
1284
		}
1284
		}
1285
	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
1285
	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
1286
		error("failed to upload file %s to %s", src, targ);
1286
		error("failed to upload file %s to %s", src, targ);
1287
		errs = 1;
1287
		errs = 1;
1288
	}
1288
	}
Lines 1519-1529 sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) Link Here
1519
		debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
1519
		debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
1520
		if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
1520
		if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
1521
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
1521
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
1522
			    pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1)
1522
			    pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
1523
				err = -1;
1523
				err = -1;
1524
		} else {
1524
		} else {
1525
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
1525
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
1526
			    pflag, 0, 0) == -1)
1526
			    pflag, 0, 0, 1) == -1)
1527
				err = -1;
1527
				err = -1;
1528
		}
1528
		}
1529
		free(abs_dst);
1529
		free(abs_dst);
(-)a/sftp-client.c (-24 / +44 lines)
Lines 1560-1566 progress_meter_path(const char *path) Link Here
1560
int
1560
int
1561
do_download(struct sftp_conn *conn, const char *remote_path,
1561
do_download(struct sftp_conn *conn, const char *remote_path,
1562
    const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
1562
    const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
1563
    int fsync_flag)
1563
    int fsync_flag, int inplace_flag)
1564
{
1564
{
1565
	struct sshbuf *msg;
1565
	struct sshbuf *msg;
1566
	u_char *handle;
1566
	u_char *handle;
Lines 1607-1614 do_download(struct sftp_conn *conn, const char *remote_path, Link Here
1607
	    &handle, &handle_len) != 0)
1607
	    &handle, &handle_len) != 0)
1608
		return -1;
1608
		return -1;
1609
1609
1610
	local_fd = open(local_path,
1610
	local_fd = open(local_path, O_WRONLY | O_CREAT |
1611
	    O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
1611
	((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR);
1612
	if (local_fd == -1) {
1612
	if (local_fd == -1) {
1613
		error("open local \"%s\": %s", local_path, strerror(errno));
1613
		error("open local \"%s\": %s", local_path, strerror(errno));
1614
		goto fail;
1614
		goto fail;
Lines 1827-1833 do_download(struct sftp_conn *conn, const char *remote_path, Link Here
1827
static int
1827
static int
1828
download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1828
download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1829
    int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
1829
    int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
1830
    int resume_flag, int fsync_flag, int follow_link_flag)
1830
    int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag)
1831
{
1831
{
1832
	int i, ret = 0;
1832
	int i, ret = 0;
1833
	SFTP_DIRENT **dir_entries;
1833
	SFTP_DIRENT **dir_entries;
Lines 1886-1892 download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, Link Here
1886
			if (download_dir_internal(conn, new_src, new_dst,
1886
			if (download_dir_internal(conn, new_src, new_dst,
1887
			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1887
			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1888
			    print_flag, resume_flag,
1888
			    print_flag, resume_flag,
1889
			    fsync_flag, follow_link_flag) == -1)
1889
			    fsync_flag, follow_link_flag, inplace_flag) == -1)
1890
				ret = -1;
1890
				ret = -1;
1891
		} else if (S_ISREG(dir_entries[i]->a.perm) ||
1891
		} else if (S_ISREG(dir_entries[i]->a.perm) ||
1892
		    (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
1892
		    (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
Lines 1898-1904 download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, Link Here
1898
			if (do_download(conn, new_src, new_dst,
1898
			if (do_download(conn, new_src, new_dst,
1899
			    S_ISLNK(dir_entries[i]->a.perm) ? NULL :
1899
			    S_ISLNK(dir_entries[i]->a.perm) ? NULL :
1900
			    &(dir_entries[i]->a),
1900
			    &(dir_entries[i]->a),
1901
			    preserve_flag, resume_flag, fsync_flag) == -1) {
1901
			    preserve_flag, resume_flag, fsync_flag,
1902
			    inplace_flag) == -1) {
1902
				error("Download of file %s to %s failed",
1903
				error("Download of file %s to %s failed",
1903
				    new_src, new_dst);
1904
				    new_src, new_dst);
1904
				ret = -1;
1905
				ret = -1;
Lines 1936-1942 download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, Link Here
1936
int
1937
int
1937
download_dir(struct sftp_conn *conn, const char *src, const char *dst,
1938
download_dir(struct sftp_conn *conn, const char *src, const char *dst,
1938
    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
1939
    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
1939
    int fsync_flag, int follow_link_flag)
1940
    int fsync_flag, int follow_link_flag, int inplace_flag)
1940
{
1941
{
1941
	char *src_canon;
1942
	char *src_canon;
1942
	int ret;
1943
	int ret;
Lines 1948-1973 download_dir(struct sftp_conn *conn, const char *src, const char *dst, Link Here
1948
1949
1949
	ret = download_dir_internal(conn, src_canon, dst, 0,
1950
	ret = download_dir_internal(conn, src_canon, dst, 0,
1950
	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
1951
	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
1951
	    follow_link_flag);
1952
	    follow_link_flag, inplace_flag);
1952
	free(src_canon);
1953
	free(src_canon);
1953
	return ret;
1954
	return ret;
1954
}
1955
}
1955
1956
1956
int
1957
int
1957
do_upload(struct sftp_conn *conn, const char *local_path,
1958
do_upload(struct sftp_conn *conn, const char *local_path,
1958
    const char *remote_path, int preserve_flag, int resume, int fsync_flag)
1959
    const char *remote_path, int preserve_flag, int resume,
1960
    int fsync_flag, int inplace_flag)
1959
{
1961
{
1960
	int r, local_fd;
1962
	int r, local_fd;
1961
	u_int status = SSH2_FX_OK;
1963
	u_int openmode, id, status = SSH2_FX_OK, reordered = 0;
1962
	u_int id;
1963
	u_char type;
1964
	off_t offset, progress_counter;
1964
	off_t offset, progress_counter;
1965
	u_char *handle, *data;
1965
	u_char type, *handle, *data;
1966
	struct sshbuf *msg;
1966
	struct sshbuf *msg;
1967
	struct stat sb;
1967
	struct stat sb;
1968
	Attrib a, *c = NULL;
1968
	Attrib a, t, *c = NULL;
1969
	u_int32_t startid;
1969
	u_int32_t startid, ackid;
1970
	u_int32_t ackid;
1970
	u_int64_t highwater = 0;
1971
	struct request *ack = NULL;
1971
	struct request *ack = NULL;
1972
	struct requests acks;
1972
	struct requests acks;
1973
	size_t handle_len;
1973
	size_t handle_len;
Lines 2019-2028 do_upload(struct sftp_conn *conn, const char *local_path, Link Here
2019
		}
2019
		}
2020
	}
2020
	}
2021
2021
2022
	openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT;
2023
	if (resume)
2024
		openmode |= SSH2_FXF_APPEND;
2025
	else if (!inplace_flag)
2026
		openmode |= SSH2_FXF_TRUNC;
2027
2022
	/* Send open request */
2028
	/* Send open request */
2023
	if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT|
2029
	if (send_open(conn, remote_path, "dest", openmode, &a,
2024
	    (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC),
2030
	    &handle, &handle_len) != 0) {
2025
	    &a, &handle, &handle_len) != 0) {
2026
		close(local_fd);
2031
		close(local_fd);
2027
		return -1;
2032
		return -1;
2028
	}
2033
	}
Lines 2103-2108 do_upload(struct sftp_conn *conn, const char *local_path, Link Here
2103
			    ack->id, ack->len, (unsigned long long)ack->offset);
2108
			    ack->id, ack->len, (unsigned long long)ack->offset);
2104
			++ackid;
2109
			++ackid;
2105
			progress_counter += ack->len;
2110
			progress_counter += ack->len;
2111
			if (!reordered && ack->offset <= highwater)
2112
				highwater = ack->offset + ack->len;
2113
			else if (!reordered && ack->offset > highwater) {
2114
				debug3_f("server reordered ACKs");
2115
				reordered = 1;
2116
			}
2106
			free(ack);
2117
			free(ack);
2107
		}
2118
		}
2108
		offset += len;
2119
		offset += len;
Lines 2120-2125 do_upload(struct sftp_conn *conn, const char *local_path, Link Here
2120
		status = SSH2_FX_FAILURE;
2131
		status = SSH2_FX_FAILURE;
2121
	}
2132
	}
2122
2133
2134
	if ((resume || inplace_flag) && (status != SSH2_FX_OK || interrupted)) {
2135
		debug("truncating at %llu", (unsigned long long)highwater);
2136
		attrib_clear(&t);
2137
		t.flags = SSH2_FILEXFER_ATTR_SIZE;
2138
		t.size = highwater;
2139
		do_fsetstat(conn, handle, handle_len, &a);
2140
	}
2141
2123
	if (close(local_fd) == -1) {
2142
	if (close(local_fd) == -1) {
2124
		error("close local \"%s\": %s", local_path, strerror(errno));
2143
		error("close local \"%s\": %s", local_path, strerror(errno));
2125
		status = SSH2_FX_FAILURE;
2144
		status = SSH2_FX_FAILURE;
Lines 2143-2149 do_upload(struct sftp_conn *conn, const char *local_path, Link Here
2143
static int
2162
static int
2144
upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
2163
upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
2145
    int depth, int preserve_flag, int print_flag, int resume, int fsync_flag,
2164
    int depth, int preserve_flag, int print_flag, int resume, int fsync_flag,
2146
    int follow_link_flag)
2165
    int follow_link_flag, int inplace_flag)
2147
{
2166
{
2148
	int ret = 0;
2167
	int ret = 0;
2149
	DIR *dirp;
2168
	DIR *dirp;
Lines 2221-2232 upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, Link Here
2221
2240
2222
			if (upload_dir_internal(conn, new_src, new_dst,
2241
			if (upload_dir_internal(conn, new_src, new_dst,
2223
			    depth + 1, preserve_flag, print_flag, resume,
2242
			    depth + 1, preserve_flag, print_flag, resume,
2224
			    fsync_flag, follow_link_flag) == -1)
2243
			    fsync_flag, follow_link_flag, inplace_flag) == -1)
2225
				ret = -1;
2244
				ret = -1;
2226
		} else if (S_ISREG(sb.st_mode) ||
2245
		} else if (S_ISREG(sb.st_mode) ||
2227
		    (follow_link_flag && S_ISLNK(sb.st_mode))) {
2246
		    (follow_link_flag && S_ISLNK(sb.st_mode))) {
2228
			if (do_upload(conn, new_src, new_dst,
2247
			if (do_upload(conn, new_src, new_dst,
2229
			    preserve_flag, resume, fsync_flag) == -1) {
2248
			    preserve_flag, resume, fsync_flag,
2249
			    inplace_flag) == -1) {
2230
				error("upload \"%s\" to \"%s\" failed",
2250
				error("upload \"%s\" to \"%s\" failed",
2231
				    new_src, new_dst);
2251
				    new_src, new_dst);
2232
				ret = -1;
2252
				ret = -1;
Lines 2246-2252 upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, Link Here
2246
int
2266
int
2247
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
2267
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
2248
    int preserve_flag, int print_flag, int resume, int fsync_flag,
2268
    int preserve_flag, int print_flag, int resume, int fsync_flag,
2249
    int follow_link_flag)
2269
    int follow_link_flag, int inplace_flag)
2250
{
2270
{
2251
	char *dst_canon;
2271
	char *dst_canon;
2252
	int ret;
2272
	int ret;
Lines 2257-2263 upload_dir(struct sftp_conn *conn, const char *src, const char *dst, Link Here
2257
	}
2277
	}
2258
2278
2259
	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
2279
	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
2260
	    print_flag, resume, fsync_flag, follow_link_flag);
2280
	    print_flag, resume, fsync_flag, follow_link_flag, inplace_flag);
2261
2281
2262
	free(dst_canon);
2282
	free(dst_canon);
2263
	return ret;
2283
	return ret;
(-)a/sftp-client.h (-7 / +8 lines)
Lines 135-162 int do_fsync(struct sftp_conn *conn, u_char *, u_int); Link Here
135
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
135
 * Download 'remote_path' to 'local_path'. Preserve permissions and times
136
 * if 'pflag' is set
136
 * if 'pflag' is set
137
 */
137
 */
138
int do_download(struct sftp_conn *, const char *, const char *,
138
int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
139
    Attrib *, int, int, int);
139
    int, int, int, int);
140
140
141
/*
141
/*
142
 * Recursively download 'remote_directory' to 'local_directory'. Preserve
142
 * Recursively download 'remote_directory' to 'local_directory'. Preserve
143
 * times if 'pflag' is set
143
 * times if 'pflag' is set
144
 */
144
 */
145
int download_dir(struct sftp_conn *, const char *, const char *,
145
int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
146
    Attrib *, int, int, int, int, int);
146
    int, int, int, int, int, int);
147
147
148
/*
148
/*
149
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
149
 * Upload 'local_path' to 'remote_path'. Preserve permissions and times
150
 * if 'pflag' is set
150
 * if 'pflag' is set
151
 */
151
 */
152
int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
152
int do_upload(struct sftp_conn *, const char *, const char *,
153
    int, int, int, int);
153
154
154
/*
155
/*
155
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve
156
 * Recursively upload 'local_directory' to 'remote_directory'. Preserve
156
 * times if 'pflag' is set
157
 * times if 'pflag' is set
157
 */
158
 */
158
int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
159
int upload_dir(struct sftp_conn *, const char *, const char *,
159
    int, int);
160
    int, int, int, int, int, int);
160
161
161
/*
162
/*
162
 * Download a 'from_path' from the 'from' connection and upload it to
163
 * Download a 'from_path' from the 'from' connection and upload it to
(-)a/sftp.c (-4 / +4 lines)
Lines 676-687 process_get(struct sftp_conn *conn, const char *src, const char *dst, Link Here
676
		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
676
		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
677
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
677
			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
678
			    pflag || global_pflag, 1, resume,
678
			    pflag || global_pflag, 1, resume,
679
			    fflag || global_fflag, 0) == -1)
679
			    fflag || global_fflag, 0, 0) == -1)
680
				err = -1;
680
				err = -1;
681
		} else {
681
		} else {
682
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
682
			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
683
			    pflag || global_pflag, resume,
683
			    pflag || global_pflag, resume,
684
			    fflag || global_fflag) == -1)
684
			    fflag || global_fflag, 0) == -1)
685
				err = -1;
685
				err = -1;
686
		}
686
		}
687
		free(abs_dst);
687
		free(abs_dst);
Lines 770-781 process_put(struct sftp_conn *conn, const char *src, const char *dst, Link Here
770
		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
770
		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
771
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
771
			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
772
			    pflag || global_pflag, 1, resume,
772
			    pflag || global_pflag, 1, resume,
773
			    fflag || global_fflag, 0) == -1)
773
			    fflag || global_fflag, 0, 0) == -1)
774
				err = -1;
774
				err = -1;
775
		} else {
775
		} else {
776
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
776
			if (do_upload(conn, g.gl_pathv[i], abs_dst,
777
			    pflag || global_pflag, resume,
777
			    pflag || global_pflag, resume,
778
			    fflag || global_fflag) == -1)
778
			    fflag || global_fflag, 0) == -1)
779
				err = -1;
779
				err = -1;
780
		}
780
		}
781
	}
781
	}

Return to bug 3431