diff options
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 |