xref: /freebsd/crypto/openssh/sftp.c (revision 0957b409)
1 /* $OpenBSD: sftp.c,v 1.185 2018/04/26 14:47:03 bluhm 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 && p[0] != '/') {
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 *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 	/* Check for leading '-' (disable error processing) */
1314 	*ignore_errors = 0;
1315 	if (*cp == '-') {
1316 		*ignore_errors = 1;
1317 		cp++;
1318 		cp = cp + strspn(cp, WHITESPACE);
1319 	}
1320 
1321 	/* Ignore blank lines and lines which begin with comment '#' char */
1322 	if (*cp == '\0' || *cp == '#')
1323 		return (0);
1324 
1325 	if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
1326 		return -1;
1327 
1328 	/* Figure out which command we have */
1329 	for (i = 0; cmds[i].c != NULL; i++) {
1330 		if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
1331 			break;
1332 	}
1333 	cmdnum = cmds[i].n;
1334 	cmd = cmds[i].c;
1335 
1336 	/* Special case */
1337 	if (*cp == '!') {
1338 		cp++;
1339 		cmdnum = I_SHELL;
1340 	} else if (cmdnum == -1) {
1341 		error("Invalid command.");
1342 		return -1;
1343 	}
1344 
1345 	/* Get arguments and parse flags */
1346 	*aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0;
1347 	*rflag = *sflag = 0;
1348 	*path1 = *path2 = NULL;
1349 	optidx = 1;
1350 	switch (cmdnum) {
1351 	case I_GET:
1352 	case I_REGET:
1353 	case I_REPUT:
1354 	case I_PUT:
1355 		if ((optidx = parse_getput_flags(cmd, argv, argc,
1356 		    aflag, fflag, pflag, rflag)) == -1)
1357 			return -1;
1358 		/* Get first pathname (mandatory) */
1359 		if (argc - optidx < 1) {
1360 			error("You must specify at least one path after a "
1361 			    "%s command.", cmd);
1362 			return -1;
1363 		}
1364 		*path1 = xstrdup(argv[optidx]);
1365 		/* Get second pathname (optional) */
1366 		if (argc - optidx > 1) {
1367 			*path2 = xstrdup(argv[optidx + 1]);
1368 			/* Destination is not globbed */
1369 			undo_glob_escape(*path2);
1370 		}
1371 		break;
1372 	case I_LINK:
1373 		if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
1374 			return -1;
1375 		goto parse_two_paths;
1376 	case I_RENAME:
1377 		if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
1378 			return -1;
1379 		goto parse_two_paths;
1380 	case I_SYMLINK:
1381 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1382 			return -1;
1383  parse_two_paths:
1384 		if (argc - optidx < 2) {
1385 			error("You must specify two paths after a %s "
1386 			    "command.", cmd);
1387 			return -1;
1388 		}
1389 		*path1 = xstrdup(argv[optidx]);
1390 		*path2 = xstrdup(argv[optidx + 1]);
1391 		/* Paths are not globbed */
1392 		undo_glob_escape(*path1);
1393 		undo_glob_escape(*path2);
1394 		break;
1395 	case I_RM:
1396 	case I_MKDIR:
1397 	case I_RMDIR:
1398 	case I_LMKDIR:
1399 		path1_mandatory = 1;
1400 		/* FALLTHROUGH */
1401 	case I_CHDIR:
1402 	case I_LCHDIR:
1403 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1404 			return -1;
1405 		/* Get pathname (mandatory) */
1406 		if (argc - optidx < 1) {
1407 			if (!path1_mandatory)
1408 				break; /* return a NULL path1 */
1409 			error("You must specify a path after a %s command.",
1410 			    cmd);
1411 			return -1;
1412 		}
1413 		*path1 = xstrdup(argv[optidx]);
1414 		/* Only "rm" globs */
1415 		if (cmdnum != I_RM)
1416 			undo_glob_escape(*path1);
1417 		break;
1418 	case I_DF:
1419 		if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
1420 		    iflag)) == -1)
1421 			return -1;
1422 		/* Default to current directory if no path specified */
1423 		if (argc - optidx < 1)
1424 			*path1 = NULL;
1425 		else {
1426 			*path1 = xstrdup(argv[optidx]);
1427 			undo_glob_escape(*path1);
1428 		}
1429 		break;
1430 	case I_LS:
1431 		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
1432 			return(-1);
1433 		/* Path is optional */
1434 		if (argc - optidx > 0)
1435 			*path1 = xstrdup(argv[optidx]);
1436 		break;
1437 	case I_LLS:
1438 		/* Skip ls command and following whitespace */
1439 		cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
1440 	case I_SHELL:
1441 		/* Uses the rest of the line */
1442 		break;
1443 	case I_LUMASK:
1444 	case I_CHMOD:
1445 		base = 8;
1446 	case I_CHOWN:
1447 	case I_CHGRP:
1448 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1449 			return -1;
1450 		/* Get numeric arg (mandatory) */
1451 		if (argc - optidx < 1)
1452 			goto need_num_arg;
1453 		errno = 0;
1454 		l = strtol(argv[optidx], &cp2, base);
1455 		if (cp2 == argv[optidx] || *cp2 != '\0' ||
1456 		    ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
1457 		    l < 0) {
1458  need_num_arg:
1459 			error("You must supply a numeric argument "
1460 			    "to the %s command.", cmd);
1461 			return -1;
1462 		}
1463 		*n_arg = l;
1464 		if (cmdnum == I_LUMASK)
1465 			break;
1466 		/* Get pathname (mandatory) */
1467 		if (argc - optidx < 2) {
1468 			error("You must specify a path after a %s command.",
1469 			    cmd);
1470 			return -1;
1471 		}
1472 		*path1 = xstrdup(argv[optidx + 1]);
1473 		break;
1474 	case I_QUIT:
1475 	case I_PWD:
1476 	case I_LPWD:
1477 	case I_HELP:
1478 	case I_VERSION:
1479 	case I_PROGRESS:
1480 		if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1481 			return -1;
1482 		break;
1483 	default:
1484 		fatal("Command not implemented");
1485 	}
1486 
1487 	*cpp = cp;
1488 	return(cmdnum);
1489 }
1490 
1491 static int
1492 parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1493     const char *startdir, int err_abort)
1494 {
1495 	char *path1, *path2, *tmp;
1496 	int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
1497 	iflag = 0;
1498 	int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
1499 	int cmdnum, i;
1500 	unsigned long n_arg = 0;
1501 	Attrib a, *aa;
1502 	char path_buf[PATH_MAX];
1503 	int err = 0;
1504 	glob_t g;
1505 
1506 	path1 = path2 = NULL;
1507 	cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
1508 	    &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
1509 	if (ignore_errors != 0)
1510 		err_abort = 0;
1511 
1512 	memset(&g, 0, sizeof(g));
1513 
1514 	/* Perform command */
1515 	switch (cmdnum) {
1516 	case 0:
1517 		/* Blank line */
1518 		break;
1519 	case -1:
1520 		/* Unrecognized command */
1521 		err = -1;
1522 		break;
1523 	case I_REGET:
1524 		aflag = 1;
1525 		/* FALLTHROUGH */
1526 	case I_GET:
1527 		err = process_get(conn, path1, path2, *pwd, pflag,
1528 		    rflag, aflag, fflag);
1529 		break;
1530 	case I_REPUT:
1531 		aflag = 1;
1532 		/* FALLTHROUGH */
1533 	case I_PUT:
1534 		err = process_put(conn, path1, path2, *pwd, pflag,
1535 		    rflag, aflag, fflag);
1536 		break;
1537 	case I_RENAME:
1538 		path1 = make_absolute(path1, *pwd);
1539 		path2 = make_absolute(path2, *pwd);
1540 		err = do_rename(conn, path1, path2, lflag);
1541 		break;
1542 	case I_SYMLINK:
1543 		sflag = 1;
1544 	case I_LINK:
1545 		if (!sflag)
1546 			path1 = make_absolute(path1, *pwd);
1547 		path2 = make_absolute(path2, *pwd);
1548 		err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
1549 		break;
1550 	case I_RM:
1551 		path1 = make_absolute(path1, *pwd);
1552 		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1553 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1554 			if (!quiet)
1555 				mprintf("Removing %s\n", g.gl_pathv[i]);
1556 			err = do_rm(conn, g.gl_pathv[i]);
1557 			if (err != 0 && err_abort)
1558 				break;
1559 		}
1560 		break;
1561 	case I_MKDIR:
1562 		path1 = make_absolute(path1, *pwd);
1563 		attrib_clear(&a);
1564 		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
1565 		a.perm = 0777;
1566 		err = do_mkdir(conn, path1, &a, 1);
1567 		break;
1568 	case I_RMDIR:
1569 		path1 = make_absolute(path1, *pwd);
1570 		err = do_rmdir(conn, path1);
1571 		break;
1572 	case I_CHDIR:
1573 		if (path1 == NULL || *path1 == '\0')
1574 			path1 = xstrdup(startdir);
1575 		path1 = make_absolute(path1, *pwd);
1576 		if ((tmp = do_realpath(conn, path1)) == NULL) {
1577 			err = 1;
1578 			break;
1579 		}
1580 		if ((aa = do_stat(conn, tmp, 0)) == NULL) {
1581 			free(tmp);
1582 			err = 1;
1583 			break;
1584 		}
1585 		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
1586 			error("Can't change directory: Can't check target");
1587 			free(tmp);
1588 			err = 1;
1589 			break;
1590 		}
1591 		if (!S_ISDIR(aa->perm)) {
1592 			error("Can't change directory: \"%s\" is not "
1593 			    "a directory", tmp);
1594 			free(tmp);
1595 			err = 1;
1596 			break;
1597 		}
1598 		free(*pwd);
1599 		*pwd = tmp;
1600 		break;
1601 	case I_LS:
1602 		if (!path1) {
1603 			do_ls_dir(conn, *pwd, *pwd, lflag);
1604 			break;
1605 		}
1606 
1607 		/* Strip pwd off beginning of non-absolute paths */
1608 		tmp = NULL;
1609 		if (*path1 != '/')
1610 			tmp = *pwd;
1611 
1612 		path1 = make_absolute(path1, *pwd);
1613 		err = do_globbed_ls(conn, path1, tmp, lflag);
1614 		break;
1615 	case I_DF:
1616 		/* Default to current directory if no path specified */
1617 		if (path1 == NULL)
1618 			path1 = xstrdup(*pwd);
1619 		path1 = make_absolute(path1, *pwd);
1620 		err = do_df(conn, path1, hflag, iflag);
1621 		break;
1622 	case I_LCHDIR:
1623 		if (path1 == NULL || *path1 == '\0')
1624 			path1 = xstrdup("~");
1625 		tmp = tilde_expand_filename(path1, getuid());
1626 		free(path1);
1627 		path1 = tmp;
1628 		if (chdir(path1) == -1) {
1629 			error("Couldn't change local directory to "
1630 			    "\"%s\": %s", path1, strerror(errno));
1631 			err = 1;
1632 		}
1633 		break;
1634 	case I_LMKDIR:
1635 		if (mkdir(path1, 0777) == -1) {
1636 			error("Couldn't create local directory "
1637 			    "\"%s\": %s", path1, strerror(errno));
1638 			err = 1;
1639 		}
1640 		break;
1641 	case I_LLS:
1642 		local_do_ls(cmd);
1643 		break;
1644 	case I_SHELL:
1645 		local_do_shell(cmd);
1646 		break;
1647 	case I_LUMASK:
1648 		umask(n_arg);
1649 		printf("Local umask: %03lo\n", n_arg);
1650 		break;
1651 	case I_CHMOD:
1652 		path1 = make_absolute(path1, *pwd);
1653 		attrib_clear(&a);
1654 		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
1655 		a.perm = n_arg;
1656 		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1657 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1658 			if (!quiet)
1659 				mprintf("Changing mode on %s\n",
1660 				    g.gl_pathv[i]);
1661 			err = do_setstat(conn, g.gl_pathv[i], &a);
1662 			if (err != 0 && err_abort)
1663 				break;
1664 		}
1665 		break;
1666 	case I_CHOWN:
1667 	case I_CHGRP:
1668 		path1 = make_absolute(path1, *pwd);
1669 		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1670 		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1671 			if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
1672 				if (err_abort) {
1673 					err = -1;
1674 					break;
1675 				} else
1676 					continue;
1677 			}
1678 			if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
1679 				error("Can't get current ownership of "
1680 				    "remote file \"%s\"", g.gl_pathv[i]);
1681 				if (err_abort) {
1682 					err = -1;
1683 					break;
1684 				} else
1685 					continue;
1686 			}
1687 			aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
1688 			if (cmdnum == I_CHOWN) {
1689 				if (!quiet)
1690 					mprintf("Changing owner on %s\n",
1691 					    g.gl_pathv[i]);
1692 				aa->uid = n_arg;
1693 			} else {
1694 				if (!quiet)
1695 					mprintf("Changing group on %s\n",
1696 					    g.gl_pathv[i]);
1697 				aa->gid = n_arg;
1698 			}
1699 			err = do_setstat(conn, g.gl_pathv[i], aa);
1700 			if (err != 0 && err_abort)
1701 				break;
1702 		}
1703 		break;
1704 	case I_PWD:
1705 		mprintf("Remote working directory: %s\n", *pwd);
1706 		break;
1707 	case I_LPWD:
1708 		if (!getcwd(path_buf, sizeof(path_buf))) {
1709 			error("Couldn't get local cwd: %s", strerror(errno));
1710 			err = -1;
1711 			break;
1712 		}
1713 		mprintf("Local working directory: %s\n", path_buf);
1714 		break;
1715 	case I_QUIT:
1716 		/* Processed below */
1717 		break;
1718 	case I_HELP:
1719 		help();
1720 		break;
1721 	case I_VERSION:
1722 		printf("SFTP protocol version %u\n", sftp_proto_version(conn));
1723 		break;
1724 	case I_PROGRESS:
1725 		showprogress = !showprogress;
1726 		if (showprogress)
1727 			printf("Progress meter enabled\n");
1728 		else
1729 			printf("Progress meter disabled\n");
1730 		break;
1731 	default:
1732 		fatal("%d is not implemented", cmdnum);
1733 	}
1734 
1735 	if (g.gl_pathc)
1736 		globfree(&g);
1737 	free(path1);
1738 	free(path2);
1739 
1740 	/* If an unignored error occurs in batch mode we should abort. */
1741 	if (err_abort && err != 0)
1742 		return (-1);
1743 	else if (cmdnum == I_QUIT)
1744 		return (1);
1745 
1746 	return (0);
1747 }
1748 
1749 #ifdef USE_LIBEDIT
1750 static char *
1751 prompt(EditLine *el)
1752 {
1753 	return ("sftp> ");
1754 }
1755 
1756 /* Display entries in 'list' after skipping the first 'len' chars */
1757 static void
1758 complete_display(char **list, u_int len)
1759 {
1760 	u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;
1761 	struct winsize ws;
1762 	char *tmp;
1763 
1764 	/* Count entries for sort and find longest */
1765 	for (y = 0; list[y]; y++)
1766 		m = MAXIMUM(m, strlen(list[y]));
1767 
1768 	if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
1769 		width = ws.ws_col;
1770 
1771 	m = m > len ? m - len : 0;
1772 	columns = width / (m + 2);
1773 	columns = MAXIMUM(columns, 1);
1774 	colspace = width / columns;
1775 	colspace = MINIMUM(colspace, width);
1776 
1777 	printf("\n");
1778 	m = 1;
1779 	for (y = 0; list[y]; y++) {
1780 		llen = strlen(list[y]);
1781 		tmp = llen > len ? list[y] + len : "";
1782 		mprintf("%-*s", colspace, tmp);
1783 		if (m >= columns) {
1784 			printf("\n");
1785 			m = 1;
1786 		} else
1787 			m++;
1788 	}
1789 	printf("\n");
1790 }
1791 
1792 /*
1793  * Given a "list" of words that begin with a common prefix of "word",
1794  * attempt to find an autocompletion to extends "word" by the next
1795  * characters common to all entries in "list".
1796  */
1797 static char *
1798 complete_ambiguous(const char *word, char **list, size_t count)
1799 {
1800 	if (word == NULL)
1801 		return NULL;
1802 
1803 	if (count > 0) {
1804 		u_int y, matchlen = strlen(list[0]);
1805 
1806 		/* Find length of common stem */
1807 		for (y = 1; list[y]; y++) {
1808 			u_int x;
1809 
1810 			for (x = 0; x < matchlen; x++)
1811 				if (list[0][x] != list[y][x])
1812 					break;
1813 
1814 			matchlen = x;
1815 		}
1816 
1817 		if (matchlen > strlen(word)) {
1818 			char *tmp = xstrdup(list[0]);
1819 
1820 			tmp[matchlen] = '\0';
1821 			return tmp;
1822 		}
1823 	}
1824 
1825 	return xstrdup(word);
1826 }
1827 
1828 /* Autocomplete a sftp command */
1829 static int
1830 complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
1831     int terminated)
1832 {
1833 	u_int y, count = 0, cmdlen, tmplen;
1834 	char *tmp, **list, argterm[3];
1835 	const LineInfo *lf;
1836 
1837 	list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));
1838 
1839 	/* No command specified: display all available commands */
1840 	if (cmd == NULL) {
1841 		for (y = 0; cmds[y].c; y++)
1842 			list[count++] = xstrdup(cmds[y].c);
1843 
1844 		list[count] = NULL;
1845 		complete_display(list, 0);
1846 
1847 		for (y = 0; list[y] != NULL; y++)
1848 			free(list[y]);
1849 		free(list);
1850 		return count;
1851 	}
1852 
1853 	/* Prepare subset of commands that start with "cmd" */
1854 	cmdlen = strlen(cmd);
1855 	for (y = 0; cmds[y].c; y++)  {
1856 		if (!strncasecmp(cmd, cmds[y].c, cmdlen))
1857 			list[count++] = xstrdup(cmds[y].c);
1858 	}
1859 	list[count] = NULL;
1860 
1861 	if (count == 0) {
1862 		free(list);
1863 		return 0;
1864 	}
1865 
1866 	/* Complete ambiguous command */
1867 	tmp = complete_ambiguous(cmd, list, count);
1868 	if (count > 1)
1869 		complete_display(list, 0);
1870 
1871 	for (y = 0; list[y]; y++)
1872 		free(list[y]);
1873 	free(list);
1874 
1875 	if (tmp != NULL) {
1876 		tmplen = strlen(tmp);
1877 		cmdlen = strlen(cmd);
1878 		/* If cmd may be extended then do so */
1879 		if (tmplen > cmdlen)
1880 			if (el_insertstr(el, tmp + cmdlen) == -1)
1881 				fatal("el_insertstr failed.");
1882 		lf = el_line(el);
1883 		/* Terminate argument cleanly */
1884 		if (count == 1) {
1885 			y = 0;
1886 			if (!terminated)
1887 				argterm[y++] = quote;
1888 			if (lastarg || *(lf->cursor) != ' ')
1889 				argterm[y++] = ' ';
1890 			argterm[y] = '\0';
1891 			if (y > 0 && el_insertstr(el, argterm) == -1)
1892 				fatal("el_insertstr failed.");
1893 		}
1894 		free(tmp);
1895 	}
1896 
1897 	return count;
1898 }
1899 
1900 /*
1901  * Determine whether a particular sftp command's arguments (if any)
1902  * represent local or remote files.
1903  */
1904 static int
1905 complete_is_remote(char *cmd) {
1906 	int i;
1907 
1908 	if (cmd == NULL)
1909 		return -1;
1910 
1911 	for (i = 0; cmds[i].c; i++) {
1912 		if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c)))
1913 			return cmds[i].t;
1914 	}
1915 
1916 	return -1;
1917 }
1918 
1919 /* Autocomplete a filename "file" */
1920 static int
1921 complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1922     char *file, int remote, int lastarg, char quote, int terminated)
1923 {
1924 	glob_t g;
1925 	char *tmp, *tmp2, ins[8];
1926 	u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
1927 	int clen;
1928 	const LineInfo *lf;
1929 
1930 	/* Glob from "file" location */
1931 	if (file == NULL)
1932 		tmp = xstrdup("*");
1933 	else
1934 		xasprintf(&tmp, "%s*", file);
1935 
1936 	/* Check if the path is absolute. */
1937 	isabs = tmp[0] == '/';
1938 
1939 	memset(&g, 0, sizeof(g));
1940 	if (remote != LOCAL) {
1941 		tmp = make_absolute(tmp, remote_path);
1942 		remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1943 	} else
1944 		glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1945 
1946 	/* Determine length of pwd so we can trim completion display */
1947 	for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
1948 		/* Terminate counting on first unescaped glob metacharacter */
1949 		if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {
1950 			if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')
1951 				hadglob = 1;
1952 			break;
1953 		}
1954 		if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')
1955 			tmplen++;
1956 		if (tmp[tmplen] == '/')
1957 			pwdlen = tmplen + 1;	/* track last seen '/' */
1958 	}
1959 	free(tmp);
1960 	tmp = NULL;
1961 
1962 	if (g.gl_matchc == 0)
1963 		goto out;
1964 
1965 	if (g.gl_matchc > 1)
1966 		complete_display(g.gl_pathv, pwdlen);
1967 
1968 	/* Don't try to extend globs */
1969 	if (file == NULL || hadglob)
1970 		goto out;
1971 
1972 	tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
1973 	tmp = path_strip(tmp2, isabs ? NULL : remote_path);
1974 	free(tmp2);
1975 
1976 	if (tmp == NULL)
1977 		goto out;
1978 
1979 	tmplen = strlen(tmp);
1980 	filelen = strlen(file);
1981 
1982 	/* Count the number of escaped characters in the input string. */
1983 	cesc = isesc = 0;
1984 	for (i = 0; i < filelen; i++) {
1985 		if (!isesc && file[i] == '\\' && i + 1 < filelen){
1986 			isesc = 1;
1987 			cesc++;
1988 		} else
1989 			isesc = 0;
1990 	}
1991 
1992 	if (tmplen > (filelen - cesc)) {
1993 		tmp2 = tmp + filelen - cesc;
1994 		len = strlen(tmp2);
1995 		/* quote argument on way out */
1996 		for (i = 0; i < len; i += clen) {
1997 			if ((clen = mblen(tmp2 + i, len - i)) < 0 ||
1998 			    (size_t)clen > sizeof(ins) - 2)
1999 				fatal("invalid multibyte character");
2000 			ins[0] = '\\';
2001 			memcpy(ins + 1, tmp2 + i, clen);
2002 			ins[clen + 1] = '\0';
2003 			switch (tmp2[i]) {
2004 			case '\'':
2005 			case '"':
2006 			case '\\':
2007 			case '\t':
2008 			case '[':
2009 			case ' ':
2010 			case '#':
2011 			case '*':
2012 				if (quote == '\0' || tmp2[i] == quote) {
2013 					if (el_insertstr(el, ins) == -1)
2014 						fatal("el_insertstr "
2015 						    "failed.");
2016 					break;
2017 				}
2018 				/* FALLTHROUGH */
2019 			default:
2020 				if (el_insertstr(el, ins + 1) == -1)
2021 					fatal("el_insertstr failed.");
2022 				break;
2023 			}
2024 		}
2025 	}
2026 
2027 	lf = el_line(el);
2028 	if (g.gl_matchc == 1) {
2029 		i = 0;
2030 		if (!terminated && quote != '\0')
2031 			ins[i++] = quote;
2032 		if (*(lf->cursor - 1) != '/' &&
2033 		    (lastarg || *(lf->cursor) != ' '))
2034 			ins[i++] = ' ';
2035 		ins[i] = '\0';
2036 		if (i > 0 && el_insertstr(el, ins) == -1)
2037 			fatal("el_insertstr failed.");
2038 	}
2039 	free(tmp);
2040 
2041  out:
2042 	globfree(&g);
2043 	return g.gl_matchc;
2044 }
2045 
2046 /* tab-completion hook function, called via libedit */
2047 static unsigned char
2048 complete(EditLine *el, int ch)
2049 {
2050 	char **argv, *line, quote;
2051 	int argc, carg;
2052 	u_int cursor, len, terminated, ret = CC_ERROR;
2053 	const LineInfo *lf;
2054 	struct complete_ctx *complete_ctx;
2055 
2056 	lf = el_line(el);
2057 	if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
2058 		fatal("%s: el_get failed", __func__);
2059 
2060 	/* Figure out which argument the cursor points to */
2061 	cursor = lf->cursor - lf->buffer;
2062 	line = xmalloc(cursor + 1);
2063 	memcpy(line, lf->buffer, cursor);
2064 	line[cursor] = '\0';
2065 	argv = makeargv(line, &carg, 1, &quote, &terminated);
2066 	free(line);
2067 
2068 	/* Get all the arguments on the line */
2069 	len = lf->lastchar - lf->buffer;
2070 	line = xmalloc(len + 1);
2071 	memcpy(line, lf->buffer, len);
2072 	line[len] = '\0';
2073 	argv = makeargv(line, &argc, 1, NULL, NULL);
2074 
2075 	/* Ensure cursor is at EOL or a argument boundary */
2076 	if (line[cursor] != ' ' && line[cursor] != '\0' &&
2077 	    line[cursor] != '\n') {
2078 		free(line);
2079 		return ret;
2080 	}
2081 
2082 	if (carg == 0) {
2083 		/* Show all available commands */
2084 		complete_cmd_parse(el, NULL, argc == carg, '\0', 1);
2085 		ret = CC_REDISPLAY;
2086 	} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ')  {
2087 		/* Handle the command parsing */
2088 		if (complete_cmd_parse(el, argv[0], argc == carg,
2089 		    quote, terminated) != 0)
2090 			ret = CC_REDISPLAY;
2091 	} else if (carg >= 1) {
2092 		/* Handle file parsing */
2093 		int remote = complete_is_remote(argv[0]);
2094 		char *filematch = NULL;
2095 
2096 		if (carg > 1 && line[cursor-1] != ' ')
2097 			filematch = argv[carg - 1];
2098 
2099 		if (remote != 0 &&
2100 		    complete_match(el, complete_ctx->conn,
2101 		    *complete_ctx->remote_pathp, filematch,
2102 		    remote, carg == argc, quote, terminated) != 0)
2103 			ret = CC_REDISPLAY;
2104 	}
2105 
2106 	free(line);
2107 	return ret;
2108 }
2109 #endif /* USE_LIBEDIT */
2110 
2111 static int
2112 interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2113 {
2114 	char *remote_path;
2115 	char *dir = NULL, *startdir = NULL;
2116 	char cmd[2048];
2117 	int err, interactive;
2118 	EditLine *el = NULL;
2119 #ifdef USE_LIBEDIT
2120 	History *hl = NULL;
2121 	HistEvent hev;
2122 	extern char *__progname;
2123 	struct complete_ctx complete_ctx;
2124 
2125 	if (!batchmode && isatty(STDIN_FILENO)) {
2126 		if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
2127 			fatal("Couldn't initialise editline");
2128 		if ((hl = history_init()) == NULL)
2129 			fatal("Couldn't initialise editline history");
2130 		history(hl, &hev, H_SETSIZE, 100);
2131 		el_set(el, EL_HIST, history, hl);
2132 
2133 		el_set(el, EL_PROMPT, prompt);
2134 		el_set(el, EL_EDITOR, "emacs");
2135 		el_set(el, EL_TERMINAL, NULL);
2136 		el_set(el, EL_SIGNAL, 1);
2137 		el_source(el, NULL);
2138 
2139 		/* Tab Completion */
2140 		el_set(el, EL_ADDFN, "ftp-complete",
2141 		    "Context sensitive argument completion", complete);
2142 		complete_ctx.conn = conn;
2143 		complete_ctx.remote_pathp = &remote_path;
2144 		el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
2145 		el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
2146 		/* enable ctrl-left-arrow and ctrl-right-arrow */
2147 		el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
2148 		el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL);
2149 		el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
2150 		el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
2151 		/* make ^w match ksh behaviour */
2152 		el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);
2153 	}
2154 #endif /* USE_LIBEDIT */
2155 
2156 	remote_path = do_realpath(conn, ".");
2157 	if (remote_path == NULL)
2158 		fatal("Need cwd");
2159 	startdir = xstrdup(remote_path);
2160 
2161 	if (file1 != NULL) {
2162 		dir = xstrdup(file1);
2163 		dir = make_absolute(dir, remote_path);
2164 
2165 		if (remote_is_dir(conn, dir) && file2 == NULL) {
2166 			if (!quiet)
2167 				mprintf("Changing to: %s\n", dir);
2168 			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
2169 			if (parse_dispatch_command(conn, cmd,
2170 			    &remote_path, startdir, 1) != 0) {
2171 				free(dir);
2172 				free(startdir);
2173 				free(remote_path);
2174 				free(conn);
2175 				return (-1);
2176 			}
2177 		} else {
2178 			/* XXX this is wrong wrt quoting */
2179 			snprintf(cmd, sizeof cmd, "get%s %s%s%s",
2180 			    global_aflag ? " -a" : "", dir,
2181 			    file2 == NULL ? "" : " ",
2182 			    file2 == NULL ? "" : file2);
2183 			err = parse_dispatch_command(conn, cmd,
2184 			    &remote_path, startdir, 1);
2185 			free(dir);
2186 			free(startdir);
2187 			free(remote_path);
2188 			free(conn);
2189 			return (err);
2190 		}
2191 		free(dir);
2192 	}
2193 
2194 	setvbuf(stdout, NULL, _IOLBF, 0);
2195 	setvbuf(infile, NULL, _IOLBF, 0);
2196 
2197 	interactive = !batchmode && isatty(STDIN_FILENO);
2198 	err = 0;
2199 	for (;;) {
2200 		char *cp;
2201 
2202 		signal(SIGINT, SIG_IGN);
2203 
2204 		if (el == NULL) {
2205 			if (interactive)
2206 				printf("sftp> ");
2207 			if (fgets(cmd, sizeof(cmd), infile) == NULL) {
2208 				if (interactive)
2209 					printf("\n");
2210 				break;
2211 			}
2212 			if (!interactive) { /* Echo command */
2213 				mprintf("sftp> %s", cmd);
2214 				if (strlen(cmd) > 0 &&
2215 				    cmd[strlen(cmd) - 1] != '\n')
2216 					printf("\n");
2217 			}
2218 		} else {
2219 #ifdef USE_LIBEDIT
2220 			const char *line;
2221 			int count = 0;
2222 
2223 			if ((line = el_gets(el, &count)) == NULL ||
2224 			    count <= 0) {
2225 				printf("\n");
2226  				break;
2227 			}
2228 			history(hl, &hev, H_ENTER, line);
2229 			if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
2230 				fprintf(stderr, "Error: input line too long\n");
2231 				continue;
2232 			}
2233 #endif /* USE_LIBEDIT */
2234 		}
2235 
2236 		cp = strrchr(cmd, '\n');
2237 		if (cp)
2238 			*cp = '\0';
2239 
2240 		/* Handle user interrupts gracefully during commands */
2241 		interrupted = 0;
2242 		signal(SIGINT, cmd_interrupt);
2243 
2244 		err = parse_dispatch_command(conn, cmd, &remote_path,
2245 		    startdir, batchmode);
2246 		if (err != 0)
2247 			break;
2248 	}
2249 	signal(SIGCHLD, SIG_DFL);
2250 	free(remote_path);
2251 	free(startdir);
2252 	free(conn);
2253 
2254 #ifdef USE_LIBEDIT
2255 	if (el != NULL)
2256 		el_end(el);
2257 #endif /* USE_LIBEDIT */
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 #ifdef USE_PIPES
2269 	int pin[2], pout[2];
2270 
2271 	if ((pipe(pin) == -1) || (pipe(pout) == -1))
2272 		fatal("pipe: %s", strerror(errno));
2273 	*in = pin[0];
2274 	*out = pout[1];
2275 	c_in = pout[0];
2276 	c_out = pin[1];
2277 #else /* USE_PIPES */
2278 	int inout[2];
2279 
2280 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
2281 		fatal("socketpair: %s", strerror(errno));
2282 	*in = *out = inout[0];
2283 	c_in = c_out = inout[1];
2284 #endif /* USE_PIPES */
2285 
2286 	if ((sshpid = fork()) == -1)
2287 		fatal("fork: %s", strerror(errno));
2288 	else if (sshpid == 0) {
2289 		if ((dup2(c_in, STDIN_FILENO) == -1) ||
2290 		    (dup2(c_out, STDOUT_FILENO) == -1)) {
2291 			fprintf(stderr, "dup2: %s\n", strerror(errno));
2292 			_exit(1);
2293 		}
2294 		close(*in);
2295 		close(*out);
2296 		close(c_in);
2297 		close(c_out);
2298 
2299 		/*
2300 		 * The underlying ssh is in the same process group, so we must
2301 		 * ignore SIGINT if we want to gracefully abort commands,
2302 		 * otherwise the signal will make it to the ssh process and
2303 		 * kill it too.  Contrawise, since sftp sends SIGTERMs to the
2304 		 * underlying ssh, it must *not* ignore that signal.
2305 		 */
2306 		signal(SIGINT, SIG_IGN);
2307 		signal(SIGTERM, SIG_DFL);
2308 		execvp(path, args);
2309 		fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
2310 		_exit(1);
2311 	}
2312 
2313 	signal(SIGTERM, killchild);
2314 	signal(SIGINT, killchild);
2315 	signal(SIGHUP, killchild);
2316 	signal(SIGTSTP, suspchild);
2317 	signal(SIGTTIN, suspchild);
2318 	signal(SIGTTOU, suspchild);
2319 	signal(SIGCHLD, sigchld_handler);
2320 	close(c_in);
2321 	close(c_out);
2322 }
2323 
2324 static void
2325 usage(void)
2326 {
2327 	extern char *__progname;
2328 
2329 	fprintf(stderr,
2330 	    "usage: %s [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2331 	    "          [-D sftp_server_path] [-F ssh_config] "
2332 	    "[-i identity_file] [-l limit]\n"
2333 	    "          [-o ssh_option] [-P port] [-R num_requests] "
2334 	    "[-S program]\n"
2335 	    "          [-s subsystem | sftp_server] destination\n",
2336 	    __progname);
2337 	exit(1);
2338 }
2339 
2340 int
2341 main(int argc, char **argv)
2342 {
2343 	int in, out, ch, err, tmp, port = -1;
2344 	char *host = NULL, *user, *cp, *file2 = NULL;
2345 	int debug_level = 0, sshver = 2;
2346 	char *file1 = NULL, *sftp_server = NULL;
2347 	char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
2348 	const char *errstr;
2349 	LogLevel ll = SYSLOG_LEVEL_INFO;
2350 	arglist args;
2351 	extern int optind;
2352 	extern char *optarg;
2353 	struct sftp_conn *conn;
2354 	size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;
2355 	size_t num_requests = DEFAULT_NUM_REQUESTS;
2356 	long long limit_kbps = 0;
2357 
2358 	ssh_malloc_init();	/* must be called before any mallocs */
2359 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2360 	sanitise_stdfd();
2361 	msetlocale();
2362 
2363 	__progname = ssh_get_progname(argv[0]);
2364 	memset(&args, '\0', sizeof(args));
2365 	args.list = NULL;
2366 	addargs(&args, "%s", ssh_program);
2367 	addargs(&args, "-oForwardX11 no");
2368 	addargs(&args, "-oForwardAgent no");
2369 	addargs(&args, "-oPermitLocalCommand no");
2370 	addargs(&args, "-oClearAllForwardings yes");
2371 
2372 	ll = SYSLOG_LEVEL_INFO;
2373 	infile = stdin;
2374 
2375 	while ((ch = getopt(argc, argv,
2376 	    "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
2377 		switch (ch) {
2378 		/* Passed through to ssh(1) */
2379 		case '4':
2380 		case '6':
2381 		case 'C':
2382 			addargs(&args, "-%c", ch);
2383 			break;
2384 		/* Passed through to ssh(1) with argument */
2385 		case 'F':
2386 		case 'c':
2387 		case 'i':
2388 		case 'o':
2389 			addargs(&args, "-%c", ch);
2390 			addargs(&args, "%s", optarg);
2391 			break;
2392 		case 'q':
2393 			ll = SYSLOG_LEVEL_ERROR;
2394 			quiet = 1;
2395 			showprogress = 0;
2396 			addargs(&args, "-%c", ch);
2397 			break;
2398 		case 'P':
2399 			port = a2port(optarg);
2400 			if (port <= 0)
2401 				fatal("Bad port \"%s\"\n", optarg);
2402 			break;
2403 		case 'v':
2404 			if (debug_level < 3) {
2405 				addargs(&args, "-v");
2406 				ll = SYSLOG_LEVEL_DEBUG1 + debug_level;
2407 			}
2408 			debug_level++;
2409 			break;
2410 		case '1':
2411 			sshver = 1;
2412 			if (sftp_server == NULL)
2413 				sftp_server = _PATH_SFTP_SERVER;
2414 			break;
2415 		case '2':
2416 			sshver = 2;
2417 			break;
2418 		case 'a':
2419 			global_aflag = 1;
2420 			break;
2421 		case 'B':
2422 			copy_buffer_len = strtol(optarg, &cp, 10);
2423 			if (copy_buffer_len == 0 || *cp != '\0')
2424 				fatal("Invalid buffer size \"%s\"", optarg);
2425 			break;
2426 		case 'b':
2427 			if (batchmode)
2428 				fatal("Batch file already specified.");
2429 
2430 			/* Allow "-" as stdin */
2431 			if (strcmp(optarg, "-") != 0 &&
2432 			    (infile = fopen(optarg, "r")) == NULL)
2433 				fatal("%s (%s).", strerror(errno), optarg);
2434 			showprogress = 0;
2435 			quiet = batchmode = 1;
2436 			addargs(&args, "-obatchmode yes");
2437 			break;
2438 		case 'f':
2439 			global_fflag = 1;
2440 			break;
2441 		case 'p':
2442 			global_pflag = 1;
2443 			break;
2444 		case 'D':
2445 			sftp_direct = optarg;
2446 			break;
2447 		case 'l':
2448 			limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
2449 			    &errstr);
2450 			if (errstr != NULL)
2451 				usage();
2452 			limit_kbps *= 1024; /* kbps */
2453 			break;
2454 		case 'r':
2455 			global_rflag = 1;
2456 			break;
2457 		case 'R':
2458 			num_requests = strtol(optarg, &cp, 10);
2459 			if (num_requests == 0 || *cp != '\0')
2460 				fatal("Invalid number of requests \"%s\"",
2461 				    optarg);
2462 			break;
2463 		case 's':
2464 			sftp_server = optarg;
2465 			break;
2466 		case 'S':
2467 			ssh_program = optarg;
2468 			replacearg(&args, 0, "%s", ssh_program);
2469 			break;
2470 		case 'h':
2471 		default:
2472 			usage();
2473 		}
2474 	}
2475 
2476 	if (!isatty(STDERR_FILENO))
2477 		showprogress = 0;
2478 
2479 	log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
2480 
2481 	if (sftp_direct == NULL) {
2482 		if (optind == argc || argc > (optind + 2))
2483 			usage();
2484 		argv += optind;
2485 
2486 		switch (parse_uri("sftp", *argv, &user, &host, &tmp, &file1)) {
2487 		case -1:
2488 			usage();
2489 			break;
2490 		case 0:
2491 			if (tmp != -1)
2492 				port = tmp;
2493 			break;
2494 		default:
2495 			if (parse_user_host_path(*argv, &user, &host,
2496 			    &file1) == -1) {
2497 				/* Treat as a plain hostname. */
2498 				host = xstrdup(*argv);
2499 				host = cleanhostname(host);
2500 			}
2501 			break;
2502 		}
2503 		file2 = *(argv + 1);
2504 
2505 		if (!*host) {
2506 			fprintf(stderr, "Missing hostname\n");
2507 			usage();
2508 		}
2509 
2510 		if (port != -1)
2511 			addargs(&args, "-oPort %d", port);
2512 		if (user != NULL) {
2513 			addargs(&args, "-l");
2514 			addargs(&args, "%s", user);
2515 		}
2516 		addargs(&args, "-oProtocol %d", sshver);
2517 
2518 		/* no subsystem if the server-spec contains a '/' */
2519 		if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
2520 			addargs(&args, "-s");
2521 
2522 		addargs(&args, "--");
2523 		addargs(&args, "%s", host);
2524 		addargs(&args, "%s", (sftp_server != NULL ?
2525 		    sftp_server : "sftp"));
2526 
2527 		connect_to_server(ssh_program, args.list, &in, &out);
2528 	} else {
2529 		args.list = NULL;
2530 		addargs(&args, "sftp-server");
2531 
2532 		connect_to_server(sftp_direct, args.list, &in, &out);
2533 	}
2534 	freeargs(&args);
2535 
2536 	conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
2537 	if (conn == NULL)
2538 		fatal("Couldn't initialise connection to server");
2539 
2540 	if (!quiet) {
2541 		if (sftp_direct == NULL)
2542 			fprintf(stderr, "Connected to %s.\n", host);
2543 		else
2544 			fprintf(stderr, "Attached to %s.\n", sftp_direct);
2545 	}
2546 
2547 	err = interactive_loop(conn, file1, file2);
2548 
2549 #if !defined(USE_PIPES)
2550 	shutdown(in, SHUT_RDWR);
2551 	shutdown(out, SHUT_RDWR);
2552 #endif
2553 
2554 	close(in);
2555 	close(out);
2556 	if (batchmode)
2557 		fclose(infile);
2558 
2559 	while (waitpid(sshpid, NULL, 0) == -1 && sshpid > 1)
2560 		if (errno != EINTR)
2561 			fatal("Couldn't wait for ssh process: %s",
2562 			    strerror(errno));
2563 
2564 	exit(err == 0 ? 0 : 1);
2565 }
2566