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