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