1 /* $OpenBSD: scp.c,v 1.261 2024/06/26 23:14:14 deraadt Exp $ */ 2 /* 3 * scp - secure remote copy. This is basically patched BSD rcp which 4 * uses ssh to do the data transfer (instead of using rcmd). 5 * 6 * NOTE: This version should NOT be suid root. (This uses ssh to 7 * do the transfer and ssh has the necessary privileges.) 8 * 9 * 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi> 10 * 11 * As far as I am concerned, the code I have written for this software 12 * can be used freely for any purpose. Any derived versions of this 13 * software must be clearly marked as such, and if the derived work is 14 * incompatible with the protocol description in the RFC file, it must be 15 * called by a name other than "ssh" or "Secure Shell". 16 */ 17 /* 18 * Copyright (c) 1999 Theo de Raadt. All rights reserved. 19 * Copyright (c) 1999 Aaron Campbell. All rights reserved. 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 */ 41 42 /* 43 * Parts from: 44 * 45 * Copyright (c) 1983, 1990, 1992, 1993, 1995 46 * The Regents of the University of California. All rights reserved. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 */ 73 74 #include "includes.h" 75 76 #include <sys/types.h> 77 #ifdef HAVE_SYS_STAT_H 78 # include <sys/stat.h> 79 #endif 80 #ifdef HAVE_POLL_H 81 #include <poll.h> 82 #else 83 # ifdef HAVE_SYS_POLL_H 84 # include <sys/poll.h> 85 # endif 86 #endif 87 #ifdef HAVE_SYS_TIME_H 88 # include <sys/time.h> 89 #endif 90 #include <sys/wait.h> 91 #include <sys/uio.h> 92 93 #include <ctype.h> 94 #include <dirent.h> 95 #include <errno.h> 96 #include <fcntl.h> 97 #ifdef HAVE_FNMATCH_H 98 #include <fnmatch.h> 99 #endif 100 #ifdef USE_SYSTEM_GLOB 101 # include <glob.h> 102 #else 103 # include "openbsd-compat/glob.h" 104 #endif 105 #ifdef HAVE_LIBGEN_H 106 #include <libgen.h> 107 #endif 108 #include <limits.h> 109 #ifdef HAVE_UTIL_H 110 # include <util.h> 111 #endif 112 #include <locale.h> 113 #include <pwd.h> 114 #include <signal.h> 115 #include <stdarg.h> 116 #ifdef HAVE_STDINT_H 117 # include <stdint.h> 118 #endif 119 #include <stdio.h> 120 #include <stdlib.h> 121 #include <string.h> 122 #include <time.h> 123 #include <unistd.h> 124 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) 125 #include <vis.h> 126 #endif 127 128 #include "xmalloc.h" 129 #include "ssh.h" 130 #include "atomicio.h" 131 #include "pathnames.h" 132 #include "log.h" 133 #include "misc.h" 134 #include "progressmeter.h" 135 #include "utf8.h" 136 #include "sftp.h" 137 138 #include "sftp-common.h" 139 #include "sftp-client.h" 140 141 extern char *__progname; 142 143 #define COPY_BUFLEN 16384 144 145 int do_cmd(char *, char *, char *, int, int, char *, int *, int *, pid_t *); 146 int do_cmd2(char *, char *, int, char *, int, int); 147 148 /* Struct for addargs */ 149 arglist args; 150 arglist remote_remote_args; 151 152 /* Bandwidth limit */ 153 long long limit_kbps = 0; 154 struct bwlimit bwlimit; 155 156 /* Name of current file being transferred. */ 157 char *curfile; 158 159 /* This is set to non-zero to enable verbose mode. */ 160 int verbose_mode = 0; 161 LogLevel log_level = SYSLOG_LEVEL_INFO; 162 163 /* This is set to zero if the progressmeter is not desired. */ 164 int showprogress = 1; 165 166 /* 167 * This is set to non-zero if remote-remote copy should be piped 168 * through this process. 169 */ 170 int throughlocal = 1; 171 172 /* Non-standard port to use for the ssh connection or -1. */ 173 int sshport = -1; 174 175 /* This is the program to execute for the secured connection. ("ssh" or -S) */ 176 char *ssh_program = _PATH_SSH_PROGRAM; 177 178 /* This is used to store the pid of ssh_program */ 179 pid_t do_cmd_pid = -1; 180 pid_t do_cmd_pid2 = -1; 181 182 /* SFTP copy parameters */ 183 size_t sftp_copy_buflen; 184 size_t sftp_nrequests; 185 186 /* Needed for sftp */ 187 volatile sig_atomic_t interrupted = 0; 188 189 int sftp_glob(struct sftp_conn *, const char *, int, 190 int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ 191 192 static void 193 killchild(int signo) 194 { 195 if (do_cmd_pid > 1) { 196 kill(do_cmd_pid, signo ? signo : SIGTERM); 197 (void)waitpid(do_cmd_pid, NULL, 0); 198 } 199 if (do_cmd_pid2 > 1) { 200 kill(do_cmd_pid2, signo ? signo : SIGTERM); 201 (void)waitpid(do_cmd_pid2, NULL, 0); 202 } 203 204 if (signo) 205 _exit(1); 206 exit(1); 207 } 208 209 static void 210 suspone(int pid, int signo) 211 { 212 int status; 213 214 if (pid > 1) { 215 kill(pid, signo); 216 while (waitpid(pid, &status, WUNTRACED) == -1 && 217 errno == EINTR) 218 ; 219 } 220 } 221 222 static void 223 suspchild(int signo) 224 { 225 int save_errno = errno; 226 suspone(do_cmd_pid, signo); 227 suspone(do_cmd_pid2, signo); 228 kill(getpid(), SIGSTOP); 229 errno = save_errno; 230 } 231 232 static int 233 do_local_cmd(arglist *a) 234 { 235 u_int i; 236 int status; 237 pid_t pid; 238 239 if (a->num == 0) 240 fatal("do_local_cmd: no arguments"); 241 242 if (verbose_mode) { 243 fprintf(stderr, "Executing:"); 244 for (i = 0; i < a->num; i++) 245 fmprintf(stderr, " %s", a->list[i]); 246 fprintf(stderr, "\n"); 247 } 248 if ((pid = fork()) == -1) 249 fatal("do_local_cmd: fork: %s", strerror(errno)); 250 251 if (pid == 0) { 252 execvp(a->list[0], a->list); 253 perror(a->list[0]); 254 exit(1); 255 } 256 257 do_cmd_pid = pid; 258 ssh_signal(SIGTERM, killchild); 259 ssh_signal(SIGINT, killchild); 260 ssh_signal(SIGHUP, killchild); 261 262 while (waitpid(pid, &status, 0) == -1) 263 if (errno != EINTR) 264 fatal("do_local_cmd: waitpid: %s", strerror(errno)); 265 266 do_cmd_pid = -1; 267 268 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 269 return (-1); 270 271 return (0); 272 } 273 274 /* 275 * This function executes the given command as the specified user on the 276 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This 277 * assigns the input and output file descriptors on success. 278 */ 279 280 int 281 do_cmd(char *program, char *host, char *remuser, int port, int subsystem, 282 char *cmd, int *fdin, int *fdout, pid_t *pid) 283 { 284 #ifdef USE_PIPES 285 int pin[2], pout[2]; 286 #else 287 int sv[2]; 288 #endif 289 290 if (verbose_mode) 291 fmprintf(stderr, 292 "Executing: program %s host %s, user %s, command %s\n", 293 program, host, 294 remuser ? remuser : "(unspecified)", cmd); 295 296 if (port == -1) 297 port = sshport; 298 299 #ifdef USE_PIPES 300 if (pipe(pin) == -1 || pipe(pout) == -1) 301 fatal("pipe: %s", strerror(errno)); 302 #else 303 /* Create a socket pair for communicating with ssh. */ 304 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) 305 fatal("socketpair: %s", strerror(errno)); 306 #endif 307 308 ssh_signal(SIGTSTP, suspchild); 309 ssh_signal(SIGTTIN, suspchild); 310 ssh_signal(SIGTTOU, suspchild); 311 312 /* Fork a child to execute the command on the remote host using ssh. */ 313 *pid = fork(); 314 switch (*pid) { 315 case -1: 316 fatal("fork: %s", strerror(errno)); 317 case 0: 318 /* Child. */ 319 #ifdef USE_PIPES 320 if (dup2(pin[0], STDIN_FILENO) == -1 || 321 dup2(pout[1], STDOUT_FILENO) == -1) { 322 error("dup2: %s", strerror(errno)); 323 _exit(1); 324 } 325 close(pin[0]); 326 close(pin[1]); 327 close(pout[0]); 328 close(pout[1]); 329 #else 330 if (dup2(sv[0], STDIN_FILENO) == -1 || 331 dup2(sv[0], STDOUT_FILENO) == -1) { 332 error("dup2: %s", strerror(errno)); 333 _exit(1); 334 } 335 close(sv[0]); 336 close(sv[1]); 337 #endif 338 replacearg(&args, 0, "%s", program); 339 if (port != -1) { 340 addargs(&args, "-p"); 341 addargs(&args, "%d", port); 342 } 343 if (remuser != NULL) { 344 addargs(&args, "-l"); 345 addargs(&args, "%s", remuser); 346 } 347 if (subsystem) 348 addargs(&args, "-s"); 349 addargs(&args, "--"); 350 addargs(&args, "%s", host); 351 addargs(&args, "%s", cmd); 352 353 execvp(program, args.list); 354 perror(program); 355 _exit(1); 356 default: 357 /* Parent. Close the other side, and return the local side. */ 358 #ifdef USE_PIPES 359 close(pin[0]); 360 close(pout[1]); 361 *fdout = pin[1]; 362 *fdin = pout[0]; 363 #else 364 close(sv[0]); 365 *fdin = sv[1]; 366 *fdout = sv[1]; 367 #endif 368 ssh_signal(SIGTERM, killchild); 369 ssh_signal(SIGINT, killchild); 370 ssh_signal(SIGHUP, killchild); 371 return 0; 372 } 373 } 374 375 /* 376 * This function executes a command similar to do_cmd(), but expects the 377 * input and output descriptors to be setup by a previous call to do_cmd(). 378 * This way the input and output of two commands can be connected. 379 */ 380 int 381 do_cmd2(char *host, char *remuser, int port, char *cmd, 382 int fdin, int fdout) 383 { 384 int status; 385 pid_t pid; 386 387 if (verbose_mode) 388 fmprintf(stderr, 389 "Executing: 2nd program %s host %s, user %s, command %s\n", 390 ssh_program, host, 391 remuser ? remuser : "(unspecified)", cmd); 392 393 if (port == -1) 394 port = sshport; 395 396 /* Fork a child to execute the command on the remote host using ssh. */ 397 pid = fork(); 398 if (pid == 0) { 399 if (dup2(fdin, 0) == -1) 400 perror("dup2"); 401 if (dup2(fdout, 1) == -1) 402 perror("dup2"); 403 404 replacearg(&args, 0, "%s", ssh_program); 405 if (port != -1) { 406 addargs(&args, "-p"); 407 addargs(&args, "%d", port); 408 } 409 if (remuser != NULL) { 410 addargs(&args, "-l"); 411 addargs(&args, "%s", remuser); 412 } 413 addargs(&args, "-oBatchMode=yes"); 414 addargs(&args, "--"); 415 addargs(&args, "%s", host); 416 addargs(&args, "%s", cmd); 417 418 execvp(ssh_program, args.list); 419 perror(ssh_program); 420 exit(1); 421 } else if (pid == -1) { 422 fatal("fork: %s", strerror(errno)); 423 } 424 while (waitpid(pid, &status, 0) == -1) 425 if (errno != EINTR) 426 fatal("do_cmd2: waitpid: %s", strerror(errno)); 427 return 0; 428 } 429 430 typedef struct { 431 size_t cnt; 432 char *buf; 433 } BUF; 434 435 BUF *allocbuf(BUF *, int, int); 436 void lostconn(int); 437 int okname(char *); 438 void run_err(const char *,...) 439 __attribute__((__format__ (printf, 1, 2))) 440 __attribute__((__nonnull__ (1))); 441 int note_err(const char *,...) 442 __attribute__((__format__ (printf, 1, 2))); 443 void verifydir(char *); 444 445 struct passwd *pwd; 446 uid_t userid; 447 int errs, remin, remout, remin2, remout2; 448 int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory; 449 450 #define CMDNEEDS 64 451 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ 452 453 enum scp_mode_e { 454 MODE_SCP, 455 MODE_SFTP 456 }; 457 458 int response(void); 459 void rsource(char *, struct stat *); 460 void sink(int, char *[], const char *); 461 void source(int, char *[]); 462 void tolocal(int, char *[], enum scp_mode_e, char *sftp_direct); 463 void toremote(int, char *[], enum scp_mode_e, char *sftp_direct); 464 void usage(void); 465 466 void source_sftp(int, char *, char *, struct sftp_conn *); 467 void sink_sftp(int, char *, const char *, struct sftp_conn *); 468 void throughlocal_sftp(struct sftp_conn *, struct sftp_conn *, 469 char *, char *); 470 471 int 472 main(int argc, char **argv) 473 { 474 int ch, fflag, tflag, status, r, n; 475 char **newargv, *argv0; 476 const char *errstr; 477 extern char *optarg; 478 extern int optind; 479 enum scp_mode_e mode = MODE_SFTP; 480 char *sftp_direct = NULL; 481 long long llv; 482 483 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 484 sanitise_stdfd(); 485 486 msetlocale(); 487 488 /* Copy argv, because we modify it */ 489 argv0 = argv[0]; 490 newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); 491 for (n = 0; n < argc; n++) 492 newargv[n] = xstrdup(argv[n]); 493 argv = newargv; 494 495 __progname = ssh_get_progname(argv[0]); 496 497 log_init(argv0, log_level, SYSLOG_FACILITY_USER, 2); 498 499 memset(&args, '\0', sizeof(args)); 500 memset(&remote_remote_args, '\0', sizeof(remote_remote_args)); 501 args.list = remote_remote_args.list = NULL; 502 addargs(&args, "%s", ssh_program); 503 addargs(&args, "-x"); 504 addargs(&args, "-oPermitLocalCommand=no"); 505 addargs(&args, "-oClearAllForwardings=yes"); 506 addargs(&args, "-oRemoteCommand=none"); 507 addargs(&args, "-oRequestTTY=no"); 508 509 fflag = Tflag = tflag = 0; 510 while ((ch = getopt(argc, argv, 511 "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:X:")) != -1) { 512 switch (ch) { 513 /* User-visible flags. */ 514 case '1': 515 fatal("SSH protocol v.1 is no longer supported"); 516 break; 517 case '2': 518 /* Ignored */ 519 break; 520 case 'A': 521 case '4': 522 case '6': 523 case 'C': 524 addargs(&args, "-%c", ch); 525 addargs(&remote_remote_args, "-%c", ch); 526 break; 527 case 'D': 528 sftp_direct = optarg; 529 break; 530 case '3': 531 throughlocal = 1; 532 break; 533 case 'R': 534 throughlocal = 0; 535 break; 536 case 'o': 537 case 'c': 538 case 'i': 539 case 'F': 540 case 'J': 541 addargs(&remote_remote_args, "-%c", ch); 542 addargs(&remote_remote_args, "%s", optarg); 543 addargs(&args, "-%c", ch); 544 addargs(&args, "%s", optarg); 545 break; 546 case 'O': 547 mode = MODE_SCP; 548 break; 549 case 's': 550 mode = MODE_SFTP; 551 break; 552 case 'P': 553 sshport = a2port(optarg); 554 if (sshport <= 0) 555 fatal("bad port \"%s\"\n", optarg); 556 break; 557 case 'B': 558 addargs(&remote_remote_args, "-oBatchmode=yes"); 559 addargs(&args, "-oBatchmode=yes"); 560 break; 561 case 'l': 562 limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, 563 &errstr); 564 if (errstr != NULL) 565 usage(); 566 limit_kbps *= 1024; /* kbps */ 567 bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN); 568 break; 569 case 'p': 570 pflag = 1; 571 break; 572 case 'r': 573 iamrecursive = 1; 574 break; 575 case 'S': 576 ssh_program = xstrdup(optarg); 577 break; 578 case 'v': 579 addargs(&args, "-v"); 580 addargs(&remote_remote_args, "-v"); 581 if (verbose_mode == 0) 582 log_level = SYSLOG_LEVEL_DEBUG1; 583 else if (log_level < SYSLOG_LEVEL_DEBUG3) 584 log_level++; 585 verbose_mode = 1; 586 break; 587 case 'q': 588 addargs(&args, "-q"); 589 addargs(&remote_remote_args, "-q"); 590 showprogress = 0; 591 break; 592 case 'X': 593 /* Please keep in sync with sftp.c -X */ 594 if (strncmp(optarg, "buffer=", 7) == 0) { 595 r = scan_scaled(optarg + 7, &llv); 596 if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { 597 r = -1; 598 errno = EINVAL; 599 } 600 if (r == -1) { 601 fatal("Invalid buffer size \"%s\": %s", 602 optarg + 7, strerror(errno)); 603 } 604 sftp_copy_buflen = (size_t)llv; 605 } else if (strncmp(optarg, "nrequests=", 10) == 0) { 606 llv = strtonum(optarg + 10, 1, 256 * 1024, 607 &errstr); 608 if (errstr != NULL) { 609 fatal("Invalid number of requests " 610 "\"%s\": %s", optarg + 10, errstr); 611 } 612 sftp_nrequests = (size_t)llv; 613 } else { 614 fatal("Invalid -X option"); 615 } 616 break; 617 618 /* Server options. */ 619 case 'd': 620 targetshouldbedirectory = 1; 621 break; 622 case 'f': /* "from" */ 623 iamremote = 1; 624 fflag = 1; 625 break; 626 case 't': /* "to" */ 627 iamremote = 1; 628 tflag = 1; 629 #ifdef HAVE_CYGWIN 630 setmode(0, O_BINARY); 631 #endif 632 break; 633 case 'T': 634 Tflag = 1; 635 break; 636 default: 637 usage(); 638 } 639 } 640 argc -= optind; 641 argv += optind; 642 643 log_init(argv0, log_level, SYSLOG_FACILITY_USER, 2); 644 645 /* Do this last because we want the user to be able to override it */ 646 addargs(&args, "-oForwardAgent=no"); 647 648 if (iamremote) 649 mode = MODE_SCP; 650 651 if ((pwd = getpwuid(userid = getuid())) == NULL) 652 fatal("unknown user %u", (u_int) userid); 653 654 if (!isatty(STDOUT_FILENO)) 655 showprogress = 0; 656 657 if (pflag) { 658 /* Cannot pledge: -p allows setuid/setgid files... */ 659 } else { 660 if (pledge("stdio rpath wpath cpath fattr tty proc exec", 661 NULL) == -1) { 662 perror("pledge"); 663 exit(1); 664 } 665 } 666 667 remin = STDIN_FILENO; 668 remout = STDOUT_FILENO; 669 670 if (fflag) { 671 /* Follow "protocol", send data. */ 672 (void) response(); 673 source(argc, argv); 674 exit(errs != 0); 675 } 676 if (tflag) { 677 /* Receive data. */ 678 sink(argc, argv, NULL); 679 exit(errs != 0); 680 } 681 if (argc < 2) 682 usage(); 683 if (argc > 2) 684 targetshouldbedirectory = 1; 685 686 remin = remout = -1; 687 do_cmd_pid = -1; 688 /* Command to be executed on remote system using "ssh". */ 689 (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", 690 verbose_mode ? " -v" : "", 691 iamrecursive ? " -r" : "", pflag ? " -p" : "", 692 targetshouldbedirectory ? " -d" : ""); 693 694 (void) ssh_signal(SIGPIPE, lostconn); 695 696 if (colon(argv[argc - 1])) /* Dest is remote host. */ 697 toremote(argc, argv, mode, sftp_direct); 698 else { 699 if (targetshouldbedirectory) 700 verifydir(argv[argc - 1]); 701 tolocal(argc, argv, mode, sftp_direct); /* Dest is local host. */ 702 } 703 /* 704 * Finally check the exit status of the ssh process, if one was forked 705 * and no error has occurred yet 706 */ 707 if (do_cmd_pid != -1 && (mode == MODE_SFTP || errs == 0)) { 708 if (remin != -1) 709 (void) close(remin); 710 if (remout != -1) 711 (void) close(remout); 712 if (waitpid(do_cmd_pid, &status, 0) == -1) 713 errs = 1; 714 else { 715 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 716 errs = 1; 717 } 718 } 719 exit(errs != 0); 720 } 721 722 /* Callback from atomicio6 to update progress meter and limit bandwidth */ 723 static int 724 scpio(void *_cnt, size_t s) 725 { 726 off_t *cnt = (off_t *)_cnt; 727 728 *cnt += s; 729 refresh_progress_meter(0); 730 if (limit_kbps > 0) 731 bandwidth_limit(&bwlimit, s); 732 return 0; 733 } 734 735 static int 736 do_times(int fd, int verb, const struct stat *sb) 737 { 738 /* strlen(2^64) == 20; strlen(10^6) == 7 */ 739 char buf[(20 + 7 + 2) * 2 + 2]; 740 741 (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n", 742 (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime), 743 (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime)); 744 if (verb) { 745 fprintf(stderr, "File mtime %lld atime %lld\n", 746 (long long)sb->st_mtime, (long long)sb->st_atime); 747 fprintf(stderr, "Sending file timestamps: %s", buf); 748 } 749 (void) atomicio(vwrite, fd, buf, strlen(buf)); 750 return (response()); 751 } 752 753 static int 754 parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp, 755 char **pathp) 756 { 757 int r; 758 759 r = parse_uri("scp", uri, userp, hostp, portp, pathp); 760 if (r == 0 && *pathp == NULL) 761 *pathp = xstrdup("."); 762 return r; 763 } 764 765 /* Appends a string to an array; returns 0 on success, -1 on alloc failure */ 766 static int 767 append(char *cp, char ***ap, size_t *np) 768 { 769 char **tmp; 770 771 if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL) 772 return -1; 773 tmp[(*np)] = cp; 774 (*np)++; 775 *ap = tmp; 776 return 0; 777 } 778 779 /* 780 * Finds the start and end of the first brace pair in the pattern. 781 * returns 0 on success or -1 for invalid patterns. 782 */ 783 static int 784 find_brace(const char *pattern, int *startp, int *endp) 785 { 786 int i; 787 int in_bracket, brace_level; 788 789 *startp = *endp = -1; 790 in_bracket = brace_level = 0; 791 for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) { 792 switch (pattern[i]) { 793 case '\\': 794 /* skip next character */ 795 if (pattern[i + 1] != '\0') 796 i++; 797 break; 798 case '[': 799 in_bracket = 1; 800 break; 801 case ']': 802 in_bracket = 0; 803 break; 804 case '{': 805 if (in_bracket) 806 break; 807 if (pattern[i + 1] == '}') { 808 /* Protect a single {}, for find(1), like csh */ 809 i++; /* skip */ 810 break; 811 } 812 if (*startp == -1) 813 *startp = i; 814 brace_level++; 815 break; 816 case '}': 817 if (in_bracket) 818 break; 819 if (*startp < 0) { 820 /* Unbalanced brace */ 821 return -1; 822 } 823 if (--brace_level <= 0) 824 *endp = i; 825 break; 826 } 827 } 828 /* unbalanced brackets/braces */ 829 if (*endp < 0 && (*startp >= 0 || in_bracket)) 830 return -1; 831 return 0; 832 } 833 834 /* 835 * Assembles and records a successfully-expanded pattern, returns -1 on 836 * alloc failure. 837 */ 838 static int 839 emit_expansion(const char *pattern, int brace_start, int brace_end, 840 int sel_start, int sel_end, char ***patternsp, size_t *npatternsp) 841 { 842 char *cp; 843 size_t pattern_len; 844 int o = 0, tail_len; 845 846 if ((pattern_len = strlen(pattern)) == 0 || pattern_len >= INT_MAX) 847 return -1; 848 849 tail_len = strlen(pattern + brace_end + 1); 850 if ((cp = malloc(brace_start + (sel_end - sel_start) + 851 tail_len + 1)) == NULL) 852 return -1; 853 854 /* Pattern before initial brace */ 855 if (brace_start > 0) { 856 memcpy(cp, pattern, brace_start); 857 o = brace_start; 858 } 859 /* Current braced selection */ 860 if (sel_end - sel_start > 0) { 861 memcpy(cp + o, pattern + sel_start, 862 sel_end - sel_start); 863 o += sel_end - sel_start; 864 } 865 /* Remainder of pattern after closing brace */ 866 if (tail_len > 0) { 867 memcpy(cp + o, pattern + brace_end + 1, tail_len); 868 o += tail_len; 869 } 870 cp[o] = '\0'; 871 if (append(cp, patternsp, npatternsp) != 0) { 872 free(cp); 873 return -1; 874 } 875 return 0; 876 } 877 878 /* 879 * Expand the first encountered brace in pattern, appending the expanded 880 * patterns it yielded to the *patternsp array. 881 * 882 * Returns 0 on success or -1 on allocation failure. 883 * 884 * Signals whether expansion was performed via *expanded and whether 885 * pattern was invalid via *invalid. 886 */ 887 static int 888 brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp, 889 int *expanded, int *invalid) 890 { 891 int i; 892 int in_bracket, brace_start, brace_end, brace_level; 893 int sel_start, sel_end; 894 895 *invalid = *expanded = 0; 896 897 if (find_brace(pattern, &brace_start, &brace_end) != 0) { 898 *invalid = 1; 899 return 0; 900 } else if (brace_start == -1) 901 return 0; 902 903 in_bracket = brace_level = 0; 904 for (i = sel_start = brace_start + 1; i < brace_end; i++) { 905 switch (pattern[i]) { 906 case '{': 907 if (in_bracket) 908 break; 909 brace_level++; 910 break; 911 case '}': 912 if (in_bracket) 913 break; 914 brace_level--; 915 break; 916 case '[': 917 in_bracket = 1; 918 break; 919 case ']': 920 in_bracket = 0; 921 break; 922 case '\\': 923 if (i < brace_end - 1) 924 i++; /* skip */ 925 break; 926 } 927 if (pattern[i] == ',' || i == brace_end - 1) { 928 if (in_bracket || brace_level > 0) 929 continue; 930 /* End of a selection, emit an expanded pattern */ 931 932 /* Adjust end index for last selection */ 933 sel_end = (i == brace_end - 1) ? brace_end : i; 934 if (emit_expansion(pattern, brace_start, brace_end, 935 sel_start, sel_end, patternsp, npatternsp) != 0) 936 return -1; 937 /* move on to the next selection */ 938 sel_start = i + 1; 939 continue; 940 } 941 } 942 if (in_bracket || brace_level > 0) { 943 *invalid = 1; 944 return 0; 945 } 946 /* success */ 947 *expanded = 1; 948 return 0; 949 } 950 951 /* Expand braces from pattern. Returns 0 on success, -1 on failure */ 952 static int 953 brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) 954 { 955 char *cp, *cp2, **active = NULL, **done = NULL; 956 size_t i, nactive = 0, ndone = 0; 957 int ret = -1, invalid = 0, expanded = 0; 958 959 *patternsp = NULL; 960 *npatternsp = 0; 961 962 /* Start the worklist with the original pattern */ 963 if ((cp = strdup(pattern)) == NULL) 964 return -1; 965 if (append(cp, &active, &nactive) != 0) { 966 free(cp); 967 return -1; 968 } 969 while (nactive > 0) { 970 cp = active[nactive - 1]; 971 nactive--; 972 if (brace_expand_one(cp, &active, &nactive, 973 &expanded, &invalid) == -1) { 974 free(cp); 975 goto fail; 976 } 977 if (invalid) 978 fatal_f("invalid brace pattern \"%s\"", cp); 979 if (expanded) { 980 /* 981 * Current entry expanded to new entries on the 982 * active list; discard the progenitor pattern. 983 */ 984 free(cp); 985 continue; 986 } 987 /* 988 * Pattern did not expand; append the finename component to 989 * the completed list 990 */ 991 if ((cp2 = strrchr(cp, '/')) != NULL) 992 *cp2++ = '\0'; 993 else 994 cp2 = cp; 995 if (append(xstrdup(cp2), &done, &ndone) != 0) { 996 free(cp); 997 goto fail; 998 } 999 free(cp); 1000 } 1001 /* success */ 1002 *patternsp = done; 1003 *npatternsp = ndone; 1004 done = NULL; 1005 ndone = 0; 1006 ret = 0; 1007 fail: 1008 for (i = 0; i < nactive; i++) 1009 free(active[i]); 1010 free(active); 1011 for (i = 0; i < ndone; i++) 1012 free(done[i]); 1013 free(done); 1014 return ret; 1015 } 1016 1017 static struct sftp_conn * 1018 do_sftp_connect(char *host, char *user, int port, char *sftp_direct, 1019 int *reminp, int *remoutp, int *pidp) 1020 { 1021 if (sftp_direct == NULL) { 1022 if (do_cmd(ssh_program, host, user, port, 1, "sftp", 1023 reminp, remoutp, pidp) < 0) 1024 return NULL; 1025 1026 } else { 1027 freeargs(&args); 1028 addargs(&args, "sftp-server"); 1029 if (do_cmd(sftp_direct, host, NULL, -1, 0, "sftp", 1030 reminp, remoutp, pidp) < 0) 1031 return NULL; 1032 } 1033 return sftp_init(*reminp, *remoutp, 1034 sftp_copy_buflen, sftp_nrequests, limit_kbps); 1035 } 1036 1037 void 1038 toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) 1039 { 1040 char *suser = NULL, *host = NULL, *src = NULL; 1041 char *bp, *tuser, *thost, *targ; 1042 int sport = -1, tport = -1; 1043 struct sftp_conn *conn = NULL, *conn2 = NULL; 1044 arglist alist; 1045 int i, r, status; 1046 struct stat sb; 1047 u_int j; 1048 1049 memset(&alist, '\0', sizeof(alist)); 1050 alist.list = NULL; 1051 1052 /* Parse target */ 1053 r = parse_scp_uri(argv[argc - 1], &tuser, &thost, &tport, &targ); 1054 if (r == -1) { 1055 fmprintf(stderr, "%s: invalid uri\n", argv[argc - 1]); 1056 ++errs; 1057 goto out; 1058 } 1059 if (r != 0) { 1060 if (parse_user_host_path(argv[argc - 1], &tuser, &thost, 1061 &targ) == -1) { 1062 fmprintf(stderr, "%s: invalid target\n", argv[argc - 1]); 1063 ++errs; 1064 goto out; 1065 } 1066 } 1067 1068 /* Parse source files */ 1069 for (i = 0; i < argc - 1; i++) { 1070 free(suser); 1071 free(host); 1072 free(src); 1073 r = parse_scp_uri(argv[i], &suser, &host, &sport, &src); 1074 if (r == -1) { 1075 fmprintf(stderr, "%s: invalid uri\n", argv[i]); 1076 ++errs; 1077 continue; 1078 } 1079 if (r != 0) { 1080 parse_user_host_path(argv[i], &suser, &host, &src); 1081 } 1082 if (suser != NULL && !okname(suser)) { 1083 ++errs; 1084 continue; 1085 } 1086 if (host && throughlocal) { /* extended remote to remote */ 1087 if (mode == MODE_SFTP) { 1088 if (remin == -1) { 1089 /* Connect to dest now */ 1090 conn = do_sftp_connect(thost, tuser, 1091 tport, sftp_direct, 1092 &remin, &remout, &do_cmd_pid); 1093 if (conn == NULL) { 1094 fatal("Unable to open " 1095 "destination connection"); 1096 } 1097 debug3_f("origin in %d out %d pid %ld", 1098 remin, remout, (long)do_cmd_pid); 1099 } 1100 /* 1101 * XXX remember suser/host/sport and only 1102 * reconnect if they change between arguments. 1103 * would save reconnections for cases like 1104 * scp -3 hosta:/foo hosta:/bar hostb: 1105 */ 1106 /* Connect to origin now */ 1107 conn2 = do_sftp_connect(host, suser, 1108 sport, sftp_direct, 1109 &remin2, &remout2, &do_cmd_pid2); 1110 if (conn2 == NULL) { 1111 fatal("Unable to open " 1112 "source connection"); 1113 } 1114 debug3_f("destination in %d out %d pid %ld", 1115 remin2, remout2, (long)do_cmd_pid2); 1116 throughlocal_sftp(conn2, conn, src, targ); 1117 (void) close(remin2); 1118 (void) close(remout2); 1119 remin2 = remout2 = -1; 1120 if (waitpid(do_cmd_pid2, &status, 0) == -1) 1121 ++errs; 1122 else if (!WIFEXITED(status) || 1123 WEXITSTATUS(status) != 0) 1124 ++errs; 1125 do_cmd_pid2 = -1; 1126 continue; 1127 } else { 1128 xasprintf(&bp, "%s -f %s%s", cmd, 1129 *src == '-' ? "-- " : "", src); 1130 if (do_cmd(ssh_program, host, suser, sport, 0, 1131 bp, &remin, &remout, &do_cmd_pid) < 0) 1132 exit(1); 1133 free(bp); 1134 xasprintf(&bp, "%s -t %s%s", cmd, 1135 *targ == '-' ? "-- " : "", targ); 1136 if (do_cmd2(thost, tuser, tport, bp, 1137 remin, remout) < 0) 1138 exit(1); 1139 free(bp); 1140 (void) close(remin); 1141 (void) close(remout); 1142 remin = remout = -1; 1143 } 1144 } else if (host) { /* standard remote to remote */ 1145 /* 1146 * Second remote user is passed to first remote side 1147 * via scp command-line. Ensure it contains no obvious 1148 * shell characters. 1149 */ 1150 if (tuser != NULL && !okname(tuser)) { 1151 ++errs; 1152 continue; 1153 } 1154 if (tport != -1 && tport != SSH_DEFAULT_PORT) { 1155 /* This would require the remote support URIs */ 1156 fatal("target port not supported with two " 1157 "remote hosts and the -R option"); 1158 } 1159 1160 freeargs(&alist); 1161 addargs(&alist, "%s", ssh_program); 1162 addargs(&alist, "-x"); 1163 addargs(&alist, "-oClearAllForwardings=yes"); 1164 addargs(&alist, "-n"); 1165 for (j = 0; j < remote_remote_args.num; j++) { 1166 addargs(&alist, "%s", 1167 remote_remote_args.list[j]); 1168 } 1169 1170 if (sport != -1) { 1171 addargs(&alist, "-p"); 1172 addargs(&alist, "%d", sport); 1173 } 1174 if (suser) { 1175 addargs(&alist, "-l"); 1176 addargs(&alist, "%s", suser); 1177 } 1178 addargs(&alist, "--"); 1179 addargs(&alist, "%s", host); 1180 addargs(&alist, "%s", cmd); 1181 addargs(&alist, "%s", src); 1182 addargs(&alist, "%s%s%s:%s", 1183 tuser ? tuser : "", tuser ? "@" : "", 1184 thost, targ); 1185 if (do_local_cmd(&alist) != 0) 1186 errs = 1; 1187 } else { /* local to remote */ 1188 if (mode == MODE_SFTP) { 1189 /* no need to glob: already done by shell */ 1190 if (stat(argv[i], &sb) != 0) { 1191 fatal("stat local \"%s\": %s", argv[i], 1192 strerror(errno)); 1193 } 1194 if (remin == -1) { 1195 /* Connect to remote now */ 1196 conn = do_sftp_connect(thost, tuser, 1197 tport, sftp_direct, 1198 &remin, &remout, &do_cmd_pid); 1199 if (conn == NULL) { 1200 fatal("Unable to open sftp " 1201 "connection"); 1202 } 1203 } 1204 1205 /* The protocol */ 1206 source_sftp(1, argv[i], targ, conn); 1207 continue; 1208 } 1209 /* SCP */ 1210 if (remin == -1) { 1211 xasprintf(&bp, "%s -t %s%s", cmd, 1212 *targ == '-' ? "-- " : "", targ); 1213 if (do_cmd(ssh_program, thost, tuser, tport, 0, 1214 bp, &remin, &remout, &do_cmd_pid) < 0) 1215 exit(1); 1216 if (response() < 0) 1217 exit(1); 1218 free(bp); 1219 } 1220 source(1, argv + i); 1221 } 1222 } 1223 out: 1224 if (mode == MODE_SFTP) 1225 free(conn); 1226 free(tuser); 1227 free(thost); 1228 free(targ); 1229 free(suser); 1230 free(host); 1231 free(src); 1232 } 1233 1234 void 1235 tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) 1236 { 1237 char *bp, *host = NULL, *src = NULL, *suser = NULL; 1238 arglist alist; 1239 struct sftp_conn *conn = NULL; 1240 int i, r, sport = -1; 1241 1242 memset(&alist, '\0', sizeof(alist)); 1243 alist.list = NULL; 1244 1245 for (i = 0; i < argc - 1; i++) { 1246 free(suser); 1247 free(host); 1248 free(src); 1249 r = parse_scp_uri(argv[i], &suser, &host, &sport, &src); 1250 if (r == -1) { 1251 fmprintf(stderr, "%s: invalid uri\n", argv[i]); 1252 ++errs; 1253 continue; 1254 } 1255 if (r != 0) 1256 parse_user_host_path(argv[i], &suser, &host, &src); 1257 if (suser != NULL && !okname(suser)) { 1258 ++errs; 1259 continue; 1260 } 1261 if (!host) { /* Local to local. */ 1262 freeargs(&alist); 1263 addargs(&alist, "%s", _PATH_CP); 1264 if (iamrecursive) 1265 addargs(&alist, "-r"); 1266 if (pflag) 1267 addargs(&alist, "-p"); 1268 addargs(&alist, "--"); 1269 addargs(&alist, "%s", argv[i]); 1270 addargs(&alist, "%s", argv[argc-1]); 1271 if (do_local_cmd(&alist)) 1272 ++errs; 1273 continue; 1274 } 1275 /* Remote to local. */ 1276 if (mode == MODE_SFTP) { 1277 conn = do_sftp_connect(host, suser, sport, 1278 sftp_direct, &remin, &remout, &do_cmd_pid); 1279 if (conn == NULL) { 1280 error("sftp connection failed"); 1281 ++errs; 1282 continue; 1283 } 1284 1285 /* The protocol */ 1286 sink_sftp(1, argv[argc - 1], src, conn); 1287 1288 free(conn); 1289 (void) close(remin); 1290 (void) close(remout); 1291 remin = remout = -1; 1292 continue; 1293 } 1294 /* SCP */ 1295 xasprintf(&bp, "%s -f %s%s", 1296 cmd, *src == '-' ? "-- " : "", src); 1297 if (do_cmd(ssh_program, host, suser, sport, 0, bp, 1298 &remin, &remout, &do_cmd_pid) < 0) { 1299 free(bp); 1300 ++errs; 1301 continue; 1302 } 1303 free(bp); 1304 sink(1, argv + argc - 1, src); 1305 (void) close(remin); 1306 remin = remout = -1; 1307 } 1308 free(suser); 1309 free(host); 1310 free(src); 1311 } 1312 1313 /* Prepare remote path, handling ~ by assuming cwd is the homedir */ 1314 static char * 1315 prepare_remote_path(struct sftp_conn *conn, const char *path) 1316 { 1317 size_t nslash; 1318 1319 /* Handle ~ prefixed paths */ 1320 if (*path == '\0' || strcmp(path, "~") == 0) 1321 return xstrdup("."); 1322 if (*path != '~') 1323 return xstrdup(path); 1324 if (strncmp(path, "~/", 2) == 0) { 1325 if ((nslash = strspn(path + 2, "/")) == strlen(path + 2)) 1326 return xstrdup("."); 1327 return xstrdup(path + 2 + nslash); 1328 } 1329 if (sftp_can_expand_path(conn)) 1330 return sftp_expand_path(conn, path); 1331 /* No protocol extension */ 1332 error("server expand-path extension is required " 1333 "for ~user paths in SFTP mode"); 1334 return NULL; 1335 } 1336 1337 void 1338 source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) 1339 { 1340 char *target = NULL, *filename = NULL, *abs_dst = NULL; 1341 int src_is_dir, target_is_dir; 1342 Attrib a; 1343 struct stat st; 1344 1345 memset(&a, '\0', sizeof(a)); 1346 if (stat(src, &st) != 0) 1347 fatal("stat local \"%s\": %s", src, strerror(errno)); 1348 src_is_dir = S_ISDIR(st.st_mode); 1349 if ((filename = basename(src)) == NULL) 1350 fatal("basename \"%s\": %s", src, strerror(errno)); 1351 1352 /* 1353 * No need to glob here - the local shell already took care of 1354 * the expansions 1355 */ 1356 if ((target = prepare_remote_path(conn, targ)) == NULL) 1357 cleanup_exit(255); 1358 target_is_dir = sftp_remote_is_dir(conn, target); 1359 if (targetshouldbedirectory && !target_is_dir) { 1360 debug("target directory \"%s\" does not exist", target); 1361 a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS; 1362 a.perm = st.st_mode | 0700; /* ensure writable */ 1363 if (sftp_mkdir(conn, target, &a, 1) != 0) 1364 cleanup_exit(255); /* error already logged */ 1365 target_is_dir = 1; 1366 } 1367 if (target_is_dir) 1368 abs_dst = sftp_path_append(target, filename); 1369 else { 1370 abs_dst = target; 1371 target = NULL; 1372 } 1373 debug3_f("copying local %s to remote %s", src, abs_dst); 1374 1375 if (src_is_dir && iamrecursive) { 1376 if (sftp_upload_dir(conn, src, abs_dst, pflag, 1377 SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { 1378 error("failed to upload directory %s to %s", src, targ); 1379 errs = 1; 1380 } 1381 } else if (sftp_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) { 1382 error("failed to upload file %s to %s", src, targ); 1383 errs = 1; 1384 } 1385 1386 free(abs_dst); 1387 free(target); 1388 } 1389 1390 void 1391 source(int argc, char **argv) 1392 { 1393 struct stat stb; 1394 static BUF buffer; 1395 BUF *bp; 1396 off_t i, statbytes; 1397 size_t amt, nr; 1398 int fd = -1, haderr, indx; 1399 char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX]; 1400 int len; 1401 1402 for (indx = 0; indx < argc; ++indx) { 1403 name = argv[indx]; 1404 statbytes = 0; 1405 len = strlen(name); 1406 while (len > 1 && name[len-1] == '/') 1407 name[--len] = '\0'; 1408 if ((fd = open(name, O_RDONLY|O_NONBLOCK)) == -1) 1409 goto syserr; 1410 if (strchr(name, '\n') != NULL) { 1411 strnvis(encname, name, sizeof(encname), VIS_NL); 1412 name = encname; 1413 } 1414 if (fstat(fd, &stb) == -1) { 1415 syserr: run_err("%s: %s", name, strerror(errno)); 1416 goto next; 1417 } 1418 if (stb.st_size < 0) { 1419 run_err("%s: %s", name, "Negative file size"); 1420 goto next; 1421 } 1422 unset_nonblock(fd); 1423 switch (stb.st_mode & S_IFMT) { 1424 case S_IFREG: 1425 break; 1426 case S_IFDIR: 1427 if (iamrecursive) { 1428 rsource(name, &stb); 1429 goto next; 1430 } 1431 /* FALLTHROUGH */ 1432 default: 1433 run_err("%s: not a regular file", name); 1434 goto next; 1435 } 1436 if ((last = strrchr(name, '/')) == NULL) 1437 last = name; 1438 else 1439 ++last; 1440 curfile = last; 1441 if (pflag) { 1442 if (do_times(remout, verbose_mode, &stb) < 0) 1443 goto next; 1444 } 1445 #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 1446 snprintf(buf, sizeof buf, "C%04o %lld %s\n", 1447 (u_int) (stb.st_mode & FILEMODEMASK), 1448 (long long)stb.st_size, last); 1449 if (verbose_mode) 1450 fmprintf(stderr, "Sending file modes: %s", buf); 1451 (void) atomicio(vwrite, remout, buf, strlen(buf)); 1452 if (response() < 0) 1453 goto next; 1454 if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { 1455 next: if (fd != -1) { 1456 (void) close(fd); 1457 fd = -1; 1458 } 1459 continue; 1460 } 1461 if (showprogress) 1462 start_progress_meter(curfile, stb.st_size, &statbytes); 1463 set_nonblock(remout); 1464 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { 1465 amt = bp->cnt; 1466 if (i + (off_t)amt > stb.st_size) 1467 amt = stb.st_size - i; 1468 if (!haderr) { 1469 if ((nr = atomicio(read, fd, 1470 bp->buf, amt)) != amt) { 1471 haderr = errno; 1472 memset(bp->buf + nr, 0, amt - nr); 1473 } 1474 } 1475 /* Keep writing after error to retain sync */ 1476 if (haderr) { 1477 (void)atomicio(vwrite, remout, bp->buf, amt); 1478 memset(bp->buf, 0, amt); 1479 continue; 1480 } 1481 if (atomicio6(vwrite, remout, bp->buf, amt, scpio, 1482 &statbytes) != amt) 1483 haderr = errno; 1484 } 1485 unset_nonblock(remout); 1486 1487 if (fd != -1) { 1488 if (close(fd) == -1 && !haderr) 1489 haderr = errno; 1490 fd = -1; 1491 } 1492 if (!haderr) 1493 (void) atomicio(vwrite, remout, "", 1); 1494 else 1495 run_err("%s: %s", name, strerror(haderr)); 1496 (void) response(); 1497 if (showprogress) 1498 stop_progress_meter(); 1499 } 1500 } 1501 1502 void 1503 rsource(char *name, struct stat *statp) 1504 { 1505 DIR *dirp; 1506 struct dirent *dp; 1507 char *last, *vect[1], path[PATH_MAX]; 1508 1509 if (!(dirp = opendir(name))) { 1510 run_err("%s: %s", name, strerror(errno)); 1511 return; 1512 } 1513 last = strrchr(name, '/'); 1514 if (last == NULL) 1515 last = name; 1516 else 1517 last++; 1518 if (pflag) { 1519 if (do_times(remout, verbose_mode, statp) < 0) { 1520 closedir(dirp); 1521 return; 1522 } 1523 } 1524 (void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", 1525 (u_int) (statp->st_mode & FILEMODEMASK), 0, last); 1526 if (verbose_mode) 1527 fmprintf(stderr, "Entering directory: %s", path); 1528 (void) atomicio(vwrite, remout, path, strlen(path)); 1529 if (response() < 0) { 1530 closedir(dirp); 1531 return; 1532 } 1533 while ((dp = readdir(dirp)) != NULL) { 1534 if (dp->d_ino == 0) 1535 continue; 1536 if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) 1537 continue; 1538 if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) { 1539 run_err("%s/%s: name too long", name, dp->d_name); 1540 continue; 1541 } 1542 (void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name); 1543 vect[0] = path; 1544 source(1, vect); 1545 } 1546 (void) closedir(dirp); 1547 (void) atomicio(vwrite, remout, "E\n", 2); 1548 (void) response(); 1549 } 1550 1551 void 1552 sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) 1553 { 1554 char *abs_src = NULL; 1555 char *abs_dst = NULL; 1556 glob_t g; 1557 char *filename, *tmp = NULL; 1558 int i, r, err = 0, dst_is_dir; 1559 struct stat st; 1560 1561 memset(&g, 0, sizeof(g)); 1562 1563 /* 1564 * Here, we need remote glob as SFTP can not depend on remote shell 1565 * expansions 1566 */ 1567 if ((abs_src = prepare_remote_path(conn, src)) == NULL) { 1568 err = -1; 1569 goto out; 1570 } 1571 1572 debug3_f("copying remote %s to local %s", abs_src, dst); 1573 if ((r = sftp_glob(conn, abs_src, GLOB_NOCHECK|GLOB_MARK, 1574 NULL, &g)) != 0) { 1575 if (r == GLOB_NOSPACE) 1576 error("%s: too many glob matches", src); 1577 else 1578 error("%s: %s", src, strerror(ENOENT)); 1579 err = -1; 1580 goto out; 1581 } 1582 1583 /* Did we actually get any matches back from the glob? */ 1584 if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { 1585 /* 1586 * If nothing matched but a path returned, then it's probably 1587 * a GLOB_NOCHECK result. Check whether the unglobbed path 1588 * exists so we can give a nice error message early. 1589 */ 1590 if (sftp_stat(conn, g.gl_pathv[0], 1, NULL) != 0) { 1591 error("%s: %s", src, strerror(ENOENT)); 1592 err = -1; 1593 goto out; 1594 } 1595 } 1596 1597 if ((r = stat(dst, &st)) != 0) 1598 debug2_f("stat local \"%s\": %s", dst, strerror(errno)); 1599 dst_is_dir = r == 0 && S_ISDIR(st.st_mode); 1600 1601 if (g.gl_matchc > 1 && !dst_is_dir) { 1602 if (r == 0) { 1603 error("Multiple files match pattern, but destination " 1604 "\"%s\" is not a directory", dst); 1605 err = -1; 1606 goto out; 1607 } 1608 debug2_f("creating destination \"%s\"", dst); 1609 if (mkdir(dst, 0777) != 0) { 1610 error("local mkdir \"%s\": %s", dst, strerror(errno)); 1611 err = -1; 1612 goto out; 1613 } 1614 dst_is_dir = 1; 1615 } 1616 1617 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 1618 tmp = xstrdup(g.gl_pathv[i]); 1619 if ((filename = basename(tmp)) == NULL) { 1620 error("basename %s: %s", tmp, strerror(errno)); 1621 err = -1; 1622 goto out; 1623 } 1624 1625 if (dst_is_dir) 1626 abs_dst = sftp_path_append(dst, filename); 1627 else 1628 abs_dst = xstrdup(dst); 1629 1630 debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); 1631 if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { 1632 if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst, 1633 NULL, pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1) 1634 err = -1; 1635 } else { 1636 if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL, 1637 pflag, 0, 0, 1) == -1) 1638 err = -1; 1639 } 1640 free(abs_dst); 1641 abs_dst = NULL; 1642 free(tmp); 1643 tmp = NULL; 1644 } 1645 1646 out: 1647 free(abs_src); 1648 free(tmp); 1649 globfree(&g); 1650 if (err == -1) 1651 errs = 1; 1652 } 1653 1654 1655 #define TYPE_OVERFLOW(type, val) \ 1656 ((sizeof(type) == 4 && (val) > INT32_MAX) || \ 1657 (sizeof(type) == 8 && (val) > INT64_MAX) || \ 1658 (sizeof(type) != 4 && sizeof(type) != 8)) 1659 1660 void 1661 sink(int argc, char **argv, const char *src) 1662 { 1663 static BUF buffer; 1664 struct stat stb; 1665 BUF *bp; 1666 off_t i; 1667 size_t j, count; 1668 int amt, exists, first, ofd; 1669 mode_t mode, omode, mask; 1670 off_t size, statbytes; 1671 unsigned long long ull; 1672 int setimes, targisdir, wrerr; 1673 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; 1674 char **patterns = NULL; 1675 size_t n, npatterns = 0; 1676 struct timeval tv[2]; 1677 1678 #define atime tv[0] 1679 #define mtime tv[1] 1680 #define SCREWUP(str) { why = str; goto screwup; } 1681 1682 if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) 1683 SCREWUP("Unexpected off_t/time_t size"); 1684 1685 setimes = targisdir = 0; 1686 mask = umask(0); 1687 if (!pflag) 1688 (void) umask(mask); 1689 if (argc != 1) { 1690 run_err("ambiguous target"); 1691 exit(1); 1692 } 1693 targ = *argv; 1694 if (targetshouldbedirectory) 1695 verifydir(targ); 1696 1697 (void) atomicio(vwrite, remout, "", 1); 1698 if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) 1699 targisdir = 1; 1700 if (src != NULL && !iamrecursive && !Tflag) { 1701 /* 1702 * Prepare to try to restrict incoming filenames to match 1703 * the requested destination file glob. 1704 */ 1705 if (brace_expand(src, &patterns, &npatterns) != 0) 1706 fatal_f("could not expand pattern"); 1707 } 1708 for (first = 1;; first = 0) { 1709 cp = buf; 1710 if (atomicio(read, remin, cp, 1) != 1) 1711 goto done; 1712 if (*cp++ == '\n') 1713 SCREWUP("unexpected <newline>"); 1714 do { 1715 if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) 1716 SCREWUP("lost connection"); 1717 *cp++ = ch; 1718 } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); 1719 *cp = 0; 1720 if (verbose_mode) 1721 fmprintf(stderr, "Sink: %s", buf); 1722 1723 if (buf[0] == '\01' || buf[0] == '\02') { 1724 if (iamremote == 0) { 1725 (void) snmprintf(visbuf, sizeof(visbuf), 1726 NULL, "%s", buf + 1); 1727 (void) atomicio(vwrite, STDERR_FILENO, 1728 visbuf, strlen(visbuf)); 1729 } 1730 if (buf[0] == '\02') 1731 exit(1); 1732 ++errs; 1733 continue; 1734 } 1735 if (buf[0] == 'E') { 1736 (void) atomicio(vwrite, remout, "", 1); 1737 goto done; 1738 } 1739 if (ch == '\n') 1740 *--cp = 0; 1741 1742 cp = buf; 1743 if (*cp == 'T') { 1744 setimes++; 1745 cp++; 1746 if (!isdigit((unsigned char)*cp)) 1747 SCREWUP("mtime.sec not present"); 1748 ull = strtoull(cp, &cp, 10); 1749 if (!cp || *cp++ != ' ') 1750 SCREWUP("mtime.sec not delimited"); 1751 if (TYPE_OVERFLOW(time_t, ull)) 1752 setimes = 0; /* out of range */ 1753 mtime.tv_sec = ull; 1754 mtime.tv_usec = strtol(cp, &cp, 10); 1755 if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 || 1756 mtime.tv_usec > 999999) 1757 SCREWUP("mtime.usec not delimited"); 1758 if (!isdigit((unsigned char)*cp)) 1759 SCREWUP("atime.sec not present"); 1760 ull = strtoull(cp, &cp, 10); 1761 if (!cp || *cp++ != ' ') 1762 SCREWUP("atime.sec not delimited"); 1763 if (TYPE_OVERFLOW(time_t, ull)) 1764 setimes = 0; /* out of range */ 1765 atime.tv_sec = ull; 1766 atime.tv_usec = strtol(cp, &cp, 10); 1767 if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || 1768 atime.tv_usec > 999999) 1769 SCREWUP("atime.usec not delimited"); 1770 (void) atomicio(vwrite, remout, "", 1); 1771 continue; 1772 } 1773 if (*cp != 'C' && *cp != 'D') { 1774 /* 1775 * Check for the case "rcp remote:foo\* local:bar". 1776 * In this case, the line "No match." can be returned 1777 * by the shell before the rcp command on the remote is 1778 * executed so the ^Aerror_message convention isn't 1779 * followed. 1780 */ 1781 if (first) { 1782 run_err("%s", cp); 1783 exit(1); 1784 } 1785 SCREWUP("expected control record"); 1786 } 1787 mode = 0; 1788 for (++cp; cp < buf + 5; cp++) { 1789 if (*cp < '0' || *cp > '7') 1790 SCREWUP("bad mode"); 1791 mode = (mode << 3) | (*cp - '0'); 1792 } 1793 if (!pflag) 1794 mode &= ~mask; 1795 if (*cp++ != ' ') 1796 SCREWUP("mode not delimited"); 1797 1798 if (!isdigit((unsigned char)*cp)) 1799 SCREWUP("size not present"); 1800 ull = strtoull(cp, &cp, 10); 1801 if (!cp || *cp++ != ' ') 1802 SCREWUP("size not delimited"); 1803 if (TYPE_OVERFLOW(off_t, ull)) 1804 SCREWUP("size out of range"); 1805 size = (off_t)ull; 1806 1807 if (*cp == '\0' || strchr(cp, '/') != NULL || 1808 strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { 1809 run_err("error: unexpected filename: %s", cp); 1810 exit(1); 1811 } 1812 if (npatterns > 0) { 1813 for (n = 0; n < npatterns; n++) { 1814 if (strcmp(patterns[n], cp) == 0 || 1815 fnmatch(patterns[n], cp, 0) == 0) 1816 break; 1817 } 1818 if (n >= npatterns) { 1819 debug2_f("incoming filename \"%s\" does not " 1820 "match any of %zu expected patterns", cp, 1821 npatterns); 1822 for (n = 0; n < npatterns; n++) { 1823 debug3_f("expected pattern %zu: \"%s\"", 1824 n, patterns[n]); 1825 } 1826 SCREWUP("filename does not match request"); 1827 } 1828 } 1829 if (targisdir) { 1830 static char *namebuf; 1831 static size_t cursize; 1832 size_t need; 1833 1834 need = strlen(targ) + strlen(cp) + 250; 1835 if (need > cursize) { 1836 free(namebuf); 1837 namebuf = xmalloc(need); 1838 cursize = need; 1839 } 1840 (void) snprintf(namebuf, need, "%s%s%s", targ, 1841 strcmp(targ, "/") ? "/" : "", cp); 1842 np = namebuf; 1843 } else 1844 np = targ; 1845 curfile = cp; 1846 exists = stat(np, &stb) == 0; 1847 if (buf[0] == 'D') { 1848 int mod_flag = pflag; 1849 if (!iamrecursive) 1850 SCREWUP("received directory without -r"); 1851 if (exists) { 1852 if (!S_ISDIR(stb.st_mode)) { 1853 errno = ENOTDIR; 1854 goto bad; 1855 } 1856 if (pflag) 1857 (void) chmod(np, mode); 1858 } else { 1859 /* Handle copying from a read-only directory */ 1860 mod_flag = 1; 1861 if (mkdir(np, mode | S_IRWXU) == -1) 1862 goto bad; 1863 } 1864 vect[0] = xstrdup(np); 1865 sink(1, vect, src); 1866 if (setimes) { 1867 setimes = 0; 1868 (void) utimes(vect[0], tv); 1869 } 1870 if (mod_flag) 1871 (void) chmod(vect[0], mode); 1872 free(vect[0]); 1873 continue; 1874 } 1875 omode = mode; 1876 mode |= S_IWUSR; 1877 if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { 1878 bad: run_err("%s: %s", np, strerror(errno)); 1879 continue; 1880 } 1881 (void) atomicio(vwrite, remout, "", 1); 1882 if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { 1883 (void) close(ofd); 1884 continue; 1885 } 1886 cp = bp->buf; 1887 wrerr = 0; 1888 1889 /* 1890 * NB. do not use run_err() unless immediately followed by 1891 * exit() below as it may send a spurious reply that might 1892 * desyncronise us from the peer. Use note_err() instead. 1893 */ 1894 statbytes = 0; 1895 if (showprogress) 1896 start_progress_meter(curfile, size, &statbytes); 1897 set_nonblock(remin); 1898 for (count = i = 0; i < size; i += bp->cnt) { 1899 amt = bp->cnt; 1900 if (i + amt > size) 1901 amt = size - i; 1902 count += amt; 1903 do { 1904 j = atomicio6(read, remin, cp, amt, 1905 scpio, &statbytes); 1906 if (j == 0) { 1907 run_err("%s", j != EPIPE ? 1908 strerror(errno) : 1909 "dropped connection"); 1910 exit(1); 1911 } 1912 amt -= j; 1913 cp += j; 1914 } while (amt > 0); 1915 1916 if (count == bp->cnt) { 1917 /* Keep reading so we stay sync'd up. */ 1918 if (!wrerr) { 1919 if (atomicio(vwrite, ofd, bp->buf, 1920 count) != count) { 1921 note_err("%s: %s", np, 1922 strerror(errno)); 1923 wrerr = 1; 1924 } 1925 } 1926 count = 0; 1927 cp = bp->buf; 1928 } 1929 } 1930 unset_nonblock(remin); 1931 if (count != 0 && !wrerr && 1932 atomicio(vwrite, ofd, bp->buf, count) != count) { 1933 note_err("%s: %s", np, strerror(errno)); 1934 wrerr = 1; 1935 } 1936 if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && 1937 ftruncate(ofd, size) != 0) 1938 note_err("%s: truncate: %s", np, strerror(errno)); 1939 if (pflag) { 1940 if (exists || omode != mode) 1941 #ifdef HAVE_FCHMOD 1942 if (fchmod(ofd, omode)) { 1943 #else /* HAVE_FCHMOD */ 1944 if (chmod(np, omode)) { 1945 #endif /* HAVE_FCHMOD */ 1946 note_err("%s: set mode: %s", 1947 np, strerror(errno)); 1948 } 1949 } else { 1950 if (!exists && omode != mode) 1951 #ifdef HAVE_FCHMOD 1952 if (fchmod(ofd, omode & ~mask)) { 1953 #else /* HAVE_FCHMOD */ 1954 if (chmod(np, omode & ~mask)) { 1955 #endif /* HAVE_FCHMOD */ 1956 note_err("%s: set mode: %s", 1957 np, strerror(errno)); 1958 } 1959 } 1960 if (close(ofd) == -1) 1961 note_err("%s: close: %s", np, strerror(errno)); 1962 (void) response(); 1963 if (showprogress) 1964 stop_progress_meter(); 1965 if (setimes && !wrerr) { 1966 setimes = 0; 1967 if (utimes(np, tv) == -1) { 1968 note_err("%s: set times: %s", 1969 np, strerror(errno)); 1970 } 1971 } 1972 /* If no error was noted then signal success for this file */ 1973 if (note_err(NULL) == 0) 1974 (void) atomicio(vwrite, remout, "", 1); 1975 } 1976 done: 1977 for (n = 0; n < npatterns; n++) 1978 free(patterns[n]); 1979 free(patterns); 1980 return; 1981 screwup: 1982 for (n = 0; n < npatterns; n++) 1983 free(patterns[n]); 1984 free(patterns); 1985 run_err("protocol error: %s", why); 1986 exit(1); 1987 } 1988 1989 void 1990 throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, 1991 char *src, char *targ) 1992 { 1993 char *target = NULL, *filename = NULL, *abs_dst = NULL; 1994 char *abs_src = NULL, *tmp = NULL; 1995 glob_t g; 1996 int i, r, targetisdir, err = 0; 1997 1998 if ((filename = basename(src)) == NULL) 1999 fatal("basename %s: %s", src, strerror(errno)); 2000 2001 if ((abs_src = prepare_remote_path(from, src)) == NULL || 2002 (target = prepare_remote_path(to, targ)) == NULL) 2003 cleanup_exit(255); 2004 memset(&g, 0, sizeof(g)); 2005 2006 targetisdir = sftp_remote_is_dir(to, target); 2007 if (!targetisdir && targetshouldbedirectory) { 2008 error("%s: destination is not a directory", targ); 2009 err = -1; 2010 goto out; 2011 } 2012 2013 debug3_f("copying remote %s to remote %s", abs_src, target); 2014 if ((r = sftp_glob(from, abs_src, GLOB_NOCHECK|GLOB_MARK, 2015 NULL, &g)) != 0) { 2016 if (r == GLOB_NOSPACE) 2017 error("%s: too many glob matches", src); 2018 else 2019 error("%s: %s", src, strerror(ENOENT)); 2020 err = -1; 2021 goto out; 2022 } 2023 2024 /* Did we actually get any matches back from the glob? */ 2025 if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { 2026 /* 2027 * If nothing matched but a path returned, then it's probably 2028 * a GLOB_NOCHECK result. Check whether the unglobbed path 2029 * exists so we can give a nice error message early. 2030 */ 2031 if (sftp_stat(from, g.gl_pathv[0], 1, NULL) != 0) { 2032 error("%s: %s", src, strerror(ENOENT)); 2033 err = -1; 2034 goto out; 2035 } 2036 } 2037 2038 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 2039 tmp = xstrdup(g.gl_pathv[i]); 2040 if ((filename = basename(tmp)) == NULL) { 2041 error("basename %s: %s", tmp, strerror(errno)); 2042 err = -1; 2043 goto out; 2044 } 2045 2046 if (targetisdir) 2047 abs_dst = sftp_path_append(target, filename); 2048 else 2049 abs_dst = xstrdup(target); 2050 2051 debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); 2052 if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { 2053 if (sftp_crossload_dir(from, to, g.gl_pathv[i], abs_dst, 2054 NULL, pflag, SFTP_PROGRESS_ONLY, 1) == -1) 2055 err = -1; 2056 } else { 2057 if (sftp_crossload(from, to, g.gl_pathv[i], abs_dst, 2058 NULL, pflag) == -1) 2059 err = -1; 2060 } 2061 free(abs_dst); 2062 abs_dst = NULL; 2063 free(tmp); 2064 tmp = NULL; 2065 } 2066 2067 out: 2068 free(abs_src); 2069 free(abs_dst); 2070 free(target); 2071 free(tmp); 2072 globfree(&g); 2073 if (err == -1) 2074 errs = 1; 2075 } 2076 2077 int 2078 response(void) 2079 { 2080 char ch, *cp, resp, rbuf[2048], visbuf[2048]; 2081 2082 if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) 2083 lostconn(0); 2084 2085 cp = rbuf; 2086 switch (resp) { 2087 case 0: /* ok */ 2088 return (0); 2089 default: 2090 *cp++ = resp; 2091 /* FALLTHROUGH */ 2092 case 1: /* error, followed by error msg */ 2093 case 2: /* fatal error, "" */ 2094 do { 2095 if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) 2096 lostconn(0); 2097 *cp++ = ch; 2098 } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); 2099 2100 if (!iamremote) { 2101 cp[-1] = '\0'; 2102 (void) snmprintf(visbuf, sizeof(visbuf), 2103 NULL, "%s\n", rbuf); 2104 (void) atomicio(vwrite, STDERR_FILENO, 2105 visbuf, strlen(visbuf)); 2106 } 2107 ++errs; 2108 if (resp == 1) 2109 return (-1); 2110 exit(1); 2111 } 2112 /* NOTREACHED */ 2113 } 2114 2115 void 2116 usage(void) 2117 { 2118 (void) fprintf(stderr, 2119 "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" 2120 " [-i identity_file] [-J destination] [-l limit] [-o ssh_option]\n" 2121 " [-P port] [-S program] [-X sftp_option] source ... target\n"); 2122 exit(1); 2123 } 2124 2125 void 2126 run_err(const char *fmt,...) 2127 { 2128 static FILE *fp; 2129 va_list ap; 2130 2131 ++errs; 2132 if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) { 2133 (void) fprintf(fp, "%c", 0x01); 2134 (void) fprintf(fp, "scp: "); 2135 va_start(ap, fmt); 2136 (void) vfprintf(fp, fmt, ap); 2137 va_end(ap); 2138 (void) fprintf(fp, "\n"); 2139 (void) fflush(fp); 2140 } 2141 2142 if (!iamremote) { 2143 va_start(ap, fmt); 2144 vfmprintf(stderr, fmt, ap); 2145 va_end(ap); 2146 fprintf(stderr, "\n"); 2147 } 2148 } 2149 2150 /* 2151 * Notes a sink error for sending at the end of a file transfer. Returns 0 if 2152 * no error has been noted or -1 otherwise. Use note_err(NULL) to flush 2153 * any active error at the end of the transfer. 2154 */ 2155 int 2156 note_err(const char *fmt, ...) 2157 { 2158 static char *emsg; 2159 va_list ap; 2160 2161 /* Replay any previously-noted error */ 2162 if (fmt == NULL) { 2163 if (emsg == NULL) 2164 return 0; 2165 run_err("%s", emsg); 2166 free(emsg); 2167 emsg = NULL; 2168 return -1; 2169 } 2170 2171 errs++; 2172 /* Prefer first-noted error */ 2173 if (emsg != NULL) 2174 return -1; 2175 2176 va_start(ap, fmt); 2177 vasnmprintf(&emsg, INT_MAX, NULL, fmt, ap); 2178 va_end(ap); 2179 return -1; 2180 } 2181 2182 void 2183 verifydir(char *cp) 2184 { 2185 struct stat stb; 2186 2187 if (!stat(cp, &stb)) { 2188 if (S_ISDIR(stb.st_mode)) 2189 return; 2190 errno = ENOTDIR; 2191 } 2192 run_err("%s: %s", cp, strerror(errno)); 2193 killchild(0); 2194 } 2195 2196 int 2197 okname(char *cp0) 2198 { 2199 int c; 2200 char *cp; 2201 2202 cp = cp0; 2203 do { 2204 c = (int)*cp; 2205 if (c & 0200) 2206 goto bad; 2207 if (!isalpha(c) && !isdigit((unsigned char)c)) { 2208 switch (c) { 2209 case '\'': 2210 case '"': 2211 case '`': 2212 case ' ': 2213 case '#': 2214 goto bad; 2215 default: 2216 break; 2217 } 2218 } 2219 } while (*++cp); 2220 return (1); 2221 2222 bad: fmprintf(stderr, "%s: invalid user name\n", cp0); 2223 return (0); 2224 } 2225 2226 BUF * 2227 allocbuf(BUF *bp, int fd, int blksize) 2228 { 2229 size_t size; 2230 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 2231 struct stat stb; 2232 2233 if (fstat(fd, &stb) == -1) { 2234 run_err("fstat: %s", strerror(errno)); 2235 return (0); 2236 } 2237 size = ROUNDUP(stb.st_blksize, blksize); 2238 if (size == 0) 2239 size = blksize; 2240 #else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 2241 size = blksize; 2242 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 2243 if (bp->cnt >= size) 2244 return (bp); 2245 bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1); 2246 bp->cnt = size; 2247 return (bp); 2248 } 2249 2250 void 2251 lostconn(int signo) 2252 { 2253 if (!iamremote) 2254 (void)write(STDERR_FILENO, "lost connection\n", 16); 2255 if (signo) 2256 _exit(1); 2257 else 2258 exit(1); 2259 } 2260 2261 void 2262 cleanup_exit(int i) 2263 { 2264 if (remin > 0) 2265 close(remin); 2266 if (remout > 0) 2267 close(remout); 2268 if (remin2 > 0) 2269 close(remin2); 2270 if (remout2 > 0) 2271 close(remout2); 2272 if (do_cmd_pid > 0) 2273 (void)waitpid(do_cmd_pid, NULL, 0); 2274 if (do_cmd_pid2 > 0) 2275 (void)waitpid(do_cmd_pid2, NULL, 0); 2276 exit(i); 2277 } 2278