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