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