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