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