diff options
author | djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org> | 2017-11-03 03:46:52 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-11-03 16:20:41 +1100 |
commit | fbe8e7ac94c2fa380421a9205a8bc966549c2f91 (patch) | |
tree | f4045b45c8dcb4bf33df5aa96bde3d5ced4cac4a /sftp.c | |
parent | 0208a48517b5e8e8b091f32fa4addcd67c31ca9e (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.c | 32 |
1 files changed, 21 insertions, 11 deletions
@@ -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 | ||
220 | int interactive_loop(struct sftp_conn *, char *file1, char *file2); | ||
221 | |||
222 | /* ARGSUSED */ | 220 | /* ARGSUSED */ |
223 | static void | 221 | static void |
224 | killchild(int signo) | 222 | killchild(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 | ||
1470 | static int | 1472 | static int |
1471 | parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | 1473 | parse_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 | ||
2086 | int | 2092 | static int |
2087 | interactive_loop(struct sftp_conn *conn, char *file1, char *file2) | 2093 | interactive_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 |