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