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