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