diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | sftp.c | 106 |
2 files changed, 62 insertions, 52 deletions
@@ -1,3 +1,11 @@ | |||
1 | 20130821 | ||
2 | - (djm) OpenBSD CVS Sync | ||
3 | - djm@cvs.openbsd.org 2013/08/06 23:03:49 | ||
4 | [sftp.c] | ||
5 | fix some whitespace at EOL | ||
6 | make list of commands an enum rather than a long list of defines | ||
7 | add -a to usage() | ||
8 | |||
1 | 20130808 | 9 | 20130808 |
2 | - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt | 10 | - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt |
3 | since some platforms (eg really old FreeBSD) don't have it. Instead, | 11 | since some platforms (eg really old FreeBSD) don't have it. Instead, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.c,v 1.148 2013/07/25 00:56:52 djm Exp $ */ | 1 | /* $OpenBSD: sftp.c,v 1.149 2013/08/06 23:03:49 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 | * |
@@ -129,32 +129,34 @@ extern char *__progname; | |||
129 | #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) | 129 | #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) |
130 | 130 | ||
131 | /* Commands for interactive mode */ | 131 | /* Commands for interactive mode */ |
132 | #define I_CHDIR 1 | 132 | enum sftp_command { |
133 | #define I_CHGRP 2 | 133 | I_CHDIR = 1, |
134 | #define I_CHMOD 3 | 134 | I_CHGRP, |
135 | #define I_CHOWN 4 | 135 | I_CHMOD, |
136 | #define I_DF 24 | 136 | I_CHOWN, |
137 | #define I_GET 5 | 137 | I_DF, |
138 | #define I_HELP 6 | 138 | I_GET, |
139 | #define I_LCHDIR 7 | 139 | I_HELP, |
140 | #define I_LINK 25 | 140 | I_LCHDIR, |
141 | #define I_LLS 8 | 141 | I_LINK, |
142 | #define I_LMKDIR 9 | 142 | I_LLS, |
143 | #define I_LPWD 10 | 143 | I_LMKDIR, |
144 | #define I_LS 11 | 144 | I_LPWD, |
145 | #define I_LUMASK 12 | 145 | I_LS, |
146 | #define I_MKDIR 13 | 146 | I_LUMASK, |
147 | #define I_PUT 14 | 147 | I_MKDIR, |
148 | #define I_PWD 15 | 148 | I_PUT, |
149 | #define I_QUIT 16 | 149 | I_PWD, |
150 | #define I_RENAME 17 | 150 | I_QUIT, |
151 | #define I_RM 18 | 151 | I_RENAME, |
152 | #define I_RMDIR 19 | 152 | I_RM, |
153 | #define I_SHELL 20 | 153 | I_RMDIR, |
154 | #define I_SYMLINK 21 | 154 | I_SHELL, |
155 | #define I_VERSION 22 | 155 | I_SYMLINK, |
156 | #define I_PROGRESS 23 | 156 | I_VERSION, |
157 | #define I_REGET 26 | 157 | I_PROGRESS, |
158 | I_REGET, | ||
159 | }; | ||
158 | 160 | ||
159 | struct CMD { | 161 | struct CMD { |
160 | const char *c; | 162 | const char *c; |
@@ -647,7 +649,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, | |||
647 | error("stat %s: %s", g.gl_pathv[i], strerror(errno)); | 649 | error("stat %s: %s", g.gl_pathv[i], strerror(errno)); |
648 | continue; | 650 | continue; |
649 | } | 651 | } |
650 | 652 | ||
651 | tmp = xstrdup(g.gl_pathv[i]); | 653 | tmp = xstrdup(g.gl_pathv[i]); |
652 | if ((filename = basename(tmp)) == NULL) { | 654 | if ((filename = basename(tmp)) == NULL) { |
653 | error("basename %s: %s", tmp, strerror(errno)); | 655 | error("basename %s: %s", tmp, strerror(errno)); |
@@ -975,7 +977,7 @@ undo_glob_escape(char *s) | |||
975 | * | 977 | * |
976 | * If "lastquote" is not NULL, the quoting character used for the last | 978 | * If "lastquote" is not NULL, the quoting character used for the last |
977 | * argument is placed in *lastquote ("\0", "'" or "\""). | 979 | * argument is placed in *lastquote ("\0", "'" or "\""). |
978 | * | 980 | * |
979 | * If "terminated" is not NULL, *terminated will be set to 1 when the | 981 | * If "terminated" is not NULL, *terminated will be set to 1 when the |
980 | * last argument's quote has been properly terminated or 0 otherwise. | 982 | * last argument's quote has been properly terminated or 0 otherwise. |
981 | * This parameter is only of use if "sloppy" is set. | 983 | * This parameter is only of use if "sloppy" is set. |
@@ -1024,7 +1026,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, | |||
1024 | state = q; | 1026 | state = q; |
1025 | if (lastquote != NULL) | 1027 | if (lastquote != NULL) |
1026 | *lastquote = arg[i]; | 1028 | *lastquote = arg[i]; |
1027 | } else if (state == MA_UNQUOTED) | 1029 | } else if (state == MA_UNQUOTED) |
1028 | state = q; | 1030 | state = q; |
1029 | else if (state == q) | 1031 | else if (state == q) |
1030 | state = MA_UNQUOTED; | 1032 | state = MA_UNQUOTED; |
@@ -1567,7 +1569,7 @@ complete_display(char **list, u_int len) | |||
1567 | char *tmp; | 1569 | char *tmp; |
1568 | 1570 | ||
1569 | /* Count entries for sort and find longest */ | 1571 | /* Count entries for sort and find longest */ |
1570 | for (y = 0; list[y]; y++) | 1572 | for (y = 0; list[y]; y++) |
1571 | m = MAX(m, strlen(list[y])); | 1573 | m = MAX(m, strlen(list[y])); |
1572 | 1574 | ||
1573 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) | 1575 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) |
@@ -1612,8 +1614,8 @@ complete_ambiguous(const char *word, char **list, size_t count) | |||
1612 | for (y = 1; list[y]; y++) { | 1614 | for (y = 1; list[y]; y++) { |
1613 | u_int x; | 1615 | u_int x; |
1614 | 1616 | ||
1615 | for (x = 0; x < matchlen; x++) | 1617 | for (x = 0; x < matchlen; x++) |
1616 | if (list[0][x] != list[y][x]) | 1618 | if (list[0][x] != list[y][x]) |
1617 | break; | 1619 | break; |
1618 | 1620 | ||
1619 | matchlen = x; | 1621 | matchlen = x; |
@@ -1625,7 +1627,7 @@ complete_ambiguous(const char *word, char **list, size_t count) | |||
1625 | tmp[matchlen] = '\0'; | 1627 | tmp[matchlen] = '\0'; |
1626 | return tmp; | 1628 | return tmp; |
1627 | } | 1629 | } |
1628 | } | 1630 | } |
1629 | 1631 | ||
1630 | return xstrdup(word); | 1632 | return xstrdup(word); |
1631 | } | 1633 | } |
@@ -1645,12 +1647,12 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, | |||
1645 | if (cmd == NULL) { | 1647 | if (cmd == NULL) { |
1646 | for (y = 0; cmds[y].c; y++) | 1648 | for (y = 0; cmds[y].c; y++) |
1647 | list[count++] = xstrdup(cmds[y].c); | 1649 | list[count++] = xstrdup(cmds[y].c); |
1648 | 1650 | ||
1649 | list[count] = NULL; | 1651 | list[count] = NULL; |
1650 | complete_display(list, 0); | 1652 | complete_display(list, 0); |
1651 | 1653 | ||
1652 | for (y = 0; list[y] != NULL; y++) | 1654 | for (y = 0; list[y] != NULL; y++) |
1653 | free(list[y]); | 1655 | free(list[y]); |
1654 | free(list); | 1656 | free(list); |
1655 | return count; | 1657 | return count; |
1656 | } | 1658 | } |
@@ -1658,7 +1660,7 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, | |||
1658 | /* Prepare subset of commands that start with "cmd" */ | 1660 | /* Prepare subset of commands that start with "cmd" */ |
1659 | cmdlen = strlen(cmd); | 1661 | cmdlen = strlen(cmd); |
1660 | for (y = 0; cmds[y].c; y++) { | 1662 | for (y = 0; cmds[y].c; y++) { |
1661 | if (!strncasecmp(cmd, cmds[y].c, cmdlen)) | 1663 | if (!strncasecmp(cmd, cmds[y].c, cmdlen)) |
1662 | list[count++] = xstrdup(cmds[y].c); | 1664 | list[count++] = xstrdup(cmds[y].c); |
1663 | } | 1665 | } |
1664 | list[count] = NULL; | 1666 | list[count] = NULL; |
@@ -1673,8 +1675,8 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, | |||
1673 | if (count > 1) | 1675 | if (count > 1) |
1674 | complete_display(list, 0); | 1676 | complete_display(list, 0); |
1675 | 1677 | ||
1676 | for (y = 0; list[y]; y++) | 1678 | for (y = 0; list[y]; y++) |
1677 | free(list[y]); | 1679 | free(list[y]); |
1678 | free(list); | 1680 | free(list); |
1679 | 1681 | ||
1680 | if (tmp != NULL) { | 1682 | if (tmp != NULL) { |
@@ -1714,7 +1716,7 @@ complete_is_remote(char *cmd) { | |||
1714 | return -1; | 1716 | return -1; |
1715 | 1717 | ||
1716 | for (i = 0; cmds[i].c; i++) { | 1718 | for (i = 0; cmds[i].c; i++) { |
1717 | if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) | 1719 | if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) |
1718 | return cmds[i].t; | 1720 | return cmds[i].t; |
1719 | } | 1721 | } |
1720 | 1722 | ||
@@ -1731,7 +1733,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1731 | u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; | 1733 | u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; |
1732 | int clen; | 1734 | int clen; |
1733 | const LineInfo *lf; | 1735 | const LineInfo *lf; |
1734 | 1736 | ||
1735 | /* Glob from "file" location */ | 1737 | /* Glob from "file" location */ |
1736 | if (file == NULL) | 1738 | if (file == NULL) |
1737 | tmp = xstrdup("*"); | 1739 | tmp = xstrdup("*"); |
@@ -1745,9 +1747,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1745 | if (remote != LOCAL) { | 1747 | if (remote != LOCAL) { |
1746 | tmp = make_absolute(tmp, remote_path); | 1748 | tmp = make_absolute(tmp, remote_path); |
1747 | remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); | 1749 | remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
1748 | } else | 1750 | } else |
1749 | glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); | 1751 | glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
1750 | 1752 | ||
1751 | /* Determine length of pwd so we can trim completion display */ | 1753 | /* Determine length of pwd so we can trim completion display */ |
1752 | for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { | 1754 | for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { |
1753 | /* Terminate counting on first unescaped glob metacharacter */ | 1755 | /* Terminate counting on first unescaped glob metacharacter */ |
@@ -1763,7 +1765,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1763 | } | 1765 | } |
1764 | free(tmp); | 1766 | free(tmp); |
1765 | 1767 | ||
1766 | if (g.gl_matchc == 0) | 1768 | if (g.gl_matchc == 0) |
1767 | goto out; | 1769 | goto out; |
1768 | 1770 | ||
1769 | if (g.gl_matchc > 1) | 1771 | if (g.gl_matchc > 1) |
@@ -1796,7 +1798,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1796 | 1798 | ||
1797 | if (tmplen > (filelen - cesc)) { | 1799 | if (tmplen > (filelen - cesc)) { |
1798 | tmp2 = tmp + filelen - cesc; | 1800 | tmp2 = tmp + filelen - cesc; |
1799 | len = strlen(tmp2); | 1801 | len = strlen(tmp2); |
1800 | /* quote argument on way out */ | 1802 | /* quote argument on way out */ |
1801 | for (i = 0; i < len; i += clen) { | 1803 | for (i = 0; i < len; i += clen) { |
1802 | if ((clen = mblen(tmp2 + i, len - i)) < 0 || | 1804 | if ((clen = mblen(tmp2 + i, len - i)) < 0 || |
@@ -1852,7 +1854,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1852 | static unsigned char | 1854 | static unsigned char |
1853 | complete(EditLine *el, int ch) | 1855 | complete(EditLine *el, int ch) |
1854 | { | 1856 | { |
1855 | char **argv, *line, quote; | 1857 | char **argv, *line, quote; |
1856 | int argc, carg; | 1858 | int argc, carg; |
1857 | u_int cursor, len, terminated, ret = CC_ERROR; | 1859 | u_int cursor, len, terminated, ret = CC_ERROR; |
1858 | const LineInfo *lf; | 1860 | const LineInfo *lf; |
@@ -1891,7 +1893,7 @@ complete(EditLine *el, int ch) | |||
1891 | } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { | 1893 | } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { |
1892 | /* Handle the command parsing */ | 1894 | /* Handle the command parsing */ |
1893 | if (complete_cmd_parse(el, argv[0], argc == carg, | 1895 | if (complete_cmd_parse(el, argv[0], argc == carg, |
1894 | quote, terminated) != 0) | 1896 | quote, terminated) != 0) |
1895 | ret = CC_REDISPLAY; | 1897 | ret = CC_REDISPLAY; |
1896 | } else if (carg >= 1) { | 1898 | } else if (carg >= 1) { |
1897 | /* Handle file parsing */ | 1899 | /* Handle file parsing */ |
@@ -1904,11 +1906,11 @@ complete(EditLine *el, int ch) | |||
1904 | if (remote != 0 && | 1906 | if (remote != 0 && |
1905 | complete_match(el, complete_ctx->conn, | 1907 | complete_match(el, complete_ctx->conn, |
1906 | *complete_ctx->remote_pathp, filematch, | 1908 | *complete_ctx->remote_pathp, filematch, |
1907 | remote, carg == argc, quote, terminated) != 0) | 1909 | remote, carg == argc, quote, terminated) != 0) |
1908 | ret = CC_REDISPLAY; | 1910 | ret = CC_REDISPLAY; |
1909 | } | 1911 | } |
1910 | 1912 | ||
1911 | free(line); | 1913 | free(line); |
1912 | return ret; | 1914 | return ret; |
1913 | } | 1915 | } |
1914 | #endif /* USE_LIBEDIT */ | 1916 | #endif /* USE_LIBEDIT */ |
@@ -1942,7 +1944,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) | |||
1942 | el_source(el, NULL); | 1944 | el_source(el, NULL); |
1943 | 1945 | ||
1944 | /* Tab Completion */ | 1946 | /* Tab Completion */ |
1945 | el_set(el, EL_ADDFN, "ftp-complete", | 1947 | el_set(el, EL_ADDFN, "ftp-complete", |
1946 | "Context sensitive argument completion", complete); | 1948 | "Context sensitive argument completion", complete); |
1947 | complete_ctx.conn = conn; | 1949 | complete_ctx.conn = conn; |
1948 | complete_ctx.remote_pathp = &remote_path; | 1950 | complete_ctx.remote_pathp = &remote_path; |
@@ -2116,7 +2118,7 @@ usage(void) | |||
2116 | extern char *__progname; | 2118 | extern char *__progname; |
2117 | 2119 | ||
2118 | fprintf(stderr, | 2120 | fprintf(stderr, |
2119 | "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" | 2121 | "usage: %s [-1246Capqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" |
2120 | " [-D sftp_server_path] [-F ssh_config] " | 2122 | " [-D sftp_server_path] [-F ssh_config] " |
2121 | "[-i identity_file] [-l limit]\n" | 2123 | "[-i identity_file] [-l limit]\n" |
2122 | " [-o ssh_option] [-P port] [-R num_requests] " | 2124 | " [-o ssh_option] [-P port] [-R num_requests] " |