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