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