Skip to content

Commit af5fc94

Browse files
committed
Fix for sending sftp recursive folder.
1 parent 5e50d2a commit af5fc94

File tree

8 files changed

+94
-60
lines changed

8 files changed

+94
-60
lines changed

contrib/win32/win32compat/fileio.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
557557

558558
int
559559
fileio_stat(const char *path, struct _stat64 *buf) {
560-
return _stat64(path, buf);
560+
wchar_t wpath[MAX_PATH];
561+
562+
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH) == 0) {
563+
errno = EFAULT;
564+
debug("WideCharToMultiByte failed - ERROR:%d", GetLastError());
565+
return GetLastError();
566+
}
567+
568+
return _wstat64(wpath, buf);
561569
}
562570

563571
long

contrib/win32/win32compat/w32fd.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,9 @@ char *w32_getcwd(char *buffer, int maxlen) {
444444
wchar_t *wpwd = _wgetcwd(wdirname, MAX_PATH);
445445

446446
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, NULL, 0, NULL, NULL)) == 0 ||
447-
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, buffer, needed, NULL, NULL) != needed)
448-
fatal("failed to covert input arguments");
447+
(needed > MAX_PATH) ||
448+
(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, buffer, needed, NULL, NULL) != needed))
449+
fatal("failed to convert input arguments");
449450

450451
return buffer;
451452
}

contrib/win32/win32compat/wmain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ utf16_to_utf8(wchar_t* utf16str) {
4141
if ((needed = WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, NULL, 0, NULL, NULL)) == 0 ||
4242
(ret = malloc(needed)) == NULL ||
4343
WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, ret, needed, NULL, NULL) != needed )
44-
fatal("failed to covert input arguments");
44+
fatal("failed to convert input arguments");
4545

4646
return ret;
4747
}

sftp-client.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
754754
status = get_status(conn, id);
755755
if (status != SSH2_FX_OK && print_flag)
756756
error("Couldn't create directory: %s", fx2txt(status));
757+
errno = status;
757758

758759
return status == SSH2_FX_OK ? 0 : -1;
759760
}
@@ -1878,7 +1879,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
18781879
* if it was created successfully.
18791880
*/
18801881
if (status != SSH2_FX_OK) {
1881-
if (status != SSH2_FX_FAILURE)
1882+
if (errno != SSH2_FX_FAILURE)
18821883
return -1;
18831884
if (do_stat(conn, dst, 0) == NULL)
18841885
return -1;

sftp-client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void free_sftp_dirents(SFTP_DIRENT **);
6868
int do_rm(struct sftp_conn *, const char *);
6969

7070
/* Create directory 'path' */
71-
int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
71+
u_int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
7272

7373
/* Remove directory 'path' */
7474
int do_rmdir(struct sftp_conn *, const char *);

sftp.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef void EditLine;
7272

7373
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
7474
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
75+
#define MAX_COMMAND_LINE 2048
7576

7677
#ifdef WINDOWS
7778
#include <io.h>
@@ -2032,7 +2033,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
20322033
{
20332034
char *remote_path;
20342035
char *dir = NULL;
2035-
char cmd[2048];
2036+
char cmd[MAX_COMMAND_LINE];
20362037
int err, interactive;
20372038
EditLine *el = NULL;
20382039
#ifdef USE_LIBEDIT
@@ -2122,7 +2123,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
21222123
if (el == NULL) {
21232124
#ifdef WINDOWS
21242125
if (interactive) {
2125-
wchar_t wcmd[2048];
2126+
wchar_t wcmd[MAX_COMMAND_LINE];
21262127
printf("sftp> ");
21272128
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
21282129
printf("\n");
@@ -2131,8 +2132,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
21312132
else {
21322133
int needed;
21332134
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, NULL, 0, NULL, NULL)) == 0 ||
2134-
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, cmd, needed, NULL, NULL) != needed)
2135-
fatal("failed to covert input arguments");
2135+
(needed > MAX_COMMAND_LINE) ||
2136+
(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, cmd, needed, NULL, NULL) != needed))
2137+
fatal("failed to convert input arguments");
21362138
}
21372139
}
21382140
else {
@@ -2350,6 +2352,8 @@ main(int argc, char **argv)
23502352
w32posix_initialize();
23512353
setvbuf(stdout, NULL, _IONBF, 0);
23522354

2355+
ConInit(STD_OUTPUT_HANDLE, TRUE);
2356+
23532357
#endif
23542358
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
23552359
sanitise_stdfd();

win32_dirent.c

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,53 @@
1414
Return a DIR stream on the directory, or NULL if it could not be opened. */
1515
DIR * opendir(char *name)
1616
{
17-
struct _finddata_t c_file;
18-
intptr_t hFile;
19-
DIR *pdir;
20-
char searchstr[256];
21-
22-
// add *.* for Windows _findfirst() search pattern
23-
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name);
24-
25-
if ((hFile = _findfirst(searchstr, &c_file)) == -1L) {
26-
if (1) // verbose
27-
printf( "No files found for %s search.\n", name );
28-
return (DIR *) NULL;
29-
}
30-
else {
31-
pdir = (DIR *) malloc( sizeof(DIR) );
32-
pdir->hFile = hFile ;
33-
pdir->c_file = c_file ;
34-
strcpy_s(pdir->initName,sizeof(pdir->initName), c_file.name);
35-
36-
return pdir ;
37-
}
17+
struct _wfinddata_t c_file;
18+
intptr_t hFile;
19+
DIR *pdir;
20+
wchar_t searchstr[MAX_PATH];
21+
wchar_t wname[MAX_PATH];
22+
int needed;
23+
24+
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
25+
26+
// add *.* for Windows _findfirst() search pattern
27+
swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname);
28+
29+
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) {
30+
if (1) // verbose
31+
printf( "No files found for %s search.\n", name );
32+
return (DIR *) NULL;
33+
}
34+
else {
35+
pdir = (DIR *) malloc( sizeof(DIR) );
36+
pdir->hFile = hFile ;
37+
pdir->c_file.attrib = c_file.attrib ;
38+
pdir->c_file.size = c_file.size;
39+
pdir->c_file.time_access = c_file.time_access;
40+
pdir->c_file.time_create = c_file.time_create;
41+
pdir->c_file.time_write = c_file.time_write;
42+
43+
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, NULL, 0, NULL, NULL)) == 0 ||
44+
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, pdir->c_file.name, needed, NULL, NULL) != needed)
45+
fatal("failed to covert input arguments");
46+
47+
strcpy_s(pdir->initName, sizeof(pdir->initName), pdir->c_file.name);
48+
49+
return pdir ;
50+
}
3851
}
3952

