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