summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2013-11-09 12:08:24 +0000
committerColin Watson <cjwatson@debian.org>2013-11-09 12:08:24 +0000
commitee196dab7c5f97f0b80c8099343a375bead92010 (patch)
treef5e86571416d84ad156949e8a3ab12ed12d681f2 /sftp.c
parente01f4f6bfd6f5a47f810fd3522a151d59815402b (diff)
parentc41345ad7ee5a22689e2c009595e85fa27b4b39a (diff)
Import 6.4p1 tarball
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c175
1 files changed, 55 insertions, 120 deletions
diff --git a/sftp.c b/sftp.c
index e21144064..969328de4 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.154 2013/08/09 03:56:42 djm Exp $ */ 1/* $OpenBSD: sftp.c,v 1.148 2013/07/25 00:56: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 *
@@ -129,34 +129,32 @@ 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 */
132enum sftp_command { 132#define I_CHDIR 1
133 I_CHDIR = 1, 133#define I_CHGRP 2
134 I_CHGRP, 134#define I_CHMOD 3
135 I_CHMOD, 135#define I_CHOWN 4
136 I_CHOWN, 136#define I_DF 24
137 I_DF, 137#define I_GET 5
138 I_GET, 138#define I_HELP 6
139 I_HELP, 139#define I_LCHDIR 7
140 I_LCHDIR, 140#define I_LINK 25
141 I_LINK, 141#define I_LLS 8
142 I_LLS, 142#define I_LMKDIR 9
143 I_LMKDIR, 143#define I_LPWD 10
144 I_LPWD, 144#define I_LS 11
145 I_LS, 145#define I_LUMASK 12
146 I_LUMASK, 146#define I_MKDIR 13
147 I_MKDIR, 147#define I_PUT 14
148 I_PUT, 148#define I_PWD 15
149 I_PWD, 149#define I_QUIT 16
150 I_QUIT, 150#define I_RENAME 17
151 I_RENAME, 151#define I_RM 18
152 I_RM, 152#define I_RMDIR 19
153 I_RMDIR, 153#define I_SHELL 20
154 I_SHELL, 154#define I_SYMLINK 21
155 I_SYMLINK, 155#define I_VERSION 22
156 I_VERSION, 156#define I_PROGRESS 23
157 I_PROGRESS, 157#define I_REGET 26
158 I_REGET,
159};
160 158
161struct CMD { 159struct CMD {
162 const char *c; 160 const char *c;
@@ -415,30 +413,6 @@ parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)
415} 413}
416 414
417static int 415static int
418parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag)
419{
420 extern int opterr, optind, optopt, optreset;
421 int ch;
422
423 optind = optreset = 1;
424 opterr = 0;
425
426 *lflag = 0;
427 while ((ch = getopt(argc, argv, "l")) != -1) {
428 switch (ch) {
429 case 'l':
430 *lflag = 1;
431 break;
432 default:
433 error("%s: Invalid flag -%c", cmd, optopt);
434 return -1;
435 }
436 }
437
438 return optind;
439}
440
441static int
442parse_ls_flags(char **argv, int argc, int *lflag) 416parse_ls_flags(char **argv, int argc, int *lflag)
443{ 417{
444 extern int opterr, optind, optopt, optreset; 418 extern int opterr, optind, optopt, optreset;
@@ -519,26 +493,6 @@ parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
519} 493}
520 494
521static int 495static int
522parse_no_flags(const char *cmd, char **argv, int argc)
523{
524 extern int opterr, optind, optopt, optreset;
525 int ch;
526
527 optind = optreset = 1;
528 opterr = 0;
529
530 while ((ch = getopt(argc, argv, "")) != -1) {
531 switch (ch) {
532 default:
533 error("%s: Invalid flag -%c", cmd, optopt);
534 return -1;
535 }
536 }
537
538 return optind;
539}
540
541static int
542is_dir(char *path) 496is_dir(char *path)
543{ 497{
544 struct stat sb; 498 struct stat sb;
@@ -693,7 +647,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
693 error("stat %s: %s", g.gl_pathv[i], strerror(errno)); 647 error("stat %s: %s", g.gl_pathv[i], strerror(errno));
694 continue; 648 continue;
695 } 649 }
696 650
697 tmp = xstrdup(g.gl_pathv[i]); 651 tmp = xstrdup(g.gl_pathv[i]);
698 if ((filename = basename(tmp)) == NULL) { 652 if ((filename = basename(tmp)) == NULL) {
699 error("basename %s: %s", tmp, strerror(errno)); 653 error("basename %s: %s", tmp, strerror(errno));
@@ -1021,7 +975,7 @@ undo_glob_escape(char *s)
1021 * 975 *
1022 * If "lastquote" is not NULL, the quoting character used for the last 976 * If "lastquote" is not NULL, the quoting character used for the last
1023 * argument is placed in *lastquote ("\0", "'" or "\""). 977 * argument is placed in *lastquote ("\0", "'" or "\"").
1024 * 978 *
1025 * If "terminated" is not NULL, *terminated will be set to 1 when the 979 * If "terminated" is not NULL, *terminated will be set to 1 when the
1026 * last argument's quote has been properly terminated or 0 otherwise. 980 * last argument's quote has been properly terminated or 0 otherwise.
1027 * This parameter is only of use if "sloppy" is set. 981 * This parameter is only of use if "sloppy" is set.
@@ -1070,7 +1024,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
1070 state = q; 1024 state = q;
1071 if (lastquote != NULL) 1025 if (lastquote != NULL)
1072 *lastquote = arg[i]; 1026 *lastquote = arg[i];
1073 } else if (state == MA_UNQUOTED) 1027 } else if (state == MA_UNQUOTED)
1074 state = q; 1028 state = q;
1075 else if (state == q) 1029 else if (state == q)
1076 state = MA_UNQUOTED; 1030 state = MA_UNQUOTED;
@@ -1254,15 +1208,8 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag,
1254 case I_LINK: 1208 case I_LINK:
1255 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) 1209 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
1256 return -1; 1210 return -1;
1257 goto parse_two_paths;
1258 case I_RENAME:
1259 if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
1260 return -1;
1261 goto parse_two_paths;
1262 case I_SYMLINK: 1211 case I_SYMLINK:
1263 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) 1212 case I_RENAME:
1264 return -1;
1265 parse_two_paths:
1266 if (argc - optidx < 2) { 1213 if (argc - optidx < 2) {
1267 error("You must specify two paths after a %s " 1214 error("You must specify two paths after a %s "
1268 "command.", cmd); 1215 "command.", cmd);
@@ -1280,8 +1227,6 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag,
1280 case I_CHDIR: 1227 case I_CHDIR:
1281 case I_LCHDIR: 1228 case I_LCHDIR:
1282 case I_LMKDIR: 1229 case I_LMKDIR:
1283 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1284 return -1;
1285 /* Get pathname (mandatory) */ 1230 /* Get pathname (mandatory) */
1286 if (argc - optidx < 1) { 1231 if (argc - optidx < 1) {
1287 error("You must specify a path after a %s command.", 1232 error("You must specify a path after a %s command.",
@@ -1323,8 +1268,6 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag,
1323 base = 8; 1268 base = 8;
1324 case I_CHOWN: 1269 case I_CHOWN:
1325 case I_CHGRP: 1270 case I_CHGRP:
1326 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1327 return -1;
1328 /* Get numeric arg (mandatory) */ 1271 /* Get numeric arg (mandatory) */
1329 if (argc - optidx < 1) 1272 if (argc - optidx < 1)
1330 goto need_num_arg; 1273 goto need_num_arg;
@@ -1355,8 +1298,6 @@ parse_args(const char **cpp, int *aflag, int *hflag, int *iflag, int *lflag,
1355 case I_HELP: 1298 case I_HELP:
1356 case I_VERSION: 1299 case I_VERSION:
1357 case I_PROGRESS: 1300 case I_PROGRESS:
1358 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
1359 return -1;
1360 break; 1301 break;
1361 default: 1302 default:
1362 fatal("Command not implemented"); 1303 fatal("Command not implemented");
@@ -1410,13 +1351,12 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1410 case I_RENAME: 1351 case I_RENAME:
1411 path1 = make_absolute(path1, *pwd); 1352 path1 = make_absolute(path1, *pwd);
1412 path2 = make_absolute(path2, *pwd); 1353 path2 = make_absolute(path2, *pwd);
1413 err = do_rename(conn, path1, path2, lflag); 1354 err = do_rename(conn, path1, path2);
1414 break; 1355 break;
1415 case I_SYMLINK: 1356 case I_SYMLINK:
1416 sflag = 1; 1357 sflag = 1;
1417 case I_LINK: 1358 case I_LINK:
1418 if (!sflag) 1359 path1 = make_absolute(path1, *pwd);
1419 path1 = make_absolute(path1, *pwd);
1420 path2 = make_absolute(path2, *pwd); 1360 path2 = make_absolute(path2, *pwd);
1421 err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2); 1361 err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
1422 break; 1362 break;
@@ -1627,7 +1567,7 @@ complete_display(char **list, u_int len)
1627 char *tmp; 1567 char *tmp;
1628 1568
1629 /* Count entries for sort and find longest */ 1569 /* Count entries for sort and find longest */
1630 for (y = 0; list[y]; y++) 1570 for (y = 0; list[y]; y++)
1631 m = MAX(m, strlen(list[y])); 1571 m = MAX(m, strlen(list[y]));
1632 1572
1633 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) 1573 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
@@ -1672,8 +1612,8 @@ complete_ambiguous(const char *word, char **list, size_t count)
1672 for (y = 1; list[y]; y++) { 1612 for (y = 1; list[y]; y++) {
1673 u_int x; 1613 u_int x;
1674 1614
1675 for (x = 0; x < matchlen; x++) 1615 for (x = 0; x < matchlen; x++)
1676 if (list[0][x] != list[y][x]) 1616 if (list[0][x] != list[y][x])
1677 break; 1617 break;
1678 1618
1679 matchlen = x; 1619 matchlen = x;
@@ -1685,7 +1625,7 @@ complete_ambiguous(const char *word, char **list, size_t count)
1685 tmp[matchlen] = '\0'; 1625 tmp[matchlen] = '\0';
1686 return tmp; 1626 return tmp;
1687 } 1627 }
1688 } 1628 }
1689 1629
1690 return xstrdup(word); 1630 return xstrdup(word);
1691} 1631}
@@ -1705,12 +1645,12 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
1705 if (cmd == NULL) { 1645 if (cmd == NULL) {
1706 for (y = 0; cmds[y].c; y++) 1646 for (y = 0; cmds[y].c; y++)
1707 list[count++] = xstrdup(cmds[y].c); 1647 list[count++] = xstrdup(cmds[y].c);
1708 1648
1709 list[count] = NULL; 1649 list[count] = NULL;
1710 complete_display(list, 0); 1650 complete_display(list, 0);
1711 1651
1712 for (y = 0; list[y] != NULL; y++) 1652 for (y = 0; list[y] != NULL; y++)
1713 free(list[y]); 1653 free(list[y]);
1714 free(list); 1654 free(list);
1715 return count; 1655 return count;
1716 } 1656 }
@@ -1718,7 +1658,7 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
1718 /* Prepare subset of commands that start with "cmd" */ 1658 /* Prepare subset of commands that start with "cmd" */
1719 cmdlen = strlen(cmd); 1659 cmdlen = strlen(cmd);
1720 for (y = 0; cmds[y].c; y++) { 1660 for (y = 0; cmds[y].c; y++) {
1721 if (!strncasecmp(cmd, cmds[y].c, cmdlen)) 1661 if (!strncasecmp(cmd, cmds[y].c, cmdlen))
1722 list[count++] = xstrdup(cmds[y].c); 1662 list[count++] = xstrdup(cmds[y].c);
1723 } 1663 }
1724 list[count] = NULL; 1664 list[count] = NULL;
@@ -1733,8 +1673,8 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
1733 if (count > 1) 1673 if (count > 1)
1734 complete_display(list, 0); 1674 complete_display(list, 0);
1735 1675
1736 for (y = 0; list[y]; y++) 1676 for (y = 0; list[y]; y++)
1737 free(list[y]); 1677 free(list[y]);
1738 free(list); 1678 free(list);
1739 1679
1740 if (tmp != NULL) { 1680 if (tmp != NULL) {
@@ -1774,7 +1714,7 @@ complete_is_remote(char *cmd) {
1774 return -1; 1714 return -1;
1775 1715
1776 for (i = 0; cmds[i].c; i++) { 1716 for (i = 0; cmds[i].c; i++) {
1777 if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) 1717 if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c)))
1778 return cmds[i].t; 1718 return cmds[i].t;
1779 } 1719 }
1780 1720
@@ -1791,7 +1731,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1791 u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; 1731 u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
1792 int clen; 1732 int clen;
1793 const LineInfo *lf; 1733 const LineInfo *lf;
1794 1734
1795 /* Glob from "file" location */ 1735 /* Glob from "file" location */
1796 if (file == NULL) 1736 if (file == NULL)
1797 tmp = xstrdup("*"); 1737 tmp = xstrdup("*");
@@ -1805,9 +1745,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1805 if (remote != LOCAL) { 1745 if (remote != LOCAL) {
1806 tmp = make_absolute(tmp, remote_path); 1746 tmp = make_absolute(tmp, remote_path);
1807 remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); 1747 remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1808 } else 1748 } else
1809 glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); 1749 glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
1810 1750
1811 /* Determine length of pwd so we can trim completion display */ 1751 /* Determine length of pwd so we can trim completion display */
1812 for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { 1752 for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
1813 /* Terminate counting on first unescaped glob metacharacter */ 1753 /* Terminate counting on first unescaped glob metacharacter */
@@ -1823,7 +1763,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1823 } 1763 }
1824 free(tmp); 1764 free(tmp);
1825 1765
1826 if (g.gl_matchc == 0) 1766 if (g.gl_matchc == 0)
1827 goto out; 1767 goto out;
1828 1768
1829 if (g.gl_matchc > 1) 1769 if (g.gl_matchc > 1)
@@ -1856,7 +1796,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1856 1796
1857 if (tmplen > (filelen - cesc)) { 1797 if (tmplen > (filelen - cesc)) {
1858 tmp2 = tmp + filelen - cesc; 1798 tmp2 = tmp + filelen - cesc;
1859 len = strlen(tmp2); 1799 len = strlen(tmp2);
1860 /* quote argument on way out */ 1800 /* quote argument on way out */
1861 for (i = 0; i < len; i += clen) { 1801 for (i = 0; i < len; i += clen) {
1862 if ((clen = mblen(tmp2 + i, len - i)) < 0 || 1802 if ((clen = mblen(tmp2 + i, len - i)) < 0 ||
@@ -1912,7 +1852,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1912static unsigned char 1852static unsigned char
1913complete(EditLine *el, int ch) 1853complete(EditLine *el, int ch)
1914{ 1854{
1915 char **argv, *line, quote; 1855 char **argv, *line, quote;
1916 int argc, carg; 1856 int argc, carg;
1917 u_int cursor, len, terminated, ret = CC_ERROR; 1857 u_int cursor, len, terminated, ret = CC_ERROR;
1918 const LineInfo *lf; 1858 const LineInfo *lf;
@@ -1951,7 +1891,7 @@ complete(EditLine *el, int ch)
1951 } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { 1891 } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') {
1952 /* Handle the command parsing */ 1892 /* Handle the command parsing */
1953 if (complete_cmd_parse(el, argv[0], argc == carg, 1893 if (complete_cmd_parse(el, argv[0], argc == carg,
1954 quote, terminated) != 0) 1894 quote, terminated) != 0)
1955 ret = CC_REDISPLAY; 1895 ret = CC_REDISPLAY;
1956 } else if (carg >= 1) { 1896 } else if (carg >= 1) {
1957 /* Handle file parsing */ 1897 /* Handle file parsing */
@@ -1964,11 +1904,11 @@ complete(EditLine *el, int ch)
1964 if (remote != 0 && 1904 if (remote != 0 &&
1965 complete_match(el, complete_ctx->conn, 1905 complete_match(el, complete_ctx->conn,
1966 *complete_ctx->remote_pathp, filematch, 1906 *complete_ctx->remote_pathp, filematch,
1967 remote, carg == argc, quote, terminated) != 0) 1907 remote, carg == argc, quote, terminated) != 0)
1968 ret = CC_REDISPLAY; 1908 ret = CC_REDISPLAY;
1969 } 1909 }
1970 1910
1971 free(line); 1911 free(line);
1972 return ret; 1912 return ret;
1973} 1913}
1974#endif /* USE_LIBEDIT */ 1914#endif /* USE_LIBEDIT */
@@ -2002,17 +1942,12 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2002 el_source(el, NULL); 1942 el_source(el, NULL);
2003 1943
2004 /* Tab Completion */ 1944 /* Tab Completion */
2005 el_set(el, EL_ADDFN, "ftp-complete", 1945 el_set(el, EL_ADDFN, "ftp-complete",
2006 "Context sensitive argument completion", complete); 1946 "Context sensitive argument completion", complete);
2007 complete_ctx.conn = conn; 1947 complete_ctx.conn = conn;
2008 complete_ctx.remote_pathp = &remote_path; 1948 complete_ctx.remote_pathp = &remote_path;
2009 el_set(el, EL_CLIENTDATA, (void*)&complete_ctx); 1949 el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
2010 el_set(el, EL_BIND, "^I", "ftp-complete", NULL); 1950 el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
2011 /* enable ctrl-left-arrow and ctrl-right-arrow */
2012 el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
2013 el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL);
2014 el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
2015 el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
2016 } 1951 }
2017#endif /* USE_LIBEDIT */ 1952#endif /* USE_LIBEDIT */
2018 1953
@@ -2181,7 +2116,7 @@ usage(void)
2181 extern char *__progname; 2116 extern char *__progname;
2182 2117
2183 fprintf(stderr, 2118 fprintf(stderr,
2184 "usage: %s [-1246aCpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" 2119 "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2185 " [-D sftp_server_path] [-F ssh_config] " 2120 " [-D sftp_server_path] [-F ssh_config] "
2186 "[-i identity_file] [-l limit]\n" 2121 "[-i identity_file] [-l limit]\n"
2187 " [-o ssh_option] [-P port] [-R num_requests] " 2122 " [-o ssh_option] [-P port] [-R num_requests] "