xref: /openbsd/usr.bin/ssh/sftp.c (revision d415bd75)
1 /* $OpenBSD: sftp.c,v 1.236 2023/09/10 23:12:32 djm Exp $ */
2 /*
3  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 #include <sys/ioctl.h>
20 #include <sys/wait.h>
21 #include <sys/stat.h>
22 #include <sys/socket.h>
23 #include <sys/statvfs.h>
24 
25 #include <ctype.h>
26 #include <errno.h>
27 #include <glob.h>
28 #include <histedit.h>
29 #include <paths.h>
30 #include <libgen.h>
31 #include <locale.h>
32 #include <signal.h>
33 #include <stdarg.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <limits.h>
39 #include <util.h>
40 
41 #include "xmalloc.h"
42 #include "log.h"
43 #include "pathnames.h"
44 #include "misc.h"
45 #include "utf8.h"
46 
47 #include "sftp.h"
48 #include "ssherr.h"
49 #include "sshbuf.h"
50 #include "sftp-common.h"
51 #include "sftp-client.h"
52 #include "sftp-usergroup.h"
53 
54 /* File to read commands from */
55 FILE* infile;
56 
57 /* Are we in batchfile mode? */
58 int batchmode = 0;
59 
60 /* PID of ssh transport process */
61 static volatile pid_t sshpid = -1;
62 
63 /* Suppress diagnostic messages */
64 int quiet = 0;
65 
66 /* This is set to 0 if the progressmeter is not desired. */
67 int showprogress = 1;
68 
69 /* When this option is set, we always recursively download/upload directories */
70 int global_rflag = 0;
71 
72 /* When this option is set, we resume download or upload if possible */
73 int global_aflag = 0;
74 
75 /* When this option is set, the file transfers will always preserve times */
76 int global_pflag = 0;
77 
78 /* When this option is set, transfers will have fsync() called on each file */
79 int global_fflag = 0;
80 
81 /* SIGINT received during command processing */
82 volatile sig_atomic_t interrupted = 0;
83 
84 /* I wish qsort() took a separate ctx for the comparison function...*/
85 int sort_flag;
86 glob_t *sort_glob;
87 
88 /* Context used for commandline completion */
89 struct complete_ctx {
90 	struct sftp_conn *conn;
91 	char **remote_pathp;
92 };
93 
94 int sftp_glob(struct sftp_conn *, const char *, int,
95     int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
96 
97 /* Separators for interactive commands */
98 #define WHITESPACE " \t\r\n"
99 
100 /* ls flags */
101 #define LS_LONG_VIEW	0x0001	/* Full view ala ls -l */
102 #define LS_SHORT_VIEW	0x0002	/* Single row view ala ls -1 */
103 #define LS_NUMERIC_VIEW	0x0004	/* Long view with numeric uid/gid */
104 #define LS_NAME_SORT	0x0008	/* Sort by name (default) */
105 #define LS_TIME_SORT	0x0010	/* Sort by mtime */
106 #define LS_SIZE_SORT	0x0020	/* Sort by file size */
107 #define LS_REVERSE_SORT	0x0040	/* Reverse sort order */
108 #define LS_SHOW_ALL	0x0080	/* Don't skip filenames starting with '.' */
109 #define LS_SI_UNITS	0x0100	/* Display sizes as K, M, G, etc. */
110 
111 #define VIEW_FLAGS	(LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS)
112 #define SORT_FLAGS	(LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT)
113 
114 /* Commands for interactive mode */
115 enum sftp_command {
116 	I_CHDIR = 1,
117 	I_CHGRP,
118 	I_CHMOD,
119 	I_CHOWN,
120 	I_COPY,
121 	I_DF,
122 	I_GET,
123 	I_HELP,
124 	I_LCHDIR,
125 	I_LINK,
126 	I_LLS,
127 	I_LMKDIR,
128 	I_LPWD,
129 	I_LS,
130 	I_LUMASK,
131 	I_MKDIR,
132 	I_PUT,
133 	I_PWD,
134 	I_QUIT,
135 	I_REGET,
136 	I_RENAME,
137 	I_REPUT,
138 	I_RM,
139 	I_RMDIR,
140 	I_SHELL,
141 	I_SYMLINK,
142 	I_VERSION,
143 	I_PROGRESS,
144 };
145 
146 struct CMD {
147 	const char *c;
148 	const int n;
149 	const int t;	/* Completion type for the first argument */
150 	const int t2;	/* completion type for the optional second argument */
151 };
152 
153 /* Type of completion */
154 #define NOARGS	0
155 #define REMOTE	1
156 #define LOCAL	2
157 
158 static const struct CMD cmds[] = {
159 	{ "bye",	I_QUIT,		NOARGS, 	NOARGS	},
160 	{ "cd",		I_CHDIR,	REMOTE, 	NOARGS	},
161 	{ "chdir",	I_CHDIR,	REMOTE, 	NOARGS	},
162 	{ "chgrp",	I_CHGRP,	REMOTE, 	NOARGS	},
163 	{ "chmod",	I_CHMOD,	REMOTE, 	NOARGS	},
164 	{ "chown",	I_CHOWN,	REMOTE, 	NOARGS	},
165 	{ "copy",	I_COPY,		REMOTE, 	LOCAL	},
166 	{ "cp",		I_COPY,		REMOTE, 	LOCAL	},
167 	{ "df",		I_DF,		REMOTE, 	NOARGS	},
168 	{ "dir",	I_LS,		REMOTE, 	NOARGS	},
169 	{ "exit",	I_QUIT,		NOARGS, 	NOARGS	},
170 	{ "get",	I_GET,		REMOTE, 	LOCAL	},
171 	{ "help",	I_HELP,		NOARGS, 	NOARGS	},
172 	{ "lcd",	I_LCHDIR,	LOCAL,		NOARGS	},
173 	{ "lchdir",	I_LCHDIR,	LOCAL,		NOARGS	},
174 	{ "lls",	I_LLS,		LOCAL,		NOARGS	},
175 	{ "lmkdir",	I_LMKDIR,	LOCAL,		NOARGS	},
176 	{ "ln",		I_LINK,		REMOTE, 	REMOTE	},
177 	{ "lpwd",	I_LPWD,		LOCAL,		NOARGS	},
178 	{ "ls",		I_LS,		REMOTE,		NOARGS	},
179 	{ "lumask",	I_LUMASK,	NOARGS,		NOARGS	},
180 	{ "mkdir",	I_MKDIR,	REMOTE,		NOARGS	},
181 	{ "mget",	I_GET,		REMOTE,		LOCAL	},
182 	{ "mput",	I_PUT,		LOCAL,		REMOTE	},
183 	{ "progress",	I_PROGRESS,	NOARGS,		NOARGS	},
184 	{ "put",	I_PUT,		LOCAL,		REMOTE	},
185 	{ "pwd",	I_PWD,		REMOTE, 	NOARGS	},
186 	{ "quit",	I_QUIT,		NOARGS, 	NOARGS	},
187 	{ "reget",	I_REGET,	REMOTE, 	LOCAL	},
188 	{ "rename",	I_RENAME,	REMOTE, 	REMOTE	},
189 	{ "reput",	I_REPUT,	LOCAL,		REMOTE	},
190 	{ "rm",		I_RM,		REMOTE,		NOARGS	},
191 	{ "rmdir",	I_RMDIR,	REMOTE,		NOARGS	},
192 	{ "symlink",	I_SYMLINK,	REMOTE,		REMOTE	},
193 	{ "version",	I_VERSION,	NOARGS, 	NOARGS	},
194 	{ "!",		I_SHELL,	NOARGS, 	NOARGS	},
195 	{ "?",		I_HELP,		NOARGS, 	NOARGS	},
196 	{ NULL,		-1,		-1,		-1	}
197 };
198 
199 static void
200 killchild(int signo)
201 {
202 	pid_t pid;
203 
204 	pid = sshpid;
205 	if (pid > 1) {
206 		kill(pid, SIGTERM);
207 		(void)waitpid(pid, NULL, 0);
208 	}
209 
210 	_exit(1);
211 }
212 
213 static void
214 suspchild(int signo)
215 {
216 	if (sshpid > 1) {
217 		kill(sshpid, signo);
218 		while (waitpid(sshpid, NULL, WUNTRACED) == -1 && errno == EINTR)
219 			continue;
220 	}
221 	kill(getpid(), SIGSTOP);
222 }
223 
224 static void
225 cmd_interrupt(int signo)
226 {
227 	const char msg[] = "\rInterrupt  \n";
228 	int olderrno = errno;
229 
230 	(void)write(STDERR_FILENO, msg, sizeof(msg) - 1);
231 	interrupted = 1;
232 	errno = olderrno;
233 }
234 
235 static void
236 read_interrupt(int signo)
237 {
238 	interrupted = 1;
239 }
240 
241 static void
242 sigchld_handler(int sig)
243 {
244 	int save_errno = errno;
245 	pid_t pid;
246 	const char msg[] = "\rConnection closed.  \n";
247 
248 	/* Report if ssh transport process dies. */
249 	while ((pid = waitpid(sshpid, NULL, WNOHANG)) == -1 && errno == EINTR)
250 		continue;
251 	if (pid == sshpid) {
252 		if (!quiet)
253 		    (void)write(STDERR_FILENO, msg, sizeof(msg) - 1);
254 		sshpid = -1;
255 	}
256 
257 	errno = save_errno;
258 }
259 
260 static void
261 help(void)
262 {
263 	printf("Available commands:\n"
264 	    "bye                                Quit sftp\n"
265 	    "cd path                            Change remote directory to 'path'\n"
266 	    "chgrp [-h] grp path                Change group of file 'path' to 'grp'\n"
267 	    "chmod [-h] mode path               Change permissions of file 'path' to 'mode'\n"
268 	    "chown [-h] own path                Change owner of file 'path' to 'own'\n"
269 	    "copy oldpath newpath               Copy remote file\n"
270 	    "cp oldpath newpath                 Copy remote file\n"
271 	    "df [-hi] [path]                    Display statistics for current directory or\n"
272 	    "                                   filesystem containing 'path'\n"
273 	    "exit                               Quit sftp\n"
274 	    "get [-afpR] remote [local]         Download file\n"
275 	    "help                               Display this help text\n"
276 	    "lcd path                           Change local directory to 'path'\n"
277 	    "lls [ls-options [path]]            Display local directory listing\n"
278 	    "lmkdir path                        Create local directory\n"
279 	    "ln [-s] oldpath newpath            Link remote file (-s for symlink)\n"
280 	    "lpwd                               Print local working directory\n"
281 	    "ls [-1afhlnrSt] [path]             Display remote directory listing\n"
282 	    "lumask umask                       Set local umask to 'umask'\n"
283 	    "mkdir path                         Create remote directory\n"
284 	    "progress                           Toggle display of progress meter\n"
285 	    "put [-afpR] local [remote]         Upload file\n"
286 	    "pwd                                Display remote working directory\n"
287 	    "quit                               Quit sftp\n"
288 	    "reget [-fpR] remote [local]        Resume download file\n"
289 	    "rename oldpath newpath             Rename remote file\n"
290 	    "reput [-fpR] local [remote]        Resume upload file\n"
291 	    "rm path                            Delete remote file\n"
292 	    "rmdir path                         Remove remote directory\n"
293 	    "symlink oldpath newpath            Symlink remote file\n"
294 	    "version                            Show SFTP version\n"
295 	    "!command                           Execute 'command' in local shell\n"
296 	    "!                                  Escape to local shell\n"
297 	    "?                                  Synonym for help\n");
298 }
299 
300 static void
301 local_do_shell(const char *args)
302 {
303 	int status;
304 	char *shell;
305 	pid_t pid;
306 
307 	if (!*args)
308 		args = NULL;
309 
310 	if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
311 		shell = _PATH_BSHELL;
312 
313 	if ((pid = fork()) == -1)
314 		fatal("Couldn't fork: %s", strerror(errno));
315 
316 	if (pid == 0) {
317 		/* XXX: child has pipe fds to ssh subproc open - issue? */
318 		if (args) {
319 			debug3("Executing %s -c \"%s\"", shell, args);
320 			execl(shell, shell, "-c", args, (char *)NULL);
321 		} else {
322 			debug3("Executing %s", shell);
323 			execl(shell, shell, (char *)NULL);
324 		}
325 		fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,
326 		    strerror(errno));
327 		_exit(1);
328 	}
329 	while (waitpid(pid, &status, 0) == -1)
330 		if (errno != EINTR)
331 			fatal("Couldn't wait for child: %s", strerror(errno));
332 	if (!WIFEXITED(status))
333 		error("Shell exited abnormally");
334 	else if (WEXITSTATUS(status))
335 		error("Shell exited with status %d", WEXITSTATUS(status));
336 }
337 
338 static void
339 local_do_ls(const char *args)
340 {
341 	if (!args || !*args)
342 		local_do_shell(_PATH_LS);
343 	else {
344 		int len = strlen(_PATH_LS " ") + strlen(args) + 1;
345 		char *buf = xmalloc(len);
346 
347 		/* XXX: quoting - rip quoting code from ftp? */
348 		snprintf(buf, len, _PATH_LS " %s", args);
349 		local_do_shell(buf);
350 		free(buf);
351 	}
352 }
353 
354 /* Strip one path (usually the pwd) from the start of another */
355 static char *
356 path_strip(const char *path, const char *strip)
357 {
358 	size_t len;
359 
360 	if (strip == NULL)
361 		return (xstrdup(path));
362 
363 	len = strlen(strip);
364 	if (strncmp(path, strip, len) == 0) {
365 		if (strip[len - 1] != '/' && path[len] == '/')
366 			len++;
367 		return (xstrdup(path + len));
368 	}
369 
370 	return (xstrdup(path));
371 }
372 
373 static int
374 parse_getput_flags(const char *cmd, char **argv, int argc,
375     int *aflag, int *fflag, int *pflag, int *rflag)
376 {
377 	extern int opterr, optind, optopt, optreset;
378 	int ch;
379 
380 	optind = optreset = 1;
381 	opterr = 0;
382 
383 	*aflag = *fflag = *rflag = *pflag = 0;
384 	while ((ch = getopt(argc, argv, "afPpRr")) != -1) {
385 		switch (ch) {
386 		case 'a':
387 			*aflag = 1;
388 			break;
389 		case 'f':
390 			*fflag = 1;
391 			break;
392 		case 'p':
393 		case 'P':
394 			*pflag = 1;
395 			break;
396 		case 'r':
397 		case 'R':
398 			*rflag = 1;
399 			break;
400 		default:
401 			error("%s: Invalid flag -%c", cmd, optopt);
402 			return -1;
403 		}
404 	}
405 
406 	return optind;
407 }
408 
409 static int
410 parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)
411 {
412 	extern int opterr, optind, optopt, optreset;
413 	int ch;
414 
415 	optind = optreset = 1;
416 	opterr = 0;
417 
418 	*sflag = 0;
419 	while ((ch = getopt(argc, argv, "s")) != -1) {
420 		switch (ch) {
421 		case 's':
422 			*sflag = 1;
423 			break;
424 		default:
425 			error("%s: Invalid flag -%c", cmd, optopt);
426 			return -1;
427 		}
428 	}
429 
430 	return optind;
431 }
432 
433 static int
434 parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag)
435 {
436 	extern int opterr, optind, optopt, optreset;
437 	int ch;
438 
439 	optind = optreset = 1;
440 	opterr = 0;
441 
442 	*lflag = 0;
443 	while ((ch = getopt(argc, argv, "l")) != -1) {
444 		switch (ch) {
445 		case 'l':
446 			*lflag = 1;
447 			break;
448 		default:
449 			error("%s: Invalid flag -%c", cmd, optopt);
450 			return -1;
451 		}
452 	}
453 
454 	return optind;
455 }
456 
457 static int
458 parse_ls_flags(char **argv, int argc, int *lflag)
459 {
460 	extern int opterr, optind, optopt, optreset;
461 	int ch;
462 
463 	optind = optreset = 1;
464 	opterr = 0;
465 
466 	*lflag = LS_NAME_SORT;
467 	while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) {
468 		switch (ch) {
469 		case '1':
470 			*lflag &= ~VIEW_FLAGS;
471 			*lflag |= LS_SHORT_VIEW;
472 			break;
473 		case 'S':
474 			*lflag &= ~SORT_FLAGS;
475 			*lflag |= LS_SIZE_SORT;
476 			break;
477 		case 'a':
478 			*lflag |= LS_SHOW_ALL;
479 			break;
480 		case 'f':
481 			*lflag &= ~SORT_FLAGS;
482 			break;
483 		case 'h':
484 			*lflag |= LS_SI_UNITS;
485 			break;
486 		case 'l':
487 			*lflag &= ~LS_SHORT_VIEW;
488 			*lflag |= LS_LONG_VIEW;
489 			break;
490 		case 'n':
491 			*lflag &= ~LS_SHORT_VIEW;
492 			*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
493 			break;
494 		case 'r':
495 			*lflag |= LS_REVERSE_SORT;
496 			break;
497 		case 't':
498 			*lflag &= ~SORT_FLAGS;
499 			*lflag |= LS_TIME_SORT;
500 			break;
501 		default:
502 			error("ls: Invalid flag -%c", optopt);
503 			return -1;
504 		}
505 	}
506 
507 	return optind;
508 }
509 
510 static int
511 parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
512 {
513 	extern int opterr, optind, optopt, optreset;
514 	int ch;
515 
516 	optind = optreset = 1;
517 	opterr = 0;
518 
519 	*hflag = *iflag = 0;
520 	while ((ch = getopt(argc, argv, "hi")) != -1) {
521 		switch (ch) {
522 		case 'h':
523 			*hflag = 1;
524 			break;
525 		case 'i':
526 			*iflag = 1;
527 			break;
528 		default:
529 			error("%s: Invalid flag -%c", cmd, optopt);
530 			return -1;
531 		}
532 	}
533 
534 	return optind;
535 }
536 
537 static int
538 parse_ch_flags(const char *cmd, char **argv, int argc, int *hflag)
539 {
540 	extern int opterr, optind, optopt, optreset;
541 	int ch;
542 
543 	optind = optreset = 1;
544 	opterr = 0;
545 
546 	*hflag = 0;
547 	while ((ch = getopt(argc, argv, "h")) != -1) {
548 		switch (ch) {
549 		case 'h':
550 			*hflag = 1;
551 			break;
552 		default:
553 			error("%s: Invalid flag -%c", cmd, optopt);
554 			return -1;
555 		}
556 	}
557 
558 	return optind;
559 }
560 
561 static int
562 parse_no_flags(const char *cmd, char **argv, int argc)
563 {
564 	extern int opterr, optind, optopt, optreset;
565 	int ch;
566 
567 	optind = optreset = 1;
568 	opterr = 0;
569 
570 	while ((ch = getopt(argc, argv, "")) != -1) {
571 		switch (ch) {
572 		default:
573 			error("%s: Invalid flag -%c", cmd, optopt);
574 			return -1;
575 		}
576 	}
577 
578 	return optind;
579 }
580 
581 static char *
582 escape_glob(const char *s)
583 {
584 	size_t i, o, len;
585 	char *ret;
586 
587 	len = strlen(s);
588 	ret = xcalloc(2, len + 1);
589 	for (i = o = 0; i < len; i++) {
590 		if (strchr("[]?*\\", s[i]) != NULL)
591 			ret[o++] = '\\';
592 		ret[o++] = s[i];
593 	}
594 	ret[o++] = '\0';
595 	return ret;
596 }
597 
598 /*
599  * Arg p must be dynamically allocated.  make_absolute will either return it
600  * or free it and allocate a new one.  Caller must free returned string.
601  */
602 static char *
603 make_absolute_pwd_glob(char *p, const char *pwd)
604 {
605 	char *ret, *escpwd;
606 
607 	escpwd = escape_glob(pwd);
608 	if (p == NULL)
609 		return escpwd;
610 	ret = sftp_make_absolute(p, escpwd);
611 	free(escpwd);
612 	return ret;
613 }
614 
615 static int
616 local_is_dir(const char *path)
617 {
618 	struct stat sb;
619 
620 	if (stat(path, &sb) == -1)
621 		return 0;
622 	return S_ISDIR(sb.st_mode);
623 }
624 
625 static int
626 process_get(struct sftp_conn *conn, const char *src, const char *dst,
627     const char *pwd, int pflag, int rflag, int resume, int fflag)
628 {
629 	char *filename, *abs_src = NULL, *abs_dst = NULL, *tmp = NULL;
630 	glob_t g;
631 	int i, r, err = 0;
632 
633 	abs_src = make_absolute_pwd_glob(xstrdup(src), pwd);
634 	memset(&g, 0, sizeof(g));
635 
636 	debug3("Looking up %s", abs_src);
637 	if ((r = sftp_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
638 		if (r == GLOB_NOSPACE) {
639 			error("Too many matches for \"%s\".", abs_src);
640 		} else {
641 			error("File \"%s\" not found.", abs_src);
642 		}
643 		err = -1;
644 		goto out;
645 	}
646 
647 	/*
648 	 * If multiple matches then dst must be a directory or
649 	 * unspecified.
650 	 */
651 	if (g.gl_matchc > 1 && dst != NULL && !local_is_dir(dst)) {
652 		error("Multiple source paths, but destination "
653 		    "\"%s\" is not a directory", dst);
654 		err = -1;
655 		goto out;
656 	}
657 
658 	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
659 		tmp = xstrdup(g.gl_pathv[i]);
660 		if ((filename = basename(tmp)) == NULL) {
661 			error("basename %s: %s", tmp, strerror(errno));
662 			free(tmp);
663 			err = -1;
664 			goto out;
665 		}
666 
667 		if (g.gl_matchc == 1 && dst) {
668 			if (local_is_dir(dst)) {
669 				abs_dst = sftp_path_append(dst, filename);
670 			} else {
671 				abs_dst = xstrdup(dst);
672 			}
673 		} else if (dst) {
674 			abs_dst = sftp_path_append(dst, filename);
675 		} else {
676 			abs_dst = xstrdup(filename);
677 		}
678 		free(tmp);
679 
680 		resume |= global_aflag;
681 		if (!quiet && resume)
682 			mprintf("Resuming %s to %s\n",
683 			    g.gl_pathv[i], abs_dst);
684 		else if (!quiet && !resume)
685 			mprintf("Fetching %s to %s\n",
686 			    g.gl_pathv[i], abs_dst);
687 		/* XXX follow link flag */
688 		if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
689 		    (rflag || global_rflag)) {
690 			if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
691 			    NULL, pflag || global_pflag, 1, resume,
692 			    fflag || global_fflag, 0, 0) == -1)
693 				err = -1;
694 		} else {
695 			if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
696 			    pflag || global_pflag, resume,
697 			    fflag || global_fflag, 0) == -1)
698 				err = -1;
699 		}
700 		free(abs_dst);
701 		abs_dst = NULL;
702 	}
703 
704 out:
705 	free(abs_src);
706 	globfree(&g);
707 	return(err);
708 }
709 
710 static int
711 process_put(struct sftp_conn *conn, const char *src, const char *dst,
712     const char *pwd, int pflag, int rflag, int resume, int fflag)
713 {
714 	char *tmp_dst = NULL;
715 	char *abs_dst = NULL;
716 	char *tmp = NULL, *filename = NULL;
717 	glob_t g;
718 	int err = 0;
719 	int i, dst_is_dir = 1;
720 	struct stat sb;
721 
722 	if (dst) {
723 		tmp_dst = xstrdup(dst);
724 		tmp_dst = sftp_make_absolute(tmp_dst, pwd);
725 	}
726 
727 	memset(&g, 0, sizeof(g));
728 	debug3("Looking up %s", src);
729 	if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) {
730 		error("File \"%s\" not found.", src);
731 		err = -1;
732 		goto out;
733 	}
734 
735 	/* If we aren't fetching to pwd then stash this status for later */
736 	if (tmp_dst != NULL)
737 		dst_is_dir = sftp_remote_is_dir(conn, tmp_dst);
738 
739 	/* If multiple matches, dst may be directory or unspecified */
740 	if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
741 		error("Multiple paths match, but destination "
742 		    "\"%s\" is not a directory", tmp_dst);
743 		err = -1;
744 		goto out;
745 	}
746 
747 	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
748 		if (stat(g.gl_pathv[i], &sb) == -1) {
749 			err = -1;
750 			error("stat %s: %s", g.gl_pathv[i], strerror(errno));
751 			continue;
752 		}
753 
754 		tmp = xstrdup(g.gl_pathv[i]);
755 		if ((filename = basename(tmp)) == NULL) {
756 			error("basename %s: %s", tmp, strerror(errno));
757 			free(tmp);
758 			err = -1;
759 			goto out;
760 		}
761 
762 		free(abs_dst);
763 		abs_dst = NULL;
764 		if (g.gl_matchc == 1 && tmp_dst) {
765 			/* If directory specified, append filename */
766 			if (dst_is_dir)
767 				abs_dst = sftp_path_append(tmp_dst, filename);
768 			else
769 				abs_dst = xstrdup(tmp_dst);
770 		} else if (tmp_dst) {
771 			abs_dst = sftp_path_append(tmp_dst, filename);
772 		} else {
773 			abs_dst = sftp_make_absolute(xstrdup(filename), pwd);
774 		}
775 		free(tmp);
776 
777 		resume |= global_aflag;
778 		if (!quiet && resume)
779 			mprintf("Resuming upload of %s to %s\n",
780 			    g.gl_pathv[i], abs_dst);
781 		else if (!quiet && !resume)
782 			mprintf("Uploading %s to %s\n",
783 			    g.gl_pathv[i], abs_dst);
784 		/* XXX follow_link_flag */
785 		if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
786 		    (rflag || global_rflag)) {
787 			if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
788 			    pflag || global_pflag, 1, resume,
789 			    fflag || global_fflag, 0, 0) == -1)
790 				err = -1;
791 		} else {
792 			if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
793 			    pflag || global_pflag, resume,
794 			    fflag || global_fflag, 0) == -1)
795 				err = -1;
796 		}
797 	}
798 
799 out:
800 	free(abs_dst);
801 	free(tmp_dst);
802 	globfree(&g);
803 	return(err);
804 }
805 
806 static int
807 sdirent_comp(const void *aa, const void *bb)
808 {
809 	SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;
810 	SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;
811 	int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
812 
813 #define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
814 	if (sort_flag & LS_NAME_SORT)
815 		return (rmul * strcmp(a->filename, b->filename));
816 	else if (sort_flag & LS_TIME_SORT)
817 		return (rmul * NCMP(a->a.mtime, b->a.mtime));
818 	else if (sort_flag & LS_SIZE_SORT)
819 		return (rmul * NCMP(a->a.size, b->a.size));
820 
821 	fatal("Unknown ls sort type");
822 }
823 
824 /* sftp ls.1 replacement for directories */
825 static int
826 do_ls_dir(struct sftp_conn *conn, const char *path,
827     const char *strip_path, int lflag)
828 {
829 	int n;
830 	u_int c = 1, colspace = 0, columns = 1;
831 	SFTP_DIRENT **d;
832 
833 	if ((n = sftp_readdir(conn, path, &d)) != 0)
834 		return (n);
835 
836 	if (!(lflag & LS_SHORT_VIEW)) {
837 		u_int m = 0, width = 80;
838 		struct winsize ws;
839 		char *tmp;
840 
841 		/* Count entries for sort and find longest filename */
842 		for (n = 0; d[n] != NULL; n++) {
843 			if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL))
844 				m = MAXIMUM(m, strlen(d[n]->filename));
845 		}
846 
847 		/* Add any subpath that also needs to be counted */
848 		tmp = path_strip(path, strip_path);
849 		m += strlen(tmp);
850 		free(tmp);
851 
852 		if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
853 			width = ws.ws_col;
854 
855 		columns = width / (m + 2);
856 		columns = MAXIMUM(columns, 1);
857 		colspace = width / columns;
858 		colspace = MINIMUM(colspace, width);
859 	}
860 
861 	if (lflag & SORT_FLAGS) {
862 		for (n = 0; d[n] != NULL; n++)
863 			;	/* count entries */
864 		sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
865 		qsort(d, n, sizeof(*d), sdirent_comp);
866 	}
867 
868 	get_remote_user_groups_from_dirents(conn, d);
869 	for (n = 0; d[n] != NULL && !interrupted; n++) {
870 		char *tmp, *fname;
871 
872 		if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
873 			continue;
874 
875 		tmp = sftp_path_append(path, d[n]->filename);
876 		fname = path_strip(tmp, strip_path);
877 		free(tmp);
878 
879 		if (lflag & LS_LONG_VIEW) {
880 			if ((lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) != 0 ||
881 			    sftp_can_get_users_groups_by_id(conn)) {
882 				char *lname;
883 				struct stat sb;
884 
885 				memset(&sb, 0, sizeof(sb));
886 				attrib_to_stat(&d[n]->a, &sb);
887 				lname = ls_file(fname, &sb, 1,
888 				    (lflag & LS_SI_UNITS),
889 				    ruser_name(sb.st_uid),
890 				    rgroup_name(sb.st_gid));
891 				mprintf("%s\n", lname);
892 				free(lname);
893 			} else
894 				mprintf("%s\n", d[n]->longname);
895 		} else {
896 			mprintf("%-*s", colspace, fname);
897 			if (c >= columns) {
898 				printf("\n");
899 				c = 1;
900 			} else
901 				c++;
902 		}
903 
904 		free(fname);
905 	}
906 
907 	if (!(lflag & LS_LONG_VIEW) && (c != 1))
908 		printf("\n");
909 
910 	sftp_free_dirents(d);
911 	return (0);
912 }
913 
914 static int
915 sglob_comp(const void *aa, const void *bb)
916 {
917 	u_int a = *(const u_int *)aa;
918 	u_int b = *(const u_int *)bb;
919 	const char *ap = sort_glob->gl_pathv[a];
920 	const char *bp = sort_glob->gl_pathv[b];
921 	const struct stat *as = sort_glob->gl_statv[a];
922 	const struct stat *bs = sort_glob->gl_statv[b];
923 	int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
924 
925 #define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
926 	if (sort_flag & LS_NAME_SORT)
927 		return (rmul * strcmp(ap, bp));
928 	else if (sort_flag & LS_TIME_SORT) {
929 		if (timespeccmp(&as->st_mtim, &bs->st_mtim, ==))
930 			return 0;
931 		return timespeccmp(&as->st_mtim, &bs->st_mtim, <) ?
932 		    rmul : -rmul;
933 	} else if (sort_flag & LS_SIZE_SORT)
934 		return (rmul * NCMP(as->st_size, bs->st_size));
935 
936 	fatal("Unknown ls sort type");
937 }
938 
939 /* sftp ls.1 replacement which handles path globs */
940 static int
941 do_globbed_ls(struct sftp_conn *conn, const char *path,
942     const char *strip_path, int lflag)
943 {
944 	char *fname, *lname;
945 	glob_t g;
946 	int err, r;
947 	struct winsize ws;
948 	u_int i, j, nentries, *indices = NULL, c = 1;
949 	u_int colspace = 0, columns = 1, m = 0, width = 80;
950 
951 	memset(&g, 0, sizeof(g));
952 
953 	if ((r = sftp_glob(conn, path,
954 	    GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT|GLOB_NOSORT,
955 	    NULL, &g)) != 0 ||
956 	    (g.gl_pathc && !g.gl_matchc)) {
957 		if (g.gl_pathc)
958 			globfree(&g);
959 		if (r == GLOB_NOSPACE) {
960 			error("Can't ls: Too many matches for \"%s\"", path);
961 		} else {
962 			error("Can't ls: \"%s\" not found", path);
963 		}
964 		return -1;
965 	}
966 
967 	if (interrupted)
968 		goto out;
969 
970 	/*
971 	 * If the glob returns a single match and it is a directory,
972 	 * then just list its contents.
973 	 */
974 	if (g.gl_matchc == 1 && g.gl_statv[0] != NULL &&
975 	    S_ISDIR(g.gl_statv[0]->st_mode)) {
976 		err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);
977 		globfree(&g);
978 		return err;
979 	}
980 
981 	if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
982 		width = ws.ws_col;
983 
984 	if (!(lflag & LS_SHORT_VIEW)) {
985 		/* Count entries for sort and find longest filename */
986 		for (i = 0; g.gl_pathv[i]; i++)
987 			m = MAXIMUM(m, strlen(g.gl_pathv[i]));
988 
989 		columns = width / (m + 2);
990 		columns = MAXIMUM(columns, 1);
991 		colspace = width / columns;
992 	}
993 
994 	/*
995 	 * Sorting: rather than mess with the contents of glob_t, prepare
996 	 * an array of indices into it and sort that. For the usual
997 	 * unsorted case, the indices are just the identity 1=1, 2=2, etc.
998 	 */
999 	for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
1000 		;	/* count entries */
1001 	indices = xcalloc(nentries, sizeof(*indices));
1002 	for (i = 0; i < nentries; i++)
1003 		indices[i] = i;
1004 
1005 	if (lflag & SORT_FLAGS) {
1006 		sort_glob = &g;
1007 		sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
1008 		qsort(indices, nentries, sizeof(*indices), sglob_comp);
1009 		sort_glob = NULL;
1010 	}
1011 
1012 	get_remote_user_groups_from_glob(conn, &g);
1013 	for (j = 0; j < nentries && !interrupted; j++) {
1014 		i = indices[j];
1015 		fname = path_strip(g.gl_pathv[i], strip_path);
1016 		if (lflag & LS_LONG_VIEW) {
1017 			if (g.gl_statv[i] == NULL) {
1018 				error("no stat information for %s", fname);
1019 				free(fname);
1020 				continue;
1021 			}
1022 			lname = ls_file(fname, g.gl_statv[i], 1,
1023 			    (lflag & LS_SI_UNITS),
1024 			    ruser_name(g.gl_statv[i]->st_uid),
1025 			    rgroup_name(g.gl_statv[i]->st_gid));
1026 			mprintf("%s\n", lname);
1027 			free(lname);
1028 		} else {
1029 			mprintf("%-*s", colspace, fname);
1030 			if (c >= columns) {
1031 				printf("\n");
1032 				c = 1;
1033 			} else
1034 				c++;
1035 		}
1036 		free(fname);
1037 	}
1038 
1039 	if (!(lflag & LS_LONG_VIEW) && (c != 1))
1040 		printf("\n");
1041 
1042  out:
1043 	if (g.gl_pathc)
1044 		globfree(&g);
1045 	free(indices);
1046 
1047 	return 0;
1048 }
1049 
1050 static int
1051 do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
1052 {
1053 	struct sftp_statvfs st;
1054 	char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE];
1055 	char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
1056 	char s_icapacity[16], s_dcapacity[16];
1057 
1058 	if (sftp_statvfs(conn, path, &st, 1) == -1)
1059 		return -1;
1060 	if (st.f_files == 0)
1061 		strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
1062 	else {
1063 		snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%",
1064 		    (unsigned long long)(100 * (st.f_files - st.f_ffree) /
1065 		    st.f_files));
1066 	}
1067 	if (st.f_blocks == 0)
1068 		strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity));
1069 	else {
1070 		snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%",
1071 		    (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
1072 		    st.f_blocks));
1073 	}
1074 	if (iflag) {
1075 		printf("     Inodes        Used       Avail      "
1076 		    "(root)    %%Capacity\n");
1077 		printf("%11llu %11llu %11llu %11llu         %s\n",
1078 		    (unsigned long long)st.f_files,
1079 		    (unsigned long long)(st.f_files - st.f_ffree),
1080 		    (unsigned long long)st.f_favail,
1081 		    (unsigned long long)st.f_ffree, s_icapacity);
1082 	} else if (hflag) {
1083 		strlcpy(s_used, "error", sizeof(s_used));
1084 		strlcpy(s_avail, "error", sizeof(s_avail));
1085 		strlcpy(s_root, "error", sizeof(s_root));
1086 		strlcpy(s_total, "error", sizeof(s_total));
1087 		fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used);
1088 		fmt_scaled(st.f_bavail * st.f_frsize, s_avail);
1089 		fmt_scaled(st.f_bfree * st.f_frsize, s_root);
1090 		fmt_scaled(st.f_blocks * st.f_frsize, s_total);
1091 		printf("    Size     Used    Avail   (root)    %%Capacity\n");
1092 		printf("%7sB %7sB %7sB %7sB         %s\n",
1093 		    s_total, s_used, s_avail, s_root, s_dcapacity);
1094 	} else {
1095 		printf("        Size         Used        Avail       "
1096 		    "(root)    %%Capacity\n");
1097 		printf("%12llu %12llu %12llu %12llu         %s\n",
1098 		    (unsigned long long)(st.f_frsize * st.f_blocks / 1024),
1099 		    (unsigned long long)(st.f_frsize *
1100 		    (st.f_blocks - st.f_bfree) / 1024),
1101 		    (unsigned long long)(st.f_frsize * st.f_bavail / 1024),
1102 		    (unsigned long long)(st.f_frsize * st.f_bfree / 1024),
1103 		    s_dcapacity);
1104 	}
1105 	return 0;
1106 }
1107 
1108 /*
1109  * Undo escaping of glob sequences in place. Used to undo extra escaping
1110  * applied in makeargv() when the string is destined for a function that
1111  * does not glob it.
1112  */
1113 static void
1114 undo_glob_escape(char *s)
1115 {
1116 	size_t i, j;
1117 
1118 	for (i = j = 0;;) {
1119 		if (s[i] == '\0') {
1120 			s[j] = '\0';
1121 			return;
1122 		}
1123 		if (s[i] != '\\') {
1124 			s[j++] = s[i++];
1125 			continue;
1126 		}
1127 		/* s[i] == '\\' */
1128 		++i;
1129 		switch (s[i]) {
1130 		case '?':
1131 		case '[':
1132 		case '*':
1133 		case '\\':
1134 			s[j++] = s[i++];
1135 			break;
1136 		case '\0':
1137 			s[j++] = '\\';
1138 			s[j] = '\0';
1139 			return;
1140 		default:
1141 			s[j++] = '\\';
1142 			s[j++] = s[i++];
1143 			break;
1144 		}
1145 	}
1146 }
1147 
1148 /*
1149  * Split a string into an argument vector using sh(1)-style quoting,
1150  * comment and escaping rules, but with some tweaks to handle glob(3)
1151  * wildcards.
1152  * The "sloppy" flag allows for recovery from missing terminating quote, for
1153  * use in parsing incomplete commandlines during tab autocompletion.
1154  *
1155  * Returns NULL on error or a NULL-terminated array of arguments.
1156  *
1157  * If "lastquote" is not NULL, the quoting character used for the last
1158  * argument is placed in *lastquote ("\0", "'" or "\"").
1159  *
1160  * If "terminated" is not NULL, *terminated will be set to 1 when the
1161  * last argument's quote has been properly terminated or 0 otherwise.
1162  * This parameter is only of use if "sloppy" is set.
1163  */
1164 #define MAXARGS		128
1165 #define MAXARGLEN	8192
1166 static char **
1167 makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
1168     u_int *terminated)
1169 {
1170 	int argc, quot;
1171 	size_t i, j;
1172 	static char argvs[MAXARGLEN];
1173 	static char *argv[MAXARGS + 1];
1174 	enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
1175 
1176 	*argcp = argc = 0;
1177 	if (strlen(arg) > sizeof(argvs) - 1) {
1178  args_too_longs:
1179 		error("string too long");
1180 		return NULL;
1181 	}
1182 	if (terminated != NULL)
1183 		*terminated = 1;
1184 	if (lastquote != NULL)
1185 		*lastquote = '\0';
1186 	state = MA_START;
1187 	i = j = 0;
1188 	for (;;) {
1189 		if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){
1190 			error("Too many arguments.");
1191 			return NULL;
1192 		}
1193 		if (isspace((unsigned char)arg[i])) {
1194 			if (state == MA_UNQUOTED) {
1195 				/* Terminate current argument */
1196 				argvs[j++] = '\0';
1197 				argc++;
1198 				state = MA_START;
1199 			} else if (state != MA_START)
1200 				argvs[j++] = arg[i];
1201 		} else if (arg[i] == '"' || arg[i] == '\'') {
1202 			q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
1203 			if (state == MA_START) {
1204 				argv[argc] = argvs + j;
1205 				state = q;
1206 				if (lastquote != NULL)
1207 					*lastquote = arg[i];
1208 			} else if (state == MA_UNQUOTED)
1209 				state = q;
1210 			else if (state == q)
1211 				state = MA_UNQUOTED;
1212 			else
1213 				argvs[j++] = arg[i];
1214 		} else if (arg[i] == '\\') {
1215 			if (state == MA_SQUOTE || state == MA_DQUOTE) {
1216 				quot = state == MA_SQUOTE ? '\'' : '"';
1217 				/* Unescape quote we are in */
1218 				/* XXX support \n and friends? */
1219 				if (arg[i + 1] == quot) {
1220 					i++;
1221 					argvs[j++] = arg[i];
1222 				} else if (arg[i + 1] == '?' ||
1223 				    arg[i + 1] == '[' || arg[i + 1] == '*') {
1224 					/*
1225 					 * Special case for sftp: append
1226 					 * double-escaped glob sequence -
1227 					 * glob will undo one level of
1228 					 * escaping. NB. string can grow here.
1229 					 */
1230 					if (j >= sizeof(argvs) - 5)
1231 						goto args_too_longs;
1232 					argvs[j++] = '\\';
1233 					argvs[j++] = arg[i++];
1234 					argvs[j++] = '\\';
1235 					argvs[j++] = arg[i];
1236 				} else {
1237 					argvs[j++] = arg[i++];
1238 					argvs[j++] = arg[i];
1239 				}
1240 			} else {
1241 				if (state == MA_START) {
1242 					argv[argc] = argvs + j;
1243 					state = MA_UNQUOTED;
1244 					if (lastquote != NULL)
1245 						*lastquote = '\0';
1246 				}
1247 				if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
1248 				    arg[i + 1] == '*' || arg[i + 1] == '\\') {
1249 					/*
1250 					 * Special case for sftp: append
1251 					 * escaped glob sequence -
1252 					 * glob will undo one level of
1253 					 * escaping.
1254 					 */
1255 					argvs[j++] = arg[i++];
1256 					argvs[j++] = arg[i];
1257 				} else {
1258 					/* Unescape everything */
1259 					/* XXX support \n and friends? */
1260 					i++;
1261 					argvs[j++] = arg[i];
1262 				}
1263 			}
1264 		} else if (arg[i] == '#') {
1265 			if (state == MA_SQUOTE || state == MA_DQUOTE)
1266 				argvs[j++] = arg[i];
1267 			else
1268 				goto string_done;
1269 		} else if (arg[i] == '\0') {
1270 			if (state == MA_SQUOTE || state == MA_DQUOTE) {
1271 				if (sloppy) {
1272 					state = MA_UNQUOTED;
1273 					if (terminated != NULL)
1274 						*terminated = 0;
1275 					goto string_done;
1276 				}
1277 				error("Unterminated quoted argument");
1278 				return NULL;
1279 			}
1280  string_done:
1281 			if (state == MA_UNQUOTED) {
1282 				argvs[j++] = '\0';
1283 				argc++;
1284 			}
1285 			break;
1286 		} else {
1287 			if (state == MA_START) {
1288 				argv[argc] = argvs + j;
1289 				state = MA_UNQUOTED;
1290 				if (lastquote != NULL)
1291 					*lastquote = '\0';
1292 			}
1293 			if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
1294 			    (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
1295 				/*
1296 				 * Special case for sftp: escape quoted
1297 				 * glob(3) wildcards. NB. string can grow
1298 				 * here.
1299 				 */
1300 				if (j >= sizeof(argvs) - 3)
1301 					goto args_too_longs;
1302 				argvs[j++] = '\\';
1303 				argvs[j++] = arg[i];
1304 			} else
1305 				argvs[j++] = arg[i];
1306 		}
1307 		i++;
1308 	}
1309 	*argcp = argc;
1310 	return argv;
1311 }
1312 
1313 static int
1314 parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
1315 	  int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
1316 	  int *rflag, int *sflag,
1317     unsigned long *n_arg, char **path1, char **path2)
1318 {
1319 	const char *cmd, *cp = *cpp;
1320 	char *cp2, **argv;
1321 	int base = 0;
1322 	long long ll;
1323 	int path1_mandatory = 0, i, cmdnum, optidx, argc;
1324 
1325 	/* Skip leading whitespace */
1326 	cp = cp + strspn(cp, WHITESPACE);
1327 
1328 	/*
1329 	 * Check for leading '-' (disable error processing) and '@' (suppress
1330 	 * command echo)
1331 	 */
1332 	*ignore_errors = 0;
1333 	*disable_echo = 0;
1334 	for (;*cp != '\0'; cp++) {
1335 		if (*cp == '-') {
1336 			*ignore_errors = 1;
1337 		} else if (*cp == '@') {
1338 			*disable_echo = 1;
1339 		} else {
1340 			/* all other characters terminate prefix processing */
1341 			break;
1342 		}
1343 	}
1344 	cp = cp + strspn(cp, WHITESPACE);
1345 
1346 	/* Ignore blank lines and lines which begin with comment '#' char */
1347 	if (*cp == '\0' || *cp == '#')
1348 		return (0);
1349 
1350 	if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
1351 		return -1;
1352 
1353 	/* Figure out which command we have */
1354 	for (i = 0; cmds[i].c != NULL; i++) {
1355 		if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
1356 			break;
1357 	}
1358 	cmdnum = cmds[i].n;
1359 	cmd = cmds[i].c;
1360 
1361 	/* Special case */
1362 	if (*cp == '!') {
1363 		cp++;
1364 		cmdnum = I_SHELL;
1365 	} else if (cmdnum == -1) {
1366 		error("Invalid command.");
1367 		return -1;
1368 	}
1369 
1370 	/* Get arguments and parse flags */
1371 	*aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0;
1372 	*rflag = *sflag = 0;
1373 	*path1 = *path2 = NULL;
1374 	optidx = 1;
1375 	switch (cmdnum) {
1376 	case I_GET:
1377 	case I_REGET:
1378 	case I_REPUT:
1379 	case I_PUT:
1380 		if ((optidx = parse_getput_flags(cmd, argv, argc,
1381 		    aflag, fflag, pflag, rflag)) == -1)
1382 			return -1;
1383 		/* Get first pathname (mandatory) */
1384 		if (argc - optidx < 1) {
1385 			error("You must specify at least one path after a "
1386 			    "%s command.", cmd);
1387 			return -1;
1388 		}
1389 		*path1 = xstrdup(argv[optidx]);
1390 		/* Get second pathname (optional) */
1391 		if (argc - optidx > 1) {
1392 			*path2 = xstrdup(argv[optidx + 1]);
1393 			/* Destination is not globbed */
1394 			undo_glob_escape(*path2);
1395 		}
1396 		break;
1397 	case I_LINK:
1398 		if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
1399 			return -1;
1400 		goto parse_two_paths;
1401 	case I_COPY:
1402 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1403 			return -1;
1404 		goto parse_two_paths;
1405 	case I_RENAME:
1406 		if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
1407 			return -1;
1408 		goto parse_two_paths;
1409 	case I_SYMLINK:
1410 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1411 			return -1;
1412  parse_two_paths:
1413 		if (argc - optidx < 2) {
1414 			error("You must specify two paths after a %s "
1415 			    "command.", cmd);
1416 			return -1;
1417 		}
1418 		*path1 = xstrdup(argv[optidx]);
1419 		*path2 = xstrdup(argv[optidx + 1]);
1420 		/* Paths are not globbed */
1421 		undo_glob_escape(*path1);
1422 		undo_glob_escape(*path2);
1423 		break;
1424 	case I_RM:
1425 	case I_MKDIR:
1426 	case I_RMDIR:
1427 	case I_LMKDIR:
1428 		path1_mandatory = 1;
1429 		/* FALLTHROUGH */
1430 	case I_CHDIR:
1431 	case I_LCHDIR:
1432 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1433 			return -1;
1434 		/* Get pathname (mandatory) */
1435 		if (argc - optidx < 1) {
1436 			if (!path1_mandatory)
1437 				break; /* return a NULL path1 */
1438 			error("You must specify a path after a %s command.",
1439 			    cmd);
1440 			return -1;
1441 		}
1442 		*path1 = xstrdup(argv[optidx]);
1443 		/* Only "rm" globs */
1444 		if (cmdnum != I_RM)
1445 			undo_glob_escape(*path1);
1446 		break;
1447 	case I_DF:
1448 		if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
1449 		    iflag)) == -1)
1450 			return -1;
1451 		/* Default to current directory if no path specified */
1452 		if (argc - optidx < 1)
1453 			*path1 = NULL;
1454 		else {
1455 			*path1 = xstrdup(argv[optidx]);
1456 			undo_glob_escape(*path1);
1457 		}
1458 		break;
1459 	case I_LS:
1460 		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
1461 			return(-1);
1462 		/* Path is optional */
1463 		if (argc - optidx > 0)
1464 			*path1 = xstrdup(argv[optidx]);
1465 		break;
1466 	case I_LLS:
1467 		/* Skip ls command and following whitespace */
1468 		cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
1469 	case I_SHELL:
1470 		/* Uses the rest of the line */
1471 		break;
1472 	case I_LUMASK:
1473 	case I_CHMOD:
1474 		base = 8;
1475 		/* FALLTHROUGH */
1476 	case I_CHOWN:
1477 	case I_CHGRP:
1478 		if ((optidx = parse_ch_flags(cmd, argv, argc, hflag)) == -1)
1479 			return -1;
1480 		/* Get numeric arg (mandatory) */
1481 		if (argc - optidx < 1)
1482 			goto need_num_arg;
1483 		errno = 0;
1484 		ll = strtoll(argv[optidx], &cp2, base);
1485 		if (cp2 == argv[optidx] || *cp2 != '\0' ||
1486 		    ((ll == LLONG_MIN || ll == LLONG_MAX) && errno == ERANGE) ||
1487 		    ll < 0 || ll > UINT32_MAX) {
1488  need_num_arg:
1489 			error("You must supply a numeric argument "
1490 			    "to the %s command.", cmd);
1491 			return -1;
1492 		}
1493 		*n_arg = ll;
1494 		if (cmdnum == I_LUMASK)
1495 			break;
1496 		/* Get pathname (mandatory) */
1497 		if (argc - optidx < 2) {
1498 			error("You must specify a path after a %s command.",
1499 			    cmd);
1500 			return -1;
1501 		}
1502 		*path1 = xstrdup(argv[optidx + 1]);
1503 		break;
1504 	case I_QUIT:
1505 	case I_PWD:
1506 	case I_LPWD:
1507 	case I_HELP:
1508 	case I_VERSION:
1509 	case I_PROGRESS:
1510 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1511 			return -1;
1512 		break;
1513 	default:
1514 		fatal("Command not implemented");
1515 	}
1516 
1517 	*cpp = cp;
1518 	return(cmdnum);
1519 }
1520 
1521 static int
1522 parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1523     const char *startdir, int err_abort, int echo_command)
1524 {
1525 	const char *ocmd = cmd;
1526 	char *path1, *path2, *tmp;
1527 	int ignore_errors = 0, disable_echo = 1;
1528 	int aflag = 0, fflag = 0, hflag = 0, iflag = 0;
1529 	int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
1530 	int cmdnum, i;
1531 	unsigned long n_arg = 0;
1532 	Attrib a, aa;
1533 	char path_buf[PATH_MAX];
1534 	int err = 0;
1535 	glob_t g;
1536 
1537 	path1 = path2 = NULL;
1538 	cmdnum = parse_args(&cmd, &ignore_errors, &disable_echo, &aflag, &fflag,
1539 	    &hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg,
1540 	    &path1, &path2);
1541 	if (ignore_errors != 0)
1542 		err_abort = 0;
1543 
1544 	if (echo_command && !disable_echo)
1545 		mprintf("sftp> %s\n", ocmd);
1546 
1547 	memset(&g, 0, sizeof(g));
1548 
1549 	/* Perform command */
1550 	switch (cmdnum) {
1551 	case 0:
1552 		/* Blank line */
1553 		break;
1554 	case -1:
1555 		/* Unrecognized command */
1556 		err = -1;
1557 		break;
1558 	case I_REGET:
1559 		aflag = 1;
1560 		/* FALLTHROUGH */
1561 	case I_GET:
1562 		err = process_get(conn, path1, path2, *pwd, pflag,
1563 		    rflag, aflag, fflag);
1564 		break;
1565 	case I_REPUT:
1566 		aflag = 1;
1567 		/* FALLTHROUGH */
1568 	case I_PUT:
1569 		err = process_put(conn, path1, path2, *pwd, pflag,
1570 		    rflag, aflag, fflag);
1571 		break;
1572 	case I_COPY:
1573 		path1 = sftp_make_absolute(path1, *pwd);
1574 		path2 = sftp_make_absolute(path2, *pwd);
1575 		err = sftp_copy(conn, path1, path2);
1576 		break;
1577 	case I_RENAME:
1578 		path1 = sftp_make_absolute(path1, *pwd);
1579 		path2 = sftp_make_absolute(path2, *pwd);
1580 		err = sftp_rename(conn, path1, path2, lflag);
1581 		break;
1582 	case I_SYMLINK:
1583 		sflag = 1;
1584 		/* FALLTHROUGH */
1585 	case I_LINK:
1586 		if (!sflag)
1587 			path1 = sftp_make_absolute(path1, *pwd);
1588 		path2 = sftp_make_absolute(path2, *pwd);
1589 		err = (sflag ? sftp_symlink : sftp_hardlink)(conn,
1590 		    path1, path2);
1591 		break;
1592 	case I_RM:
1593 		path1 = make_absolute_pwd_glob(path1, *pwd);
1594 		sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1595 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1596 			if (!quiet)
1597 				mprintf("Removing %s\n", g.gl_pathv[i]);
1598 			err = sftp_rm(conn, g.gl_pathv[i]);
1599 			if (err != 0 && err_abort)
1600 				break;
1601 		}
1602 		break;
1603 	case I_MKDIR:
1604 		path1 = sftp_make_absolute(path1, *pwd);
1605 		attrib_clear(&a);
1606 		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
1607 		a.perm = 0777;
1608 		err = sftp_mkdir(conn, path1, &a, 1);
1609 		break;
1610 	case I_RMDIR:
1611 		path1 = sftp_make_absolute(path1, *pwd);
1612 		err = sftp_rmdir(conn, path1);
1613 		break;
1614 	case I_CHDIR:
1615 		if (path1 == NULL || *path1 == '\0')
1616 			path1 = xstrdup(startdir);
1617 		path1 = sftp_make_absolute(path1, *pwd);
1618 		if ((tmp = sftp_realpath(conn, path1)) == NULL) {
1619 			err = 1;
1620 			break;
1621 		}
1622 		if (sftp_stat(conn, tmp, 0, &aa) != 0) {
1623 			free(tmp);
1624 			err = 1;
1625 			break;
1626 		}
1627 		if (!(aa.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
1628 			error("Can't change directory: Can't check target");
1629 			free(tmp);
1630 			err = 1;
1631 			break;
1632 		}
1633 		if (!S_ISDIR(aa.perm)) {
1634 			error("Can't change directory: \"%s\" is not "
1635 			    "a directory", tmp);
1636 			free(tmp);
1637 			err = 1;
1638 			break;
1639 		}
1640 		free(*pwd);
1641 		*pwd = tmp;
1642 		break;
1643 	case I_LS:
1644 		if (!path1) {
1645 			do_ls_dir(conn, *pwd, *pwd, lflag);
1646 			break;
1647 		}
1648 
1649 		/* Strip pwd off beginning of non-absolute paths */
1650 		tmp = NULL;
1651 		if (!path_absolute(path1))
1652 			tmp = *pwd;
1653 
1654 		path1 = make_absolute_pwd_glob(path1, *pwd);
1655 		err = do_globbed_ls(conn, path1, tmp, lflag);
1656 		break;
1657 	case I_DF:
1658 		/* Default to current directory if no path specified */
1659 		if (path1 == NULL)
1660 			path1 = xstrdup(*pwd);
1661 		path1 = sftp_make_absolute(path1, *pwd);
1662 		err = do_df(conn, path1, hflag, iflag);
1663 		break;
1664 	case I_LCHDIR:
1665 		if (path1 == NULL || *path1 == '\0')
1666 			path1 = xstrdup("~");
1667 		tmp = tilde_expand_filename(path1, getuid());
1668 		free(path1);
1669 		path1 = tmp;
1670 		if (chdir(path1) == -1) {
1671 			error("Couldn't change local directory to "
1672 			    "\"%s\": %s", path1, strerror(errno));
1673 			err = 1;
1674 		}
1675 		break;
1676 	case I_LMKDIR:
1677 		if (mkdir(path1, 0777) == -1) {
1678 			error("Couldn't create local directory "
1679 			    "\"%s\": %s", path1, strerror(errno));
1680 			err = 1;
1681 		}
1682 		break;
1683 	case I_LLS:
1684 		local_do_ls(cmd);
1685 		break;
1686 	case I_SHELL:
1687 		local_do_shell(cmd);
1688 		break;
1689 	case I_LUMASK:
1690 		umask(n_arg);
1691 		printf("Local umask: %03lo\n", n_arg);
1692 		break;
1693 	case I_CHMOD:
1694 		path1 = make_absolute_pwd_glob(path1, *pwd);
1695 		attrib_clear(&a);
1696 		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
1697 		a.perm = n_arg;
1698 		sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1699 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1700 			if (!quiet)
1701 				mprintf("Changing mode on %s\n",
1702 				    g.gl_pathv[i]);
1703 			err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
1704 			    g.gl_pathv[i], &a);
1705 			if (err != 0 && err_abort)
1706 				break;
1707 		}
1708 		break;
1709 	case I_CHOWN:
1710 	case I_CHGRP:
1711 		path1 = make_absolute_pwd_glob(path1, *pwd);
1712 		sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1713 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1714 			if ((hflag ? sftp_lstat : sftp_stat)(conn,
1715 			    g.gl_pathv[i], 0, &aa) != 0) {
1716 				if (err_abort) {
1717 					err = -1;
1718 					break;
1719 				} else
1720 					continue;
1721 			}
1722 			if (!(aa.flags & SSH2_FILEXFER_ATTR_UIDGID)) {
1723 				error("Can't get current ownership of "
1724 				    "remote file \"%s\"", g.gl_pathv[i]);
1725 				if (err_abort) {
1726 					err = -1;
1727 					break;
1728 				} else
1729 					continue;
1730 			}
1731 			aa.flags &= SSH2_FILEXFER_ATTR_UIDGID;
1732 			if (cmdnum == I_CHOWN) {
1733 				if (!quiet)
1734 					mprintf("Changing owner on %s\n",
1735 					    g.gl_pathv[i]);
1736 				aa.uid = n_arg;
1737 			} else {
1738 				if (!quiet)
1739 					mprintf("Changing group on %s\n",
1740 					    g.gl_pathv[i]);
1741 				aa.gid = n_arg;
1742 			}
1743 			err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
1744 			    g.gl_pathv[i], &aa);
1745 			if (err != 0 && err_abort)
1746 				break;
1747 		}
1748 		break;
1749 	case I_PWD:
1750 		mprintf("Remote working directory: %s\n", *pwd);
1751 		break;
1752 	case I_LPWD:
1753 		if (!getcwd(path_buf, sizeof(path_buf))) {
1754 			error("Couldn't get local cwd: %s", strerror(errno));
1755 			err = -1;
1756 			break;
1757 		}
1758 		mprintf("Local working directory: %s\n", path_buf);
1759 		break;
1760 	case I_QUIT:
1761 		/* Processed below */
1762 		break;
1763 	case I_HELP:
1764 		help();
1765 		break;
1766 	case I_VERSION:
1767 		printf("SFTP protocol version %u\n", sftp_proto_version(conn));
1768 		break;
1769 	case I_PROGRESS:
1770 		showprogress = !showprogress;
1771 		if (showprogress)
1772 			printf("Progress meter enabled\n");
1773 		else
1774 			printf("Progress meter disabled\n");
1775 		break;
1776 	default:
1777 		fatal("%d is not implemented", cmdnum);
1778 	}
1779 
1780 	if (g.gl_pathc)
1781 		globfree(&g);
1782 	free(path1);
1783 	free(path2);
1784 
1785 	/* If an unignored error occurs in batch mode we should abort. */
1786 	if (err_abort && err != 0)
1787 		return (-1);
1788 	else if (cmdnum == I_QUIT)
1789 		return (1);
1790 
1791 	return (0);
1792 }
1793 
1794 static char *
1795 prompt(EditLine *el)
1796 {
1797 	return ("sftp> ");
1798 }
1799 
1800 /* Display entries in 'list' after skipping the first 'len' chars */
1801 static void
1802 complete_display(char **list, u_int len)
1803 {
1804 	u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;
1805 	struct winsize ws;
1806 	char *tmp;
1807 
1808 	/* Count entries for sort and find longest */
1809 	for (y = 0; list[y]; y++)
1810 		m = MAXIMUM(m, strlen(list[y]));
1811 
1812 	if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
1813 		width = ws.ws_col;
1814 
1815 	m = m > len ? m - len : 0;
1816 	columns = width / (m + 2);
1817 	columns = MAXIMUM(columns, 1);
1818 	colspace = width / columns;
1819 	colspace = MINIMUM(colspace, width);
1820 
1821 	printf("\n");
1822 	m = 1;
1823 	for (y = 0; list[y]; y++) {
1824 		llen = strlen(list[y]);
1825 		tmp = llen > len ? list[y] + len : "";
1826 		mprintf("%-*s", colspace, tmp);
1827 		if (m >= columns) {
1828 			printf("\n");
1829 			m = 1;
1830 		} else
1831 			m++;
1832 	}
1833 	printf("\n");
1834 }
1835 
1836 /*
1837  * Given a "list" of words that begin with a common prefix of "word",
1838  * attempt to find an autocompletion to extends "word" by the next
1839  * characters common to all entries in "list".
1840  */
1841 static char *
1842 complete_ambiguous(const char *word, char **list, size_t count)
1843 {
1844 	if (word == NULL)
1845 		return NULL;
1846 
1847 	if (count > 0) {
1848 		u_int y, matchlen = strlen(list[0]);
1849 
1850 		/* Find length of common stem */
1851 		for (y = 1; list[y]; y++) {
1852 			u_int x;
1853 
1854 			for (x = 0; x < matchlen; x++)
1855 				if (list[0][x] != list[y][x])
1856 					break;
1857 
1858 			matchlen = x;
1859 		}
1860 
1861 		if (matchlen > strlen(word)) {
1862 			char *tmp = xstrdup(list[0]);
1863 
1864 			tmp[matchlen] = '\0';
1865 			return tmp;
1866 		}
1867 	}
1868 
1869 	return xstrdup(word);
1870 }
1871 
1872 /* Autocomplete a sftp command */
1873 static int
1874 complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
1875     int terminated)
1876 {
1877 	u_int y, count = 0, cmdlen, tmplen;
1878 	char *tmp, **list, argterm[3];
1879 	const LineInfo *lf;
1880 
1881 	list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));
1882 
1883 	/* No command specified: display all available commands */
1884 	if (cmd == NULL) {
1885 		for (y = 0; cmds[y].c; y++)
1886 			list[count++] = xstrdup(cmds[y].c);
1887 
1888 		list[count] = NULL;
1889 		complete_display(list, 0);
1890 
1891 		for (y = 0; list[y] != NULL; y++)
1892 			free(list[y]);
1893 		free(list);
1894 		return count;
1895 	}
1896 
1897 	/* Prepare subset of commands that start with "cmd" */
1898 	cmdlen = strlen(cmd);
1899 	for (y = 0; cmds[y].c; y++)  {
1900 		if (!strncasecmp(cmd, cmds[y].c, cmdlen))
1901 			list[count++] = xstrdup(cmds[y].c);
1902 	}
1903 	list[count] = NULL;
1904 
1905 	if (count == 0) {
1906 		free(list);
1907 		return 0;
1908 	}
1909 
1910 	/* Complete ambiguous command */
1911 	tmp = complete_ambiguous(cmd, list, count);
1912 	if (count > 1)
1913 		complete_display(list, 0);
1914 
1915 	for (y = 0; list[y]; y++)
1916 		free(list[y]);
1917 	free(list);
1918 
1919 	if (tmp != NULL) {
1920 		tmplen = strlen(tmp);
1921 		cmdlen = strlen(cmd);
1922 		/* If cmd may be extended then do so */
1923 		if (tmplen > cmdlen)
1924 			if (el_insertstr(el, tmp + cmdlen) == -1)
1925 				fatal("el_insertstr failed.");
1926 		lf = el_line(el);
1927 		/* Terminate argument cleanly */
1928 		if (count == 1) {
1929 			y = 0;
1930 			if (!terminated)
1931 				argterm[y++] = quote;
1932 			if (lastarg || *(lf->cursor) != ' ')
1933 				argterm[y++] = ' ';
1934 			argterm[y] = '\0';
1935 			if (y > 0 && el_insertstr(el, argterm) == -1)
1936 				fatal("el_insertstr failed.");
1937 		}
1938 		free(tmp);
1939 	}
1940 
1941 	return count;
1942 }
1943 
1944 /*
1945  * Determine whether a particular sftp command's arguments (if any) represent
1946  * local or remote files. The "cmdarg" argument specifies the actual argument
1947  * and accepts values 1 or 2.
1948  */
1949 static int
1950 complete_is_remote(char *cmd, int cmdarg) {
1951 	int i;
1952 
1953 	if (cmd == NULL)
1954 		return -1;
1955 
1956 	for (i = 0; cmds[i].c; i++) {
1957 		if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) {
1958 			if (cmdarg == 1)
1959 				return cmds[i].t;
1960 			else if (cmdarg == 2)
1961 				return cmds[i].t2;
1962 			break;
1963 		}
1964 	}
1965 
1966 	return -1;
1967 }
1968 
1969 /* Autocomplete a filename "file" */
1970 static int
1971 complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1972     char *file, int remote, int lastarg, char quote, int terminated)
1973 {
1974 	glob_t g;
1975 	char *tmp, *tmp2, ins[8];
1976 	u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
1977 	int clen;
1978 	const LineInfo *lf;
1979 
1980 	/* Glob from "file" location */
1981 	if (file == NULL)
1982 		tmp = xstrdup("*");
1983 	else
1984 		xasprintf(&tmp, "%s*", file);
1985 
1986 	/* Check if the path is absolute. */
1987 	isabs = path_absolute(tmp);
1988 
1989 	memset(&g, 0, sizeof(g));
1990 	if (remote != LOCAL) {
1991 		tmp = make_absolute_pwd_glob(tmp, remote_path);
1992 		sftp_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1993 	} else
1994 		(void)glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1995 
1996 	/* Determine length of pwd so we can trim completion display */
1997 	for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
1998 		/* Terminate counting on first unescaped glob metacharacter */
1999 		if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {
2000 			if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')
2001 				hadglob = 1;
2002 			break;
2003 		}
2004 		if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')
2005 			tmplen++;
2006 		if (tmp[tmplen] == '/')
2007 			pwdlen = tmplen + 1;	/* track last seen '/' */
2008 	}
2009 	free(tmp);
2010 	tmp = NULL;
2011 
2012 	if (g.gl_matchc == 0)
2013 		goto out;
2014 
2015 	if (g.gl_matchc > 1)
2016 		complete_display(g.gl_pathv, pwdlen);
2017 
2018 	/* Don't try to extend globs */
2019 	if (file == NULL || hadglob)
2020 		goto out;
2021 
2022 	tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
2023 	tmp = path_strip(tmp2, isabs ? NULL : remote_path);
2024 	free(tmp2);
2025 
2026 	if (tmp == NULL)
2027 		goto out;
2028 
2029 	tmplen = strlen(tmp);
2030 	filelen = strlen(file);
2031 
2032 	/* Count the number of escaped characters in the input string. */
2033 	cesc = isesc = 0;
2034 	for (i = 0; i < filelen; i++) {
2035 		if (!isesc && file[i] == '\\' && i + 1 < filelen){
2036 			isesc = 1;
2037 			cesc++;
2038 		} else
2039 			isesc = 0;
2040 	}
2041 
2042 	if (tmplen > (filelen - cesc)) {
2043 		tmp2 = tmp + filelen - cesc;
2044 		len = strlen(tmp2);
2045 		/* quote argument on way out */
2046 		for (i = 0; i < len; i += clen) {
2047 			if ((clen = mblen(tmp2 + i, len - i)) < 0 ||
2048 			    (size_t)clen > sizeof(ins) - 2)
2049 				fatal("invalid multibyte character");
2050 			ins[0] = '\\';
2051 			memcpy(ins + 1, tmp2 + i, clen);
2052 			ins[clen + 1] = '\0';
2053 			switch (tmp2[i]) {
2054 			case '\'':
2055 			case '"':
2056 			case '\\':
2057 			case '\t':
2058 			case '[':
2059 			case ' ':
2060 			case '#':
2061 			case '*':
2062 				if (quote == '\0' || tmp2[i] == quote) {
2063 					if (el_insertstr(el, ins) == -1)
2064 						fatal("el_insertstr "
2065 						    "failed.");
2066 					break;
2067 				}
2068 				/* FALLTHROUGH */
2069 			default:
2070 				if (el_insertstr(el, ins + 1) == -1)
2071 					fatal("el_insertstr failed.");
2072 				break;
2073 			}
2074 		}
2075 	}
2076 
2077 	lf = el_line(el);
2078 	if (g.gl_matchc == 1) {
2079 		i = 0;
2080 		if (!terminated && quote != '\0')
2081 			ins[i++] = quote;
2082 		if (*(lf->cursor - 1) != '/' &&
2083 		    (lastarg || *(lf->cursor) != ' '))
2084 			ins[i++] = ' ';
2085 		ins[i] = '\0';
2086 		if (i > 0 && el_insertstr(el, ins) == -1)
2087 			fatal("el_insertstr failed.");
2088 	}
2089 	free(tmp);
2090 
2091  out:
2092 	globfree(&g);
2093 	return g.gl_matchc;
2094 }
2095 
2096 /* tab-completion hook function, called via libedit */
2097 static unsigned char
2098 complete(EditLine *el, int ch)
2099 {
2100 	char **argv, *line, quote;
2101 	int argc, carg;
2102 	u_int cursor, len, terminated, ret = CC_ERROR;
2103 	const LineInfo *lf;
2104 	struct complete_ctx *complete_ctx;
2105 
2106 	lf = el_line(el);
2107 	if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
2108 		fatal_f("el_get failed");
2109 
2110 	/* Figure out which argument the cursor points to */
2111 	cursor = lf->cursor - lf->buffer;
2112 	line = xmalloc(cursor + 1);
2113 	memcpy(line, lf->buffer, cursor);
2114 	line[cursor] = '\0';
2115 	argv = makeargv(line, &carg, 1, &quote, &terminated);
2116 	free(line);
2117 
2118 	/* Get all the arguments on the line */
2119 	len = lf->lastchar - lf->buffer;
2120 	line = xmalloc(len + 1);
2121 	memcpy(line, lf->buffer, len);
2122 	line[len] = '\0';
2123 	argv = makeargv(line, &argc, 1, NULL, NULL);
2124 
2125 	/* Ensure cursor is at EOL or a argument boundary */
2126 	if (line[cursor] != ' ' && line[cursor] != '\0' &&
2127 	    line[cursor] != '\n') {
2128 		free(line);
2129 		return ret;
2130 	}
2131 
2132 	if (carg == 0) {
2133 		/* Show all available commands */
2134 		complete_cmd_parse(el, NULL, argc == carg, '\0', 1);
2135 		ret = CC_REDISPLAY;
2136 	} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ')  {
2137 		/* Handle the command parsing */
2138 		if (complete_cmd_parse(el, argv[0], argc == carg,
2139 		    quote, terminated) != 0)
2140 			ret = CC_REDISPLAY;
2141 	} else if (carg >= 1) {
2142 		/* Handle file parsing */
2143 		int remote = 0;
2144 		int i = 0, cmdarg = 0;
2145 		char *filematch = NULL;
2146 
2147 		if (carg > 1 && line[cursor-1] != ' ')
2148 			filematch = argv[carg - 1];
2149 
2150 		for (i = 1; i < carg; i++) {
2151 			/* Skip flags */
2152 			if (argv[i][0] != '-')
2153 				cmdarg++;
2154 		}
2155 
2156 		/*
2157 		 * If previous argument is complete, then offer completion
2158 		 * on the next one.
2159 		 */
2160 		if (line[cursor - 1] == ' ')
2161 			cmdarg++;
2162 
2163 		remote = complete_is_remote(argv[0], cmdarg);
2164 
2165 		if ((remote == REMOTE || remote == LOCAL) &&
2166 		    complete_match(el, complete_ctx->conn,
2167 		    *complete_ctx->remote_pathp, filematch,
2168 		    remote, carg == argc, quote, terminated) != 0)
2169 			ret = CC_REDISPLAY;
2170 	}
2171 
2172 	free(line);
2173 	return ret;
2174 }
2175 
2176 static int
2177 interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2178 {
2179 	char *remote_path;
2180 	char *dir = NULL, *startdir = NULL;
2181 	char cmd[2048];
2182 	int err, interactive;
2183 	EditLine *el = NULL;
2184 	History *hl = NULL;
2185 	HistEvent hev;
2186 	extern char *__progname;
2187 	struct complete_ctx complete_ctx;
2188 
2189 	if (!batchmode && isatty(STDIN_FILENO)) {
2190 		if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
2191 			fatal("Couldn't initialise editline");
2192 		if ((hl = history_init()) == NULL)
2193 			fatal("Couldn't initialise editline history");
2194 		history(hl, &hev, H_SETSIZE, 100);
2195 		el_set(el, EL_HIST, history, hl);
2196 
2197 		el_set(el, EL_PROMPT, prompt);
2198 		el_set(el, EL_EDITOR, "emacs");
2199 		el_set(el, EL_TERMINAL, NULL);
2200 		el_set(el, EL_SIGNAL, 1);
2201 		el_source(el, NULL);
2202 
2203 		/* Tab Completion */
2204 		el_set(el, EL_ADDFN, "ftp-complete",
2205 		    "Context sensitive argument completion", complete);
2206 		complete_ctx.conn = conn;
2207 		complete_ctx.remote_pathp = &remote_path;
2208 		el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
2209 		el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
2210 		/* enable ctrl-left-arrow and ctrl-right-arrow */
2211 		el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
2212 		el_set(el, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
2213 		el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
2214 		el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
2215 		/* make ^w match ksh behaviour */
2216 		el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);
2217 	}
2218 
2219 	if ((remote_path = sftp_realpath(conn, ".")) == NULL)
2220 		fatal("Need cwd");
2221 	startdir = xstrdup(remote_path);
2222 
2223 	if (file1 != NULL) {
2224 		dir = xstrdup(file1);
2225 		dir = sftp_make_absolute(dir, remote_path);
2226 
2227 		if (sftp_remote_is_dir(conn, dir) && file2 == NULL) {
2228 			if (!quiet)
2229 				mprintf("Changing to: %s\n", dir);
2230 			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
2231 			if (parse_dispatch_command(conn, cmd,
2232 			    &remote_path, startdir, 1, 0) != 0) {
2233 				free(dir);
2234 				free(startdir);
2235 				free(remote_path);
2236 				free(conn);
2237 				return (-1);
2238 			}
2239 		} else {
2240 			/* XXX this is wrong wrt quoting */
2241 			snprintf(cmd, sizeof cmd, "get%s %s%s%s",
2242 			    global_aflag ? " -a" : "", dir,
2243 			    file2 == NULL ? "" : " ",
2244 			    file2 == NULL ? "" : file2);
2245 			err = parse_dispatch_command(conn, cmd,
2246 			    &remote_path, startdir, 1, 0);
2247 			free(dir);
2248 			free(startdir);
2249 			free(remote_path);
2250 			free(conn);
2251 			return (err);
2252 		}
2253 		free(dir);
2254 	}
2255 
2256 	setvbuf(stdout, NULL, _IOLBF, 0);
2257 	setvbuf(infile, NULL, _IOLBF, 0);
2258 
2259 	interactive = !batchmode && isatty(STDIN_FILENO);
2260 	err = 0;
2261 	for (;;) {
2262 		struct sigaction sa;
2263 		const char *line;
2264 		int count = 0;
2265 
2266 		interrupted = 0;
2267 		memset(&sa, 0, sizeof(sa));
2268 		sa.sa_handler = interactive ? read_interrupt : killchild;
2269 		if (sigaction(SIGINT, &sa, NULL) == -1) {
2270 			debug3("sigaction(%s): %s", strsignal(SIGINT),
2271 			    strerror(errno));
2272 			break;
2273 		}
2274 		if (el == NULL) {
2275 			if (interactive)
2276 				printf("sftp> ");
2277 			if (fgets(cmd, sizeof(cmd), infile) == NULL) {
2278 				if (interactive)
2279 					printf("\n");
2280 				if (interrupted)
2281 					continue;
2282 				break;
2283 			}
2284 		} else {
2285 			if ((line = el_gets(el, &count)) == NULL ||
2286 			    count <= 0) {
2287 				printf("\n");
2288 				if (interrupted)
2289 					continue;
2290 				break;
2291 			}
2292 			history(hl, &hev, H_ENTER, line);
2293 			if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
2294 				fprintf(stderr, "Error: input line too long\n");
2295 				continue;
2296 			}
2297 		}
2298 
2299 		cmd[strcspn(cmd, "\n")] = '\0';
2300 
2301 		/* Handle user interrupts gracefully during commands */
2302 		interrupted = 0;
2303 		ssh_signal(SIGINT, cmd_interrupt);
2304 
2305 		err = parse_dispatch_command(conn, cmd, &remote_path,
2306 		    startdir, batchmode, !interactive && el == NULL);
2307 		if (err != 0)
2308 			break;
2309 	}
2310 	ssh_signal(SIGCHLD, SIG_DFL);
2311 	free(remote_path);
2312 	free(startdir);
2313 	free(conn);
2314 
2315 	if (el != NULL)
2316 		el_end(el);
2317 
2318 	/* err == 1 signifies normal "quit" exit */
2319 	return (err >= 0 ? 0 : -1);
2320 }
2321 
2322 static void
2323 connect_to_server(char *path, char **args, int *in, int *out)
2324 {
2325 	int c_in, c_out, inout[2];
2326 
2327 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
2328 		fatal("socketpair: %s", strerror(errno));
2329 	*in = *out = inout[0];
2330 	c_in = c_out = inout[1];
2331 
2332 	if ((sshpid = fork()) == -1)
2333 		fatal("fork: %s", strerror(errno));
2334 	else if (sshpid == 0) {
2335 		if ((dup2(c_in, STDIN_FILENO) == -1) ||
2336 		    (dup2(c_out, STDOUT_FILENO) == -1)) {
2337 			fprintf(stderr, "dup2: %s\n", strerror(errno));
2338 			_exit(1);
2339 		}
2340 		close(*in);
2341 		close(*out);
2342 		close(c_in);
2343 		close(c_out);
2344 
2345 		/*
2346 		 * The underlying ssh is in the same process group, so we must
2347 		 * ignore SIGINT if we want to gracefully abort commands,
2348 		 * otherwise the signal will make it to the ssh process and
2349 		 * kill it too.  Contrawise, since sftp sends SIGTERMs to the
2350 		 * underlying ssh, it must *not* ignore that signal.
2351 		 */
2352 		ssh_signal(SIGINT, SIG_IGN);
2353 		ssh_signal(SIGTERM, SIG_DFL);
2354 		execvp(path, args);
2355 		fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
2356 		_exit(1);
2357 	}
2358 
2359 	ssh_signal(SIGTERM, killchild);
2360 	ssh_signal(SIGINT, killchild);
2361 	ssh_signal(SIGHUP, killchild);
2362 	ssh_signal(SIGTSTP, suspchild);
2363 	ssh_signal(SIGTTIN, suspchild);
2364 	ssh_signal(SIGTTOU, suspchild);
2365 	ssh_signal(SIGCHLD, sigchld_handler);
2366 	close(c_in);
2367 	close(c_out);
2368 }
2369 
2370 static void
2371 usage(void)
2372 {
2373 	extern char *__progname;
2374 
2375 	fprintf(stderr,
2376 	    "usage: %s [-46AaCfNpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2377 	    "          [-D sftp_server_command] [-F ssh_config] [-i identity_file]\n"
2378 	    "          [-J destination] [-l limit] [-o ssh_option] [-P port]\n"
2379 	    "          [-R num_requests] [-S program] [-s subsystem | sftp_server]\n"
2380 	    "          [-X sftp_option] destination\n",
2381 	    __progname);
2382 	exit(1);
2383 }
2384 
2385 int
2386 main(int argc, char **argv)
2387 {
2388 	int r, in, out, ch, err, tmp, port = -1, noisy = 0;
2389 	char *host = NULL, *user, *cp, **cpp, *file2 = NULL;
2390 	int debug_level = 0;
2391 	char *file1 = NULL, *sftp_server = NULL;
2392 	char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
2393 	const char *errstr;
2394 	LogLevel ll = SYSLOG_LEVEL_INFO;
2395 	arglist args;
2396 	extern int optind;
2397 	extern char *optarg;
2398 	struct sftp_conn *conn;
2399 	size_t copy_buffer_len = 0;
2400 	size_t num_requests = 0;
2401 	long long llv, limit_kbps = 0;
2402 
2403 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2404 	sanitise_stdfd();
2405 	setlocale(LC_CTYPE, "");
2406 
2407 	memset(&args, '\0', sizeof(args));
2408 	args.list = NULL;
2409 	addargs(&args, "%s", ssh_program);
2410 	addargs(&args, "-oForwardX11 no");
2411 	addargs(&args, "-oPermitLocalCommand no");
2412 	addargs(&args, "-oClearAllForwardings yes");
2413 
2414 	ll = SYSLOG_LEVEL_INFO;
2415 	infile = stdin;
2416 
2417 	while ((ch = getopt(argc, argv,
2418 	    "1246AafhNpqrvCc:D:i:l:o:s:S:b:B:F:J:P:R:X:")) != -1) {
2419 		switch (ch) {
2420 		/* Passed through to ssh(1) */
2421 		case 'A':
2422 		case '4':
2423 		case '6':
2424 		case 'C':
2425 			addargs(&args, "-%c", ch);
2426 			break;
2427 		/* Passed through to ssh(1) with argument */
2428 		case 'F':
2429 		case 'J':
2430 		case 'c':
2431 		case 'i':
2432 		case 'o':
2433 			addargs(&args, "-%c", ch);
2434 			addargs(&args, "%s", optarg);
2435 			break;
2436 		case 'q':
2437 			ll = SYSLOG_LEVEL_ERROR;
2438 			quiet = 1;
2439 			showprogress = 0;
2440 			addargs(&args, "-%c", ch);
2441 			break;
2442 		case 'P':
2443 			port = a2port(optarg);
2444 			if (port <= 0)
2445 				fatal("Bad port \"%s\"\n", optarg);
2446 			break;
2447 		case 'v':
2448 			if (debug_level < 3) {
2449 				addargs(&args, "-v");
2450 				ll = SYSLOG_LEVEL_DEBUG1 + debug_level;
2451 			}
2452 			debug_level++;
2453 			break;
2454 		case '1':
2455 			fatal("SSH protocol v.1 is no longer supported");
2456 			break;
2457 		case '2':
2458 			/* accept silently */
2459 			break;
2460 		case 'a':
2461 			global_aflag = 1;
2462 			break;
2463 		case 'B':
2464 			copy_buffer_len = strtol(optarg, &cp, 10);
2465 			if (copy_buffer_len == 0 || *cp != '\0')
2466 				fatal("Invalid buffer size \"%s\"", optarg);
2467 			break;
2468 		case 'b':
2469 			if (batchmode)
2470 				fatal("Batch file already specified.");
2471 
2472 			/* Allow "-" as stdin */
2473 			if (strcmp(optarg, "-") != 0 &&
2474 			    (infile = fopen(optarg, "r")) == NULL)
2475 				fatal("%s (%s).", strerror(errno), optarg);
2476 			showprogress = 0;
2477 			quiet = batchmode = 1;
2478 			addargs(&args, "-obatchmode yes");
2479 			break;
2480 		case 'f':
2481 			global_fflag = 1;
2482 			break;
2483 		case 'N':
2484 			noisy = 1; /* Used to clear quiet mode after getopt */
2485 			break;
2486 		case 'p':
2487 			global_pflag = 1;
2488 			break;
2489 		case 'D':
2490 			sftp_direct = optarg;
2491 			break;
2492 		case 'l':
2493 			limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
2494 			    &errstr);
2495 			if (errstr != NULL)
2496 				usage();
2497 			limit_kbps *= 1024; /* kbps */
2498 			break;
2499 		case 'r':
2500 			global_rflag = 1;
2501 			break;
2502 		case 'R':
2503 			num_requests = strtol(optarg, &cp, 10);
2504 			if (num_requests == 0 || *cp != '\0')
2505 				fatal("Invalid number of requests \"%s\"",
2506 				    optarg);
2507 			break;
2508 		case 's':
2509 			sftp_server = optarg;
2510 			break;
2511 		case 'S':
2512 			ssh_program = optarg;
2513 			replacearg(&args, 0, "%s", ssh_program);
2514 			break;
2515 		case 'X':
2516 			/* Please keep in sync with ssh.c -X */
2517 			if (strncmp(optarg, "buffer=", 7) == 0) {
2518 				r = scan_scaled(optarg + 7, &llv);
2519 				if (r == 0 && (llv <= 0 || llv > 256 * 1024)) {
2520 					r = -1;
2521 					errno = EINVAL;
2522 				}
2523 				if (r == -1) {
2524 					fatal("Invalid buffer size \"%s\": %s",
2525 					     optarg + 7, strerror(errno));
2526 				}
2527 				copy_buffer_len = (size_t)llv;
2528 			} else if (strncmp(optarg, "nrequests=", 10) == 0) {
2529 				llv = strtonum(optarg + 10, 1, 256 * 1024,
2530 				    &errstr);
2531 				if (errstr != NULL) {
2532 					fatal("Invalid number of requests "
2533 					    "\"%s\": %s", optarg + 10, errstr);
2534 				}
2535 				num_requests = (size_t)llv;
2536 			} else {
2537 				fatal("Invalid -X option");
2538 			}
2539 			break;
2540 		case 'h':
2541 		default:
2542 			usage();
2543 		}
2544 	}
2545 
2546 	/* Do this last because we want the user to be able to override it */
2547 	addargs(&args, "-oForwardAgent no");
2548 
2549 	if (!isatty(STDERR_FILENO))
2550 		showprogress = 0;
2551 
2552 	if (noisy)
2553 		quiet = 0;
2554 
2555 	log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
2556 
2557 	if (sftp_direct == NULL) {
2558 		if (optind == argc || argc > (optind + 2))
2559 			usage();
2560 		argv += optind;
2561 
2562 		switch (parse_uri("sftp", *argv, &user, &host, &tmp, &file1)) {
2563 		case -1:
2564 			usage();
2565 			break;
2566 		case 0:
2567 			if (tmp != -1)
2568 				port = tmp;
2569 			break;
2570 		default:
2571 			/* Try with user, host and path. */
2572 			if (parse_user_host_path(*argv, &user, &host,
2573 			    &file1) == 0)
2574 				break;
2575 			/* Try with user and host. */
2576 			if (parse_user_host_port(*argv, &user, &host, NULL)
2577 			    == 0)
2578 				break;
2579 			/* Treat as a plain hostname. */
2580 			host = xstrdup(*argv);
2581 			host = cleanhostname(host);
2582 			break;
2583 		}
2584 		file2 = *(argv + 1);
2585 
2586 		if (!*host) {
2587 			fprintf(stderr, "Missing hostname\n");
2588 			usage();
2589 		}
2590 
2591 		if (port != -1)
2592 			addargs(&args, "-oPort %d", port);
2593 		if (user != NULL) {
2594 			addargs(&args, "-l");
2595 			addargs(&args, "%s", user);
2596 		}
2597 
2598 		/* no subsystem if the server-spec contains a '/' */
2599 		if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
2600 			addargs(&args, "-s");
2601 
2602 		addargs(&args, "--");
2603 		addargs(&args, "%s", host);
2604 		addargs(&args, "%s", (sftp_server != NULL ?
2605 		    sftp_server : "sftp"));
2606 
2607 		connect_to_server(ssh_program, args.list, &in, &out);
2608 	} else {
2609 		if ((r = argv_split(sftp_direct, &tmp, &cpp, 1)) != 0)
2610 			fatal_r(r, "Parse -D arguments");
2611 		if (cpp[0] == 0)
2612 			fatal("No sftp server specified via -D");
2613 		connect_to_server(cpp[0], cpp, &in, &out);
2614 		argv_free(cpp, tmp);
2615 	}
2616 	freeargs(&args);
2617 
2618 	conn = sftp_init(in, out, copy_buffer_len, num_requests, limit_kbps);
2619 	if (conn == NULL)
2620 		fatal("Couldn't initialise connection to server");
2621 
2622 	if (!quiet) {
2623 		if (sftp_direct == NULL)
2624 			fprintf(stderr, "Connected to %s.\n", host);
2625 		else
2626 			fprintf(stderr, "Attached to %s.\n", sftp_direct);
2627 	}
2628 
2629 	err = interactive_loop(conn, file1, file2);
2630 
2631 	close(in);
2632 	close(out);
2633 	if (batchmode)
2634 		fclose(infile);
2635 
2636 	while (waitpid(sshpid, NULL, 0) == -1 && sshpid > 1)
2637 		if (errno != EINTR)
2638 			fatal("Couldn't wait for ssh process: %s",
2639 			    strerror(errno));
2640 
2641 	exit(err == 0 ? 0 : 1);
2642 }
2643