summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authordjm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>2017-11-03 03:46:52 +0000
committerDamien Miller <djm@mindrot.org>2017-11-03 16:20:41 +1100
commitfbe8e7ac94c2fa380421a9205a8bc966549c2f91 (patch)
treef4045b45c8dcb4bf33df5aa96bde3d5ced4cac4a /sftp.c
parent0208a48517b5e8e8b091f32fa4addcd67c31ca9e (diff)
upstream commit
allow "cd" and "lcd" commands with no explicit path argument. lcd will change to the local user's home directory as usual. cd will change to the starting directory for session (because the protocol offers no way to obtain the remote user's home directory). bz#2760 ok dtucker@ OpenBSD-Commit-ID: 15333f5087cee8c1ed1330cac1bd0a3e6a767393
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/sftp.c b/sftp.c
index 9aee2fafe..5ce864eeb 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.181 2017/10/21 23:06:24 millert Exp $ */ 1/* $OpenBSD: sftp.c,v 1.182 2017/11/03 03:46:52 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -217,8 +217,6 @@ static const struct CMD cmds[] = {
217 { NULL, -1, -1 } 217 { NULL, -1, -1 }
218}; 218};
219 219
220int interactive_loop(struct sftp_conn *, char *file1, char *file2);
221
222/* ARGSUSED */ 220/* ARGSUSED */
223static void 221static void
224killchild(int signo) 222killchild(int signo)
@@ -1288,7 +1286,7 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
1288 char *cp2, **argv; 1286 char *cp2, **argv;
1289 int base = 0; 1287 int base = 0;
1290 long l; 1288 long l;
1291 int i, cmdnum, optidx, argc; 1289 int path1_mandatory = 0, i, cmdnum, optidx, argc;
1292 1290
1293 /* Skip leading whitespace */ 1291 /* Skip leading whitespace */
1294 cp = cp + strspn(cp, WHITESPACE); 1292 cp = cp + strspn(cp, WHITESPACE);
@@ -1378,13 +1376,17 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
1378 case I_RM: 1376 case I_RM:
1379 case I_MKDIR: 1377 case I_MKDIR:
1380 case I_RMDIR: 1378 case I_RMDIR:
1379 case I_LMKDIR:
1380 path1_mandatory = 1;
1381 /* FALLTHROUGH */
1381 case I_CHDIR: 1382 case I_CHDIR:
1382 case I_LCHDIR: 1383 case I_LCHDIR:
1383 case I_LMKDIR:
1384 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) 1384 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1385 return -1; 1385 return -1;
1386 /* Get pathname (mandatory) */ 1386 /* Get pathname (mandatory) */
1387 if (argc - optidx < 1) { 1387 if (argc - optidx < 1) {
1388 if (!path1_mandatory)
1389 break; /* return a NULL path1 */
1388 error("You must specify a path after a %s command.", 1390 error("You must specify a path after a %s command.",
1389 cmd); 1391 cmd);
1390 return -1; 1392 return -1;
@@ -1469,7 +1471,7 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
1469 1471
1470static int 1472static int
1471parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, 1473parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1472 int err_abort) 1474 const char *startdir, int err_abort)
1473{ 1475{
1474 char *path1, *path2, *tmp; 1476 char *path1, *path2, *tmp;
1475 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, 1477 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
@@ -1549,6 +1551,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1549 err = do_rmdir(conn, path1); 1551 err = do_rmdir(conn, path1);
1550 break; 1552 break;
1551 case I_CHDIR: 1553 case I_CHDIR:
1554 if (path1 == NULL || *path1 == '\0')
1555 path1 = xstrdup(startdir);
1552 path1 = make_absolute(path1, *pwd); 1556 path1 = make_absolute(path1, *pwd);
1553 if ((tmp = do_realpath(conn, path1)) == NULL) { 1557 if ((tmp = do_realpath(conn, path1)) == NULL) {
1554 err = 1; 1558 err = 1;
@@ -1597,6 +1601,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1597 err = do_df(conn, path1, hflag, iflag); 1601 err = do_df(conn, path1, hflag, iflag);
1598 break; 1602 break;
1599 case I_LCHDIR: 1603 case I_LCHDIR:
1604 if (path1 == NULL || *path1 == '\0')
1605 path1 = xstrdup("~");
1600 tmp = tilde_expand_filename(path1, getuid()); 1606 tmp = tilde_expand_filename(path1, getuid());
1601 free(path1); 1607 free(path1);
1602 path1 = tmp; 1608 path1 = tmp;
@@ -2083,11 +2089,11 @@ complete(EditLine *el, int ch)
2083} 2089}
2084#endif /* USE_LIBEDIT */ 2090#endif /* USE_LIBEDIT */
2085 2091
2086int 2092static int
2087interactive_loop(struct sftp_conn *conn, char *file1, char *file2) 2093interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2088{ 2094{
2089 char *remote_path; 2095 char *remote_path;
2090 char *dir = NULL; 2096 char *dir = NULL, *startdir = NULL;
2091 char cmd[2048]; 2097 char cmd[2048];
2092 int err, interactive; 2098 int err, interactive;
2093 EditLine *el = NULL; 2099 EditLine *el = NULL;
@@ -2131,6 +2137,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2131 remote_path = do_realpath(conn, "."); 2137 remote_path = do_realpath(conn, ".");
2132 if (remote_path == NULL) 2138 if (remote_path == NULL)
2133 fatal("Need cwd"); 2139 fatal("Need cwd");
2140 startdir = xstrdup(remote_path);
2134 2141
2135 if (file1 != NULL) { 2142 if (file1 != NULL) {
2136 dir = xstrdup(file1); 2143 dir = xstrdup(file1);
@@ -2141,8 +2148,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2141 mprintf("Changing to: %s\n", dir); 2148 mprintf("Changing to: %s\n", dir);
2142 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); 2149 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
2143 if (parse_dispatch_command(conn, cmd, 2150 if (parse_dispatch_command(conn, cmd,
2144 &remote_path, 1) != 0) { 2151 &remote_path, startdir, 1) != 0) {
2145 free(dir); 2152 free(dir);
2153 free(startdir);
2146 free(remote_path); 2154 free(remote_path);
2147 free(conn); 2155 free(conn);
2148 return (-1); 2156 return (-1);
@@ -2154,8 +2162,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2154 file2 == NULL ? "" : " ", 2162 file2 == NULL ? "" : " ",
2155 file2 == NULL ? "" : file2); 2163 file2 == NULL ? "" : file2);
2156 err = parse_dispatch_command(conn, cmd, 2164 err = parse_dispatch_command(conn, cmd,
2157 &remote_path, 1); 2165 &remote_path, startdir, 1);
2158 free(dir); 2166 free(dir);
2167 free(startdir);
2159 free(remote_path); 2168 free(remote_path);
2160 free(conn); 2169 free(conn);
2161 return (err); 2170 return (err);
@@ -2214,11 +2223,12 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2214 signal(SIGINT, cmd_interrupt); 2223 signal(SIGINT, cmd_interrupt);
2215 2224
2216 err = parse_dispatch_command(conn, cmd, &remote_path, 2225 err = parse_dispatch_command(conn, cmd, &remote_path,
2217 batchmode); 2226 startdir, batchmode);
2218 if (err != 0) 2227 if (err != 0)
2219 break; 2228 break;
2220 } 2229 }
2221 free(remote_path); 2230 free(remote_path);
2231 free(startdir);
2222 free(conn); 2232 free(conn);
2223 2233
2224#ifdef USE_LIBEDIT 2234#ifdef USE_LIBEDIT