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