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