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