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

Collapse All | Expand All

(-)sftp-client.h (-1 / +1 lines)
Lines 106-112 int do_symlink(struct sftp_conn *, char 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 
(-)sftp-client.c (-11 / +66 lines)
Lines 15-20 Link Here
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
16
 */
17
17
18
/*
19
 * Copyright (c) 2012 Loganaden Velvindron
20
 *
21
 * Permission to use, copy, modify, and distribute this software for any
22
 * purpose with or without fee is hereby granted, provided that the above
23
 * copyright notice and this permission notice appear in all copies.
24
 *
25
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
26
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
27
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
28
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32
 *
33
 * Sponsored by AfriNIC.
34
 */
35
18
/* XXX: memleaks */
36
/* XXX: memleaks */
19
/* XXX: signed vs unsigned */
37
/* XXX: signed vs unsigned */
20
/* XXX: remove all logging, only return status codes */
38
/* XXX: remove all logging, only return status codes */
Lines 988-1003 send_read_request(struct sftp_conn *conn Link Here
988
1006
989
int
1007
int
990
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
1008
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
991
    Attrib *a, int pflag)
1009
    Attrib *a, int pflag, int resume)
992
{
1010
{
993
	Attrib junk;
1011
	Attrib junk;
994
	Buffer msg;
1012
	Buffer msg;
995
	char *handle;
1013
	char *handle;
996
	int local_fd, status = 0, write_error;
1014
	int local_fd = -1, status = 0, write_error, bigger;
997
	int read_error, write_errno;
1015
	int read_error, write_errno;
998
	u_int64_t offset, size;
1016
	u_int64_t offset = 0, size, highwater;
999
	u_int handle_len, mode, type, id, buflen, num_req, max_req;
1017
	u_int handle_len, mode, type, id, buflen, num_req, max_req;
1000
	off_t progress_counter;
1018
	off_t progress_counter;
1019
	struct stat st;
1001
	struct request {
1020
	struct request {
1002
		u_int id;
1021
		u_int id;
1003
		u_int len;
1022
		u_int len;
Lines 1050-1060 do_download(struct sftp_conn *conn, char Link Here
1050
		return(-1);
1069
		return(-1);
1051
	}
1070
	}
1052
1071
1053
	local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC,
1072
	if (resume) {
1054
	    mode | S_IWRITE);
1073
		if (stat(local_path, &st) == -1) {
1074
			offset = 0;
1075
			highwater = 0;
1076
			local_fd = open(local_path, O_WRONLY | O_CREAT,
1077
					mode | S_IWRITE);
1078
		}
1079
		else {
1080
			if ((size_t)st.st_size > size) {
1081
				bigger = 1;
1082
				local_fd = -1;
1083
			}
1084
			else {
1085
				offset = st.st_size;
1086
				highwater = st.st_size;	
1087
				local_fd = open(local_path,
1088
						O_WRONLY | O_CREAT,
1089
						mode | S_IWRITE);
1090
			}
1091
		}
1092
	}
1093
	else
1094
		local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC,
1095
				mode | S_IWRITE);
1055
	if (local_fd == -1) {
1096
	if (local_fd == -1) {
1056
		error("Couldn't open local file \"%s\" for writing: %s",
1097
		if (bigger)
1057
		    local_path, strerror(errno));
1098
			error("destination file bigger than source file");
1099
		else
1100
			error("Couldn't open local file \"%s\" for writing: %s",
1101
		    	      local_path, strerror(errno));
1058
		do_close(conn, handle, handle_len);
1102
		do_close(conn, handle, handle_len);
1059
		buffer_free(&msg);
1103
		buffer_free(&msg);
1060
		xfree(handle);
1104
		xfree(handle);
Lines 1062-1070 do_download(struct sftp_conn *conn, char Link Here
1062
	}
1106
	}
1063
1107
1064
	/* Read from remote and write to local */
1108
	/* Read from remote and write to local */
1065
	write_error = read_error = write_errno = num_req = offset = 0;
1109
	write_error = read_error = write_errno = num_req = 0;
1066
	max_req = 1;
1110
	max_req = 1;
1067
	progress_counter = 0;
1111
	progress_counter = offset;
1068
1112
1069
	if (showprogress && size != 0)
1113
	if (showprogress && size != 0)
1070
		start_progress_meter(remote_path, size, &progress_counter);
1114
		start_progress_meter(remote_path, size, &progress_counter);
Lines 1139-1144 do_download(struct sftp_conn *conn, char Link Here
1139
				write_error = 1;
1183
				write_error = 1;
1140
				max_req = 0;
1184
				max_req = 0;
1141
			}
1185
			}
1186
			else if (req->offset <= highwater)
1187
				highwater = req->offset + len;
1188
			else if (req->offset > highwater) {
1189
				ftruncate(local_fd, 0);
1190
				printf("reordered blocks detected");	
1191
			}	
1142
			progress_counter += len;
1192
			progress_counter += len;
1143
			xfree(data);
1193
			xfree(data);
1144
1194
Lines 1187-1192 do_download(struct sftp_conn *conn, char Link Here
1187
	/* Sanity check */
1237
	/* Sanity check */
1188
	if (TAILQ_FIRST(&requests) != NULL)
1238
	if (TAILQ_FIRST(&requests) != NULL)
1189
		fatal("Transfer complete, but requests still in queue");
1239
		fatal("Transfer complete, but requests still in queue");
1240
	/* Truncate at highest contiguous point to avoid holes on interrupt */
1241
	if (read_error || write_error || interrupted) {
1242
		debug("truncating at %llu", highwater);
1243
		ftruncate(local_fd, highwater);
1244
	}
1190
1245
1191
	if (read_error) {
1246
	if (read_error) {
1192
		error("Couldn't read from remote file \"%s\" : %s",
1247
		error("Couldn't read from remote file \"%s\" : %s",
Lines 1233-1238 download_dir_internal(struct sftp_conn * Link Here
1233
	SFTP_DIRENT **dir_entries;
1288
	SFTP_DIRENT **dir_entries;
1234
	char *filename, *new_src, *new_dst;
1289
	char *filename, *new_src, *new_dst;
1235
	mode_t mode = 0777;
1290
	mode_t mode = 0777;
1291
	int resume = 0;
1236
1292
1237
	if (depth >= MAX_DIR_DEPTH) {
1293
	if (depth >= MAX_DIR_DEPTH) {
1238
		error("Maximum directory depth exceeded: %d levels", depth);
1294
		error("Maximum directory depth exceeded: %d levels", depth);
Lines 1284-1290 download_dir_internal(struct sftp_conn * Link Here
1284
				ret = -1;
1340
				ret = -1;
1285
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1341
		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1286
			if (do_download(conn, new_src, new_dst,
1342
			if (do_download(conn, new_src, new_dst,
1287
			    &(dir_entries[i]->a), pflag) == -1) {
1343
			    &(dir_entries[i]->a), pflag, resume) == -1) {
1288
				error("Download of file %s to %s failed",
1344
				error("Download of file %s to %s failed",
1289
				    new_src, new_dst);
1345
				    new_src, new_dst);
1290
				ret = -1;
1346
				ret = -1;
Lines 1638-1641 path_append(char *p1, char *p2) Link Here
1638
1694
1639
	return(ret);
1695
	return(ret);
1640
}
1696
}
1641

Return to bug 2021