diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index c460575..148efe9 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -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 diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index ec0e4f4..d6da8aa 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -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; } diff --git a/contrib/win32/win32compat/wmain.c b/contrib/win32/win32compat/wmain.c index 0c58d48..0b2e301 100644 --- a/contrib/win32/win32compat/wmain.c +++ b/contrib/win32/win32compat/wmain.c @@ -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; } diff --git a/sftp-client.c b/sftp-client.c index 83cdfb0..3034b77 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -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; diff --git a/sftp-client.h b/sftp-client.h index f814b07..7d70477 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -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 *); diff --git a/sftp.c b/sftp.c index 8c6678a..47f35dd 100644 --- a/sftp.c +++ b/sftp.c @@ -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 @@ -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(); diff --git a/win32_dirent.c b/win32_dirent.c index 4036a8d..c5337bc 100644 --- a/win32_dirent.c +++ b/win32_dirent.c @@ -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. diff --git a/win32_dirent.h b/win32_dirent.h index 29a3323..2b2bec6 100644 --- a/win32_dirent.h +++ b/win32_dirent.h @@ -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);