xref: /openssh-portable/sftp-client.c (revision e5895e8e)
1 /* $OpenBSD: sftp-client.c,v 1.140 2021/03/10 04:58:45 djm Exp $ */
2 /*
3  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* XXX: memleaks */
19 /* XXX: signed vs unsigned */
20 /* XXX: remove all logging, only return status codes */
21 /* XXX: copy between two remote sites */
22 
23 #include "includes.h"
24 
25 #include <sys/types.h>
26 #ifdef HAVE_SYS_STATVFS_H
27 #include <sys/statvfs.h>
28 #endif
29 #include "openbsd-compat/sys-queue.h"
30 #ifdef HAVE_SYS_STAT_H
31 # include <sys/stat.h>
32 #endif
33 #ifdef HAVE_SYS_TIME_H
34 # include <sys/time.h>
35 #endif
36 #include <sys/uio.h>
37 
38 #include <dirent.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 
48 #include "xmalloc.h"
49 #include "ssherr.h"
50 #include "sshbuf.h"
51 #include "log.h"
52 #include "atomicio.h"
53 #include "progressmeter.h"
54 #include "misc.h"
55 #include "utf8.h"
56 
57 #include "sftp.h"
58 #include "sftp-common.h"
59 #include "sftp-client.h"
60 
61 extern volatile sig_atomic_t interrupted;
62 extern int showprogress;
63 
64 /* Minimum amount of data to read at a time */
65 #define MIN_READ_SIZE	512
66 
67 /* Maximum depth to descend in directory trees */
68 #define MAX_DIR_DEPTH 64
69 
70 /* Directory separator characters */
71 #ifdef HAVE_CYGWIN
72 # define SFTP_DIRECTORY_CHARS      "/\\"
73 #else /* HAVE_CYGWIN */
74 # define SFTP_DIRECTORY_CHARS      "/"
75 #endif /* HAVE_CYGWIN */
76 
77 struct sftp_conn {
78 	int fd_in;
79 	int fd_out;
80 	u_int transfer_buflen;
81 	u_int num_requests;
82 	u_int version;
83 	u_int msg_id;
84 #define SFTP_EXT_POSIX_RENAME	0x00000001
85 #define SFTP_EXT_STATVFS	0x00000002
86 #define SFTP_EXT_FSTATVFS	0x00000004
87 #define SFTP_EXT_HARDLINK	0x00000008
88 #define SFTP_EXT_FSYNC		0x00000010
89 #define SFTP_EXT_LSETSTAT	0x00000020
90 	u_int exts;
91 	u_int64_t limit_kbps;
92 	struct bwlimit bwlimit_in, bwlimit_out;
93 };
94 
95 static u_char *
96 get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
97     const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
98 
99 /* ARGSUSED */
100 static int
101 sftpio(void *_bwlimit, size_t amount)
102 {
103 	struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
104 
105 	refresh_progress_meter(0);
106 	if (bwlimit != NULL)
107 		bandwidth_limit(bwlimit, amount);
108 	return 0;
109 }
110 
111 static void
112 send_msg(struct sftp_conn *conn, struct sshbuf *m)
113 {
114 	u_char mlen[4];
115 	struct iovec iov[2];
116 
117 	if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH)
118 		fatal("Outbound message too long %zu", sshbuf_len(m));
119 
120 	/* Send length first */
121 	put_u32(mlen, sshbuf_len(m));
122 	iov[0].iov_base = mlen;
123 	iov[0].iov_len = sizeof(mlen);
124 	iov[1].iov_base = (u_char *)sshbuf_ptr(m);
125 	iov[1].iov_len = sshbuf_len(m);
126 
127 	if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio,
128 	    conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) !=
129 	    sshbuf_len(m) + sizeof(mlen))
130 		fatal("Couldn't send packet: %s", strerror(errno));
131 
132 	sshbuf_reset(m);
133 }
134 
135 static void
136 get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
137 {
138 	u_int msg_len;
139 	u_char *p;
140 	int r;
141 
142 	if ((r = sshbuf_reserve(m, 4, &p)) != 0)
143 		fatal_fr(r, "reserve");
144 	if (atomicio6(read, conn->fd_in, p, 4, sftpio,
145 	    conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) {
146 		if (errno == EPIPE || errno == ECONNRESET)
147 			fatal("Connection closed");
148 		else
149 			fatal("Couldn't read packet: %s", strerror(errno));
150 	}
151 
152 	if ((r = sshbuf_get_u32(m, &msg_len)) != 0)
153 		fatal_fr(r, "sshbuf_get_u32");
154 	if (msg_len > SFTP_MAX_MSG_LENGTH) {
155 		do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL,
156 		    "Received message too long %u", msg_len);
157 		fatal("Ensure the remote shell produces no output "
158 		    "for non-interactive sessions.");
159 	}
160 
161 	if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
162 		fatal_fr(r, "reserve");
163 	if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
164 	    conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
165 	    != msg_len) {
166 		if (errno == EPIPE)
167 			fatal("Connection closed");
168 		else
169 			fatal("Read packet: %s", strerror(errno));
170 	}
171 }
172 
173 static void
174 get_msg(struct sftp_conn *conn, struct sshbuf *m)
175 {
176 	get_msg_extended(conn, m, 0);
177 }
178 
179 static void
180 send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
181     u_int len)
182 {
183 	struct sshbuf *msg;
184 	int r;
185 
186 	if ((msg = sshbuf_new()) == NULL)
187 		fatal_f("sshbuf_new failed");
188 	if ((r = sshbuf_put_u8(msg, code)) != 0 ||
189 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
190 	    (r = sshbuf_put_string(msg, s, len)) != 0)
191 		fatal_fr(r, "compose");
192 	send_msg(conn, msg);
193 	debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
194 	sshbuf_free(msg);
195 }
196 
197 static void
198 send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
199     const void *s, u_int len, Attrib *a)
200 {
201 	struct sshbuf *msg;
202 	int r;
203 
204 	if ((msg = sshbuf_new()) == NULL)
205 		fatal_f("sshbuf_new failed");
206 	if ((r = sshbuf_put_u8(msg, code)) != 0 ||
207 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
208 	    (r = sshbuf_put_string(msg, s, len)) != 0 ||
209 	    (r = encode_attrib(msg, a)) != 0)
210 		fatal_fr(r, "compose");
211 	send_msg(conn, msg);
212 	debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
213 	sshbuf_free(msg);
214 }
215 
216 static u_int
217 get_status(struct sftp_conn *conn, u_int expected_id)
218 {
219 	struct sshbuf *msg;
220 	u_char type;
221 	u_int id, status;
222 	int r;
223 
224 	if ((msg = sshbuf_new()) == NULL)
225 		fatal_f("sshbuf_new failed");
226 	get_msg(conn, msg);
227 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
228 	    (r = sshbuf_get_u32(msg, &id)) != 0)
229 		fatal_fr(r, "compose");
230 
231 	if (id != expected_id)
232 		fatal("ID mismatch (%u != %u)", id, expected_id);
233 	if (type != SSH2_FXP_STATUS)
234 		fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u",
235 		    SSH2_FXP_STATUS, type);
236 
237 	if ((r = sshbuf_get_u32(msg, &status)) != 0)
238 		fatal_fr(r, "parse");
239 	sshbuf_free(msg);
240 
241 	debug3("SSH2_FXP_STATUS %u", status);
242 
243 	return status;
244 }
245 
246 static u_char *
247 get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
248     const char *errfmt, ...)
249 {
250 	struct sshbuf *msg;
251 	u_int id, status;
252 	u_char type;
253 	u_char *handle;
254 	char errmsg[256];
255 	va_list args;
256 	int r;
257 
258 	va_start(args, errfmt);
259 	if (errfmt != NULL)
260 		vsnprintf(errmsg, sizeof(errmsg), errfmt, args);
261 	va_end(args);
262 
263 	if ((msg = sshbuf_new()) == NULL)
264 		fatal_f("sshbuf_new failed");
265 	get_msg(conn, msg);
266 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
267 	    (r = sshbuf_get_u32(msg, &id)) != 0)
268 		fatal_fr(r, "parse");
269 
270 	if (id != expected_id)
271 		fatal("%s: ID mismatch (%u != %u)",
272 		    errfmt == NULL ? __func__ : errmsg, id, expected_id);
273 	if (type == SSH2_FXP_STATUS) {
274 		if ((r = sshbuf_get_u32(msg, &status)) != 0)
275 			fatal_fr(r, "parse status");
276 		if (errfmt != NULL)
277 			error("%s: %s", errmsg, fx2txt(status));
278 		sshbuf_free(msg);
279 		return(NULL);
280 	} else if (type != SSH2_FXP_HANDLE)
281 		fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u",
282 		    errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
283 
284 	if ((r = sshbuf_get_string(msg, &handle, len)) != 0)
285 		fatal_fr(r, "parse handle");
286 	sshbuf_free(msg);
287 
288 	return handle;
289 }
290 
291 static Attrib *
292 get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
293 {
294 	struct sshbuf *msg;
295 	u_int id;
296 	u_char type;
297 	int r;
298 	static Attrib a;
299 
300 	if ((msg = sshbuf_new()) == NULL)
301 		fatal_f("sshbuf_new failed");
302 	get_msg(conn, msg);
303 
304 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
305 	    (r = sshbuf_get_u32(msg, &id)) != 0)
306 		fatal_fr(r, "parse");
307 
308 	debug3("Received stat reply T:%u I:%u", type, id);
309 	if (id != expected_id)
310 		fatal("ID mismatch (%u != %u)", id, expected_id);
311 	if (type == SSH2_FXP_STATUS) {
312 		u_int status;
313 
314 		if ((r = sshbuf_get_u32(msg, &status)) != 0)
315 			fatal_fr(r, "parse status");
316 		if (quiet)
317 			debug("Couldn't stat remote file: %s", fx2txt(status));
318 		else
319 			error("Couldn't stat remote file: %s", fx2txt(status));
320 		sshbuf_free(msg);
321 		return(NULL);
322 	} else if (type != SSH2_FXP_ATTRS) {
323 		fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
324 		    SSH2_FXP_ATTRS, type);
325 	}
326 	if ((r = decode_attrib(msg, &a)) != 0) {
327 		error_fr(r, "decode_attrib");
328 		sshbuf_free(msg);
329 		return NULL;
330 	}
331 	sshbuf_free(msg);
332 
333 	return &a;
334 }
335 
336 static int
337 get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
338     u_int expected_id, int quiet)
339 {
340 	struct sshbuf *msg;
341 	u_char type;
342 	u_int id;
343 	u_int64_t flag;
344 	int r;
345 
346 	if ((msg = sshbuf_new()) == NULL)
347 		fatal_f("sshbuf_new failed");
348 	get_msg(conn, msg);
349 
350 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
351 	    (r = sshbuf_get_u32(msg, &id)) != 0)
352 		fatal_fr(r, "parse");
353 
354 	debug3("Received statvfs reply T:%u I:%u", type, id);
355 	if (id != expected_id)
356 		fatal("ID mismatch (%u != %u)", id, expected_id);
357 	if (type == SSH2_FXP_STATUS) {
358 		u_int status;
359 
360 		if ((r = sshbuf_get_u32(msg, &status)) != 0)
361 			fatal_fr(r, "parse status");
362 		if (quiet)
363 			debug("Couldn't statvfs: %s", fx2txt(status));
364 		else
365 			error("Couldn't statvfs: %s", fx2txt(status));
366 		sshbuf_free(msg);
367 		return -1;
368 	} else if (type != SSH2_FXP_EXTENDED_REPLY) {
369 		fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
370 		    SSH2_FXP_EXTENDED_REPLY, type);
371 	}
372 
373 	memset(st, 0, sizeof(*st));
374 	if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 ||
375 	    (r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 ||
376 	    (r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 ||
377 	    (r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 ||
378 	    (r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 ||
379 	    (r = sshbuf_get_u64(msg, &st->f_files)) != 0 ||
380 	    (r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 ||
381 	    (r = sshbuf_get_u64(msg, &st->f_favail)) != 0 ||
382 	    (r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 ||
383 	    (r = sshbuf_get_u64(msg, &flag)) != 0 ||
384 	    (r = sshbuf_get_u64(msg, &st->f_namemax)) != 0)
385 		fatal_fr(r, "parse statvfs");
386 
387 	st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
388 	st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
389 
390 	sshbuf_free(msg);
391 
392 	return 0;
393 }
394 
395 struct sftp_conn *
396 do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
397     u_int64_t limit_kbps)
398 {
399 	u_char type;
400 	struct sshbuf *msg;
401 	struct sftp_conn *ret;
402 	int r;
403 
404 	ret = xcalloc(1, sizeof(*ret));
405 	ret->msg_id = 1;
406 	ret->fd_in = fd_in;
407 	ret->fd_out = fd_out;
408 	ret->transfer_buflen = transfer_buflen;
409 	ret->num_requests = num_requests;
410 	ret->exts = 0;
411 	ret->limit_kbps = 0;
412 
413 	if ((msg = sshbuf_new()) == NULL)
414 		fatal_f("sshbuf_new failed");
415 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 ||
416 	    (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
417 		fatal_fr(r, "parse");
418 
419 	send_msg(ret, msg);
420 
421 	get_msg_extended(ret, msg, 1);
422 
423 	/* Expecting a VERSION reply */
424 	if ((r = sshbuf_get_u8(msg, &type)) != 0)
425 		fatal_fr(r, "parse type");
426 	if (type != SSH2_FXP_VERSION) {
427 		error("Invalid packet back from SSH2_FXP_INIT (type %u)",
428 		    type);
429 		sshbuf_free(msg);
430 		free(ret);
431 		return(NULL);
432 	}
433 	if ((r = sshbuf_get_u32(msg, &ret->version)) != 0)
434 		fatal_fr(r, "parse version");
435 
436 	debug2("Remote version: %u", ret->version);
437 
438 	/* Check for extensions */
439 	while (sshbuf_len(msg) > 0) {
440 		char *name;
441 		u_char *value;
442 		size_t vlen;
443 		int known = 0;
444 
445 		if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 ||
446 		    (r = sshbuf_get_string(msg, &value, &vlen)) != 0)
447 			fatal_fr(r, "parse extension");
448 		if (strcmp(name, "posix-rename@openssh.com") == 0 &&
449 		    strcmp((char *)value, "1") == 0) {
450 			ret->exts |= SFTP_EXT_POSIX_RENAME;
451 			known = 1;
452 		} else if (strcmp(name, "statvfs@openssh.com") == 0 &&
453 		    strcmp((char *)value, "2") == 0) {
454 			ret->exts |= SFTP_EXT_STATVFS;
455 			known = 1;
456 		} else if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
457 		    strcmp((char *)value, "2") == 0) {
458 			ret->exts |= SFTP_EXT_FSTATVFS;
459 			known = 1;
460 		} else if (strcmp(name, "hardlink@openssh.com") == 0 &&
461 		    strcmp((char *)value, "1") == 0) {
462 			ret->exts |= SFTP_EXT_HARDLINK;
463 			known = 1;
464 		} else if (strcmp(name, "fsync@openssh.com") == 0 &&
465 		    strcmp((char *)value, "1") == 0) {
466 			ret->exts |= SFTP_EXT_FSYNC;
467 			known = 1;
468 		} else if (strcmp(name, "lsetstat@openssh.com") == 0 &&
469 		    strcmp((char *)value, "1") == 0) {
470 			ret->exts |= SFTP_EXT_LSETSTAT;
471 			known = 1;
472 		}
473 		if (known) {
474 			debug2("Server supports extension \"%s\" revision %s",
475 			    name, value);
476 		} else {
477 			debug2("Unrecognised server extension \"%s\"", name);
478 		}
479 		free(name);
480 		free(value);
481 	}
482 
483 	sshbuf_free(msg);
484 
485 	/* Some filexfer v.0 servers don't support large packets */
486 	if (ret->version == 0)
487 		ret->transfer_buflen = MINIMUM(ret->transfer_buflen, 20480);
488 
489 	ret->limit_kbps = limit_kbps;
490 	if (ret->limit_kbps > 0) {
491 		bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
492 		    ret->transfer_buflen);
493 		bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
494 		    ret->transfer_buflen);
495 	}
496 
497 	return ret;
498 }
499 
500 u_int
501 sftp_proto_version(struct sftp_conn *conn)
502 {
503 	return conn->version;
504 }
505 
506 int
507 do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
508 {
509 	u_int id, status;
510 	struct sshbuf *msg;
511 	int r;
512 
513 	if ((msg = sshbuf_new()) == NULL)
514 		fatal_f("sshbuf_new failed");
515 
516 	id = conn->msg_id++;
517 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 ||
518 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
519 	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
520 		fatal_fr(r, "parse");
521 	send_msg(conn, msg);
522 	debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
523 
524 	status = get_status(conn, id);
525 	if (status != SSH2_FX_OK)
526 		error("Couldn't close file: %s", fx2txt(status));
527 
528 	sshbuf_free(msg);
529 
530 	return status == SSH2_FX_OK ? 0 : -1;
531 }
532 
533 
534 static int
535 do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
536     SFTP_DIRENT ***dir)
537 {
538 	struct sshbuf *msg;
539 	u_int count, id, i, expected_id, ents = 0;
540 	size_t handle_len;
541 	u_char type, *handle;
542 	int status = SSH2_FX_FAILURE;
543 	int r;
544 
545 	if (dir)
546 		*dir = NULL;
547 
548 	id = conn->msg_id++;
549 
550 	if ((msg = sshbuf_new()) == NULL)
551 		fatal_f("sshbuf_new failed");
552 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 ||
553 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
554 	    (r = sshbuf_put_cstring(msg, path)) != 0)
555 		fatal_fr(r, "compose OPENDIR");
556 	send_msg(conn, msg);
557 
558 	handle = get_handle(conn, id, &handle_len,
559 	    "remote readdir(\"%s\")", path);
560 	if (handle == NULL) {
561 		sshbuf_free(msg);
562 		return -1;
563 	}
564 
565 	if (dir) {
566 		ents = 0;
567 		*dir = xcalloc(1, sizeof(**dir));
568 		(*dir)[0] = NULL;
569 	}
570 
571 	for (; !interrupted;) {
572 		id = expected_id = conn->msg_id++;
573 
574 		debug3("Sending SSH2_FXP_READDIR I:%u", id);
575 
576 		sshbuf_reset(msg);
577 		if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 ||
578 		    (r = sshbuf_put_u32(msg, id)) != 0 ||
579 		    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
580 			fatal_fr(r, "compose READDIR");
581 		send_msg(conn, msg);
582 
583 		sshbuf_reset(msg);
584 
585 		get_msg(conn, msg);
586 
587 		if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
588 		    (r = sshbuf_get_u32(msg, &id)) != 0)
589 			fatal_fr(r, "parse");
590 
591 		debug3("Received reply T:%u I:%u", type, id);
592 
593 		if (id != expected_id)
594 			fatal("ID mismatch (%u != %u)", id, expected_id);
595 
596 		if (type == SSH2_FXP_STATUS) {
597 			u_int rstatus;
598 
599 			if ((r = sshbuf_get_u32(msg, &rstatus)) != 0)
600 				fatal_fr(r, "parse status");
601 			debug3("Received SSH2_FXP_STATUS %d", rstatus);
602 			if (rstatus == SSH2_FX_EOF)
603 				break;
604 			error("Couldn't read directory: %s", fx2txt(rstatus));
605 			goto out;
606 		} else if (type != SSH2_FXP_NAME)
607 			fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
608 			    SSH2_FXP_NAME, type);
609 
610 		if ((r = sshbuf_get_u32(msg, &count)) != 0)
611 			fatal_fr(r, "parse count");
612 		if (count > SSHBUF_SIZE_MAX)
613 			fatal_f("nonsensical number of entries");
614 		if (count == 0)
615 			break;
616 		debug3("Received %d SSH2_FXP_NAME responses", count);
617 		for (i = 0; i < count; i++) {
618 			char *filename, *longname;
619 			Attrib a;
620 
621 			if ((r = sshbuf_get_cstring(msg, &filename,
622 			    NULL)) != 0 ||
623 			    (r = sshbuf_get_cstring(msg, &longname,
624 			    NULL)) != 0)
625 				fatal_fr(r, "parse filenames");
626 			if ((r = decode_attrib(msg, &a)) != 0) {
627 				error_fr(r, "couldn't decode attrib");
628 				free(filename);
629 				free(longname);
630 				goto out;
631 			}
632 
633 			if (print_flag)
634 				mprintf("%s\n", longname);
635 
636 			/*
637 			 * Directory entries should never contain '/'
638 			 * These can be used to attack recursive ops
639 			 * (e.g. send '../../../../etc/passwd')
640 			 */
641 			if (strpbrk(filename, SFTP_DIRECTORY_CHARS) != NULL) {
642 				error("Server sent suspect path \"%s\" "
643 				    "during readdir of \"%s\"", filename, path);
644 			} else if (dir) {
645 				*dir = xreallocarray(*dir, ents + 2, sizeof(**dir));
646 				(*dir)[ents] = xcalloc(1, sizeof(***dir));
647 				(*dir)[ents]->filename = xstrdup(filename);
648 				(*dir)[ents]->longname = xstrdup(longname);
649 				memcpy(&(*dir)[ents]->a, &a, sizeof(a));
650 				(*dir)[++ents] = NULL;
651 			}
652 			free(filename);
653 			free(longname);
654 		}
655 	}
656 	status = 0;
657 
658  out:
659 	sshbuf_free(msg);
660 	do_close(conn, handle, handle_len);
661 	free(handle);
662 
663 	if (status != 0 && dir != NULL) {
664 		/* Don't return results on error */
665 		free_sftp_dirents(*dir);
666 		*dir = NULL;
667 	} else if (interrupted && dir != NULL && *dir != NULL) {
668 		/* Don't return partial matches on interrupt */
669 		free_sftp_dirents(*dir);
670 		*dir = xcalloc(1, sizeof(**dir));
671 		**dir = NULL;
672 	}
673 
674 	return status == SSH2_FX_OK ? 0 : -1;
675 }
676 
677 int
678 do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
679 {
680 	return(do_lsreaddir(conn, path, 0, dir));
681 }
682 
683 void free_sftp_dirents(SFTP_DIRENT **s)
684 {
685 	int i;
686 
687 	if (s == NULL)
688 		return;
689 	for (i = 0; s[i]; i++) {
690 		free(s[i]->filename);
691 		free(s[i]->longname);
692 		free(s[i]);
693 	}
694 	free(s);
695 }
696 
697 int
698 do_rm(struct sftp_conn *conn, const char *path)
699 {
700 	u_int status, id;
701 
702 	debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
703 
704 	id = conn->msg_id++;
705 	send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
706 	status = get_status(conn, id);
707 	if (status != SSH2_FX_OK)
708 		error("Couldn't delete file: %s", fx2txt(status));
709 	return status == SSH2_FX_OK ? 0 : -1;
710 }
711 
712 int
713 do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
714 {
715 	u_int status, id;
716 
717 	id = conn->msg_id++;
718 	send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
719 	    strlen(path), a);
720 
721 	status = get_status(conn, id);
722 	if (status != SSH2_FX_OK && print_flag)
723 		error("Couldn't create directory: %s", fx2txt(status));
724 
725 	return status == SSH2_FX_OK ? 0 : -1;
726 }
727 
728 int
729 do_rmdir(struct sftp_conn *conn, const char *path)
730 {
731 	u_int status, id;
732 
733 	id = conn->msg_id++;
734 	send_string_request(conn, id, SSH2_FXP_RMDIR, path,
735 	    strlen(path));
736 
737 	status = get_status(conn, id);
738 	if (status != SSH2_FX_OK)
739 		error("Couldn't remove directory: %s", fx2txt(status));
740 
741 	return status == SSH2_FX_OK ? 0 : -1;
742 }
743 
744 Attrib *
745 do_stat(struct sftp_conn *conn, const char *path, int quiet)
746 {
747 	u_int id;
748 
749 	id = conn->msg_id++;
750 
751 	send_string_request(conn, id,
752 	    conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
753 	    path, strlen(path));
754 
755 	return(get_decode_stat(conn, id, quiet));
756 }
757 
758 Attrib *
759 do_lstat(struct sftp_conn *conn, const char *path, int quiet)
760 {
761 	u_int id;
762 
763 	if (conn->version == 0) {
764 		if (quiet)
765 			debug("Server version does not support lstat operation");
766 		else
767 			logit("Server version does not support lstat operation");
768 		return(do_stat(conn, path, quiet));
769 	}
770 
771 	id = conn->msg_id++;
772 	send_string_request(conn, id, SSH2_FXP_LSTAT, path,
773 	    strlen(path));
774 
775 	return(get_decode_stat(conn, id, quiet));
776 }
777 
778 #ifdef notyet
779 Attrib *
780 do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
781     int quiet)
782 {
783 	u_int id;
784 
785 	id = conn->msg_id++;
786 	send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
787 	    handle_len);
788 
789 	return(get_decode_stat(conn, id, quiet));
790 }
791 #endif
792 
793 int
794 do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
795 {
796 	u_int status, id;
797 
798 	id = conn->msg_id++;
799 	send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
800 	    strlen(path), a);
801 
802 	status = get_status(conn, id);
803 	if (status != SSH2_FX_OK)
804 		error("Couldn't setstat on \"%s\": %s", path,
805 		    fx2txt(status));
806 
807 	return status == SSH2_FX_OK ? 0 : -1;
808 }
809 
810 int
811 do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
812     Attrib *a)
813 {
814 	u_int status, id;
815 
816 	id = conn->msg_id++;
817 	send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
818 	    handle_len, a);
819 
820 	status = get_status(conn, id);
821 	if (status != SSH2_FX_OK)
822 		error("Couldn't fsetstat: %s", fx2txt(status));
823 
824 	return status == SSH2_FX_OK ? 0 : -1;
825 }
826 
827 char *
828 do_realpath(struct sftp_conn *conn, const char *path)
829 {
830 	struct sshbuf *msg;
831 	u_int expected_id, count, id;
832 	char *filename, *longname;
833 	Attrib a;
834 	u_char type;
835 	int r;
836 
837 	expected_id = id = conn->msg_id++;
838 	send_string_request(conn, id, SSH2_FXP_REALPATH, path,
839 	    strlen(path));
840 
841 	if ((msg = sshbuf_new()) == NULL)
842 		fatal_f("sshbuf_new failed");
843 
844 	get_msg(conn, msg);
845 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
846 	    (r = sshbuf_get_u32(msg, &id)) != 0)
847 		fatal_fr(r, "parse");
848 
849 	if (id != expected_id)
850 		fatal("ID mismatch (%u != %u)", id, expected_id);
851 
852 	if (type == SSH2_FXP_STATUS) {
853 		u_int status;
854 
855 		if ((r = sshbuf_get_u32(msg, &status)) != 0)
856 			fatal_fr(r, "parse status");
857 		error("Couldn't canonicalize: %s", fx2txt(status));
858 		sshbuf_free(msg);
859 		return NULL;
860 	} else if (type != SSH2_FXP_NAME)
861 		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
862 		    SSH2_FXP_NAME, type);
863 
864 	if ((r = sshbuf_get_u32(msg, &count)) != 0)
865 		fatal_fr(r, "parse count");
866 	if (count != 1)
867 		fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count);
868 
869 	if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
870 	    (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
871 	    (r = decode_attrib(msg, &a)) != 0)
872 		fatal_fr(r, "parse filename/attrib");
873 
874 	debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename,
875 	    (unsigned long)a.size);
876 
877 	free(longname);
878 
879 	sshbuf_free(msg);
880 
881 	return(filename);
882 }
883 
884 int
885 do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
886     int force_legacy)
887 {
888 	struct sshbuf *msg;
889 	u_int status, id;
890 	int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy;
891 
892 	if ((msg = sshbuf_new()) == NULL)
893 		fatal_f("sshbuf_new failed");
894 
895 	/* Send rename request */
896 	id = conn->msg_id++;
897 	if (use_ext) {
898 		if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
899 		    (r = sshbuf_put_u32(msg, id)) != 0 ||
900 		    (r = sshbuf_put_cstring(msg,
901 		    "posix-rename@openssh.com")) != 0)
902 			fatal_fr(r, "compose posix-rename");
903 	} else {
904 		if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
905 		    (r = sshbuf_put_u32(msg, id)) != 0)
906 			fatal_fr(r, "compose rename");
907 	}
908 	if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
909 	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
910 		fatal_fr(r, "compose paths");
911 	send_msg(conn, msg);
912 	debug3("Sent message %s \"%s\" -> \"%s\"",
913 	    use_ext ? "posix-rename@openssh.com" :
914 	    "SSH2_FXP_RENAME", oldpath, newpath);
915 	sshbuf_free(msg);
916 
917 	status = get_status(conn, id);
918 	if (status != SSH2_FX_OK)
919 		error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
920 		    newpath, fx2txt(status));
921 
922 	return status == SSH2_FX_OK ? 0 : -1;
923 }
924 
925 int
926 do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
927 {
928 	struct sshbuf *msg;
929 	u_int status, id;
930 	int r;
931 
932 	if ((conn->exts & SFTP_EXT_HARDLINK) == 0) {
933 		error("Server does not support hardlink@openssh.com extension");
934 		return -1;
935 	}
936 
937 	if ((msg = sshbuf_new()) == NULL)
938 		fatal_f("sshbuf_new failed");
939 
940 	/* Send link request */
941 	id = conn->msg_id++;
942 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
943 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
944 	    (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
945 	    (r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
946 	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
947 		fatal_fr(r, "compose");
948 	send_msg(conn, msg);
949 	debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"",
950 	       oldpath, newpath);
951 	sshbuf_free(msg);
952 
953 	status = get_status(conn, id);
954 	if (status != SSH2_FX_OK)
955 		error("Couldn't link file \"%s\" to \"%s\": %s", oldpath,
956 		    newpath, fx2txt(status));
957 
958 	return status == SSH2_FX_OK ? 0 : -1;
959 }
960 
961 int
962 do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
963 {
964 	struct sshbuf *msg;
965 	u_int status, id;
966 	int r;
967 
968 	if (conn->version < 3) {
969 		error("This server does not support the symlink operation");
970 		return(SSH2_FX_OP_UNSUPPORTED);
971 	}
972 
973 	if ((msg = sshbuf_new()) == NULL)
974 		fatal_f("sshbuf_new failed");
975 
976 	/* Send symlink request */
977 	id = conn->msg_id++;
978 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 ||
979 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
980 	    (r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
981 	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
982 		fatal_fr(r, "compose");
983 	send_msg(conn, msg);
984 	debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
985 	    newpath);
986 	sshbuf_free(msg);
987 
988 	status = get_status(conn, id);
989 	if (status != SSH2_FX_OK)
990 		error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
991 		    newpath, fx2txt(status));
992 
993 	return status == SSH2_FX_OK ? 0 : -1;
994 }
995 
996 int
997 do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
998 {
999 	struct sshbuf *msg;
1000 	u_int status, id;
1001 	int r;
1002 
1003 	/* Silently return if the extension is not supported */
1004 	if ((conn->exts & SFTP_EXT_FSYNC) == 0)
1005 		return -1;
1006 
1007 	/* Send fsync request */
1008 	if ((msg = sshbuf_new()) == NULL)
1009 		fatal_f("sshbuf_new failed");
1010 	id = conn->msg_id++;
1011 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1012 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1013 	    (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 ||
1014 	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
1015 		fatal_fr(r, "compose");
1016 	send_msg(conn, msg);
1017 	debug3("Sent message fsync@openssh.com I:%u", id);
1018 	sshbuf_free(msg);
1019 
1020 	status = get_status(conn, id);
1021 	if (status != SSH2_FX_OK)
1022 		error("Couldn't sync file: %s", fx2txt(status));
1023 
1024 	return status == SSH2_FX_OK ? 0 : -1;
1025 }
1026 
1027 #ifdef notyet
1028 char *
1029 do_readlink(struct sftp_conn *conn, const char *path)
1030 {
1031 	struct sshbuf *msg;
1032 	u_int expected_id, count, id;
1033 	char *filename, *longname;
1034 	Attrib a;
1035 	u_char type;
1036 	int r;
1037 
1038 	expected_id = id = conn->msg_id++;
1039 	send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
1040 
1041 	if ((msg = sshbuf_new()) == NULL)
1042 		fatal_f("sshbuf_new failed");
1043 
1044 	get_msg(conn, msg);
1045 	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1046 	    (r = sshbuf_get_u32(msg, &id)) != 0)
1047 		fatal_fr(r, "parse");
1048 
1049 	if (id != expected_id)
1050 		fatal("ID mismatch (%u != %u)", id, expected_id);
1051 
1052 	if (type == SSH2_FXP_STATUS) {
1053 		u_int status;
1054 
1055 		if ((r = sshbuf_get_u32(msg, &status)) != 0)
1056 			fatal_fr(r, "parse status");
1057 		error("Couldn't readlink: %s", fx2txt(status));
1058 		sshbuf_free(msg);
1059 		return(NULL);
1060 	} else if (type != SSH2_FXP_NAME)
1061 		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
1062 		    SSH2_FXP_NAME, type);
1063 
1064 	if ((r = sshbuf_get_u32(msg, &count)) != 0)
1065 		fatal_fr(r, "parse count");
1066 	if (count != 1)
1067 		fatal("Got multiple names (%d) from SSH_FXP_READLINK", count);
1068 
1069 	if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
1070 	    (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
1071 	    (r = decode_attrib(msg, &a)) != 0)
1072 		fatal_fr(r, "parse filenames/attrib");
1073 
1074 	debug3("SSH_FXP_READLINK %s -> %s", path, filename);
1075 
1076 	free(longname);
1077 
1078 	sshbuf_free(msg);
1079 
1080 	return filename;
1081 }
1082 #endif
1083 
1084 int
1085 do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
1086     int quiet)
1087 {
1088 	struct sshbuf *msg;
1089 	u_int id;
1090 	int r;
1091 
1092 	if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
1093 		error("Server does not support statvfs@openssh.com extension");
1094 		return -1;
1095 	}
1096 
1097 	id = conn->msg_id++;
1098 
1099 	if ((msg = sshbuf_new()) == NULL)
1100 		fatal_f("sshbuf_new failed");
1101 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1102 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1103 	    (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
1104 	    (r = sshbuf_put_cstring(msg, path)) != 0)
1105 		fatal_fr(r, "compose");
1106 	send_msg(conn, msg);
1107 	sshbuf_free(msg);
1108 
1109 	return get_decode_statvfs(conn, st, id, quiet);
1110 }
1111 
1112 #ifdef notyet
1113 int
1114 do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
1115     struct sftp_statvfs *st, int quiet)
1116 {
1117 	struct sshbuf *msg;
1118 	u_int id;
1119 
1120 	if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
1121 		error("Server does not support fstatvfs@openssh.com extension");
1122 		return -1;
1123 	}
1124 
1125 	id = conn->msg_id++;
1126 
1127 	if ((msg = sshbuf_new()) == NULL)
1128 		fatal_f("sshbuf_new failed");
1129 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1130 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1131 	    (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
1132 	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
1133 		fatal_fr(r, "compose");
1134 	send_msg(conn, msg);
1135 	sshbuf_free(msg);
1136 
1137 	return get_decode_statvfs(conn, st, id, quiet);
1138 }
1139 #endif
1140 
1141 int
1142 do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
1143 {
1144 	struct sshbuf *msg;
1145 	u_int status, id;
1146 	int r;
1147 
1148 	if ((conn->exts & SFTP_EXT_LSETSTAT) == 0) {
1149 		error("Server does not support lsetstat@openssh.com extension");
1150 		return -1;
1151 	}
1152 
1153 	id = conn->msg_id++;
1154 	if ((msg = sshbuf_new()) == NULL)
1155 		fatal_f("sshbuf_new failed");
1156 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1157 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1158 	    (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 ||
1159 	    (r = sshbuf_put_cstring(msg, path)) != 0 ||
1160 	    (r = encode_attrib(msg, a)) != 0)
1161 		fatal_fr(r, "compose");
1162 	send_msg(conn, msg);
1163 	sshbuf_free(msg);
1164 
1165 	status = get_status(conn, id);
1166 	if (status != SSH2_FX_OK)
1167 		error("Couldn't setstat on \"%s\": %s", path,
1168 		    fx2txt(status));
1169 
1170 	return status == SSH2_FX_OK ? 0 : -1;
1171 }
1172 
1173 static void
1174 send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
1175     u_int len, const u_char *handle, u_int handle_len)
1176 {
1177 	struct sshbuf *msg;
1178 	int r;
1179 
1180 	if ((msg = sshbuf_new()) == NULL)
1181 		fatal_f("sshbuf_new failed");
1182 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 ||
1183 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1184 	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0 ||
1185 	    (r = sshbuf_put_u64(msg, offset)) != 0 ||
1186 	    (r = sshbuf_put_u32(msg, len)) != 0)
1187 		fatal_fr(r, "compose");
1188 	send_msg(conn, msg);
1189 	sshbuf_free(msg);
1190 }
1191 
1192 int
1193 do_download(struct sftp_conn *conn, const char *remote_path,
1194     const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
1195     int fsync_flag)
1196 {
1197 	Attrib junk;
1198 	struct sshbuf *msg;
1199 	u_char *handle;
1200 	int local_fd = -1, write_error;
1201 	int read_error, write_errno, lmodified = 0, reordered = 0, r;
1202 	u_int64_t offset = 0, size, highwater;
1203 	u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK;
1204 	off_t progress_counter;
1205 	size_t handle_len;
1206 	struct stat st;
1207 	struct request {
1208 		u_int id;
1209 		size_t len;
1210 		u_int64_t offset;
1211 		TAILQ_ENTRY(request) tq;
1212 	};
1213 	TAILQ_HEAD(reqhead, request) requests;
1214 	struct request *req;
1215 	u_char type;
1216 
1217 	TAILQ_INIT(&requests);
1218 
1219 	if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
1220 		return -1;
1221 
1222 	/* Do not preserve set[ug]id here, as we do not preserve ownership */
1223 	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
1224 		mode = a->perm & 0777;
1225 	else
1226 		mode = 0666;
1227 
1228 	if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
1229 	    (!S_ISREG(a->perm))) {
1230 		error("Cannot download non-regular file: %s", remote_path);
1231 		return(-1);
1232 	}
1233 
1234 	if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
1235 		size = a->size;
1236 	else
1237 		size = 0;
1238 
1239 	buflen = conn->transfer_buflen;
1240 	if ((msg = sshbuf_new()) == NULL)
1241 		fatal_f("sshbuf_new failed");
1242 
1243 	attrib_clear(&junk); /* Send empty attributes */
1244 
1245 	/* Send open request */
1246 	id = conn->msg_id++;
1247 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
1248 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1249 	    (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
1250 	    (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 ||
1251 	    (r = encode_attrib(msg, &junk)) != 0)
1252 		fatal_fr(r, "compose");
1253 	send_msg(conn, msg);
1254 	debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
1255 
1256 	handle = get_handle(conn, id, &handle_len,
1257 	    "remote open(\"%s\")", remote_path);
1258 	if (handle == NULL) {
1259 		sshbuf_free(msg);
1260 		return(-1);
1261 	}
1262 
1263 	local_fd = open(local_path,
1264 	    O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
1265 	if (local_fd == -1) {
1266 		error("Couldn't open local file \"%s\" for writing: %s",
1267 		    local_path, strerror(errno));
1268 		goto fail;
1269 	}
1270 	offset = highwater = 0;
1271 	if (resume_flag) {
1272 		if (fstat(local_fd, &st) == -1) {
1273 			error("Unable to stat local file \"%s\": %s",
1274 			    local_path, strerror(errno));
1275 			goto fail;
1276 		}
1277 		if (st.st_size < 0) {
1278 			error("\"%s\" has negative size", local_path);
1279 			goto fail;
1280 		}
1281 		if ((u_int64_t)st.st_size > size) {
1282 			error("Unable to resume download of \"%s\": "
1283 			    "local file is larger than remote", local_path);
1284  fail:
1285 			do_close(conn, handle, handle_len);
1286 			sshbuf_free(msg);
1287 			free(handle);
1288 			if (local_fd != -1)
1289 				close(local_fd);
1290 			return -1;
1291 		}
1292 		offset = highwater = st.st_size;
1293 	}
1294 
1295 	/* Read from remote and write to local */
1296 	write_error = read_error = write_errno = num_req = 0;
1297 	max_req = 1;
1298 	progress_counter = offset;
1299 
1300 	if (showprogress && size != 0)
1301 		start_progress_meter(remote_path, size, &progress_counter);
1302 
1303 	while (num_req > 0 || max_req > 0) {
1304 		u_char *data;
1305 		size_t len;
1306 
1307 		/*
1308 		 * Simulate EOF on interrupt: stop sending new requests and
1309 		 * allow outstanding requests to drain gracefully
1310 		 */
1311 		if (interrupted) {
1312 			if (num_req == 0) /* If we haven't started yet... */
1313 				break;
1314 			max_req = 0;
1315 		}
1316 
1317 		/* Send some more requests */
1318 		while (num_req < max_req) {
1319 			debug3("Request range %llu -> %llu (%d/%d)",
1320 			    (unsigned long long)offset,
1321 			    (unsigned long long)offset + buflen - 1,
1322 			    num_req, max_req);
1323 			req = xcalloc(1, sizeof(*req));
1324 			req->id = conn->msg_id++;
1325 			req->len = buflen;
1326 			req->offset = offset;
1327 			offset += buflen;
1328 			num_req++;
1329 			TAILQ_INSERT_TAIL(&requests, req, tq);
1330 			send_read_request(conn, req->id, req->offset,
1331 			    req->len, handle, handle_len);
1332 		}
1333 
1334 		sshbuf_reset(msg);
1335 		get_msg(conn, msg);
1336 		if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1337 		    (r = sshbuf_get_u32(msg, &id)) != 0)
1338 			fatal_fr(r, "parse");
1339 		debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
1340 
1341 		/* Find the request in our queue */
1342 		for (req = TAILQ_FIRST(&requests);
1343 		    req != NULL && req->id != id;
1344 		    req = TAILQ_NEXT(req, tq))
1345 			;
1346 		if (req == NULL)
1347 			fatal("Unexpected reply %u", id);
1348 
1349 		switch (type) {
1350 		case SSH2_FXP_STATUS:
1351 			if ((r = sshbuf_get_u32(msg, &status)) != 0)
1352 				fatal_fr(r, "parse status");
1353 			if (status != SSH2_FX_EOF)
1354 				read_error = 1;
1355 			max_req = 0;
1356 			TAILQ_REMOVE(&requests, req, tq);
1357 			free(req);
1358 			num_req--;
1359 			break;
1360 		case SSH2_FXP_DATA:
1361 			if ((r = sshbuf_get_string(msg, &data, &len)) != 0)
1362 				fatal_fr(r, "parse data");
1363 			debug3("Received data %llu -> %llu",
1364 			    (unsigned long long)req->offset,
1365 			    (unsigned long long)req->offset + len - 1);
1366 			if (len > req->len)
1367 				fatal("Received more data than asked for "
1368 				    "%zu > %zu", len, req->len);
1369 			lmodified = 1;
1370 			if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
1371 			    atomicio(vwrite, local_fd, data, len) != len) &&
1372 			    !write_error) {
1373 				write_errno = errno;
1374 				write_error = 1;
1375 				max_req = 0;
1376 			}
1377 			else if (!reordered && req->offset <= highwater)
1378 				highwater = req->offset + len;
1379 			else if (!reordered && req->offset > highwater)
1380 				reordered = 1;
1381 			progress_counter += len;
1382 			free(data);
1383 
1384 			if (len == req->len) {
1385 				TAILQ_REMOVE(&requests, req, tq);
1386 				free(req);
1387 				num_req--;
1388 			} else {
1389 				/* Resend the request for the missing data */
1390 				debug3("Short data block, re-requesting "
1391 				    "%llu -> %llu (%2d)",
1392 				    (unsigned long long)req->offset + len,
1393 				    (unsigned long long)req->offset +
1394 				    req->len - 1, num_req);
1395 				req->id = conn->msg_id++;
1396 				req->len -= len;
1397 				req->offset += len;
1398 				send_read_request(conn, req->id,
1399 				    req->offset, req->len, handle, handle_len);
1400 				/* Reduce the request size */
1401 				if (len < buflen)
1402 					buflen = MAXIMUM(MIN_READ_SIZE, len);
1403 			}
1404 			if (max_req > 0) { /* max_req = 0 iff EOF received */
1405 				if (size > 0 && offset > size) {
1406 					/* Only one request at a time
1407 					 * after the expected EOF */
1408 					debug3("Finish at %llu (%2d)",
1409 					    (unsigned long long)offset,
1410 					    num_req);
1411 					max_req = 1;
1412 				} else if (max_req < conn->num_requests) {
1413 					++max_req;
1414 				}
1415 			}
1416 			break;
1417 		default:
1418 			fatal("Expected SSH2_FXP_DATA(%u) packet, got %u",
1419 			    SSH2_FXP_DATA, type);
1420 		}
1421 	}
1422 
1423 	if (showprogress && size)
1424 		stop_progress_meter();
1425 
1426 	/* Sanity check */
1427 	if (TAILQ_FIRST(&requests) != NULL)
1428 		fatal("Transfer complete, but requests still in queue");
1429 	/* Truncate at highest contiguous point to avoid holes on interrupt */
1430 	if (read_error || write_error || interrupted) {
1431 		if (reordered && resume_flag) {
1432 			error("Unable to resume download of \"%s\": "
1433 			    "server reordered requests", local_path);
1434 		}
1435 		debug("truncating at %llu", (unsigned long long)highwater);
1436 		if (ftruncate(local_fd, highwater) == -1)
1437 			error("ftruncate \"%s\": %s", local_path,
1438 			    strerror(errno));
1439 	}
1440 	if (read_error) {
1441 		error("Couldn't read from remote file \"%s\" : %s",
1442 		    remote_path, fx2txt(status));
1443 		status = -1;
1444 		do_close(conn, handle, handle_len);
1445 	} else if (write_error) {
1446 		error("Couldn't write to \"%s\": %s", local_path,
1447 		    strerror(write_errno));
1448 		status = SSH2_FX_FAILURE;
1449 		do_close(conn, handle, handle_len);
1450 	} else {
1451 		if (do_close(conn, handle, handle_len) != 0 || interrupted)
1452 			status = SSH2_FX_FAILURE;
1453 		else
1454 			status = SSH2_FX_OK;
1455 		/* Override umask and utimes if asked */
1456 #ifdef HAVE_FCHMOD
1457 		if (preserve_flag && fchmod(local_fd, mode) == -1)
1458 #else
1459 		if (preserve_flag && chmod(local_path, mode) == -1)
1460 #endif /* HAVE_FCHMOD */
1461 			error("Couldn't set mode on \"%s\": %s", local_path,
1462 			    strerror(errno));
1463 		if (preserve_flag &&
1464 		    (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
1465 			struct timeval tv[2];
1466 			tv[0].tv_sec = a->atime;
1467 			tv[1].tv_sec = a->mtime;
1468 			tv[0].tv_usec = tv[1].tv_usec = 0;
1469 			if (utimes(local_path, tv) == -1)
1470 				error("Can't set times on \"%s\": %s",
1471 				    local_path, strerror(errno));
1472 		}
1473 		if (resume_flag && !lmodified)
1474 			logit("File \"%s\" was not modified", local_path);
1475 		else if (fsync_flag) {
1476 			debug("syncing \"%s\"", local_path);
1477 			if (fsync(local_fd) == -1)
1478 				error("Couldn't sync file \"%s\": %s",
1479 				    local_path, strerror(errno));
1480 		}
1481 	}
1482 	close(local_fd);
1483 	sshbuf_free(msg);
1484 	free(handle);
1485 
1486 	return status == SSH2_FX_OK ? 0 : -1;
1487 }
1488 
1489 static int
1490 download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1491     int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
1492     int resume_flag, int fsync_flag)
1493 {
1494 	int i, ret = 0;
1495 	SFTP_DIRENT **dir_entries;
1496 	char *filename, *new_src = NULL, *new_dst = NULL;
1497 	mode_t mode = 0777, tmpmode = mode;
1498 
1499 	if (depth >= MAX_DIR_DEPTH) {
1500 		error("Maximum directory depth exceeded: %d levels", depth);
1501 		return -1;
1502 	}
1503 
1504 	if (dirattrib == NULL &&
1505 	    (dirattrib = do_stat(conn, src, 1)) == NULL) {
1506 		error("Unable to stat remote directory \"%s\"", src);
1507 		return -1;
1508 	}
1509 	if (!S_ISDIR(dirattrib->perm)) {
1510 		error("\"%s\" is not a directory", src);
1511 		return -1;
1512 	}
1513 	if (print_flag)
1514 		mprintf("Retrieving %s\n", src);
1515 
1516 	if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
1517 		mode = dirattrib->perm & 01777;
1518 		tmpmode = mode | (S_IWUSR|S_IXUSR);
1519 	} else {
1520 		debug("Server did not send permissions for "
1521 		    "directory \"%s\"", dst);
1522 	}
1523 
1524 	if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
1525 		error("mkdir %s: %s", dst, strerror(errno));
1526 		return -1;
1527 	}
1528 
1529 	if (do_readdir(conn, src, &dir_entries) == -1) {
1530 		error("%s: Failed to get directory contents", src);
1531 		return -1;
1532 	}
1533 
1534 	for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
1535 		free(new_dst);
1536 		free(new_src);
1537 
1538 		filename = dir_entries[i]->filename;
1539 		new_dst = path_append(dst, filename);
1540 		new_src = path_append(src, filename);
1541 
1542 		if (S_ISDIR(dir_entries[i]->a.perm)) {
1543 			if (strcmp(filename, ".") == 0 ||
1544 			    strcmp(filename, "..") == 0)
1545 				continue;
1546 			if (download_dir_internal(conn, new_src, new_dst,
1547 			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1548 			    print_flag, resume_flag, fsync_flag) == -1)
1549 				ret = -1;
1550 		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1551 			if (do_download(conn, new_src, new_dst,
1552 			    &(dir_entries[i]->a), preserve_flag,
1553 			    resume_flag, fsync_flag) == -1) {
1554 				error("Download of file %s to %s failed",
1555 				    new_src, new_dst);
1556 				ret = -1;
1557 			}
1558 		} else
1559 			logit("%s: not a regular file\n", new_src);
1560 
1561 	}
1562 	free(new_dst);
1563 	free(new_src);
1564 
1565 	if (preserve_flag) {
1566 		if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
1567 			struct timeval tv[2];
1568 			tv[0].tv_sec = dirattrib->atime;
1569 			tv[1].tv_sec = dirattrib->mtime;
1570 			tv[0].tv_usec = tv[1].tv_usec = 0;
1571 			if (utimes(dst, tv) == -1)
1572 				error("Can't set times on \"%s\": %s",
1573 				    dst, strerror(errno));
1574 		} else
1575 			debug("Server did not send times for directory "
1576 			    "\"%s\"", dst);
1577 	}
1578 
1579 	if (mode != tmpmode && chmod(dst, mode) == -1)
1580 		error("Can't set final mode on \"%s\": %s", dst,
1581 		    strerror(errno));
1582 
1583 	free_sftp_dirents(dir_entries);
1584 
1585 	return ret;
1586 }
1587 
1588 int
1589 download_dir(struct sftp_conn *conn, const char *src, const char *dst,
1590     Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
1591     int fsync_flag)
1592 {
1593 	char *src_canon;
1594 	int ret;
1595 
1596 	if ((src_canon = do_realpath(conn, src)) == NULL) {
1597 		error("Unable to canonicalize path \"%s\"", src);
1598 		return -1;
1599 	}
1600 
1601 	ret = download_dir_internal(conn, src_canon, dst, 0,
1602 	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag);
1603 	free(src_canon);
1604 	return ret;
1605 }
1606 
1607 int
1608 do_upload(struct sftp_conn *conn, const char *local_path,
1609     const char *remote_path, int preserve_flag, int resume, int fsync_flag)
1610 {
1611 	int r, local_fd;
1612 	u_int status = SSH2_FX_OK;
1613 	u_int id;
1614 	u_char type;
1615 	off_t offset, progress_counter;
1616 	u_char *handle, *data;
1617 	struct sshbuf *msg;
1618 	struct stat sb;
1619 	Attrib a, *c = NULL;
1620 	u_int32_t startid;
1621 	u_int32_t ackid;
1622 	struct outstanding_ack {
1623 		u_int id;
1624 		u_int len;
1625 		off_t offset;
1626 		TAILQ_ENTRY(outstanding_ack) tq;
1627 	};
1628 	TAILQ_HEAD(ackhead, outstanding_ack) acks;
1629 	struct outstanding_ack *ack = NULL;
1630 	size_t handle_len;
1631 
1632 	TAILQ_INIT(&acks);
1633 
1634 	if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
1635 		error("Couldn't open local file \"%s\" for reading: %s",
1636 		    local_path, strerror(errno));
1637 		return(-1);
1638 	}
1639 	if (fstat(local_fd, &sb) == -1) {
1640 		error("Couldn't fstat local file \"%s\": %s",
1641 		    local_path, strerror(errno));
1642 		close(local_fd);
1643 		return(-1);
1644 	}
1645 	if (!S_ISREG(sb.st_mode)) {
1646 		error("%s is not a regular file", local_path);
1647 		close(local_fd);
1648 		return(-1);
1649 	}
1650 	stat_to_attrib(&sb, &a);
1651 
1652 	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1653 	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1654 	a.perm &= 0777;
1655 	if (!preserve_flag)
1656 		a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
1657 
1658 	if (resume) {
1659 		/* Get remote file size if it exists */
1660 		if ((c = do_stat(conn, remote_path, 0)) == NULL) {
1661 			close(local_fd);
1662 			return -1;
1663 		}
1664 
1665 		if ((off_t)c->size >= sb.st_size) {
1666 			error("destination file bigger or same size as "
1667 			      "source file");
1668 			close(local_fd);
1669 			return -1;
1670 		}
1671 
1672 		if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) {
1673 			close(local_fd);
1674 			return -1;
1675 		}
1676 	}
1677 
1678 	if ((msg = sshbuf_new()) == NULL)
1679 		fatal_f("sshbuf_new failed");
1680 
1681 	/* Send open request */
1682 	id = conn->msg_id++;
1683 	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
1684 	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1685 	    (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
1686 	    (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
1687 	    (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 ||
1688 	    (r = encode_attrib(msg, &a)) != 0)
1689 		fatal_fr(r, "compose");
1690 	send_msg(conn, msg);
1691 	debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
1692 
1693 	sshbuf_reset(msg);
1694 
1695 	handle = get_handle(conn, id, &handle_len,
1696 	    "remote open(\"%s\")", remote_path);
1697 	if (handle == NULL) {
1698 		close(local_fd);
1699 		sshbuf_free(msg);
1700 		return -1;
1701 	}
1702 
1703 	startid = ackid = id + 1;
1704 	data = xmalloc(conn->transfer_buflen);
1705 
1706 	/* Read from local and write to remote */
1707 	offset = progress_counter = (resume ? c->size : 0);
1708 	if (showprogress)
1709 		start_progress_meter(local_path, sb.st_size,
1710 		    &progress_counter);
1711 
1712 	for (;;) {
1713 		int len;
1714 
1715 		/*
1716 		 * Can't use atomicio here because it returns 0 on EOF,
1717 		 * thus losing the last block of the file.
1718 		 * Simulate an EOF on interrupt, allowing ACKs from the
1719 		 * server to drain.
1720 		 */
1721 		if (interrupted || status != SSH2_FX_OK)
1722 			len = 0;
1723 		else do
1724 			len = read(local_fd, data, conn->transfer_buflen);
1725 		while ((len == -1) &&
1726 		    (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
1727 
1728 		if (len == -1)
1729 			fatal("Couldn't read from \"%s\": %s", local_path,
1730 			    strerror(errno));
1731 
1732 		if (len != 0) {
1733 			ack = xcalloc(1, sizeof(*ack));
1734 			ack->id = ++id;
1735 			ack->offset = offset;
1736 			ack->len = len;
1737 			TAILQ_INSERT_TAIL(&acks, ack, tq);
1738 
1739 			sshbuf_reset(msg);
1740 			if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
1741 			    (r = sshbuf_put_u32(msg, ack->id)) != 0 ||
1742 			    (r = sshbuf_put_string(msg, handle,
1743 			    handle_len)) != 0 ||
1744 			    (r = sshbuf_put_u64(msg, offset)) != 0 ||
1745 			    (r = sshbuf_put_string(msg, data, len)) != 0)
1746 				fatal_fr(r, "compose");
1747 			send_msg(conn, msg);
1748 			debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
1749 			    id, (unsigned long long)offset, len);
1750 		} else if (TAILQ_FIRST(&acks) == NULL)
1751 			break;
1752 
1753 		if (ack == NULL)
1754 			fatal("Unexpected ACK %u", id);
1755 
1756 		if (id == startid || len == 0 ||
1757 		    id - ackid >= conn->num_requests) {
1758 			u_int rid;
1759 
1760 			sshbuf_reset(msg);
1761 			get_msg(conn, msg);
1762 			if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1763 			    (r = sshbuf_get_u32(msg, &rid)) != 0)
1764 				fatal_fr(r, "parse");
1765 
1766 			if (type != SSH2_FXP_STATUS)
1767 				fatal("Expected SSH2_FXP_STATUS(%d) packet, "
1768 				    "got %d", SSH2_FXP_STATUS, type);
1769 
1770 			if ((r = sshbuf_get_u32(msg, &status)) != 0)
1771 				fatal_fr(r, "parse status");
1772 			debug3("SSH2_FXP_STATUS %u", status);
1773 
1774 			/* Find the request in our queue */
1775 			for (ack = TAILQ_FIRST(&acks);
1776 			    ack != NULL && ack->id != rid;
1777 			    ack = TAILQ_NEXT(ack, tq))
1778 				;
1779 			if (ack == NULL)
1780 				fatal("Can't find request for ID %u", rid);
1781 			TAILQ_REMOVE(&acks, ack, tq);
1782 			debug3("In write loop, ack for %u %u bytes at %lld",
1783 			    ack->id, ack->len, (long long)ack->offset);
1784 			++ackid;
1785 			progress_counter += ack->len;
1786 			free(ack);
1787 		}
1788 		offset += len;
1789 		if (offset < 0)
1790 			fatal_f("offset < 0");
1791 	}
1792 	sshbuf_free(msg);
1793 
1794 	if (showprogress)
1795 		stop_progress_meter();
1796 	free(data);
1797 
1798 	if (status != SSH2_FX_OK) {
1799 		error("Couldn't write to remote file \"%s\": %s",
1800 		    remote_path, fx2txt(status));
1801 		status = SSH2_FX_FAILURE;
1802 	}
1803 
1804 	if (close(local_fd) == -1) {
1805 		error("Couldn't close local file \"%s\": %s", local_path,
1806 		    strerror(errno));
1807 		status = SSH2_FX_FAILURE;
1808 	}
1809 
1810 	/* Override umask and utimes if asked */
1811 	if (preserve_flag)
1812 		do_fsetstat(conn, handle, handle_len, &a);
1813 
1814 	if (fsync_flag)
1815 		(void)do_fsync(conn, handle, handle_len);
1816 
1817 	if (do_close(conn, handle, handle_len) != 0)
1818 		status = SSH2_FX_FAILURE;
1819 
1820 	free(handle);
1821 
1822 	return status == SSH2_FX_OK ? 0 : -1;
1823 }
1824 
1825 static int
1826 upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1827     int depth, int preserve_flag, int print_flag, int resume, int fsync_flag)
1828 {
1829 	int ret = 0;
1830 	DIR *dirp;
1831 	struct dirent *dp;
1832 	char *filename, *new_src = NULL, *new_dst = NULL;
1833 	struct stat sb;
1834 	Attrib a, *dirattrib;
1835 	u_int32_t saved_perm;
1836 
1837 	if (depth >= MAX_DIR_DEPTH) {
1838 		error("Maximum directory depth exceeded: %d levels", depth);
1839 		return -1;
1840 	}
1841 
1842 	if (stat(src, &sb) == -1) {
1843 		error("Couldn't stat directory \"%s\": %s",
1844 		    src, strerror(errno));
1845 		return -1;
1846 	}
1847 	if (!S_ISDIR(sb.st_mode)) {
1848 		error("\"%s\" is not a directory", src);
1849 		return -1;
1850 	}
1851 	if (print_flag)
1852 		mprintf("Entering %s\n", src);
1853 
1854 	attrib_clear(&a);
1855 	stat_to_attrib(&sb, &a);
1856 	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1857 	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1858 	a.perm &= 01777;
1859 	if (!preserve_flag)
1860 		a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
1861 
1862 	/*
1863 	 * sftp lacks a portable status value to match errno EEXIST,
1864 	 * so if we get a failure back then we must check whether
1865 	 * the path already existed and is a directory.  Ensure we can
1866 	 * write to the directory we create for the duration of the transfer.
1867 	 */
1868 	saved_perm = a.perm;
1869 	a.perm |= (S_IWUSR|S_IXUSR);
1870 	if (do_mkdir(conn, dst, &a, 0) != 0) {
1871 		if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
1872 			return -1;
1873 		if (!S_ISDIR(dirattrib->perm)) {
1874 			error("\"%s\" exists but is not a directory", dst);
1875 			return -1;
1876 		}
1877 	}
1878 	a.perm = saved_perm;
1879 
1880 	if ((dirp = opendir(src)) == NULL) {
1881 		error("Failed to open dir \"%s\": %s", src, strerror(errno));
1882 		return -1;
1883 	}
1884 
1885 	while (((dp = readdir(dirp)) != NULL) && !interrupted) {
1886 		if (dp->d_ino == 0)
1887 			continue;
1888 		free(new_dst);
1889 		free(new_src);
1890 		filename = dp->d_name;
1891 		new_dst = path_append(dst, filename);
1892 		new_src = path_append(src, filename);
1893 
1894 		if (lstat(new_src, &sb) == -1) {
1895 			logit("%s: lstat failed: %s", filename,
1896 			    strerror(errno));
1897 			ret = -1;
1898 		} else if (S_ISDIR(sb.st_mode)) {
1899 			if (strcmp(filename, ".") == 0 ||
1900 			    strcmp(filename, "..") == 0)
1901 				continue;
1902 
1903 			if (upload_dir_internal(conn, new_src, new_dst,
1904 			    depth + 1, preserve_flag, print_flag, resume,
1905 			    fsync_flag) == -1)
1906 				ret = -1;
1907 		} else if (S_ISREG(sb.st_mode)) {
1908 			if (do_upload(conn, new_src, new_dst,
1909 			    preserve_flag, resume, fsync_flag) == -1) {
1910 				error("Uploading of file %s to %s failed!",
1911 				    new_src, new_dst);
1912 				ret = -1;
1913 			}
1914 		} else
1915 			logit("%s: not a regular file\n", filename);
1916 	}
1917 	free(new_dst);
1918 	free(new_src);
1919 
1920 	do_setstat(conn, dst, &a);
1921 
1922 	(void) closedir(dirp);
1923 	return ret;
1924 }
1925 
1926 int
1927 upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
1928     int preserve_flag, int print_flag, int resume, int fsync_flag)
1929 {
1930 	char *dst_canon;
1931 	int ret;
1932 
1933 	if ((dst_canon = do_realpath(conn, dst)) == NULL) {
1934 		error("Unable to canonicalize path \"%s\"", dst);
1935 		return -1;
1936 	}
1937 
1938 	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
1939 	    print_flag, resume, fsync_flag);
1940 
1941 	free(dst_canon);
1942 	return ret;
1943 }
1944 
1945 char *
1946 path_append(const char *p1, const char *p2)
1947 {
1948 	char *ret;
1949 	size_t len = strlen(p1) + strlen(p2) + 2;
1950 
1951 	ret = xmalloc(len);
1952 	strlcpy(ret, p1, len);
1953 	if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
1954 		strlcat(ret, "/", len);
1955 	strlcat(ret, p2, len);
1956 
1957 	return(ret);
1958 }
1959 
1960 char *
1961 make_absolute(char *p, const char *pwd)
1962 {
1963 	char *abs_str;
1964 
1965 	/* Derelativise */
1966 	if (p && !path_absolute(p)) {
1967 		abs_str = path_append(pwd, p);
1968 		free(p);
1969 		return(abs_str);
1970 	} else
1971 		return(p);
1972 }
1973 
1974 int
1975 remote_is_dir(struct sftp_conn *conn, const char *path)
1976 {
1977 	Attrib *a;
1978 
1979 	/* XXX: report errors? */
1980 	if ((a = do_stat(conn, path, 1)) == NULL)
1981 		return(0);
1982 	if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
1983 		return(0);
1984 	return(S_ISDIR(a->perm));
1985 }
1986 
1987 
1988 int
1989 local_is_dir(const char *path)
1990 {
1991 	struct stat sb;
1992 
1993 	/* XXX: report errors? */
1994 	if (stat(path, &sb) == -1)
1995 		return(0);
1996 
1997 	return(S_ISDIR(sb.st_mode));
1998 }
1999 
2000 /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
2001 int
2002 globpath_is_dir(const char *pathname)
2003 {
2004 	size_t l = strlen(pathname);
2005 
2006 	return l > 0 && pathname[l - 1] == '/';
2007 }
2008 
2009