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