4053
/* Close the directory stream DIRP.
4154
Return 0 if successful, -1 if not. */
4255
int closedir(DIR *dirp)
4356
{
44-
if ( dirp && (dirp->hFile) ) {
45-
_findclose( dirp->hFile );
46-
dirp->hFile = 0;
47-
free (dirp);
48-
}
57+
if ( dirp && (dirp->hFile) ) {
58+
_findclose( dirp->hFile );
59+
dirp->hFile = 0;
60+
free (dirp);
61+
}
4962

50-
return 0;
63+
return 0;
5164
}
5265

5366
/* Read a directory entry from DIRP.
@@ -56,24 +69,31 @@ int closedir(DIR *dirp)
5669
by a later readdir call on the same DIR stream. */
5770
struct dirent *readdir(void *avp)
5871
{
59-
struct dirent *pdirentry;
60-
DIR *dirp = (DIR *)avp;
61-
62-
for (;;) {
63-
if ( _findnext( dirp->hFile, &(dirp->c_file) ) == 0 ) {
64-
if ( ( strcmp (dirp->c_file.name,".") == 0 ) ||
65-
( strcmp (dirp->c_file.name,"..") == 0 ) ) {
66-
continue ;
67-
}
68-
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
69-
pdirentry->d_name = dirp->c_file.name ;
70-
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
71-
return pdirentry ;
72-
}
73-
else {
74-
return (struct dirent *) NULL;
75-
}
76-
}
72+
int needed;
73+
struct dirent *pdirentry;
74+
struct _wfinddata_t c_file;
75+
DIR *dirp = (DIR *)avp;
76+
77+
for (;;) {
78+
if ( _wfindnext( dirp->hFile, &c_file ) == 0 ) {
79+
if ( ( wcscmp (c_file.name, L".") == 0 ) ||
80+
( wcscmp (c_file.name, L"..") == 0 ) ) {
81+
continue ;
82+
}
83+
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
84+
85+
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, NULL, 0, NULL, NULL)) == 0 ||
86+
(pdirentry->d_name = malloc(needed)) == NULL ||
87+
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, pdirentry->d_name, needed, NULL, NULL) != needed)
88+
fatal("failed to covert input arguments");
89+
90+
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
91+
return pdirentry ;
92+
}
93+
else {
94+
return (struct dirent *) NULL;
95+
}
96+
}
7797
}
7898

7999
// return last part of a path. The last path being a filename.

win32_dirent.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ struct dirent {
1818
};
1919

2020
typedef struct {
21-
intptr_t hFile;
22-
struct _finddata_t c_file;
23-
int bRoot;
24-
int bDrive;
25-
char initName[260];
21+
intptr_t hFile;
22+
struct _finddata_t c_file;
23+
int bRoot;
24+
int bDrive;
25+
char initName[260];
2626
} DIR;
2727

2828
DIR * opendir(char *name);

0 commit comments

Comments
 (0)