Fix for sending sftp recursive folder.

This commit is contained in:
Ray Hayes 2016-10-19 15:27:16 -07:00
parent 5e50d2a9e7
commit af5fc94823
8 changed files with 90 additions and 56 deletions

View File

@ -557,7 +557,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
int
fileio_stat(const char *path, struct _stat64 *buf) {
return _stat64(path, buf);
wchar_t wpath[MAX_PATH];
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH) == 0) {
errno = EFAULT;
debug("WideCharToMultiByte failed - ERROR:%d", GetLastError());
return GetLastError();
}
return _wstat64(wpath, buf);
}
long

View File

@ -444,8 +444,9 @@ char *w32_getcwd(char *buffer, int maxlen) {
wchar_t *wpwd = _wgetcwd(wdirname, MAX_PATH);
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, NULL, 0, NULL, NULL)) == 0 ||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, buffer, needed, NULL, NULL) != needed)
fatal("failed to covert input arguments");
(needed > MAX_PATH) ||
(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, buffer, needed, NULL, NULL) != needed))
fatal("failed to convert input arguments");
return buffer;
}

View File

@ -41,7 +41,7 @@ utf16_to_utf8(wchar_t* utf16str) {
if ((needed = WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, NULL, 0, NULL, NULL)) == 0 ||
(ret = malloc(needed)) == NULL ||
WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, ret, needed, NULL, NULL) != needed )
fatal("failed to covert input arguments");
fatal("failed to convert input arguments");
return ret;
}

View File

@ -754,6 +754,7 @@ do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
status = get_status(conn, id);
if (status != SSH2_FX_OK && print_flag)
error("Couldn't create directory: %s", fx2txt(status));
errno = status;
return status == SSH2_FX_OK ? 0 : -1;
}
@ -1878,7 +1879,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
* if it was created successfully.
*/
if (status != SSH2_FX_OK) {
if (status != SSH2_FX_FAILURE)
if (errno != SSH2_FX_FAILURE)
return -1;
if (do_stat(conn, dst, 0) == NULL)
return -1;

View File

@ -68,7 +68,7 @@ void free_sftp_dirents(SFTP_DIRENT **);
int do_rm(struct sftp_conn *, const char *);
/* Create directory 'path' */
int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
u_int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
/* Remove directory 'path' */
int do_rmdir(struct sftp_conn *, const char *);

12
sftp.c
View File

@ -72,6 +72,7 @@ typedef void EditLine;
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
#define MAX_COMMAND_LINE 2048
#ifdef WINDOWS
#include <io.h>
@ -2032,7 +2033,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
{
char *remote_path;
char *dir = NULL;
char cmd[2048];
char cmd[MAX_COMMAND_LINE];
int err, interactive;
EditLine *el = NULL;
#ifdef USE_LIBEDIT
@ -2122,7 +2123,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
if (el == NULL) {
#ifdef WINDOWS
if (interactive) {
wchar_t wcmd[2048];
wchar_t wcmd[MAX_COMMAND_LINE];
printf("sftp> ");
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
printf("\n");
@ -2131,8 +2132,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
else {
int needed;
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, NULL, 0, NULL, NULL)) == 0 ||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, cmd, needed, NULL, NULL) != needed)
fatal("failed to covert input arguments");
(needed > MAX_COMMAND_LINE) ||
(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wcmd, -1, cmd, needed, NULL, NULL) != needed))
fatal("failed to convert input arguments");
}
}
else {
@ -2350,6 +2352,8 @@ main(int argc, char **argv)
w32posix_initialize();
setvbuf(stdout, NULL, _IONBF, 0);
ConInit(STD_OUTPUT_HANDLE, TRUE);
#endif
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();

View File

@ -14,40 +14,53 @@
Return a DIR stream on the directory, or NULL if it could not be opened. */
DIR * opendir(char *name)
{
struct _finddata_t c_file;
intptr_t hFile;
DIR *pdir;
char searchstr[256];
struct _wfinddata_t c_file;
intptr_t hFile;
DIR *pdir;
wchar_t searchstr[MAX_PATH];
wchar_t wname[MAX_PATH];
int needed;
// add *.* for Windows _findfirst() search pattern
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name);
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
if ((hFile = _findfirst(searchstr, &c_file)) == -1L) {
if (1) // verbose
printf( "No files found for %s search.\n", name );
return (DIR *) NULL;
}
else {
pdir = (DIR *) malloc( sizeof(DIR) );
pdir->hFile = hFile ;
pdir->c_file = c_file ;
strcpy_s(pdir->initName,sizeof(pdir->initName), c_file.name);
// add *.* for Windows _findfirst() search pattern
swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname);
return pdir ;
}
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) {
if (1) // verbose
printf( "No files found for %s search.\n", name );
return (DIR *) NULL;
}
else {
pdir = (DIR *) malloc( sizeof(DIR) );
pdir->hFile = hFile ;
pdir->c_file.attrib = c_file.attrib ;
pdir->c_file.size = c_file.size;
pdir->c_file.time_access = c_file.time_access;
pdir->c_file.time_create = c_file.time_create;
pdir->c_file.time_write = c_file.time_write;
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, NULL, 0, NULL, NULL)) == 0 ||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, pdir->c_file.name, needed, NULL, NULL) != needed)
fatal("failed to covert input arguments");
strcpy_s(pdir->initName, sizeof(pdir->initName), pdir->c_file.name);
return pdir ;
}
}
/* Close the directory stream DIRP.
Return 0 if successful, -1 if not. */
int closedir(DIR *dirp)
{
if ( dirp && (dirp->hFile) ) {
_findclose( dirp->hFile );
dirp->hFile = 0;
free (dirp);
}
if ( dirp && (dirp->hFile) ) {
_findclose( dirp->hFile );
dirp->hFile = 0;
free (dirp);
}
return 0;
return 0;
}
/* Read a directory entry from DIRP.
@ -56,24 +69,31 @@ int closedir(DIR *dirp)
by a later readdir call on the same DIR stream. */
struct dirent *readdir(void *avp)
{
struct dirent *pdirentry;
DIR *dirp = (DIR *)avp;
int needed;
struct dirent *pdirentry;
struct _wfinddata_t c_file;
DIR *dirp = (DIR *)avp;
for (;;) {
if ( _findnext( dirp->hFile, &(dirp->c_file) ) == 0 ) {
if ( ( strcmp (dirp->c_file.name,".") == 0 ) ||
( strcmp (dirp->c_file.name,"..") == 0 ) ) {
continue ;
}
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
pdirentry->d_name = dirp->c_file.name ;
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
return pdirentry ;
}
else {
return (struct dirent *) NULL;
}
}
for (;;) {
if ( _wfindnext( dirp->hFile, &c_file ) == 0 ) {
if ( ( wcscmp (c_file.name, L".") == 0 ) ||
( wcscmp (c_file.name, L"..") == 0 ) ) {
continue ;
}
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, NULL, 0, NULL, NULL)) == 0 ||
(pdirentry->d_name = malloc(needed)) == NULL ||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, c_file.name, -1, pdirentry->d_name, needed, NULL, NULL) != needed)
fatal("failed to covert input arguments");
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
return pdirentry ;
}
else {
return (struct dirent *) NULL;
}
}
}
// return last part of a path. The last path being a filename.

View File

@ -18,11 +18,11 @@ struct dirent {
};
typedef struct {
intptr_t hFile;
struct _finddata_t c_file;
int bRoot;
int bDrive;
char initName[260];
intptr_t hFile;
struct _finddata_t c_file;
int bRoot;
int bDrive;
char initName[260];
} DIR;
DIR * opendir(char *name);