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