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 int
fileio_stat(const char *path, struct _stat64 *buf) { 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 long

View File

@ -444,8 +444,9 @@ char *w32_getcwd(char *buffer, int maxlen) {
wchar_t *wpwd = _wgetcwd(wdirname, MAX_PATH); wchar_t *wpwd = _wgetcwd(wdirname, MAX_PATH);
if ((needed = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, NULL, 0, NULL, NULL)) == 0 || 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) (needed > MAX_PATH) ||
fatal("failed to covert input arguments"); (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wdirname, -1, buffer, needed, NULL, NULL) != needed))
fatal("failed to convert input arguments");
return buffer; 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 || if ((needed = WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, NULL, 0, NULL, NULL)) == 0 ||
(ret = malloc(needed)) == NULL || (ret = malloc(needed)) == NULL ||
WideCharToMultiByte(CP_UTF8, 0, utf16str, -1, ret, needed, NULL, NULL) != needed ) 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; 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); status = get_status(conn, id);
if (status != SSH2_FX_OK && print_flag) if (status != SSH2_FX_OK && print_flag)
error("Couldn't create directory: %s", fx2txt(status)); error("Couldn't create directory: %s", fx2txt(status));
errno = status;
return status == SSH2_FX_OK ? 0 : -1; 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 it was created successfully.
*/ */
if (status != SSH2_FX_OK) { if (status != SSH2_FX_OK) {
if (status != SSH2_FX_FAILURE) if (errno != SSH2_FX_FAILURE)
return -1; return -1;
if (do_stat(conn, dst, 0) == NULL) if (do_stat(conn, dst, 0) == NULL)
return -1; return -1;

View File

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

View File

@ -14,15 +14,19 @@
Return a DIR stream on the directory, or NULL if it could not be opened. */ Return a DIR stream on the directory, or NULL if it could not be opened. */
DIR * opendir(char *name) DIR * opendir(char *name)
{ {
struct _finddata_t c_file; struct _wfinddata_t c_file;
intptr_t hFile; intptr_t hFile;
DIR *pdir; DIR *pdir;
char searchstr[256]; wchar_t searchstr[MAX_PATH];
wchar_t wname[MAX_PATH];
int needed;
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
// add *.* for Windows _findfirst() search pattern // add *.* for Windows _findfirst() search pattern
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name); swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname);
if ((hFile = _findfirst(searchstr, &c_file)) == -1L) { if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) {
if (1) // verbose if (1) // verbose
printf( "No files found for %s search.\n", name ); printf( "No files found for %s search.\n", name );
return (DIR *) NULL; return (DIR *) NULL;
@ -30,8 +34,17 @@ DIR * opendir(char *name)
else { else {
pdir = (DIR *) malloc( sizeof(DIR) ); pdir = (DIR *) malloc( sizeof(DIR) );
pdir->hFile = hFile ; pdir->hFile = hFile ;
pdir->c_file = c_file ; pdir->c_file.attrib = c_file.attrib ;
strcpy_s(pdir->initName,sizeof(pdir->initName), c_file.name); 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 ; return pdir ;
} }
@ -56,17 +69,24 @@ int closedir(DIR *dirp)
by a later readdir call on the same DIR stream. */ by a later readdir call on the same DIR stream. */
struct dirent *readdir(void *avp) struct dirent *readdir(void *avp)
{ {
int needed;
struct dirent *pdirentry; struct dirent *pdirentry;
struct _wfinddata_t c_file;
DIR *dirp = (DIR *)avp; DIR *dirp = (DIR *)avp;
for (;;) { for (;;) {
if ( _findnext( dirp->hFile, &(dirp->c_file) ) == 0 ) { if ( _wfindnext( dirp->hFile, &c_file ) == 0 ) {
if ( ( strcmp (dirp->c_file.name,".") == 0 ) || if ( ( wcscmp (c_file.name, L".") == 0 ) ||
( strcmp (dirp->c_file.name,"..") == 0 ) ) { ( wcscmp (c_file.name, L"..") == 0 ) ) {
continue ; continue ;
} }
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) ); pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
pdirentry->d_name = dirp->c_file.name ;
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 pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
return pdirentry ; return pdirentry ;
} }