summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/sftp.c b/sftp.c
index 235c6ad04..342ae7efc 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.136 2012/06/22 14:36:33 dtucker Exp $ */ 1/* $OpenBSD: sftp.c,v 1.142 2013/02/08 00:41:12 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 *
@@ -54,10 +54,6 @@ typedef void EditLine;
54# include <util.h> 54# include <util.h>
55#endif 55#endif
56 56
57#ifdef HAVE_LIBUTIL_H
58# include <libutil.h>
59#endif
60
61#include "xmalloc.h" 57#include "xmalloc.h"
62#include "log.h" 58#include "log.h"
63#include "pathnames.h" 59#include "pathnames.h"
@@ -991,6 +987,10 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
991 state = MA_START; 987 state = MA_START;
992 i = j = 0; 988 i = j = 0;
993 for (;;) { 989 for (;;) {
990 if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){
991 error("Too many arguments.");
992 return NULL;
993 }
994 if (isspace(arg[i])) { 994 if (isspace(arg[i])) {
995 if (state == MA_UNQUOTED) { 995 if (state == MA_UNQUOTED) {
996 /* Terminate current argument */ 996 /* Terminate current argument */
@@ -1141,7 +1141,7 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1141 1141
1142 /* Figure out which command we have */ 1142 /* Figure out which command we have */
1143 for (i = 0; cmds[i].c != NULL; i++) { 1143 for (i = 0; cmds[i].c != NULL; i++) {
1144 if (strcasecmp(cmds[i].c, argv[0]) == 0) 1144 if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
1145 break; 1145 break;
1146 } 1146 }
1147 cmdnum = cmds[i].n; 1147 cmdnum = cmds[i].n;
@@ -1695,7 +1695,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1695{ 1695{
1696 glob_t g; 1696 glob_t g;
1697 char *tmp, *tmp2, ins[3]; 1697 char *tmp, *tmp2, ins[3];
1698 u_int i, hadglob, pwdlen, len, tmplen, filelen; 1698 u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
1699 const LineInfo *lf; 1699 const LineInfo *lf;
1700 1700
1701 /* Glob from "file" location */ 1701 /* Glob from "file" location */
@@ -1704,6 +1704,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1704 else 1704 else
1705 xasprintf(&tmp, "%s*", file); 1705 xasprintf(&tmp, "%s*", file);
1706 1706
1707 /* Check if the path is absolute. */
1708 isabs = tmp[0] == '/';
1709
1707 memset(&g, 0, sizeof(g)); 1710 memset(&g, 0, sizeof(g));
1708 if (remote != LOCAL) { 1711 if (remote != LOCAL) {
1709 tmp = make_absolute(tmp, remote_path); 1712 tmp = make_absolute(tmp, remote_path);
@@ -1738,7 +1741,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1738 goto out; 1741 goto out;
1739 1742
1740 tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc); 1743 tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
1741 tmp = path_strip(tmp2, remote_path); 1744 tmp = path_strip(tmp2, isabs ? NULL : remote_path);
1742 xfree(tmp2); 1745 xfree(tmp2);
1743 1746
1744 if (tmp == NULL) 1747 if (tmp == NULL)
@@ -1747,8 +1750,18 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1747 tmplen = strlen(tmp); 1750 tmplen = strlen(tmp);
1748 filelen = strlen(file); 1751 filelen = strlen(file);
1749 1752
1750 if (tmplen > filelen) { 1753 /* Count the number of escaped characters in the input string. */
1751 tmp2 = tmp + filelen; 1754 cesc = isesc = 0;
1755 for (i = 0; i < filelen; i++) {
1756 if (!isesc && file[i] == '\\' && i + 1 < filelen){
1757 isesc = 1;
1758 cesc++;
1759 } else
1760 isesc = 0;
1761 }
1762
1763 if (tmplen > (filelen - cesc)) {
1764 tmp2 = tmp + filelen - cesc;
1752 len = strlen(tmp2); 1765 len = strlen(tmp2);
1753 /* quote argument on way out */ 1766 /* quote argument on way out */
1754 for (i = 0; i < len; i++) { 1767 for (i = 0; i < len; i++) {
@@ -1762,6 +1775,8 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
1762 case '\t': 1775 case '\t':
1763 case '[': 1776 case '[':
1764 case ' ': 1777 case ' ':
1778 case '#':
1779 case '*':
1765 if (quote == '\0' || tmp2[i] == quote) { 1780 if (quote == '\0' || tmp2[i] == quote) {
1766 if (el_insertstr(el, ins) == -1) 1781 if (el_insertstr(el, ins) == -1)
1767 fatal("el_insertstr " 1782 fatal("el_insertstr "
@@ -1917,6 +1932,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
1917 return (-1); 1932 return (-1);
1918 } 1933 }
1919 } else { 1934 } else {
1935 /* XXX this is wrong wrt quoting */
1920 if (file2 == NULL) 1936 if (file2 == NULL)
1921 snprintf(cmd, sizeof cmd, "get %s", dir); 1937 snprintf(cmd, sizeof cmd, "get %s", dir);
1922 else 1938 else