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