Home | History | Annotate | Line # | Download | only in dist
scp.c revision 1.31
      1 /*	$NetBSD: scp.c,v 1.31 2021/04/19 14:40:15 christos Exp $	*/
      2 /* $OpenBSD: scp.c,v 1.214 2021/04/03 06:18:40 djm Exp $ */
      3 
      4 /*
      5  * scp - secure remote copy.  This is basically patched BSD rcp which
      6  * uses ssh to do the data transfer (instead of using rcmd).
      7  *
      8  * NOTE: This version should NOT be suid root.  (This uses ssh to
      9  * do the transfer and ssh has the necessary privileges.)
     10  *
     11  * 1995 Timo Rinne <tri (at) iki.fi>, Tatu Ylonen <ylo (at) cs.hut.fi>
     12  *
     13  * As far as I am concerned, the code I have written for this software
     14  * can be used freely for any purpose.  Any derived versions of this
     15  * software must be clearly marked as such, and if the derived work is
     16  * incompatible with the protocol description in the RFC file, it must be
     17  * called by a name other than "ssh" or "Secure Shell".
     18  */
     19 /*
     20  * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
     21  * Copyright (c) 1999 Aaron Campbell.  All rights reserved.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the above copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  *
     32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     33  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     34  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     35  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     36  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     37  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     41  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     42  */
     43 
     44 /*
     45  * Parts from:
     46  *
     47  * Copyright (c) 1983, 1990, 1992, 1993, 1995
     48  *	The Regents of the University of California.  All rights reserved.
     49  *
     50  * Redistribution and use in source and binary forms, with or without
     51  * modification, are permitted provided that the following conditions
     52  * are met:
     53  * 1. Redistributions of source code must retain the above copyright
     54  *    notice, this list of conditions and the following disclaimer.
     55  * 2. Redistributions in binary form must reproduce the above copyright
     56  *    notice, this list of conditions and the following disclaimer in the
     57  *    documentation and/or other materials provided with the distribution.
     58  * 3. Neither the name of the University nor the names of its contributors
     59  *    may be used to endorse or promote products derived from this software
     60  *    without specific prior written permission.
     61  *
     62  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     63  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     64  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     65  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     66  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     67  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     68  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     69  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     70  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     71  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     72  * SUCH DAMAGE.
     73  *
     74  */
     75 
     76 #include "includes.h"
     77 __RCSID("$NetBSD: scp.c,v 1.31 2021/04/19 14:40:15 christos Exp $");
     78 
     79 #include <sys/param.h>	/* roundup MAX */
     80 #include <sys/types.h>
     81 #include <sys/poll.h>
     82 #include <sys/wait.h>
     83 #include <sys/stat.h>
     84 #include <sys/time.h>
     85 #include <sys/uio.h>
     86 
     87 #include <ctype.h>
     88 #include <dirent.h>
     89 #include <errno.h>
     90 #include <fcntl.h>
     91 #include <fnmatch.h>
     92 #include <locale.h>
     93 #include <pwd.h>
     94 #include <signal.h>
     95 #include <stdarg.h>
     96 #include <stdint.h>
     97 #include <stdio.h>
     98 #include <stdlib.h>
     99 #include <string.h>
    100 #include <time.h>
    101 #include <unistd.h>
    102 #include <limits.h>
    103 #include <vis.h>
    104 
    105 #include "xmalloc.h"
    106 #include "ssh.h"
    107 #include "atomicio.h"
    108 #include "pathnames.h"
    109 #include "log.h"
    110 #include "misc.h"
    111 #include "progressmeter.h"
    112 #include "utf8.h"
    113 
    114 #define COPY_BUFLEN	16384
    115 
    116 int do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout);
    117 int do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout);
    118 
    119 static char empty[] = "";
    120 
    121 /* Struct for addargs */
    122 arglist args;
    123 arglist remote_remote_args;
    124 
    125 /* Bandwidth limit */
    126 long long limit_kbps = 0;
    127 struct bwlimit bwlimit;
    128 
    129 /* Name of current file being transferred. */
    130 char *curfile;
    131 
    132 /* This is set to non-zero to enable verbose mode. */
    133 int verbose_mode = 0;
    134 
    135 /* This is set to zero if the progressmeter is not desired. */
    136 int showprogress = 1;
    137 
    138 /*
    139  * This is set to non-zero if remote-remote copy should be piped
    140  * through this process.
    141  */
    142 int throughlocal = 0;
    143 
    144 /* Non-standard port to use for the ssh connection or -1. */
    145 int sshport = -1;
    146 
    147 /* This is the program to execute for the secured connection. ("ssh" or -S) */
    148 #ifdef RESCUEDIR
    149 const char *ssh_program = RESCUEDIR "/ssh";
    150 #else
    151 const char *ssh_program = _PATH_SSH_PROGRAM;
    152 #endif
    153 
    154 /* This is used to store the pid of ssh_program */
    155 pid_t do_cmd_pid = -1;
    156 
    157 __dead static void
    158 killchild(int signo)
    159 {
    160 	if (do_cmd_pid > 1) {
    161 		kill(do_cmd_pid, signo ? signo : SIGTERM);
    162 		waitpid(do_cmd_pid, NULL, 0);
    163 	}
    164 
    165 	if (signo)
    166 		_exit(1);
    167 	exit(1);
    168 }
    169 
    170 static void
    171 suspchild(int signo)
    172 {
    173 	int status;
    174 
    175 	if (do_cmd_pid > 1) {
    176 		kill(do_cmd_pid, signo);
    177 		while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&
    178 		    errno == EINTR)
    179 			;
    180 		kill(getpid(), SIGSTOP);
    181 	}
    182 }
    183 
    184 static int
    185 do_local_cmd(arglist *a)
    186 {
    187 	u_int i;
    188 	int status;
    189 	pid_t pid;
    190 
    191 	if (a->num == 0)
    192 		fatal("do_local_cmd: no arguments");
    193 
    194 	if (verbose_mode) {
    195 		fprintf(stderr, "Executing:");
    196 		for (i = 0; i < a->num; i++)
    197 			fmprintf(stderr, " %s", a->list[i]);
    198 		fprintf(stderr, "\n");
    199 	}
    200 	if ((pid = fork()) == -1)
    201 		fatal("do_local_cmd: fork: %s", strerror(errno));
    202 
    203 	if (pid == 0) {
    204 		execvp(a->list[0], a->list);
    205 		perror(a->list[0]);
    206 		exit(1);
    207 	}
    208 
    209 	do_cmd_pid = pid;
    210 	ssh_signal(SIGTERM, killchild);
    211 	ssh_signal(SIGINT, killchild);
    212 	ssh_signal(SIGHUP, killchild);
    213 
    214 	while (waitpid(pid, &status, 0) == -1)
    215 		if (errno != EINTR)
    216 			fatal("do_local_cmd: waitpid: %s", strerror(errno));
    217 
    218 	do_cmd_pid = -1;
    219 
    220 	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
    221 		return (-1);
    222 
    223 	return (0);
    224 }
    225 
    226 /*
    227  * This function executes the given command as the specified user on the
    228  * given host.  This returns < 0 if execution fails, and >= 0 otherwise. This
    229  * assigns the input and output file descriptors on success.
    230  */
    231 
    232 int
    233 do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
    234 {
    235 	int pin[2], pout[2], reserved[2];
    236 
    237 	if (verbose_mode)
    238 		fmprintf(stderr,
    239 		    "Executing: program %s host %s, user %s, command %s\n",
    240 		    ssh_program, host,
    241 		    remuser ? remuser : "(unspecified)", cmd);
    242 
    243 	if (port == -1)
    244 		port = sshport;
    245 
    246 	/*
    247 	 * Reserve two descriptors so that the real pipes won't get
    248 	 * descriptors 0 and 1 because that will screw up dup2 below.
    249 	 */
    250 	if (pipe(reserved) == -1)
    251 		fatal("pipe: %s", strerror(errno));
    252 
    253 	/* Create a socket pair for communicating with ssh. */
    254 	if (pipe(pin) == -1)
    255 		fatal("pipe: %s", strerror(errno));
    256 	if (pipe(pout) == -1)
    257 		fatal("pipe: %s", strerror(errno));
    258 
    259 	/* Free the reserved descriptors. */
    260 	close(reserved[0]);
    261 	close(reserved[1]);
    262 
    263 	ssh_signal(SIGTSTP, suspchild);
    264 	ssh_signal(SIGTTIN, suspchild);
    265 	ssh_signal(SIGTTOU, suspchild);
    266 
    267 	/* Fork a child to execute the command on the remote host using ssh. */
    268 	do_cmd_pid = fork();
    269 	if (do_cmd_pid == 0) {
    270 		/* Child. */
    271 		close(pin[1]);
    272 		close(pout[0]);
    273 		dup2(pin[0], 0);
    274 		dup2(pout[1], 1);
    275 		close(pin[0]);
    276 		close(pout[1]);
    277 
    278 		replacearg(&args, 0, "%s", ssh_program);
    279 		if (port != -1) {
    280 			addargs(&args, "-p");
    281 			addargs(&args, "%d", port);
    282 		}
    283 		if (remuser != NULL) {
    284 			addargs(&args, "-l");
    285 			addargs(&args, "%s", remuser);
    286 		}
    287 		addargs(&args, "--");
    288 		addargs(&args, "%s", host);
    289 		addargs(&args, "%s", cmd);
    290 
    291 		execvp(ssh_program, args.list);
    292 		perror(ssh_program);
    293 		exit(1);
    294 	} else if (do_cmd_pid == -1) {
    295 		fatal("fork: %s", strerror(errno));
    296 	}
    297 	/* Parent.  Close the other side, and return the local side. */
    298 	close(pin[0]);
    299 	*fdout = pin[1];
    300 	close(pout[1]);
    301 	*fdin = pout[0];
    302 	ssh_signal(SIGTERM, killchild);
    303 	ssh_signal(SIGINT, killchild);
    304 	ssh_signal(SIGHUP, killchild);
    305 	return 0;
    306 }
    307 
    308 /*
    309  * This function executes a command similar to do_cmd(), but expects the
    310  * input and output descriptors to be setup by a previous call to do_cmd().
    311  * This way the input and output of two commands can be connected.
    312  */
    313 int
    314 do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout)
    315 {
    316 	pid_t pid;
    317 	int status;
    318 
    319 	if (verbose_mode)
    320 		fmprintf(stderr,
    321 		    "Executing: 2nd program %s host %s, user %s, command %s\n",
    322 		    ssh_program, host,
    323 		    remuser ? remuser : "(unspecified)", cmd);
    324 
    325 	if (port == -1)
    326 		port = sshport;
    327 
    328 	/* Fork a child to execute the command on the remote host using ssh. */
    329 	pid = fork();
    330 	if (pid == 0) {
    331 		dup2(fdin, 0);
    332 		dup2(fdout, 1);
    333 
    334 		replacearg(&args, 0, "%s", ssh_program);
    335 		if (port != -1) {
    336 			addargs(&args, "-p");
    337 			addargs(&args, "%d", port);
    338 		}
    339 		if (remuser != NULL) {
    340 			addargs(&args, "-l");
    341 			addargs(&args, "%s", remuser);
    342 		}
    343 		addargs(&args, "-oBatchMode=yes");
    344 		addargs(&args, "--");
    345 		addargs(&args, "%s", host);
    346 		addargs(&args, "%s", cmd);
    347 
    348 		execvp(ssh_program, args.list);
    349 		perror(ssh_program);
    350 		exit(1);
    351 	} else if (pid == -1) {
    352 		fatal("fork: %s", strerror(errno));
    353 	}
    354 	while (waitpid(pid, &status, 0) == -1)
    355 		if (errno != EINTR)
    356 			fatal("do_cmd2: waitpid: %s", strerror(errno));
    357 	return 0;
    358 }
    359 
    360 typedef struct {
    361 	size_t cnt;
    362 	char *buf;
    363 } BUF;
    364 
    365 BUF *allocbuf(BUF *, int, int);
    366 __dead static void lostconn(int);
    367 int okname(char *);
    368 void run_err(const char *,...)
    369     __attribute__((__format__ (printf, 1, 2)))
    370     __attribute__((__nonnull__ (1)));
    371 int note_err(const char *,...)
    372     __attribute__((__format__ (printf, 1, 2)));
    373 void verifydir(char *);
    374 
    375 struct passwd *pwd;
    376 uid_t userid;
    377 int errs, remin, remout;
    378 int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
    379 
    380 #define	CMDNEEDS	64
    381 char cmd[CMDNEEDS];		/* must hold "rcp -r -p -d\0" */
    382 
    383 int response(void);
    384 void rsource(char *, struct stat *);
    385 void sink(int, char *[], const char *);
    386 void source(int, char *[]);
    387 static void tolocal(int, char *[]);
    388 static void toremote(int, char *[]);
    389 __dead static void usage(void);
    390 
    391 int
    392 main(int argc, char **argv)
    393 {
    394 	int ch, fflag, tflag, status, n;
    395 	char **newargv;
    396 	const char *errstr;
    397 	extern char *optarg;
    398 	extern int optind;
    399 
    400 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
    401 	sanitise_stdfd();
    402 
    403 	setlocale(LC_CTYPE, "");
    404 
    405 	/* Copy argv, because we modify it */
    406 	newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv));
    407 	for (n = 0; n < argc; n++)
    408 		newargv[n] = xstrdup(argv[n]);
    409 	argv = newargv;
    410 
    411 	memset(&args, '\0', sizeof(args));
    412 	memset(&remote_remote_args, '\0', sizeof(remote_remote_args));
    413 	args.list = remote_remote_args.list = NULL;
    414 	addargs(&args, "%s", ssh_program);
    415 	addargs(&args, "-x");
    416 	addargs(&args, "-oPermitLocalCommand=no");
    417 	addargs(&args, "-oClearAllForwardings=yes");
    418 	addargs(&args, "-oRemoteCommand=none");
    419 	addargs(&args, "-oRequestTTY=no");
    420 
    421 	fflag = Tflag = tflag = 0;
    422 	while ((ch = getopt(argc, argv,
    423 	    "12346ABCTdfpqrtvF:J:P:S:c:i:l:o:")) != -1) {
    424 		switch (ch) {
    425 		/* User-visible flags. */
    426 		case '1':
    427 			fatal("SSH protocol v.1 is no longer supported");
    428 			break;
    429 		case '2':
    430 			/* Ignored */
    431 			break;
    432 		case 'A':
    433 		case '4':
    434 		case '6':
    435 		case 'C':
    436 			addargs(&args, "-%c", ch);
    437 			addargs(&remote_remote_args, "-%c", ch);
    438 			break;
    439 		case '3':
    440 			throughlocal = 1;
    441 			break;
    442 		case 'o':
    443 		case 'c':
    444 		case 'i':
    445 		case 'F':
    446 		case 'J':
    447 			addargs(&remote_remote_args, "-%c", ch);
    448 			addargs(&remote_remote_args, "%s", optarg);
    449 			addargs(&args, "-%c", ch);
    450 			addargs(&args, "%s", optarg);
    451 			break;
    452 		case 'P':
    453 			sshport = a2port(optarg);
    454 			if (sshport <= 0)
    455 				fatal("bad port \"%s\"\n", optarg);
    456 			break;
    457 		case 'B':
    458 			addargs(&remote_remote_args, "-oBatchmode=yes");
    459 			addargs(&args, "-oBatchmode=yes");
    460 			break;
    461 		case 'l':
    462 			limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
    463 			    &errstr);
    464 			if (errstr != NULL)
    465 				usage();
    466 			limit_kbps *= 1024; /* kbps */
    467 			bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN);
    468 			break;
    469 		case 'p':
    470 			pflag = 1;
    471 			break;
    472 		case 'r':
    473 			iamrecursive = 1;
    474 			break;
    475 		case 'S':
    476 			ssh_program = xstrdup(optarg);
    477 			break;
    478 		case 'v':
    479 			addargs(&args, "-v");
    480 			addargs(&remote_remote_args, "-v");
    481 			verbose_mode = 1;
    482 			break;
    483 		case 'q':
    484 			addargs(&args, "-q");
    485 			addargs(&remote_remote_args, "-q");
    486 			showprogress = 0;
    487 			break;
    488 
    489 		/* Server options. */
    490 		case 'd':
    491 			targetshouldbedirectory = 1;
    492 			break;
    493 		case 'f':	/* "from" */
    494 			iamremote = 1;
    495 			fflag = 1;
    496 			break;
    497 		case 't':	/* "to" */
    498 			iamremote = 1;
    499 			tflag = 1;
    500 			break;
    501 		case 'T':
    502 			Tflag = 1;
    503 			break;
    504 		default:
    505 			usage();
    506 		}
    507 	}
    508 	argc -= optind;
    509 	argv += optind;
    510 
    511 	/* Do this last because we want the user to be able to override it */
    512 	addargs(&args, "-oForwardAgent=no");
    513 
    514 	if ((pwd = getpwuid(userid = getuid())) == NULL)
    515 		fatal("unknown user %u", (u_int) userid);
    516 
    517 	if (!isatty(STDOUT_FILENO))
    518 		showprogress = 0;
    519 
    520 	if (pflag) {
    521 		/* Cannot pledge: -p allows setuid/setgid files... */
    522 	} else {
    523 #ifdef __OpenBSD__
    524 		if (pledge("stdio rpath wpath cpath fattr tty proc exec",
    525 		    NULL) == -1) {
    526 			perror("pledge");
    527 			exit(1);
    528 		}
    529 #endif
    530 	}
    531 
    532 	remin = STDIN_FILENO;
    533 	remout = STDOUT_FILENO;
    534 
    535 	if (fflag) {
    536 		/* Follow "protocol", send data. */
    537 		(void) response();
    538 		source(argc, argv);
    539 		exit(errs != 0);
    540 	}
    541 	if (tflag) {
    542 		/* Receive data. */
    543 		sink(argc, argv, NULL);
    544 		exit(errs != 0);
    545 	}
    546 	if (argc < 2)
    547 		usage();
    548 	if (argc > 2)
    549 		targetshouldbedirectory = 1;
    550 
    551 	remin = remout = -1;
    552 	do_cmd_pid = -1;
    553 	/* Command to be executed on remote system using "ssh". */
    554 	(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
    555 	    verbose_mode ? " -v" : "",
    556 	    iamrecursive ? " -r" : "", pflag ? " -p" : "",
    557 	    targetshouldbedirectory ? " -d" : "");
    558 
    559 	(void) ssh_signal(SIGPIPE, lostconn);
    560 
    561 	if (colon(argv[argc - 1]))	/* Dest is remote host. */
    562 		toremote(argc, argv);
    563 	else {
    564 		if (targetshouldbedirectory)
    565 			verifydir(argv[argc - 1]);
    566 		tolocal(argc, argv);	/* Dest is local host. */
    567 	}
    568 	/*
    569 	 * Finally check the exit status of the ssh process, if one was forked
    570 	 * and no error has occurred yet
    571 	 */
    572 	if (do_cmd_pid != -1 && errs == 0) {
    573 		if (remin != -1)
    574 		    (void) close(remin);
    575 		if (remout != -1)
    576 		    (void) close(remout);
    577 		if (waitpid(do_cmd_pid, &status, 0) == -1)
    578 			errs = 1;
    579 		else {
    580 			if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
    581 				errs = 1;
    582 		}
    583 	}
    584 	exit(errs != 0);
    585 }
    586 
    587 /* Callback from atomicio6 to update progress meter and limit bandwidth */
    588 static int
    589 scpio(void *_cnt, size_t s)
    590 {
    591 	off_t *cnt = (off_t *)_cnt;
    592 
    593 	*cnt += s;
    594 	refresh_progress_meter(0);
    595 	if (limit_kbps > 0)
    596 		bandwidth_limit(&bwlimit, s);
    597 	return 0;
    598 }
    599 
    600 static int
    601 do_times(int fd, int verb, const struct stat *sb)
    602 {
    603 	/* strlen(2^64) == 20; strlen(10^6) == 7 */
    604 	char buf[(20 + 7 + 2) * 2 + 2];
    605 
    606 	(void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
    607 	    (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
    608 	    (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
    609 	if (verb) {
    610 		fprintf(stderr, "File mtime %lld atime %lld\n",
    611 		    (long long)sb->st_mtime, (long long)sb->st_atime);
    612 		fprintf(stderr, "Sending file timestamps: %s", buf);
    613 	}
    614 	(void) atomicio(vwrite, fd, buf, strlen(buf));
    615 	return (response());
    616 }
    617 
    618 static int
    619 parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp,
    620     char **pathp)
    621 {
    622 	int r;
    623 
    624 	r = parse_uri("scp", uri, userp, hostp, portp, pathp);
    625 	if (r == 0 && *pathp == NULL)
    626 		*pathp = xstrdup(".");
    627 	return r;
    628 }
    629 
    630 /* Appends a string to an array; returns 0 on success, -1 on alloc failure */
    631 static int
    632 append(char *cp, char ***ap, size_t *np)
    633 {
    634 	char **tmp;
    635 
    636 	if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL)
    637 		return -1;
    638 	tmp[(*np)] = cp;
    639 	(*np)++;
    640 	*ap = tmp;
    641 	return 0;
    642 }
    643 
    644 /*
    645  * Finds the start and end of the first brace pair in the pattern.
    646  * returns 0 on success or -1 for invalid patterns.
    647  */
    648 static int
    649 find_brace(const char *pattern, int *startp, int *endp)
    650 {
    651 	int i;
    652 	int in_bracket, brace_level;
    653 
    654 	*startp = *endp = -1;
    655 	in_bracket = brace_level = 0;
    656 	for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) {
    657 		switch (pattern[i]) {
    658 		case '\\':
    659 			/* skip next character */
    660 			if (pattern[i + 1] != '\0')
    661 				i++;
    662 			break;
    663 		case '[':
    664 			in_bracket = 1;
    665 			break;
    666 		case ']':
    667 			in_bracket = 0;
    668 			break;
    669 		case '{':
    670 			if (in_bracket)
    671 				break;
    672 			if (pattern[i + 1] == '}') {
    673 				/* Protect a single {}, for find(1), like csh */
    674 				i++; /* skip */
    675 				break;
    676 			}
    677 			if (*startp == -1)
    678 				*startp = i;
    679 			brace_level++;
    680 			break;
    681 		case '}':
    682 			if (in_bracket)
    683 				break;
    684 			if (*startp < 0) {
    685 				/* Unbalanced brace */
    686 				return -1;
    687 			}
    688 			if (--brace_level <= 0)
    689 				*endp = i;
    690 			break;
    691 		}
    692 	}
    693 	/* unbalanced brackets/braces */
    694 	if (*endp < 0 && (*startp >= 0 || in_bracket))
    695 		return -1;
    696 	return 0;
    697 }
    698 
    699 /*
    700  * Assembles and records a successfully-expanded pattern, returns -1 on
    701  * alloc failure.
    702  */
    703 static int
    704 emit_expansion(const char *pattern, int brace_start, int brace_end,
    705     int sel_start, int sel_end, char ***patternsp, size_t *npatternsp)
    706 {
    707 	char *cp;
    708 	int o = 0, tail_len = strlen(pattern + brace_end + 1);
    709 
    710 	if ((cp = malloc(brace_start + (sel_end - sel_start) +
    711 	    tail_len + 1)) == NULL)
    712 		return -1;
    713 
    714 	/* Pattern before initial brace */
    715 	if (brace_start > 0) {
    716 		memcpy(cp, pattern, brace_start);
    717 		o = brace_start;
    718 	}
    719 	/* Current braced selection */
    720 	if (sel_end - sel_start > 0) {
    721 		memcpy(cp + o, pattern + sel_start,
    722 		    sel_end - sel_start);
    723 		o += sel_end - sel_start;
    724 	}
    725 	/* Remainder of pattern after closing brace */
    726 	if (tail_len > 0) {
    727 		memcpy(cp + o, pattern + brace_end + 1, tail_len);
    728 		o += tail_len;
    729 	}
    730 	cp[o] = '\0';
    731 	if (append(cp, patternsp, npatternsp) != 0) {
    732 		free(cp);
    733 		return -1;
    734 	}
    735 	return 0;
    736 }
    737 
    738 /*
    739  * Expand the first encountered brace in pattern, appending the expanded
    740  * patterns it yielded to the *patternsp array.
    741  *
    742  * Returns 0 on success or -1 on allocation failure.
    743  *
    744  * Signals whether expansion was performed via *expanded and whether
    745  * pattern was invalid via *invalid.
    746  */
    747 static int
    748 brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp,
    749     int *expanded, int *invalid)
    750 {
    751 	int i;
    752 	int in_bracket, brace_start, brace_end, brace_level;
    753 	int sel_start, sel_end;
    754 
    755 	*invalid = *expanded = 0;
    756 
    757 	if (find_brace(pattern, &brace_start, &brace_end) != 0) {
    758 		*invalid = 1;
    759 		return 0;
    760 	} else if (brace_start == -1)
    761 		return 0;
    762 
    763 	in_bracket = brace_level = 0;
    764 	for (i = sel_start = brace_start + 1; i < brace_end; i++) {
    765 		switch (pattern[i]) {
    766 		case '{':
    767 			if (in_bracket)
    768 				break;
    769 			brace_level++;
    770 			break;
    771 		case '}':
    772 			if (in_bracket)
    773 				break;
    774 			brace_level--;
    775 			break;
    776 		case '[':
    777 			in_bracket = 1;
    778 			break;
    779 		case ']':
    780 			in_bracket = 0;
    781 			break;
    782 		case '\\':
    783 			if (i < brace_end - 1)
    784 				i++; /* skip */
    785 			break;
    786 		}
    787 		if (pattern[i] == ',' || i == brace_end - 1) {
    788 			if (in_bracket || brace_level > 0)
    789 				continue;
    790 			/* End of a selection, emit an expanded pattern */
    791 
    792 			/* Adjust end index for last selection */
    793 			sel_end = (i == brace_end - 1) ? brace_end : i;
    794 			if (emit_expansion(pattern, brace_start, brace_end,
    795 			    sel_start, sel_end, patternsp, npatternsp) != 0)
    796 				return -1;
    797 			/* move on to the next selection */
    798 			sel_start = i + 1;
    799 			continue;
    800 		}
    801 	}
    802 	if (in_bracket || brace_level > 0) {
    803 		*invalid = 1;
    804 		return 0;
    805 	}
    806 	/* success */
    807 	*expanded = 1;
    808 	return 0;
    809 }
    810 
    811 /* Expand braces from pattern. Returns 0 on success, -1 on failure */
    812 static int
    813 brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
    814 {
    815 	char *cp, *cp2, **active = NULL, **done = NULL;
    816 	size_t i, nactive = 0, ndone = 0;
    817 	int ret = -1, invalid = 0, expanded = 0;
    818 
    819 	*patternsp = NULL;
    820 	*npatternsp = 0;
    821 
    822 	/* Start the worklist with the original pattern */
    823 	if ((cp = strdup(pattern)) == NULL)
    824 		return -1;
    825 	if (append(cp, &active, &nactive) != 0) {
    826 		free(cp);
    827 		return -1;
    828 	}
    829 	while (nactive > 0) {
    830 		cp = active[nactive - 1];
    831 		nactive--;
    832 		if (brace_expand_one(cp, &active, &nactive,
    833 		    &expanded, &invalid) == -1) {
    834 			free(cp);
    835 			goto fail;
    836 		}
    837 		if (invalid)
    838 			fatal_f("invalid brace pattern \"%s\"", cp);
    839 		if (expanded) {
    840 			/*
    841 			 * Current entry expanded to new entries on the
    842 			 * active list; discard the progenitor pattern.
    843 			 */
    844 			free(cp);
    845 			continue;
    846 		}
    847 		/*
    848 		 * Pattern did not expand; append the finename component to
    849 		 * the completed list
    850 		 */
    851 		if ((cp2 = strrchr(cp, '/')) != NULL)
    852 			*cp2++ = '\0';
    853 		else
    854 			cp2 = cp;
    855 		if (append(xstrdup(cp2), &done, &ndone) != 0) {
    856 			free(cp);
    857 			goto fail;
    858 		}
    859 		free(cp);
    860 	}
    861 	/* success */
    862 	*patternsp = done;
    863 	*npatternsp = ndone;
    864 	done = NULL;
    865 	ndone = 0;
    866 	ret = 0;
    867  fail:
    868 	for (i = 0; i < nactive; i++)
    869 		free(active[i]);
    870 	free(active);
    871 	for (i = 0; i < ndone; i++)
    872 		free(done[i]);
    873 	free(done);
    874 	return ret;
    875 }
    876 
    877 void
    878 toremote(int argc, char **argv)
    879 {
    880 	char *suser = NULL, *host = NULL, *src = NULL;
    881 	char *bp, *tuser, *thost, *targ;
    882 	int sport = -1, tport = -1;
    883 	arglist alist;
    884 	int i, r;
    885 	u_int j;
    886 
    887 	memset(&alist, '\0', sizeof(alist));
    888 	alist.list = NULL;
    889 
    890 	/* Parse target */
    891 	r = parse_scp_uri(argv[argc - 1], &tuser, &thost, &tport, &targ);
    892 	if (r == -1) {
    893 		fmprintf(stderr, "%s: invalid uri\n", argv[argc - 1]);
    894 		++errs;
    895 		goto out;
    896 	}
    897 	if (r != 0) {
    898 		if (parse_user_host_path(argv[argc - 1], &tuser, &thost,
    899 		    &targ) == -1) {
    900 			fmprintf(stderr, "%s: invalid target\n", argv[argc - 1]);
    901 			++errs;
    902 			goto out;
    903 		}
    904 	}
    905 	if (tuser != NULL && !okname(tuser)) {
    906 		++errs;
    907 		goto out;
    908 	}
    909 
    910 	/* Parse source files */
    911 	for (i = 0; i < argc - 1; i++) {
    912 		free(suser);
    913 		free(host);
    914 		free(src);
    915 		r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
    916 		if (r == -1) {
    917 			fmprintf(stderr, "%s: invalid uri\n", argv[i]);
    918 			++errs;
    919 			continue;
    920 		}
    921 		if (r != 0) {
    922 			parse_user_host_path(argv[i], &suser, &host, &src);
    923 		}
    924 		if (suser != NULL && !okname(suser)) {
    925 			++errs;
    926 			continue;
    927 		}
    928 		if (host && throughlocal) {	/* extended remote to remote */
    929 			xasprintf(&bp, "%s -f %s%s", cmd,
    930 			    *src == '-' ? "-- " : "", src);
    931 			if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0)
    932 				exit(1);
    933 			free(bp);
    934 			xasprintf(&bp, "%s -t %s%s", cmd,
    935 			    *targ == '-' ? "-- " : "", targ);
    936 			if (do_cmd2(thost, tuser, tport, bp, remin, remout) < 0)
    937 				exit(1);
    938 			free(bp);
    939 			(void) close(remin);
    940 			(void) close(remout);
    941 			remin = remout = -1;
    942 		} else if (host) {	/* standard remote to remote */
    943 			if (tport != -1 && tport != SSH_DEFAULT_PORT) {
    944 				/* This would require the remote support URIs */
    945 				fatal("target port not supported with two "
    946 				    "remote hosts without the -3 option");
    947 			}
    948 
    949 			freeargs(&alist);
    950 			addargs(&alist, "%s", ssh_program);
    951 			addargs(&alist, "-x");
    952 			addargs(&alist, "-oClearAllForwardings=yes");
    953 			addargs(&alist, "-n");
    954 			for (j = 0; j < remote_remote_args.num; j++) {
    955 				addargs(&alist, "%s",
    956 				    remote_remote_args.list[j]);
    957 			}
    958 			if (sport != -1) {
    959 				addargs(&alist, "-p");
    960 				addargs(&alist, "%d", sport);
    961 			}
    962 			if (suser) {
    963 				addargs(&alist, "-l");
    964 				addargs(&alist, "%s", suser);
    965 			}
    966 			addargs(&alist, "--");
    967 			addargs(&alist, "%s", host);
    968 			addargs(&alist, "%s", cmd);
    969 			addargs(&alist, "%s", src);
    970 			addargs(&alist, "%s%s%s:%s",
    971 			    tuser ? tuser : "", tuser ? "@" : "",
    972 			    thost, targ);
    973 			if (do_local_cmd(&alist) != 0)
    974 				errs = 1;
    975 		} else {	/* local to remote */
    976 			if (remin == -1) {
    977 				xasprintf(&bp, "%s -t %s%s", cmd,
    978 				    *targ == '-' ? "-- " : "", targ);
    979 				if (do_cmd(thost, tuser, tport, bp, &remin,
    980 				    &remout) < 0)
    981 					exit(1);
    982 				if (response() < 0)
    983 					exit(1);
    984 				free(bp);
    985 			}
    986 			source(1, argv + i);
    987 		}
    988 	}
    989 out:
    990 	free(tuser);
    991 	free(thost);
    992 	free(targ);
    993 	free(suser);
    994 	free(host);
    995 	free(src);
    996 }
    997 
    998 static void
    999 tolocal(int argc, char **argv)
   1000 {
   1001 	char *bp, *host = NULL, *suser = NULL, *src = NULL;
   1002 	arglist alist;
   1003 	int i, r, sport = -1;
   1004 
   1005 	memset(&alist, '\0', sizeof(alist));
   1006 	alist.list = NULL;
   1007 
   1008 	for (i = 0; i < argc - 1; i++) {
   1009 		free(suser);
   1010 		free(host);
   1011 		free(src);
   1012 		r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
   1013 		if (r == -1) {
   1014 			fmprintf(stderr, "%s: invalid uri\n", argv[i]);
   1015 			++errs;
   1016 			continue;
   1017 		}
   1018 		if (r != 0)
   1019 			parse_user_host_path(argv[i], &suser, &host, &src);
   1020 		if (suser != NULL && !okname(suser)) {
   1021 			++errs;
   1022 			continue;
   1023 		}
   1024 		if (!host) {	/* Local to local. */
   1025 			freeargs(&alist);
   1026 			addargs(&alist, "%s", _PATH_CP);
   1027 			if (iamrecursive)
   1028 				addargs(&alist, "-r");
   1029 			if (pflag)
   1030 				addargs(&alist, "-p");
   1031 			addargs(&alist, "--");
   1032 			addargs(&alist, "%s", argv[i]);
   1033 			addargs(&alist, "%s", argv[argc-1]);
   1034 			if (do_local_cmd(&alist))
   1035 				++errs;
   1036 			continue;
   1037 		}
   1038 		/* Remote to local. */
   1039 		xasprintf(&bp, "%s -f %s%s",
   1040 		    cmd, *src == '-' ? "-- " : "", src);
   1041 		if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0) {
   1042 			free(bp);
   1043 			++errs;
   1044 			continue;
   1045 		}
   1046 		free(bp);
   1047 		sink(1, argv + argc - 1, src);
   1048 		(void) close(remin);
   1049 		remin = remout = -1;
   1050 	}
   1051 	free(suser);
   1052 	free(host);
   1053 	free(src);
   1054 }
   1055 
   1056 void
   1057 source(int argc, char **argv)
   1058 {
   1059 	struct stat stb;
   1060 	static BUF buffer;
   1061 	BUF *bp;
   1062 	off_t i, statbytes;
   1063 	size_t amt, nr;
   1064 	int fd = -1, haderr, indx;
   1065 	char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX];
   1066 	int len;
   1067 
   1068 	for (indx = 0; indx < argc; ++indx) {
   1069 		fd = -1;
   1070 		name = argv[indx];
   1071 		statbytes = 0;
   1072 		len = strlen(name);
   1073 		while (len > 1 && name[len-1] == '/')
   1074 			name[--len] = '\0';
   1075 		if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) == -1)
   1076 			goto syserr;
   1077 		if (strchr(name, '\n') != NULL) {
   1078 			strvisx(encname, name, len, VIS_NL);
   1079 			name = encname;
   1080 		}
   1081 		if (fstat(fd, &stb) == -1) {
   1082 syserr:			run_err("%s: %s", name, strerror(errno));
   1083 			goto next;
   1084 		}
   1085 		if (stb.st_size < 0) {
   1086 			run_err("%s: %s", name, "Negative file size");
   1087 			goto next;
   1088 		}
   1089 		unset_nonblock(fd);
   1090 		switch (stb.st_mode & S_IFMT) {
   1091 		case S_IFREG:
   1092 			break;
   1093 		case S_IFDIR:
   1094 			if (iamrecursive) {
   1095 				rsource(name, &stb);
   1096 				goto next;
   1097 			}
   1098 			/* FALLTHROUGH */
   1099 		default:
   1100 			run_err("%s: not a regular file", name);
   1101 			goto next;
   1102 		}
   1103 		if ((last = strrchr(name, '/')) == NULL)
   1104 			last = name;
   1105 		else
   1106 			++last;
   1107 		curfile = last;
   1108 		if (pflag) {
   1109 			if (do_times(remout, verbose_mode, &stb) < 0)
   1110 				goto next;
   1111 		}
   1112 #define	FILEMODEMASK	(S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
   1113 		snprintf(buf, sizeof buf, "C%04o %lld %s\n",
   1114 		    (u_int) (stb.st_mode & FILEMODEMASK),
   1115 		    (long long)stb.st_size, last);
   1116 		if (verbose_mode)
   1117 			fmprintf(stderr, "Sending file modes: %s", buf);
   1118 		(void) atomicio(vwrite, remout, buf, strlen(buf));
   1119 		if (response() < 0)
   1120 			goto next;
   1121 		if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) {
   1122 next:			if (fd != -1) {
   1123 				(void) close(fd);
   1124 				fd = -1;
   1125 			}
   1126 			continue;
   1127 		}
   1128 		if (showprogress)
   1129 			start_progress_meter(curfile, stb.st_size, &statbytes);
   1130 		set_nonblock(remout);
   1131 		for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
   1132 			amt = bp->cnt;
   1133 			if (i + (off_t)amt > stb.st_size)
   1134 				amt = stb.st_size - i;
   1135 			if (!haderr) {
   1136 				if ((nr = atomicio(read, fd,
   1137 				    bp->buf, amt)) != amt) {
   1138 					haderr = errno;
   1139 					memset(bp->buf + nr, 0, amt - nr);
   1140 				}
   1141 			}
   1142 			/* Keep writing after error to retain sync */
   1143 			if (haderr) {
   1144 				(void)atomicio(vwrite, remout, bp->buf, amt);
   1145 				memset(bp->buf, 0, amt);
   1146 				continue;
   1147 			}
   1148 			if (atomicio6(vwrite, remout, bp->buf, amt, scpio,
   1149 			    &statbytes) != amt)
   1150 				haderr = errno;
   1151 		}
   1152 		unset_nonblock(remout);
   1153 
   1154 		if (fd != -1) {
   1155 			if (close(fd) == -1 && !haderr)
   1156 				haderr = errno;
   1157 			fd = -1;
   1158 		}
   1159 		if (!haderr)
   1160 			(void) atomicio(vwrite, remout, empty, 1);
   1161 		else
   1162 			run_err("%s: %s", name, strerror(haderr));
   1163 		(void) response();
   1164 		if (showprogress)
   1165 			stop_progress_meter();
   1166 	}
   1167 }
   1168 
   1169 void
   1170 rsource(char *name, struct stat *statp)
   1171 {
   1172 	DIR *dirp;
   1173 	struct dirent *dp;
   1174 	char *last, *vect[1], path[PATH_MAX + 20];
   1175 
   1176 	if (!(dirp = opendir(name))) {
   1177 		run_err("%s: %s", name, strerror(errno));
   1178 		return;
   1179 	}
   1180 	last = strrchr(name, '/');
   1181 	if (last == NULL)
   1182 		last = name;
   1183 	else
   1184 		last++;
   1185 	if (pflag) {
   1186 		if (do_times(remout, verbose_mode, statp) < 0) {
   1187 			closedir(dirp);
   1188 			return;
   1189 		}
   1190 	}
   1191 	(void) snprintf(path, sizeof path, "D%04o %d %.1024s\n",
   1192 	    (u_int) (statp->st_mode & FILEMODEMASK), 0, last);
   1193 	if (verbose_mode)
   1194 		fmprintf(stderr, "Entering directory: %s", path);
   1195 	(void) atomicio(vwrite, remout, path, strlen(path));
   1196 	if (response() < 0) {
   1197 		closedir(dirp);
   1198 		return;
   1199 	}
   1200 	while ((dp = readdir(dirp)) != NULL) {
   1201 		if (dp->d_ino == 0)
   1202 			continue;
   1203 		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
   1204 			continue;
   1205 		if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) {
   1206 			run_err("%s/%s: name too long", name, dp->d_name);
   1207 			continue;
   1208 		}
   1209 		(void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name);
   1210 		vect[0] = path;
   1211 		source(1, vect);
   1212 	}
   1213 	(void) closedir(dirp);
   1214 	(void) atomicio(vwrite, remout, __UNCONST("E\n"), 2);
   1215 	(void) response();
   1216 }
   1217 
   1218 #define TYPE_OVERFLOW(type, val) \
   1219 	((sizeof(type) == 4 && (val) > INT32_MAX) || \
   1220 	 (sizeof(type) == 8 && (val) > INT64_MAX) || \
   1221 	 (sizeof(type) != 4 && sizeof(type) != 8))
   1222 
   1223 void
   1224 sink(int argc, char **argv, const char *src)
   1225 {
   1226 	static BUF buffer;
   1227 	struct stat stb;
   1228 	BUF *bp;
   1229 	off_t i;
   1230 	size_t j, count;
   1231 	int amt, exists, first, ofd;
   1232 	mode_t mode, omode, mask;
   1233 	off_t size, statbytes;
   1234 	unsigned long long ull;
   1235 	int setimes, targisdir, wrerr;
   1236 	char ch, *cp, *np, *targ, *vect[1], buf[2048], visbuf[2048];
   1237 	const char *why;
   1238 	char **patterns = NULL;
   1239 	size_t n, npatterns = 0;
   1240 	struct timeval tv[2];
   1241 
   1242 #define	atime	tv[0]
   1243 #define	mtime	tv[1]
   1244 #define	SCREWUP(str)	{ why = str; goto screwup; }
   1245 
   1246 	if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
   1247 		SCREWUP("Unexpected off_t/time_t size");
   1248 
   1249 	setimes = targisdir = 0;
   1250 	mask = umask(0);
   1251 	if (!pflag)
   1252 		(void) umask(mask);
   1253 	if (argc != 1) {
   1254 		run_err("ambiguous target");
   1255 		exit(1);
   1256 	}
   1257 	targ = *argv;
   1258 	if (targetshouldbedirectory)
   1259 		verifydir(targ);
   1260 
   1261 	(void) atomicio(vwrite, remout, empty, 1);
   1262 	if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
   1263 		targisdir = 1;
   1264 	if (src != NULL && !iamrecursive && !Tflag) {
   1265 		/*
   1266 		 * Prepare to try to restrict incoming filenames to match
   1267 		 * the requested destination file glob.
   1268 		 */
   1269 		if (brace_expand(src, &patterns, &npatterns) != 0)
   1270 			fatal_f("could not expand pattern");
   1271 	}
   1272 	for (first = 1;; first = 0) {
   1273 		cp = buf;
   1274 		if (atomicio(read, remin, cp, 1) != 1)
   1275 			goto done;
   1276 		if (*cp++ == '\n')
   1277 			SCREWUP("unexpected <newline>");
   1278 		do {
   1279 			if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
   1280 				SCREWUP("lost connection");
   1281 			*cp++ = ch;
   1282 		} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
   1283 		*cp = 0;
   1284 		if (verbose_mode)
   1285 			fmprintf(stderr, "Sink: %s", buf);
   1286 
   1287 		if (buf[0] == '\01' || buf[0] == '\02') {
   1288 			if (iamremote == 0) {
   1289 				(void) snmprintf(visbuf, sizeof(visbuf),
   1290 				    NULL, "%s", buf + 1);
   1291 				(void) atomicio(vwrite, STDERR_FILENO,
   1292 				    visbuf, strlen(visbuf));
   1293 			}
   1294 			if (buf[0] == '\02')
   1295 				exit(1);
   1296 			++errs;
   1297 			continue;
   1298 		}
   1299 		if (buf[0] == 'E') {
   1300 			(void) atomicio(vwrite, remout, __UNCONST(""), 1);
   1301 			goto done;
   1302 		}
   1303 		if (ch == '\n')
   1304 			*--cp = 0;
   1305 
   1306 		cp = buf;
   1307 		if (*cp == 'T') {
   1308 			setimes++;
   1309 			cp++;
   1310 			if (!isdigit((unsigned char)*cp))
   1311 				SCREWUP("mtime.sec not present");
   1312 			ull = strtoull(cp, &cp, 10);
   1313 			if (!cp || *cp++ != ' ')
   1314 				SCREWUP("mtime.sec not delimited");
   1315 			if (TYPE_OVERFLOW(time_t, ull))
   1316 				setimes = 0;	/* out of range */
   1317 			mtime.tv_sec = ull;
   1318 			mtime.tv_usec = strtol(cp, &cp, 10);
   1319 			if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
   1320 			    mtime.tv_usec > 999999)
   1321 				SCREWUP("mtime.usec not delimited");
   1322 			if (!isdigit((unsigned char)*cp))
   1323 				SCREWUP("atime.sec not present");
   1324 			ull = strtoull(cp, &cp, 10);
   1325 			if (!cp || *cp++ != ' ')
   1326 				SCREWUP("atime.sec not delimited");
   1327 			if (TYPE_OVERFLOW(time_t, ull))
   1328 				setimes = 0;	/* out of range */
   1329 			atime.tv_sec = ull;
   1330 			atime.tv_usec = strtol(cp, &cp, 10);
   1331 			if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
   1332 			    atime.tv_usec > 999999)
   1333 				SCREWUP("atime.usec not delimited");
   1334 			(void) atomicio(vwrite, remout, empty, 1);
   1335 			continue;
   1336 		}
   1337 		if (*cp != 'C' && *cp != 'D') {
   1338 			/*
   1339 			 * Check for the case "rcp remote:foo\* local:bar".
   1340 			 * In this case, the line "No match." can be returned
   1341 			 * by the shell before the rcp command on the remote is
   1342 			 * executed so the ^Aerror_message convention isn't
   1343 			 * followed.
   1344 			 */
   1345 			if (first) {
   1346 				run_err("%s", cp);
   1347 				exit(1);
   1348 			}
   1349 			SCREWUP("expected control record");
   1350 		}
   1351 		mode = 0;
   1352 		for (++cp; cp < buf + 5; cp++) {
   1353 			if (*cp < '0' || *cp > '7')
   1354 				SCREWUP("bad mode");
   1355 			mode = (mode << 3) | (*cp - '0');
   1356 		}
   1357 		if (!pflag)
   1358 			mode &= ~mask;
   1359 		if (*cp++ != ' ')
   1360 			SCREWUP("mode not delimited");
   1361 
   1362 		if (!isdigit((unsigned char)*cp))
   1363 			SCREWUP("size not present");
   1364 		ull = strtoull(cp, &cp, 10);
   1365 		if (!cp || *cp++ != ' ')
   1366 			SCREWUP("size not delimited");
   1367 		if (TYPE_OVERFLOW(off_t, ull))
   1368 			SCREWUP("size out of range");
   1369 		size = (off_t)ull;
   1370 
   1371 		if (*cp == '\0' || strchr(cp, '/') != NULL ||
   1372 		    strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) {
   1373 			run_err("error: unexpected filename: %s", cp);
   1374 			exit(1);
   1375 		}
   1376 		if (npatterns > 0) {
   1377 			for (n = 0; n < npatterns; n++) {
   1378 				if (fnmatch(patterns[n], cp, 0) == 0)
   1379 					break;
   1380 			}
   1381 			if (n >= npatterns)
   1382 				SCREWUP("filename does not match request");
   1383 		}
   1384 		if (targisdir) {
   1385 			static char *namebuf;
   1386 			static size_t cursize;
   1387 			size_t need;
   1388 
   1389 			need = strlen(targ) + strlen(cp) + 250;
   1390 			if (need > cursize) {
   1391 				free(namebuf);
   1392 				namebuf = xmalloc(need);
   1393 				cursize = need;
   1394 			}
   1395 			(void) snprintf(namebuf, need, "%s%s%s", targ,
   1396 			    strcmp(targ, "/") ? "/" : "", cp);
   1397 			np = namebuf;
   1398 		} else
   1399 			np = targ;
   1400 		curfile = cp;
   1401 		exists = stat(np, &stb) == 0;
   1402 		if (buf[0] == 'D') {
   1403 			int mod_flag = pflag;
   1404 			if (!iamrecursive)
   1405 				SCREWUP("received directory without -r");
   1406 			if (exists) {
   1407 				if (!S_ISDIR(stb.st_mode)) {
   1408 					errno = ENOTDIR;
   1409 					goto bad;
   1410 				}
   1411 				if (pflag)
   1412 					(void) chmod(np, mode);
   1413 			} else {
   1414 				/* Handle copying from a read-only directory */
   1415 				mod_flag = 1;
   1416 				if (mkdir(np, mode | S_IRWXU) == -1)
   1417 					goto bad;
   1418 			}
   1419 			vect[0] = xstrdup(np);
   1420 			sink(1, vect, src);
   1421 			if (setimes) {
   1422 				setimes = 0;
   1423 				(void) utimes(vect[0], tv);
   1424 			}
   1425 			if (mod_flag)
   1426 				(void) chmod(vect[0], mode);
   1427 			free(vect[0]);
   1428 			continue;
   1429 		}
   1430 		omode = mode;
   1431 		mode |= S_IWUSR;
   1432 		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
   1433 bad:			run_err("%s: %s", np, strerror(errno));
   1434 			continue;
   1435 		}
   1436 		(void) atomicio(vwrite, remout, empty, 1);
   1437 		if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) {
   1438 			(void) close(ofd);
   1439 			continue;
   1440 		}
   1441 		cp = bp->buf;
   1442 		wrerr = 0;
   1443 
   1444 		/*
   1445 		 * NB. do not use run_err() unless immediately followed by
   1446 		 * exit() below as it may send a spurious reply that might
   1447 		 * desyncronise us from the peer. Use note_err() instead.
   1448 		 */
   1449 		statbytes = 0;
   1450 		if (showprogress)
   1451 			start_progress_meter(curfile, size, &statbytes);
   1452 		set_nonblock(remin);
   1453 		for (count = i = 0; i < size; i += bp->cnt) {
   1454 			amt = bp->cnt;
   1455 			if (i + amt > size)
   1456 				amt = size - i;
   1457 			count += amt;
   1458 			do {
   1459 				j = atomicio6(read, remin, cp, amt,
   1460 				    scpio, &statbytes);
   1461 				if (j == 0) {
   1462 					run_err("%s", j != EPIPE ?
   1463 					    strerror(errno) :
   1464 					    "dropped connection");
   1465 					exit(1);
   1466 				}
   1467 				amt -= j;
   1468 				cp += j;
   1469 			} while (amt > 0);
   1470 
   1471 			if (count == bp->cnt) {
   1472 				/* Keep reading so we stay sync'd up. */
   1473 				if (!wrerr) {
   1474 					if (atomicio(vwrite, ofd, bp->buf,
   1475 					    count) != count) {
   1476 						note_err("%s: %s", np,
   1477 						    strerror(errno));
   1478 						wrerr = 1;
   1479 					}
   1480 				}
   1481 				count = 0;
   1482 				cp = bp->buf;
   1483 			}
   1484 		}
   1485 		unset_nonblock(remin);
   1486 		if (count != 0 && !wrerr &&
   1487 		    atomicio(vwrite, ofd, bp->buf, count) != count) {
   1488 			note_err("%s: %s", np, strerror(errno));
   1489 			wrerr = 1;
   1490 		}
   1491 		if (!wrerr && (!exists || S_ISREG(stb.st_mode)) &&
   1492 		    ftruncate(ofd, size) != 0)
   1493 			note_err("%s: truncate: %s", np, strerror(errno));
   1494 		if (pflag) {
   1495 			if (exists || omode != mode)
   1496 				if (fchmod(ofd, omode)) {
   1497 					note_err("%s: set mode: %s",
   1498 					    np, strerror(errno));
   1499 				}
   1500 		} else {
   1501 			if (!exists && omode != mode)
   1502 				if (fchmod(ofd, omode & ~mask)) {
   1503 					note_err("%s: set mode: %s",
   1504 					    np, strerror(errno));
   1505 				}
   1506 		}
   1507 		if (close(ofd) == -1)
   1508 			note_err("%s: close: %s", np, strerror(errno));
   1509 		(void) response();
   1510 		if (showprogress)
   1511 			stop_progress_meter();
   1512 		if (setimes && !wrerr) {
   1513 			setimes = 0;
   1514 			if (utimes(np, tv) == -1) {
   1515 				note_err("%s: set times: %s",
   1516 				    np, strerror(errno));
   1517 			}
   1518 		}
   1519 		/* If no error was noted then signal success for this file */
   1520 		if (note_err(NULL) == 0)
   1521 			(void) atomicio(vwrite, remout, __UNCONST(""), 1);
   1522 	}
   1523 done:
   1524 	for (n = 0; n < npatterns; n++)
   1525 		free(patterns[n]);
   1526 	free(patterns);
   1527 	return;
   1528 screwup:
   1529 	for (n = 0; n < npatterns; n++)
   1530 		free(patterns[n]);
   1531 	free(patterns);
   1532 	run_err("protocol error: %s", why);
   1533 	exit(1);
   1534 }
   1535 
   1536 int
   1537 response(void)
   1538 {
   1539 	char ch, *cp, resp, rbuf[2048], visbuf[2048];
   1540 
   1541 	if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp))
   1542 		lostconn(0);
   1543 
   1544 	cp = rbuf;
   1545 	switch (resp) {
   1546 	case 0:		/* ok */
   1547 		return (0);
   1548 	default:
   1549 		*cp++ = resp;
   1550 		/* FALLTHROUGH */
   1551 	case 1:		/* error, followed by error msg */
   1552 	case 2:		/* fatal error, "" */
   1553 		do {
   1554 			if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
   1555 				lostconn(0);
   1556 			*cp++ = ch;
   1557 		} while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
   1558 
   1559 		if (!iamremote) {
   1560 			cp[-1] = '\0';
   1561 			(void) snmprintf(visbuf, sizeof(visbuf),
   1562 			    NULL, "%s\n", rbuf);
   1563 			(void) atomicio(vwrite, STDERR_FILENO,
   1564 			    visbuf, strlen(visbuf));
   1565 		}
   1566 		++errs;
   1567 		if (resp == 1)
   1568 			return (-1);
   1569 		exit(1);
   1570 	}
   1571 	/* NOTREACHED */
   1572 }
   1573 
   1574 void
   1575 usage(void)
   1576 {
   1577 	(void) fprintf(stderr,
   1578 	    "usage: scp [-346ABCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
   1579 	    "            [-J destination] [-l limit] [-o ssh_option] [-P port]\n"
   1580 	    "            [-S program] source ... target\n");
   1581 	exit(1);
   1582 }
   1583 
   1584 void
   1585 run_err(const char *fmt,...)
   1586 {
   1587 	static FILE *fp;
   1588 	va_list ap;
   1589 
   1590 	++errs;
   1591 	if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) {
   1592 		(void) fprintf(fp, "%c", 0x01);
   1593 		(void) fprintf(fp, "scp: ");
   1594 		va_start(ap, fmt);
   1595 		(void) vfprintf(fp, fmt, ap);
   1596 		va_end(ap);
   1597 		(void) fprintf(fp, "\n");
   1598 		(void) fflush(fp);
   1599 	}
   1600 
   1601 	if (!iamremote) {
   1602 		va_start(ap, fmt);
   1603 		vfmprintf(stderr, fmt, ap);
   1604 		va_end(ap);
   1605 		fprintf(stderr, "\n");
   1606 	}
   1607 }
   1608 
   1609 /*
   1610  * Notes a sink error for sending at the end of a file transfer. Returns 0 if
   1611  * no error has been noted or -1 otherwise. Use note_err(NULL) to flush
   1612  * any active error at the end of the transfer.
   1613  */
   1614 int
   1615 note_err(const char *fmt, ...)
   1616 {
   1617 	static char *emsg;
   1618 	va_list ap;
   1619 
   1620 	/* Replay any previously-noted error */
   1621 	if (fmt == NULL) {
   1622 		if (emsg == NULL)
   1623 			return 0;
   1624 		run_err("%s", emsg);
   1625 		free(emsg);
   1626 		emsg = NULL;
   1627 		return -1;
   1628 	}
   1629 
   1630 	errs++;
   1631 	/* Prefer first-noted error */
   1632 	if (emsg != NULL)
   1633 		return -1;
   1634 
   1635 	va_start(ap, fmt);
   1636 	vasnmprintf(&emsg, INT_MAX, NULL, fmt, ap);
   1637 	va_end(ap);
   1638 	return -1;
   1639 }
   1640 
   1641 void
   1642 verifydir(char *cp)
   1643 {
   1644 	struct stat stb;
   1645 
   1646 	if (!stat(cp, &stb)) {
   1647 		if (S_ISDIR(stb.st_mode))
   1648 			return;
   1649 		errno = ENOTDIR;
   1650 	}
   1651 	run_err("%s: %s", cp, strerror(errno));
   1652 	killchild(0);
   1653 }
   1654 
   1655 int
   1656 okname(char *cp0)
   1657 {
   1658 	int c;
   1659 	char *cp;
   1660 
   1661 	cp = cp0;
   1662 	do {
   1663 		c = (int)*cp;
   1664 		if (c & 0200)
   1665 			goto bad;
   1666 		if (!isalpha(c) && !isdigit((unsigned char)c)) {
   1667 			switch (c) {
   1668 			case '\'':
   1669 			case '"':
   1670 			case '`':
   1671 			case ' ':
   1672 			case '#':
   1673 				goto bad;
   1674 			default:
   1675 				break;
   1676 			}
   1677 		}
   1678 	} while (*++cp);
   1679 	return (1);
   1680 
   1681 bad:	fmprintf(stderr, "%s: invalid user name\n", cp0);
   1682 	return (0);
   1683 }
   1684 
   1685 BUF *
   1686 allocbuf(BUF *bp, int fd, int blksize)
   1687 {
   1688 	size_t size;
   1689 	struct stat stb;
   1690 
   1691 	if (fstat(fd, &stb) == -1) {
   1692 		run_err("fstat: %s", strerror(errno));
   1693 		return (0);
   1694 	}
   1695 	size = ROUNDUP(stb.st_blksize, blksize);
   1696 	if (size == 0)
   1697 		size = blksize;
   1698 	if (bp->cnt >= size)
   1699 		return (bp);
   1700 	bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
   1701 	bp->cnt = size;
   1702 	return (bp);
   1703 }
   1704 
   1705 static void
   1706 lostconn(int signo)
   1707 {
   1708 	if (!iamremote)
   1709 		(void)write(STDERR_FILENO, "lost connection\n", 16);
   1710 	if (signo)
   1711 		_exit(1);
   1712 	else
   1713 		exit(1);
   1714 }
   1715