diff --git a/.gitignore b/.gitignore
index dcbf920..aa1a453 100644
--- a/.gitignore
+++ b/.gitignore
@@ -277,5 +277,17 @@ Makefile.in
d2utmpa*
configure
contrib/win32/openssh/Win32-OpenSSH.VC.opendb
+contrib/win32/openssh/Win32-OpenSSH.VC.db
*.opendb
*.db
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
\ No newline at end of file
diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs
index 51e9445..38b38a8 100644
--- a/contrib/win32/openssh/config.h.vs
+++ b/contrib/win32/openssh/config.h.vs
@@ -1632,6 +1632,9 @@
#define HAVE_STRNCASECMP 1
#endif
+/* Define to 1 if you have the locale.h header. */
+#define HAVE_LOCALE_H 1
+
#define HAVE_STRUCT_IN6_ADDR 1
#define HAVE_STRUCT_SOCKADDR_IN6 1
#define HAVE_STRUCT_TIMEVAL 1
@@ -1725,6 +1728,6 @@ typedef long ssize_t;
#define HAVE_MBLEN 1
#define SSHDIR "."
-#define _PATH_SFTP_SERVER "./sftp-server.exe"
-#define _PATH_SSH_PROGRAM "./ssh.exe"
+#define _PATH_SFTP_SERVER "sftp-server.exe"
+#define _PATH_SSH_PROGRAM "ssh.exe"
#define _PATH_LS "dir"
diff --git a/contrib/win32/openssh/paths.targets b/contrib/win32/openssh/paths.targets
index 21322fe..0d37f85 100644
--- a/contrib/win32/openssh/paths.targets
+++ b/contrib/win32/openssh/paths.targets
@@ -4,10 +4,12 @@
$(SolutionDir)..\..\..\
$(SolutionDir)..\..\..\bin\
$(SolutionDir)lib\
- $(SolutionDir)..\..\..\..\OpenSSL\1.0.2d\VS2015\
- $(SolutionDir)..\..\..\..\OpenSSL\1.0.2d\VS2015\Win32\Release\
- $(SolutionDir)..\..\..\..\OpenSSL\1.0.2d\VS2015\Win32\Debug\
- $(SolutionDir)..\..\..\..\OpenSSL\1.0.2d\VS2015\x64\Release\
- $(SolutionDir)..\..\..\..\OpenSSL\1.0.2d\VS2015\x64\Debug\
+ g:\openssl-1.0.2h-x64\OpenSSLInstallx64_vs2015-debug\
+ g:\openssl-1.0.2h-x86\OpenSSLInstallx86_vs2015\
+ g:\openssl-1.0.2h-x86\OpenSSLInstallx86_vs2015-debug\
+ g:\openssl-1.0.2h-x64\OpenSSLInstallx64_vs2015\
+ g:\openssl-1.0.2h-x64\OpenSSLInstallx64_vs2015-debug\
+ g:\openssl-1.0.2h-arm-x86\OpenSSLInstallx86_vs2015\
+ g:\openssl-1.0.2h-arm-x86\OpenSSLInstallx86_vs2015\
diff --git a/contrib/win32/openssh/scp.vcxproj b/contrib/win32/openssh/scp.vcxproj
index f6b879f..18a8740 100644
--- a/contrib/win32/openssh/scp.vcxproj
+++ b/contrib/win32/openssh/scp.vcxproj
@@ -21,6 +21,7 @@
+
@@ -116,6 +117,7 @@
Console
true
Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -135,6 +137,7 @@
Console
true
Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -158,6 +161,7 @@
true
true
Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -181,6 +185,7 @@
true
true
Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
diff --git a/contrib/win32/openssh/scp.vcxproj.filters b/contrib/win32/openssh/scp.vcxproj.filters
index 4da1894..7aa9873 100644
--- a/contrib/win32/openssh/scp.vcxproj.filters
+++ b/contrib/win32/openssh/scp.vcxproj.filters
@@ -18,6 +18,9 @@
Source Files
+
+ Source Files
+
diff --git a/contrib/win32/openssh/sftp-server.vcxproj b/contrib/win32/openssh/sftp-server.vcxproj
index 1c91ed5..bcb75a8 100644
--- a/contrib/win32/openssh/sftp-server.vcxproj
+++ b/contrib/win32/openssh/sftp-server.vcxproj
@@ -23,6 +23,7 @@
+
@@ -118,7 +119,8 @@
Console
true
- Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
diff --git a/contrib/win32/openssh/sftp-server.vcxproj.filters b/contrib/win32/openssh/sftp-server.vcxproj.filters
index 7e84e8c..2179a95 100644
--- a/contrib/win32/openssh/sftp-server.vcxproj.filters
+++ b/contrib/win32/openssh/sftp-server.vcxproj.filters
@@ -24,6 +24,9 @@
Source Files
+
+ Source Files
+
diff --git a/contrib/win32/openssh/sftp.vcxproj b/contrib/win32/openssh/sftp.vcxproj
index dfd557d..b59ab65 100644
--- a/contrib/win32/openssh/sftp.vcxproj
+++ b/contrib/win32/openssh/sftp.vcxproj
@@ -25,6 +25,7 @@
+
@@ -120,7 +121,8 @@
Console
true
- Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -140,7 +142,8 @@
Console
true
- Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -163,7 +166,8 @@
false
true
true
- Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
@@ -186,7 +190,8 @@
false
true
true
- Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Netapi32.lib;win32iocompat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;win32compat.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories)
wmainCRTStartup
diff --git a/contrib/win32/openssh/sftp.vcxproj.filters b/contrib/win32/openssh/sftp.vcxproj.filters
index 19d11ba..30e54f3 100644
--- a/contrib/win32/openssh/sftp.vcxproj.filters
+++ b/contrib/win32/openssh/sftp.vcxproj.filters
@@ -30,6 +30,9 @@
Source Files
+
+ Source Files
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index 1573471..167f8c6 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -150,8 +150,10 @@
-
-
+
+
+
+
@@ -170,9 +172,12 @@
-
-
-
+
+
+
+
+
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index 433a8c8..6b4ea8a 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -10,8 +10,10 @@
-
-
+
+
+
+
@@ -54,14 +56,22 @@
-
+
+
inc
+
-
+
+
+
inc\sys
+
-
+
+
+
inc
+
diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c
index 415c14c..59a7d90 100644
--- a/contrib/win32/win32compat/fileio.c
+++ b/contrib/win32/win32compat/fileio.c
@@ -559,8 +559,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
int
fileio_stat(const char *path, struct _stat64 *buf) {
- /* TODO - path is UTD -8, support unicode*/
- return _stat64(path, buf);
+ wchar_t wpath[MAX_PATH];
+ wchar_t* wtmp = NULL;
+
+ if ((wtmp = utf8_to_utf16(path)) == NULL)
+ fatal("failed to covert input arguments");
+ wcscpy(&wpath[0], wtmp);
+ free(wtmp);
+
+ return _wstat64(wpath, buf);
}
long
diff --git a/contrib/win32/win32compat/inc/defs.h b/contrib/win32/win32compat/inc/defs.h
index 7f49745..9338000 100644
--- a/contrib/win32/win32compat/inc/defs.h
+++ b/contrib/win32/win32compat/inc/defs.h
@@ -47,9 +47,10 @@
#define W32_SIGTERM 8
#define W32_SIGTTIN 9
#define W32_SIGTTOU 10
-#define W32_SIGWINCH 11
+#define W32_SIGWINCH 11
#define W32_SIGMAX 12
+#define W32_SIGSTOP 13
/* singprocmask "how" codes*/
#define SIG_BLOCK 0
diff --git a/contrib/win32/win32compat/inc/fcntl.h b/contrib/win32/win32compat/inc/fcntl.h
index 8fe222f..8f874e5 100644
--- a/contrib/win32/win32compat/inc/fcntl.h
+++ b/contrib/win32/win32compat/inc/fcntl.h
@@ -11,4 +11,8 @@
#define O_TRUNC 0x0200 // open and truncate
#define O_EXCL 0x0400 // open only if file doesn't already exist
-#define O_BINARY 0x8000 // file mode is binary (untranslated)
\ No newline at end of file
+#define O_TEXT 0x4000 /* file mode is text (translated) */
+#define O_BINARY 0x8000 /* file mode is binary (untranslated) */
+#define O_WTEXT 0x10000 /* file mode is UTF16 (translated) */
+#define O_U16TEXT 0x20000 /* file mode is UTF16 no BOM (translated) */
+#define O_U8TEXT 0x40000 /* file mode is UTF8 no BOM (translated) */
diff --git a/contrib/win32/win32compat/inc/signal.h b/contrib/win32/win32compat/inc/signal.h
index f99d990..71bfc97 100644
--- a/contrib/win32/win32compat/inc/signal.h
+++ b/contrib/win32/win32compat/inc/signal.h
@@ -12,6 +12,7 @@
#define mysignal(a,b) w32_signal((a), (b))
#define raise(a) w32_raise(a)
#define kill(a,b) w32_kill((a), (b))
+#define ftruncate(a, b) w32_ftruncate((a), (b))
#define sigprocmask(a,b,c) w32_sigprocmask((a), (b), (c))
#define SIGINT W32_SIGINT
@@ -26,6 +27,7 @@
#define SIGTTIN W32_SIGTTIN
#define SIGTTOU W32_SIGTTOU
#define SIGWINCH W32_SIGWINCH
+#define SIGSTOP W32_SIGSTOP
#define SIG_DFL W32_SIG_DFL
#define SIG_IGN W32_SIG_IGN
diff --git a/contrib/win32/win32compat/inc/sys/socket.h b/contrib/win32/win32compat/inc/sys/socket.h
index 32b3ae1..a792438 100644
--- a/contrib/win32/win32compat/inc/sys/socket.h
+++ b/contrib/win32/win32compat/inc/sys/socket.h
@@ -13,12 +13,12 @@
#define getsockopt(a,b,c,d,e) w32_getsockopt((a), (b), (c), (d), (e))
#define getsockname(a,b,c) w32_getsockname((a), (b), (c))
#define getpeername(a,b,c) w32_getpeername((a), (b), (c))
-#define listen(a,b) w32_listen((a), (b))
-#define bind(a,b,c) w32_bind((a), (b), (c))
+#define listen(a,b) w32_listen((a), (b))
+#define bind(a,b,c) w32_bind((a), (b), (c))
#define connect(a,b,c) w32_connect((a), (b), (c))
#define recv(a,b,c,d) w32_recv((a), (b), (c), (d))
#define send(a,b,c,d) w32_send((a), (b), (c), (d))
#define shutdown(a,b) w32_shutdown((a), (b))
#define socketpair(a,b,c,d) w32_socketpair((a), (b), (c), (d))
-#define freeaddrinfo w32_freeaddrinfo
-#define getaddrinfo w32_getaddrinfo
+#define freeaddrinfo w32_freeaddrinfo
+#define getaddrinfo w32_getaddrinfo
diff --git a/contrib/win32/win32compat/inc/sys/stat.h b/contrib/win32/win32compat/inc/sys/stat.h
index e18f2bb..b8a2521 100644
--- a/contrib/win32/win32compat/inc/sys/stat.h
+++ b/contrib/win32/win32compat/inc/sys/stat.h
@@ -29,6 +29,8 @@
#define stat w32_stat
#define lstat w32_stat
#define mkdir w32_mkdir
+#define chdir w32_chdir
+#define getcwd w32_getcwd
struct w32_stat {
dev_t st_dev; /* ID of device containing file */
diff --git a/contrib/win32/win32compat/inc/sys/wait.h b/contrib/win32/win32compat/inc/sys/wait.h
index 25ad69f..312486b 100644
--- a/contrib/win32/win32compat/inc/sys/wait.h
+++ b/contrib/win32/win32compat/inc/sys/wait.h
@@ -13,5 +13,7 @@
#define WIFSIGNALED(w) FALSE
#define WEXITSTATUS(w) w
#define WTERMSIG(w) -1
+#define WNOHANG 1
+#define WUNTRACED 2
int waitpid(int pid, int *status, int options);
\ No newline at end of file
diff --git a/contrib/win32/win32compat/inc/unistd.h b/contrib/win32/win32compat/inc/unistd.h
index f4831a8..d526aa8 100644
--- a/contrib/win32/win32compat/inc/unistd.h
+++ b/contrib/win32/win32compat/inc/unistd.h
@@ -24,6 +24,7 @@
#define open w32_open
#define read w32_read
#define write w32_write
+#define writev w32_writev
//#define isatty w32_isatty
#define close w32_close
#define dup w32_dup
diff --git a/contrib/win32/win32compat/inc/w32posix.h b/contrib/win32/win32compat/inc/w32posix.h
index 2c09793..eb67eaa 100644
--- a/contrib/win32/win32compat/inc/w32posix.h
+++ b/contrib/win32/win32compat/inc/w32posix.h
@@ -10,6 +10,15 @@
#include "defs.h"
#include "utf.h"
+#ifndef _OFF_T_DEFINED
+#define _OFF_T_DEFINED
+
+typedef long _off_t; // file offset value
+
+#if !__STDC__
+typedef _off_t off_t;
+#endif
+#endif
typedef struct w32_fd_set_ {
unsigned char bitmap[MAX_FDS >> 3];
@@ -45,6 +54,7 @@ int w32_pipe(int *pfds);
int w32_open(const char *pathname, int flags, ...);
int w32_read(int fd, void *dst, size_t max);
int w32_write(int fd, const void *buf, unsigned int max);
+int w32_writev(int fd, const struct iovec *iov, int iovcnt);
int w32_fstat(int fd, struct w32_stat *buf);
int w32_stat(const char *path, struct w32_stat *buf);
long w32_lseek( int fd, long offset, int origin);
@@ -52,6 +62,8 @@ long w32_lseek( int fd, long offset, int origin);
int w32_isatty(int fd);
FILE* w32_fdopen(int fd, const char *mode);
int w32_mkdir(const char *pathname, unsigned short mode);
+int w32_chdir(const char *dirname);
+char *w32_getcwd(char *buffer, int maxlen);
/*common i/o*/
#define fcntl(a,b,...) w32_fcntl((a), (b), __VA_ARGS__)
@@ -75,6 +87,7 @@ void w32_freeaddrinfo(struct addrinfo *);
int w32_getaddrinfo(const char *, const char *,
const struct addrinfo *, struct addrinfo **);
FILE* w32_fopen_utf8(const char *, const char *);
+int w32_ftruncate(int fd, off_t length);
char* w32_programdir();
@@ -124,7 +137,6 @@ int sw_add_child(HANDLE child, DWORD pid);
#define allocate_sfd(a, b) w32_allocate_fd_for_handle((a, b))
//#define WSHELPwopen(a, b) w32_open((a, b))
-
/* TODO - These defs need to revisited and positioned appropriately */
#define environ _environ
diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c
index 292f31a..8f0022f 100644
--- a/contrib/win32/win32compat/w32fd.c
+++ b/contrib/win32/win32compat/w32fd.c
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
/* internal table that stores the fd to w32_io mapping*/
struct w32fd_table {
@@ -384,6 +385,23 @@ w32_write(int fd, const void *buf, unsigned int max) {
return fileio_write(fd_table.w32_ios[fd], buf, max);
}
+int w32_writev(int fd, const struct iovec *iov, int iovcnt) {
+ int written = 0;
+ int i = 0;
+
+ CHECK_FD(fd);
+
+ for (i = 0; i < iovcnt; i++) {
+ int ret = w32_write(fd, iov[i].iov_base, iov[i].iov_len);
+
+ if (ret > 0) {
+ written += ret;
+ }
+ }
+
+ return written;
+}
+
int
w32_fstat(int fd, struct w32_stat *buf) {
CHECK_FD(fd);
@@ -403,12 +421,36 @@ w32_lseek(int fd, long offset, int origin) {
int
w32_mkdir(const char *path_utf8, unsigned short mode) {
- wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
- if (path_utf16 == NULL) {
- errno = ENOMEM;
- return -1;
- }
- return _wmkdir(path_utf16);
+ wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
+ if (path_utf16 == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ return _wmkdir(path_utf16);
+}
+
+int w32_chdir(const char *dirname_utf8) {
+ wchar_t *dirname_utf16 = utf8_to_utf16(dirname_utf8);
+ if (dirname_utf16 == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return _wchdir(dirname_utf16);
+}
+
+char *w32_getcwd(char *buffer, int maxlen) {
+ wchar_t wdirname[MAX_PATH];
+ char* putf8 = NULL;
+
+ wchar_t *wpwd = _wgetcwd(&wdirname[0], MAX_PATH);
+
+ if ((putf8 = utf16_to_utf8(&wdirname[0])) == NULL)
+ fatal("failed to convert input arguments");
+ strcpy(buffer, putf8);
+ free(putf8);
+
+ return buffer;
}
int
@@ -806,4 +848,18 @@ w32_raise(int sig) {
int
w32_kill(int pid, int sig) {
return sw_kill(pid, sig);
+}
+
+int
+w32_ftruncate(int fd, off_t length) {
+ CHECK_FD(fd);
+
+ if (!SetEndOfFile(w32_fd_to_handle(fd)))
+ return -1;
+ if (!SetFileValidData(w32_fd_to_handle(fd), length))
+ return -1;
+ if (!SetFilePointer(w32_fd_to_handle(fd), 0, 0, FILE_BEGIN))
+ return -1;
+
+ return 0;
}
\ No newline at end of file
diff --git a/defines.h b/defines.h
index 14b3bc3..2dd7432 100644
--- a/defines.h
+++ b/defines.h
@@ -172,6 +172,8 @@ enum
# define S_IRWXU 0000700 /* read, write, execute */
# define S_IRWXG 0000070 /* read, write, execute */
# define S_IRWXO 0000007 /* read, write, execute */
+# define S_ISUID 0x800
+# define S_ISGID 0x400
#endif /* S_IXUSR */
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
diff --git a/misc.c b/misc.c
index 797e4cd..02a4d55 100644
--- a/misc.c
+++ b/misc.c
@@ -222,6 +222,8 @@ pwcopy(struct passwd *pw)
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
copy->pw_class = xstrdup(pw->pw_class);
#endif
+
+
copy->pw_dir = xstrdup(pw->pw_dir);
copy->pw_shell = xstrdup(pw->pw_shell);
return copy;
@@ -431,9 +433,34 @@ char *
colon(char *cp)
{
int flag = 0;
+ int len = 0;
if (*cp == ':') /* Leading colon is part of file name. */
return NULL;
+
+#ifdef WINDOWS
+ for (; *cp; ++cp) {
+ len++;
+
+ if (*cp == '[')
+ flag = 1;
+
+ if (flag && *cp != ']')
+ continue;
+
+ if (*cp == ']')
+ flag = 0;
+
+ if (*cp == ':') {
+ if (len != 2) { // avoid x: format for drive letter in Windows
+ return (cp);
+ }
+ }
+ // if ( (*cp == '/') || (*cp == '\\') )
+ // return (0);
+ }
+ return NULL;
+#else
if (*cp == '[')
flag = 1;
@@ -447,7 +474,8 @@ colon(char *cp)
if (*cp == '/')
return NULL;
}
- return NULL;
+ return NULL;
+#endif
}
/* function to assist building execv() arguments */
diff --git a/progressmeter.c b/progressmeter.c
index 233283d..3d6f56b 100644
--- a/progressmeter.c
+++ b/progressmeter.c
@@ -78,13 +78,23 @@ static volatile sig_atomic_t win_resized; /* for window resizing */
/* units for format_size */
static const char unit[] = " KMGT";
+#ifdef WINDOWS
+extern int ScreenX;
+#endif
+
static int
can_output(void)
{
-#ifndef WIN32_FIXME//R
- return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
+#ifndef WINDOWS
+ return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
#else
- return 1;
+ DWORD dwProcessId = -1;
+ if (GetWindowThreadProcessId(GetStdHandle(STD_OUTPUT_HANDLE), &dwProcessId)) {
+ return(GetCurrentProcess() == dwProcessId);
+ }
+ else {
+ return -1;
+ }
#endif
}
@@ -227,7 +237,14 @@ refresh_progress_meter(void)
strlcat(buf, " ", win_size);
}
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(buf);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+#else
atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
+#endif
last_update = now;
}
@@ -298,7 +315,7 @@ sig_winch(int sig)
static void
setscreensize(void)
{
- #ifndef WIN32_FIXME//N
+#ifndef WINDOWS
struct winsize winsize;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
@@ -310,6 +327,7 @@ setscreensize(void)
} else
win_size = DEFAULT_WINSIZE;
win_size += 1; /* trailing \0 */
+#else
+ win_size = ConScreenSizeX() + 1;
#endif
- win_size = DEFAULT_WINSIZE + 1;
}
diff --git a/scp.c b/scp.c
index e59a167..a9c2f1b 100644
--- a/scp.c
+++ b/scp.c
@@ -73,6 +73,14 @@
#include "includes.h"
+#ifndef WINDOWS
+#include
+#else
+#include
+#include
+#include "win32_dirent.h"
+#endif
+
#include
#include
#ifdef HAVE_SYS_STAT_H
@@ -93,10 +101,6 @@
#include
-#ifndef WIN32_FIXME
-#include
-#endif
-
#include
#include
#include
@@ -119,7 +123,7 @@
#include "misc.h"
#include "progressmeter.h"
-#ifdef WIN32_VS
+#ifdef WINDOWS
#include
#endif
extern char *__progname;
@@ -159,14 +163,11 @@ char *ssh_program = _PATH_SSH_PROGRAM;
pid_t do_cmd_pid = -1;
-#ifdef WIN32_FIXME
+#ifdef WINDOWS
typedef BOOL bool;
#define false FALSE
#define true TRUE
-char *win32colon(char *);
-#define colon win32colon
-
#ifndef _SH_DENYNO
#define _SH_DENYNO 0x40
#endif
@@ -250,6 +251,9 @@ char *port = NULL;
/* This is set password if given on the command line. */
char *password = NULL;
+/* This is set ssh_config if given on the command line. */
+char *ssh_config = NULL;
+
int ipv_restrict = 0;
#define ONLY_IPV4 1
@@ -287,27 +291,32 @@ CHAR g_HomeDir[MAX_PATH];
CHAR g_FSRoot[MAX_PATH];
int isRootedPath = 0; // set to 1 if we prepend a home root
-char *TranslatePath(char *, bool *bDirSpec);
int start_process_io(char *exename, char **argv, char **envv,
HANDLE StdInput, HANDLE StdOutput, HANDLE StdError,
unsigned long CreateFlags, PROCESS_INFORMATION *pi,
char *homedir, char *lpDesktop);
-// InitForMicrosoftWindows() will initialize Unix like settings in Windows operating system.
+#ifdef WINDOWS
struct passwd pw;
char username[128];
+
+// InitForMicrosoftWindows() will initialize Unix like settings in Windows operating system.
int InitForMicrosoftWindows()
{
- int rc;
- struct passwd *pwd;
+ int rc;
+ struct passwd *pwd;
- /* Get user\'s passwd structure. We need this for the home directory. */
- pwd = &pw ;
- rc = sizeof(username);
- GetUserName(username,(LPDWORD)&rc);
- pwd->pw_name = username;
+ /* Get user\'s passwd structure. We need this for the home directory. */
+ pwd = &pw ;
+ rc = sizeof(username);
+ if (GetUserName(username, (LPDWORD)&rc)) {
+ pwd->pw_name = username;
+ }
+ else {
+ return GetLastError();
+ }
- return 0;
+ return 0;
}
// start of direntry functions in Windows NT like UNIX
@@ -324,8 +333,8 @@ struct scp_dirent {
};
typedef struct {
- long hFile;
- struct _finddata_t c_file;
+ long hFile;
+ struct _finddata_t c_file;
} SCPDIR;
@@ -343,21 +352,7 @@ char * fixslashes(char * str)
return str;
}
-char * unfixslashes(char * str)
-{
- int i;
- if (str == NULL)
- return str;
-
- int len = (int)strlen(str);
-
- for (i = 0; i < len; i++)
- if (str[i] == '//')
- str[i] = '/';
- return str;
-}
-
-// force path separator to
+// force path separator to sep
char * forcepathsep(char * str, char sep)
{
int i;
@@ -374,7 +369,6 @@ char * forcepathsep(char * str, char sep)
if (sep == '/')
antisep = '\\';
-
int len = (int)strlen(str);
for (i = 0; i < len; i++)
@@ -406,13 +400,10 @@ bool getRootFrompath(char * path, char * root)
return (lastslash != NULL);
}
-
-
/*
* get option letter from argument vector
*/
-
char * getfilenamefrompath(char * path)
{
char * lastslash;
@@ -447,7 +438,7 @@ char * getfilenamefrompath(char * path)
}
return NULL;
}
-
+#endif
#define EMSG ""
#define BADCH (int)'~'
@@ -562,44 +553,6 @@ SCPDIR * scp_opendir(char *name)
}
}
-/* Close the directory stream SCPDIRP.
- Return 0 if successful, -1 if not. */
-int closedir(SCPDIR *dirp)
-{
- if ( dirp && (dirp->hFile) ) {
- _findclose( dirp->hFile );
- dirp->hFile = 0;
- free (dirp);
- }
-
- return 0;
-}
-
-/* Read a directory entry from SCPDIRP.
- Return a pointer to a `struct scp_dirent' describing the entry,
- or NULL for EOF or error. The storage returned may be overwritten
- by a later readdir call on the same SCPDIR stream. */
-struct scp_dirent *readdir(SCPDIR *dirp)
-{
- struct scp_dirent *pdirentry;
-
- 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 scp_dirent *)malloc( sizeof(struct scp_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 scp_dirent *) NULL;
- }
- }
-}
-
int _utimedir (char *name, struct _utimbuf *filetime)
{
int rc, chandle;
@@ -625,33 +578,59 @@ int _utimedir (char *name, struct _utimbuf *filetime)
// end of direntry functions
HANDLE hprocess=(HANDLE) 0; // we made it a global to stop child process(ssh) of scp
#else
+
+/* Read a directory entry from SCPDIRP.
+Return a pointer to a `struct scp_dirent' describing the entry,
+or NULL for EOF or error. The storage returned may be overwritten
+by a later readdir call on the same SCPDIR stream. */
+struct scp_dirent *readdir(SCPDIR *dirp)
+{
+ struct scp_dirent *pdirentry;
+
+ 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 scp_dirent *)malloc(sizeof(struct scp_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 scp_dirent *) NULL;
+ }
+ }
+}
+#endif
+
static void
killchild(int signo)
{
- if (do_cmd_pid > 1) {
- kill(do_cmd_pid, signo ? signo : SIGTERM);
- waitpid(do_cmd_pid, NULL, 0);
- }
+ if (do_cmd_pid > 1) {
+ kill(do_cmd_pid, signo ? signo : SIGTERM);
+ waitpid(do_cmd_pid, NULL, 0);
+ }
- if (signo)
- _exit(1);
- exit(1);
+ if (signo)
+ _exit(1);
+ exit(1);
}
static void
suspchild(int signo)
{
- int status;
+ int status;
- if (do_cmd_pid > 1) {
- kill(do_cmd_pid, signo);
- while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&
- errno == EINTR)
- ;
- kill(getpid(), SIGSTOP);
- }
+ if (do_cmd_pid > 1) {
+ kill(do_cmd_pid, signo);
+ while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&
+ errno == EINTR)
+ ;
+ kill(getpid(), SIGSTOP);
+ }
}
-#endif
static int
do_local_cmd(arglist *a)
@@ -669,7 +648,7 @@ do_local_cmd(arglist *a)
fprintf(stderr, " %s", a->list[i]);
fprintf(stderr, "\n");
}
- #ifdef WIN32_FIXME
+#ifdef WINDOWS
// flatten the cmd into a long space separated string and execute using system(cmd) api
char cmdstr[2048] ;
cmdstr[0] = '\0' ;
@@ -680,7 +659,7 @@ do_local_cmd(arglist *a)
if (system(cmdstr))
return (-1); // failure executing
return (0); // success
- #else
+#else
if ((pid = fork()) == -1)
fatal("do_local_cmd: fork: %s", strerror(errno));
@@ -705,7 +684,7 @@ do_local_cmd(arglist *a)
return (-1);
return (0);
- #endif
+#endif
}
static int pipe_counter = 1;
@@ -770,179 +749,186 @@ error:
int
do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
{
- #ifdef WIN32_FIXME
- size_t i, j;
+#ifdef WINDOWS
+ size_t i, j;
- HANDLE hSaveStdout, hSaveStdin ;
- HANDLE hstdout[2], hstdin[2] ;
- PROCESS_INFORMATION pi;
- SECURITY_ATTRIBUTES sa ; /* simple */
- int rc;
- HANDLE rfdfromssh, wfdtossh ;
- char *args[256];
+ HANDLE hSaveStdout, hSaveStdin ;
+ HANDLE hstdout[2], hstdin[2] ;
+ PROCESS_INFORMATION pi;
+ SECURITY_ATTRIBUTES sa ; /* simple */
+ int rc;
+ HANDLE rfdfromssh, wfdtossh ;
+ char *args[256];
- if (verbose_mode)
- fprintf(stderr, "Executing: host %s, user %s, command %s\n",
- host, remuser ? remuser : "(unspecified)", cmd);
+ if (verbose_mode)
+ fprintf(stderr, "Executing: host %s, user %s, command %s\n",
+ host, remuser ? remuser : "(unspecified)", cmd);
// Child code in Windows OS will be a new created process of ssh.exe.
// Child to execute the command on the remote host using ssh.
- if (1) { // No fork in Windows OS, so we code it such that we use CreateProcess()
+ i = 0;
+ args[i++] = ssh_program;
+ size_t len;
+ for(j = 0; j < ssh_options_cnt; j++) {
+ args[i++] = "-o";
- i = 0;
- args[i++] = ssh_program;
- size_t len;
- for(j = 0; j < ssh_options_cnt; j++) {
- args[i++] = "-o";
+ //args[i++] = ssh_options[j];
+ len = strlen(ssh_options[j])+3;
- //args[i++] = ssh_options[j];
- len = strlen(ssh_options[j])+3;
+ args[i] = (char *) malloc(len); // add quotes
+ strcpy_s(args[i],len, "\"");
+ strcat_s(args[i],len, ssh_options[j]);
+ strcat_s(args[i],len, "\"");
+ i++ ;
- args[i] = (char *) malloc(len); // add quotes
- strcpy_s(args[i],len, "\"");
- strcat_s(args[i],len, ssh_options[j]);
- strcat_s(args[i],len, "\"");
- i++ ;
+ if (i > 250)
+ fatal("Too many -o options (total number of arguments is more than 256)");
+ }
+ args[i++] = "-x";
+ args[i++] = "-a";
+ args[i++] = "\"-oFallBackToRsh no\""; // extra double quote needed for
+ // Windows platforms
+ //7/2/2001 args[i++] = "\"-oClearAllForwardings yes\"";
+ if (verbose_mode)
+ args[i++] = "-v";
+ if (compress)
+ args[i++] = "-C";
+ if (!use_privileged_port)
+ args[i++] = "-P";
+ if (batchmode)
+ args[i++] = "\"-oBatchMode yes\"";
+ if (password != NULL) {
+ args[i++] = "-A";
+ args[i++] = password;
+ }
+ if (cipher != NULL) {
+ args[i++] = "-c";
+ args[i++] = cipher;
+ }
+ if (identity != NULL) {
+ args[i++] = "-i";
+ args[i++] = identity;
+ }
+ if (port != NULL) {
+ args[i++] = "-p";
+ args[i++] = port;
+ }
+ if (ssh_config) {
+ args[i++] = "-F";
+ args[i++] = ssh_config;
+ }
+ if (remuser != NULL) {
+ args[i++] = "-l";
+ args[i++] = remuser;
+ }
- if (i > 250)
- fatal("Too many -o options (total number of arguments is more than 256)");
- }
- args[i++] = "-x";
- args[i++] = "-a";
- args[i++] = "\"-oFallBackToRsh no\""; // extra double quote needed for
- // Windows platforms
- //7/2/2001 args[i++] = "\"-oClearAllForwardings yes\"";
- if (verbose_mode)
- args[i++] = "-v";
- if (compress)
- args[i++] = "-C";
- if (!use_privileged_port)
- args[i++] = "-P";
- if (batchmode)
- args[i++] = "\"-oBatchMode yes\"";
- if (password != NULL)
- {
- args[i++] = "-A";
- args[i++] = password;
- }
- if (cipher != NULL)
- {
- args[i++] = "-c";
- args[i++] = cipher;
- }
- if (identity != NULL)
- {
- args[i++] = "-i";
- args[i++] = identity;
- }
- if (port != NULL)
- {
- args[i++] = "-p";
- args[i++] = port;
- }
- if (remuser != NULL)
- {
- args[i++] = "-l";
- args[i++] = remuser;
- }
+ if (ipv_restrict == ONLY_IPV4)
+ args[i++] = "-4";
+ if (ipv_restrict == ONLY_IPV6)
+ args[i++] = "-6";
- if (ipv_restrict == ONLY_IPV4)
- args[i++] = "-4";
- if (ipv_restrict == ONLY_IPV6)
- args[i++] = "-6";
+ args[i++] = host;
+ args[i++] = cmd;
+ args[i++] = NULL;
- args[i++] = host;
- args[i++] = cmd;
- args[i++] = NULL;
+ // Create a pair of pipes for communicating with ssh
+ // which we will spawn
+ // Do the plunmbing so that child ssh process to be spawned has its
+ // standard input from the pout[0] and its standard output going to
+ // pin[1]
- // Create a pair of pipes for communicating with ssh
- // which we will spawn
- // Do the plunmbing so that child ssh process to be spawned has its
- // standard input from the pout[0] and its standard output going to
- // pin[1]
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE ; /* pipe handles to be inherited */
+ sa.lpSecurityDescriptor = NULL;
+ /* command processor output redirected to a nameless pipe */
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = TRUE ; /* pipe handles to be inherited */
- sa.lpSecurityDescriptor = NULL;
- /* command processor output redirected to a nameless pipe */
+ rc = CreateOverlappedPipe( &hstdout[0], &hstdout[1], &sa, 0 ) ;
+ /* read from this fd to get data from ssh.exe*/
- rc = CreateOverlappedPipe( &hstdout[0], &hstdout[1], &sa, 0 ) ;
- /* read from this fd to get data from ssh.exe*/
+ // make scp's pipe read handle not inheritable by ssh
+ rc = DuplicateHandle(GetCurrentProcess(), hstdout[0],
+ GetCurrentProcess(), (PHANDLE) &rfdfromssh,
+ 0, // this parm ignored if DUPLICATE_SAME_ACCESS below
+ FALSE, // not inherited
+ DUPLICATE_SAME_ACCESS);
+ CloseHandle(hstdout[0]); // this CloseHandle() is a crucial must do
+ hstdout[0] = rfdfromssh ;
- // make scp's pipe read handle not inheritable by ssh
- rc = DuplicateHandle(GetCurrentProcess(), hstdout[0],
- GetCurrentProcess(), (PHANDLE) &rfdfromssh,
- 0, // this parm ignored if DUPLICATE_SAME_ACCESS below
- FALSE, // not inherited
- DUPLICATE_SAME_ACCESS);
- CloseHandle(hstdout[0]); // this CloseHandle() is a crucial must do
- hstdout[0] = rfdfromssh ;
+ *fdin = _open_osfhandle((intptr_t)hstdout[0],0);
+ _setmode (*fdin, O_BINARY); // set this file handle for binary I/O
+ w32_allocate_fd_for_handle(hstdout[0], FALSE);
+ rc = CreateOverlappedPipe( &hstdin[0], &hstdin[1], &sa, 0 ) ;
+ /* write to this fd to get data into ssh.exe*/
- *fdin = _open_osfhandle((intptr_t)hstdout[0],0);
- _setmode (*fdin, O_BINARY); // set this file handle for binary I/O
+ // make scp's pipe write handle not inheritable by ssh
+ rc = DuplicateHandle(GetCurrentProcess(), hstdin[1],
+ GetCurrentProcess(), (PHANDLE) &wfdtossh,
+ 0, // this parm ignored if DUPLICATE_SAME_ACCESS below
+ FALSE, // not inherited
+ DUPLICATE_SAME_ACCESS);
+ CloseHandle(hstdin[1]); // this CloseHandle() is a crucial must do
+ hstdin[1] = (HANDLE) wfdtossh ;
- rc = CreateOverlappedPipe( &hstdin[0], &hstdin[1], &sa, 0 ) ;
- /* write to this fd to get data into ssh.exe*/
+ *fdout = _open_osfhandle((intptr_t)hstdin[1],0);
+ _setmode (*fdout, O_BINARY); // set this file handle for binary I/O
+ w32_allocate_fd_for_handle(hstdin[1], FALSE);
- // make scp's pipe write handle not inheritable by ssh
- rc = DuplicateHandle(GetCurrentProcess(), hstdin[1],
- GetCurrentProcess(), (PHANDLE) &wfdtossh,
- 0, // this parm ignored if DUPLICATE_SAME_ACCESS below
- FALSE, // not inherited
- DUPLICATE_SAME_ACCESS);
- CloseHandle(hstdin[1]); // this CloseHandle() is a crucial must do
- hstdin[1] = (HANDLE) wfdtossh ;
+ hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ //hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
+ hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
+ // Set a write handle to the pipe to be STDOUT.
+ SetStdHandle(STD_OUTPUT_HANDLE, hstdout[1]);
+ // Set a write handle to the pipe to be STDERR.
+ //SetStdHandle(STD_ERROR_HANDLE, hstdout[1]);
+ // Set a input handle to the pipe to be STDIN.
+ SetStdHandle(STD_INPUT_HANDLE, hstdin[0]);
- *fdout = _open_osfhandle((intptr_t)hstdin[1],0);
- _setmode (*fdout, O_BINARY); // set this file handle for binary I/O
+ // start the child process(ssh)
+ rc = start_process_io(
+ NULL, /* executable name with .ext found in argv[0] */
+ &args[0], /* argv */
+ NULL ,
+ hstdin[0], /* std input for cmd.exe */
+ hstdout[1], /* std output for cmd.exe */
+ GetStdHandle(STD_ERROR_HANDLE), //hstdout[1], /* std error for cmd.exe */
+ 0, // dwStartupFlags,
+ &pi,
+ NULL, /* current directory is default directory we set before */
+ NULL
+ );
- hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- //hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
- hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
+ if (port)
+ free(port);
- // Set a write handle to the pipe to be STDOUT.
- SetStdHandle(STD_OUTPUT_HANDLE, hstdout[1]);
- // Set a write handle to the pipe to be STDERR.
- //SetStdHandle(STD_ERROR_HANDLE, hstdout[1]);
- // Set a input handle to the pipe to be STDIN.
- SetStdHandle(STD_INPUT_HANDLE, hstdin[0]);
+ if (cipher)
+ free(cipher);
+ if (identity)
+ free(identity);
- // start the child process(ssh)
- rc = start_process_io(
- NULL, /* executable name with .ext found in argv[0] */
- &args[0], /* argv */
- NULL ,
- hstdin[0], /* std input for cmd.exe */
- hstdout[1], /* std output for cmd.exe */
- GetStdHandle(STD_ERROR_HANDLE), //hstdout[1], /* std error for cmd.exe */
- 0, // dwStartupFlags,
- &pi,
- NULL, /* current directory is default directory we set before */
- NULL
- );
+ if (ssh_config)
+ free(ssh_config);
- if (!rc) {
- printf("%s could not be started\n", ssh_program);
- exit(1);
- }
- else {
- hprocess = pi.hProcess ;
- }
+ if (!rc) {
+ printf("%s could not be started\n", ssh_program);
+ exit(1);
+ }
+ else {
+ hprocess = pi.hProcess ;
+ }
- // After process creation, restore the saved STDOUT and STDERR.
- SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
- //SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
- SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
+ // After process creation, restore the saved STDOUT and STDERR.
+ SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
+ //SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
+ SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
- /* now close the pipe's side that the ssh.exe will use as write handle */
- CloseHandle(hstdout[1]) ;
- /* now close the pipe's side that the ssh.exe will use as read handle */
- CloseHandle(hstdin[0]) ;
- }
+ /* now close the pipe's side that the ssh.exe will use as write handle */
+ CloseHandle(hstdout[1]) ;
+ /* now close the pipe's side that the ssh.exe will use as read handle */
+ CloseHandle(hstdin[0]) ;
// update passed variables with where other funstions should read and write
// from to get I/O from above child process over pipe.
@@ -950,8 +936,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
//*fdout = remout;
//*fdin = remin;
- return 0;
- #else
+ return 0;
+#else
int pin[2], pout[2], reserved[2];
if (verbose_mode)
@@ -1016,7 +1002,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
signal(SIGINT, killchild);
signal(SIGHUP, killchild);
return 0;
- #endif
+#endif
}
/*
@@ -1027,8 +1013,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
int
do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
{
- #ifndef WIN32_FIXME
-
+#ifndef WIN32_FIXME
pid_t pid;
int status;
@@ -1062,7 +1047,7 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("do_cmd2: waitpid: %s", strerror(errno));
- #endif
+#endif
return 0;
}
@@ -1103,10 +1088,12 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
+#ifdef WINDOWS
+ ConInit(STD_OUTPUT_HANDLE, TRUE);
+#endif
+
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
- #ifndef WIN32_FIXME
sanitise_stdfd();
- #endif
/* Copy argv, because we modify it */
newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv));
@@ -1121,9 +1108,9 @@ main(int argc, char **argv)
args.list = remote_remote_args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "-x");
- addargs(&args, "-oForwardAgent=no");
- addargs(&args, "-oPermitLocalCommand=no");
- addargs(&args, "-oClearAllForwardings=yes");
+ addargs(&args, "\"-oForwardAgent no\"");
+ addargs(&args, "\"-oPermitLocalCommand no\"");
+ addargs(&args, "\"-oClearAllForwardings yes\"");
fflag = tflag = 0;
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
@@ -1132,32 +1119,67 @@ main(int argc, char **argv)
case '1':
case '2':
case '4':
+ ipv_restrict = ONLY_IPV4;
+ break;
case '6':
+ ipv_restrict = ONLY_IPV6;
+ break;
case 'C':
addargs(&args, "-%c", ch);
addargs(&remote_remote_args, "-%c", ch);
+
+ compress = ch;
+
break;
case '3':
throughlocal = 1;
break;
case 'o':
case 'c':
+ addargs(&remote_remote_args, "-%c", ch);
+ addargs(&remote_remote_args, "%s", optarg);
+ addargs(&args, "-%c", ch);
+ addargs(&args, "%s", optarg);
+
+ cipher = malloc(strlen(optarg) + 1);
+ if (cipher)
+ strcpy(cipher, optarg);
+ break;
case 'i':
- case 'F':
+ addargs(&remote_remote_args, "-%c", ch);
+ addargs(&remote_remote_args, "%s", optarg);
+ addargs(&args, "-%c", ch);
+ addargs(&args, "%s", optarg);
+
+ identity = malloc(strlen(optarg) + 1);
+ if (identity)
+ strcpy(identity, optarg);
+ break;
+ case 'F':
addargs(&remote_remote_args, "-%c", ch);
addargs(&remote_remote_args, "%s", optarg);
addargs(&args, "-%c", ch);
addargs(&args, "%s", optarg);
- break;
+
+ ssh_config = malloc(strlen(optarg) + 1);
+ if (ssh_config)
+ strcpy(ssh_config, optarg);
+ break;
case 'P':
addargs(&remote_remote_args, "-p");
addargs(&remote_remote_args, "%s", optarg);
addargs(&args, "-p");
addargs(&args, "%s", optarg);
+
+ port = malloc(strlen(optarg) + 1);
+ if (port)
+ strcpy(port, optarg);
break;
case 'B':
- addargs(&remote_remote_args, "-oBatchmode=yes");
- addargs(&args, "-oBatchmode=yes");
+ addargs(&remote_remote_args, "\"-oBatchmode yes\"");
+ addargs(&args, "\"-oBatchmode yes\"");
+
+ batchmode = 1;
break;
case 'l':
limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
@@ -1208,22 +1230,18 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
- #ifndef WIN32_FIXME
+#ifndef WINDOWS
if ((pwd = getpwuid(userid = getuid())) == NULL)
fatal("unknown user %u", (u_int) userid);
- #else
+#else
InitForMicrosoftWindows(); // picks the username, user home dir
- #endif
+#endif
if (!isatty(STDOUT_FILENO))
showprogress = 0;
remin = STDIN_FILENO;
remout = STDOUT_FILENO;
- #ifdef WIN32_FIXME
- _setmode(remin,O_BINARY); // needed for Windows OS to avoid CrLf translations of text mode
- _setmode(remout,O_BINARY);
- #endif
if (fflag) {
/* Follow "protocol", send data. */
@@ -1249,7 +1267,7 @@ main(int argc, char **argv)
iamrecursive ? " -r" : "", pflag ? " -p" : "",
targetshouldbedirectory ? " -d" : "");
- #ifndef WIN32_FIXME
+ #ifndef WINDOWS
(void) signal(SIGPIPE, lostconn);
#endif
@@ -1264,7 +1282,7 @@ main(int argc, char **argv)
* Finally check the exit status of the ssh process, if one was forked
* and no error has occurred yet
*/
- #ifndef WIN32_FIXME
+#ifndef WINDOWS
if (do_cmd_pid != -1 && errs == 0) {
if (remin != -1)
(void) close(remin);
@@ -1277,7 +1295,7 @@ main(int argc, char **argv)
errs = 1;
}
}
- #endif
+#endif
exit(errs != 0);
}
@@ -1380,7 +1398,7 @@ toremote(char *targ, int argc, char **argv)
freeargs(&alist);
addargs(&alist, "%s", ssh_program);
addargs(&alist, "-x");
- addargs(&alist, "-oClearAllForwardings=yes");
+ addargs(&alist, "-\"oClearAllForwardings yes\"");
addargs(&alist, "-n");
for (j = 0; j < remote_remote_args.num; j++) {
addargs(&alist, "%s",
@@ -1443,7 +1461,6 @@ tolocal(int argc, char **argv)
for (i = 0; i < argc - 1; i++) {
if (!(src = colon(argv[i]))) { /* Local to local. */
- #ifndef WIN32_FIXME
freeargs(&alist);
addargs(&alist, "%s", _PATH_CP);
if (iamrecursive)
@@ -1455,7 +1472,6 @@ tolocal(int argc, char **argv)
addargs(&alist, "%s", argv[argc-1]);
if (do_local_cmd(&alist))
++errs;
- #endif
continue;
}
*src++ = 0;
@@ -1484,735 +1500,7 @@ tolocal(int argc, char **argv)
remin = remout = -1;
}
}
-#ifdef WIN32_FIXME
-void
-source(int argc, char *argv[])
-{
- struct stat stb;
- static BUF buffer;
- BUF *bp;
- off_t i;
- int haderr;
- size_t amt, indx, result;
- int fd;
- char *last, *name, buf[16384];
- unsigned short locfmode;
- char * originalname = NULL;
- char aggregatePath[MAX_PATH] = "";
- char * pArgPath;
- bool bDirSpec = false;
- char * filenames[1024];
- int numfiles = 0;
-
- WIN32_FIND_DATA FindFileData;
- HANDLE hFind;
-
- char FileRoot[MAX_PATH];
- bool bHasRoot = false;
-
- for (indx = 0; indx < (size_t)argc; ++indx) {
- if (strchr(argv[indx],'*'))
- {
- bHasRoot = getRootFrompath(argv[indx],FileRoot);
-
- if (1){//!iamremote) {
- hFind = FindFirstFile(argv[indx], &FindFileData);
- if (hFind != INVALID_HANDLE_VALUE){
-
- do {
- if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- if (bHasRoot)
- {
- filenames[numfiles] = (char *)malloc(MAX_PATH);
- sprintf(filenames[numfiles++],"%s/%s",FileRoot,FindFileData.cFileName);
- }
- else
- filenames[numfiles++] = strdup(FindFileData.cFileName);
-
- if (numfiles >= 1024)
- {
- break;
- }
- }
- while (FindNextFile(hFind,&FindFileData));
- FindClose(hFind);
- }
-
- }
- // expand
- }
- else
- filenames[numfiles++] = strdup(argv[indx]);
-
- if (numfiles >= 1024)
- break;
- }
-
-
- // loop through filenames list
- for (indx = 0; indx < (size_t)numfiles; ++indx) {
-
- {
- pArgPath = filenames[indx];
- }
-
- originalname = pArgPath;
- name = TranslatePath(pArgPath, &bDirSpec);
- if (name == NULL)
- {
-// strerror_s(buf, EPERM);
- strerror_s(buf, sizeof(buf), ENOENT);
- run_err("%s: %s", pArgPath, buf);
- continue;
- }
-
- if (_sopen_s(&fd, name, O_RDONLY | O_BINARY, _SH_DENYNO, 0) != 0) {
- // in NT, we have to check if it is a directory
- if (stat(name, &stb) >= 0) {
- goto switchpoint;
- }
- else
- goto syserr;
- }
-
- if (_fstati64(fd, &stb) < 0) {
-syserr:
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: %s", originalname, buf);
- goto next;
- }
-switchpoint:
- switch (stb.st_mode & _S_IFMT) {
- case _S_IFREG:
- break;
- case _S_IFDIR:
- if (iamrecursive) {
- rsource(name, &stb);
- goto next;
- }
- /* FALLTHROUGH */
- default:
- run_err("%s: not a regular file", name);
- goto next;
- }
-
- last = getfilenamefrompath(originalname);
-
- if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void)sprintf_s(buf, sizeof(buf), "T%lu 0 %lu 0\n",
- (unsigned long)stb.st_mtime,
- (unsigned long)stb.st_atime);
- (void)_write(remout, buf, (unsigned int)strlen(buf));
- if (response() < 0)
- goto next;
- }
-//CHECK #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
-//#define FILEMODEMASK (S_IRWXU|S_IRWXG|S_IRWXO)
-#define FILEMODEMASK (S_IREAD|S_IWRITE|S_IEXEC)
- locfmode = stb.st_mode & FILEMODEMASK;
- locfmode |= ((locfmode & _S_IREAD) >> 3); // group access, just read bit now
- locfmode |= ((locfmode & _S_IREAD) >> 6); // world access, just read bit now
-
-
- (void)sprintf_s(buf, sizeof(buf), "C%04o %I64u %s\n",
- (unsigned int)(locfmode), //(stb.st_mode & FILEMODEMASK),
- (u_int64_t)stb.st_size,
- last);
- if (scpverbose)
- {
- fprintf(stderr, "Sending file modes: %s", buf);
- fflush(stderr);
- }
- (void)_write(remout, buf, (unsigned int)strlen(buf));
- if (response() < 0)
- goto next;
- if ((bp = allocbuf(&buffer, fd, 16384)) == NULL) {
-next: if (fd != -1) (void)_close(fd);
- continue;
- }
-#ifdef WITH_SCP_STATS
- if (!iamremote && statistics)
- {
- statbytes = 0;
- ratebs = 0.0;
- stat_starttime = time(NULL);
- stat_starttimems = GetTickCount();
- }
-#endif /* WITH_SCP_STATS */
-
- /* Keep writing after an error so that we stay sync'd up. */
- for (haderr = 0, i = 0; i < (size_t)stb.st_size; i += bp->cnt) {
- amt = bp->cnt;
- if (i + amt > (size_t)stb.st_size)
- amt = (size_t)(stb.st_size - i);
- if (!haderr) {
- result = _read(fd, bp->buf, (unsigned int)amt);
- if (result != amt)
- haderr = result >= 0 ? EIO : errno;
- }
- if (haderr)
- {
- (void)_write(remout, bp->buf, (unsigned int)amt);
-#ifdef WITH_SCP_STATS
- if (!iamremote && statistics)
- {
- if ((time(NULL) - stat_lasttime) > 0)
- {
- int bwritten;
- bwritten = fprintf(SOME_STATS_FILE,
- "\r%s : ERROR..continuing to end of file anyway", last);
- stats_fixlen(bwritten);
- fflush(SOME_STATS_FILE);
- stat_lasttime = time(NULL);
- }
- }
-#endif /* WITH_SCP_STATS */
- }
- else {
- result = _write(remout, bp->buf, (unsigned int)amt);
- if (result != amt)
- haderr = result >= 0 ? EIO : errno;
-#ifdef WITH_SCP_STATS
- if (!iamremote && statistics)
- {
- statbytes += result;
- /* At least one second delay between
- outputs, or if finished */
- if (time(NULL) - stat_lasttime > 0 ||
- //(result + i) == stb.st_size)
- statbytes == stb.st_size)
- {
- int bwritten;
-
- if (time(NULL) == stat_starttime)
- {
- stat_starttime -= 1;
- // stat_starttimems -= 1000;
- }
- ratebs = ssh_max(1.0,
- (double) statbytes /
- (time(NULL) -
- stat_starttime));
- bwritten =
- fprintf(SOME_STATS_FILE,
- "\r%-25.25s | %10I64d KB | %7.1f kB/s | %s | %3d%%",
- last,
- statbytes / 1024,
- ratebs / 1024,
- stat_eta_new((int) ( GetTickCount() - stat_starttimems)),
-//stat_eta((int) ( time(NULL) - stat_starttime)),
- (int) (100.0 *
- (double) statbytes /
- stb.st_size));
- if (all_statistics && /*(result + i)*/ statbytes ==
- stb.st_size)
- bwritten += fprintf(SOME_STATS_FILE,
- "\n");
- fflush(SOME_STATS_FILE);
- stats_fixlen(bwritten);
- stat_lasttime = time(NULL);
- }
- }
-#endif /* WITH_SCP_STATS */
- }
- }
-
-
-
- if (_close(fd) < 0 && !haderr)
- haderr = errno;
- if (!haderr)
- (void)_write(remout, "", 1);
- else
- {
- strerror_s(buf, sizeof(buf), haderr);
- run_err("%s: %s", originalname, buf);
- }
- (void)response();
- }
- int ii;
- if (numfiles > 0)
- for (ii = 0;iist_mtime,
- (unsigned long)statp->st_atime);
- (void)_write(remout, path, (unsigned int)strlen(path));
- if (response() < 0) {
- closedir(dirp);
- return;
- }
- }
- locfmode = statp->st_mode & FILEMODEMASK;
- locfmode |= ((locfmode & (_S_IREAD | _S_IEXEC)) >> 3); // group access, read,exec bit now
- locfmode |= ((locfmode & (_S_IREAD | _S_IEXEC)) >> 6); // world access, read,exec bit now
-
- (void)sprintf_s(path, sizeof(path),
- "D%04o %d %.1024s\n", (unsigned int)(locfmode),
- 0, last);
- if (scpverbose)
- fprintf(stderr, "Entering directory: %s", path);
- (void)_write(remout, path, (unsigned int)strlen(path));
- if (response() < 0) {
- closedir(dirp);
- return;
- }
- while ((dp = readdir(dirp))) {
- //if (dp->d_ino == 0) //commented out as not needed
- // continue;
-
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
- continue;
- if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) {
- run_err("%s/%s: name too long", name, dp->d_name);
- continue;
- }
- (void)sprintf_s(path, sizeof(path), "%s/%s", name, dp->d_name);
- vect[0] = path;
- source(1, vect);
- }
- (void)closedir(dirp);
- (void)_write(remout, "E\n", 2);
- (void)response();
-}
-
-void sink(int argc, char *argv[])
-{
-// DWORD dwread;
- static BUF buffer;
- struct stat stb;
- enum { YES, NO, DISPLAYED } wrerr;
- BUF *bp;
- size_t i, j, size;
- size_t amt, count, exists, first;
- int mask, mode, ofd, omode;
- int setimes, targisdir, wrerrno = 0;
- char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
- char aggregatePath[MAX_PATH] = "";
- struct _utimbuf ut;
- int dummy_usec;
- bool bDirSpec = false;
-
-#ifdef WITH_SCP_STATS
- char *statslast;
-#endif /* WITH_SCP_STATS */
-
-#define SCREWUP(str) { why = str; goto screwup; }
-
-
-
- setimes = targisdir = 0;
- _umask_s(0, &mask);
- int oldmask;
- if (!pflag)
- _umask_s(mask,&oldmask);
- if (argc != 1) {
- if (!iamremote)
- {
- run_err("ambiguous target");
- exit(1);
- }
- int i;
- for (i = 0; i");
- do {
- if (_read(remin, &ch, sizeof(ch)) != sizeof(ch))
- SCREWUP("lost connection");
- *cp++ = ch;
- } while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
- *cp = 0;
-
- if (buf[0] == '\01' || buf[0] == '\02') {
- if (iamremote == 0)
- (void)_write(STDERR_FILENO,
- buf + 1, (unsigned int)strlen(buf + 1));
- if (buf[0] == '\02')
- exit(1);
- ++errs;
- continue;
- }
- if (buf[0] == 'E') {
- (void)_write(remout, "", 1);
- return;
- }
-
- if (ch == '\n')
- *--cp = 0;
-
-#define getnum(t) (t) = 0; \
- while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0');
- cp = buf;
- if (*cp == 'T') {
- setimes++;
- cp++;
- getnum(ut.modtime);
- if (*cp++ != ' ')
- SCREWUP("mtime.sec not delimited");
- getnum(dummy_usec);
- if (*cp++ != ' ')
- SCREWUP("mtime.usec not delimited");
- getnum(ut.actime);
- if (*cp++ != ' ')
- SCREWUP("atime.sec not delimited");
- getnum(dummy_usec);
- if (*cp++ != '\0')
- SCREWUP("atime.usec not delimited");
- (void)_write(remout, "", 1);
- goto keepgoing; // added 5/3/2001 by QI for -p not working !!!
- // in place of next continue commented out
- //continue;
- }
- if (*cp != 'C' && *cp != 'D') {
- /*
- * Check for the case "rcp remote:foo\* local:bar".
- * In this case, the line "No match." can be returned
- * by the shell before the rcp command on the remote is
- * executed so the ^Aerror_message convention isn't
- * followed.
- */
- if (first) {
- run_err("%s", cp);
- exit(1);
- }
- SCREWUP("expected control record");
- }
- mode = 0;
- for (++cp; cp < buf + 5; cp++) {
- if (*cp < '0' || *cp > '7')
- SCREWUP("bad mode");
- mode = (mode << 3) | (*cp - '0');
- }
- if (*cp++ != ' ')
- SCREWUP("mode not delimited");
-
- for (size = 0; *cp >= '0' && *cp <= '9';)
- size = size * 10 + (*cp++ - '0');
- if (*cp++ != ' ')
- SCREWUP("size not delimited");
- if (targisdir) {
- static char *namebuf;
- static unsigned int cursize;
- size_t need;
-
- need = strlen(targ) + strlen(cp) + 250;
- if (need > cursize)
- namebuf = (char *)xmalloc(need);
- (void)sprintf_s(namebuf, need, "%s%s%s", targ,
- *targ ? "/" : "", cp);
- np = namebuf;
- } else
- np = targ;
- exists = stat(np, &stb) == 0;
- if (buf[0] == 'D') {
- int mod_flag = pflag;
- if (exists) {
- if (!S_ISDIR(stb.st_mode)) {
- errno = ENOTDIR;
- goto bad;
- }
- if (pflag)
- (void)_chmod(np, mode);
- } else {
- /* Handle copying from a read-only directory */
- mod_flag = 1;
- if (_mkdir(np) < 0) // was mkdir(np, mode | S_IRWXU) < 0)
- {
- if (errno == EEXIST) // stat returned didn't exist, but mkdir returned it does - see this when user doesn't have access
- errno = EPERM;
- np = targ;
- goto bad;
- }
- }
- vect[0] = np;
- sink(1, vect);
- if (setimes) {
- setimes = 0;
- //if (_utime(np, &ut) < 0)
- // in NT cannot set directory time by _utime(), we have our
- // call _utimedir() above in this file.
- if (_utimedir(np, &ut) < 0)
- //run_err("%s: set times: %s", np, strerror(errno));
- run_err("setting times on %s failed:", np );
- }
- if (mod_flag)
- (void)_chmod(np, mode);
- continue;
- }
- omode = mode;
-#ifdef HAVE_FTRUNCATE
- /* Don't use O_TRUNC so the file doesn't get corrupted if
- copying on itself. */
- ofd = open(np, O_WRONLY|O_CREAT|O_BINARY, mode);
-#else /* HAVE_FTRUNCATE */
- _sopen_s(&ofd, np, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, _SH_DENYNO, S_IWRITE);
-#endif /* HAVE_FTRUNCATE */
- if (ofd < 0) {
-bad: strerror_s(buf, sizeof(buf), errno);
-
- if (isRootedPath && (strlen(np) > strlen(g_HomeDir)))
- np += strlen(g_HomeDir);
- run_err("%s: %s", np, buf);
- continue;
- }
- (void)_write(remout, "", 1);
- if ((bp = allocbuf(&buffer, ofd, 16384)) == NULL) {
- (void)_close(ofd);
- continue;
- }
- cp = bp->buf;
- wrerr = NO;
-#ifdef WITH_SCP_STATS
- if (!iamremote && statistics)
- {
- statbytes = 0;
- ratebs = 0.0;
- stat_starttime = time(NULL);
- stat_starttimems = GetTickCount();
- statslast = getfilenamefrompath(np);
-
- }
-#endif /* WITH_SCP_STATS */
- for (count = i = 0; i < size; i += 16384) {
- amt = 16384;
- if (i + amt > size)
- amt = size - i;
- count += amt;
- do {
- j = _read(remin, cp, (unsigned int)amt);
- if (j <= 0) {
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s", j ? buf :
- "dropped connection");
- exit(1);
- }
-
-#ifdef WITH_SCP_STATS
- if (!iamremote && statistics){
- int bwritten;
- statbytes += j;
- if ( (time(NULL) - stat_lasttime > 0) || ( statbytes == size) ) {
- if (time(NULL) == stat_starttime) {
- stat_starttime -= 1;
-// stat_starttimems -= 1000;
- }
- ratebs = ssh_max(1.0,
- (double)
- statbytes /
- (time(NULL) -
- stat_starttime));
- bwritten =
- fprintf(SOME_STATS_FILE,
- "\r%-25.25s | %10I64d KB | %7.1f kB/s | %s | %3d%%",
- statslast,
- statbytes / 1024,
- ratebs / 1024,
-// stat_eta((int)
-// (time(NULL) - stat_starttime)),
- stat_eta_new((int)(GetTickCount() - stat_starttimems)),
- (int) (100.0 *
- (double) statbytes /size));
- if (all_statistics && statbytes == size)
- bwritten += fprintf(SOME_STATS_FILE, "\n");
- fflush(SOME_STATS_FILE);
- stats_fixlen(bwritten);
- stat_lasttime = time(NULL);
- }
- }
-#endif /* WITH_SCP_STATS */
- amt -= j;
- cp += j;
- } while (amt > 0);
- if (count == bp->cnt) {
- /* Keep reading so we stay sync'd up. */
- if (wrerr == NO) {
- j = _write(ofd, bp->buf, (unsigned int)count);
- if (j != count) {
- wrerr = YES;
- wrerrno = j >= 0 ? EIO : errno;
- }
- }
- count = 0;
- cp = bp->buf;
- }
- } // end of main 16384 byte read for loop
- if (count != 0 && wrerr == NO &&
- (j = _write(ofd, bp->buf, (unsigned int)count)) != count) {
- wrerr = YES;
- wrerrno = j >= 0 ? EIO : errno;
- }
-#ifdef HAVE_FTRUNCATE
- if (ftruncate(ofd, size)) {
- run_err("%s: truncate: %s", np, strerror(errno));
- wrerr = DISPLAYED;
- }
-#endif /* HAVE_FTRUNCATE */
- if (pflag) {
- if (exists || omode != mode)
- {
-#ifdef HAVE_FCHMOD
- if (fchmod(ofd, omode)) {
-#else /* HAVE_FCHMOD */
- if (_chmod(np, omode)) {
-#endif /* HAVE_FCHMOD */
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: set mode: %s",
- np, buf);
- }
- }
- } else {
- if (!exists && omode != mode)
-#ifdef HAVE_FCHMOD
- if (fchmod(ofd, omode & ~mask)) {
-#else /* HAVE_FCHMOD */
- if (_chmod(np, omode & ~mask)) {
-#endif /* HAVE_FCHMOD */
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: set mode: %s",
- np, buf);
- }
- }
- (void)_close(ofd);
- (void)response();
- if (setimes && wrerr == NO) {
- setimes = 0;
- if (_utime(np, &ut) < 0) {
-
- // see if the error was due to read only file permission
- if ( _access(np,2) < 0 ) {
- // lacks write permission, so give it for now
- _chmod(np, _S_IWRITE);
- if (_utime(np, &ut) < 0) {
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: set times: %s", np, buf);
- wrerr = DISPLAYED;
- }
- _chmod(np, _S_IREAD); // read only permission set again
- }
- else {
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: set times: %s",
- np, buf);
- wrerr = DISPLAYED;
- }
- }
- }
- switch(wrerr) {
- case YES:
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: %s", np, buf);
- break;
- case NO:
- (void)_write(remout, "", 1);
- fflush(stdout);
- fflush(stdin);
- break;
- case DISPLAYED:
- break;
- }
- }
-
- if (targ)
- LocalFree(targ);
-
- if ( first > 1 ) {
- return;
- }
-screwup:
- run_err("protocol error: %s", why);
- exit(1);
-}
-
-int response(void)
-{
- char ch, *cp, resp, rbuf[2048];
-
- if (_read(remin, &resp, sizeof(resp)) != sizeof(resp))
- lostconn(0);
-
- cp = rbuf;
- switch(resp) {
- case 0: /* ok */
- return (0);
- default:
- *cp++ = resp;
- /* FALLTHROUGH */
- case 1: /* error, followed by error msg */
- case 2: /* fatal error, "" */
- do {
- if (_read(remin, &ch, sizeof(ch)) != sizeof(ch))
- lostconn(0);
- *cp++ = ch;
- } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
-
- if (!iamremote)
- (void)_write(STDERR_FILENO, rbuf, (unsigned int)(cp - rbuf));
- ++errs;
- if (resp == 1)
- return (-1);
- exit(1);
- }
- /* NOTREACHED */
-}
-#else
void
source(int argc, char **argv)
{
@@ -2222,7 +1510,7 @@ source(int argc, char **argv)
off_t i, statbytes;
size_t amt, nr;
int fd = -1, haderr, indx;
- char *last, *name, buf[2048], encname[PATH_MAX];
+ char *last, *lastf, *lastr, *name, buf[2048], encname[PATH_MAX];
int len;
for (indx = 0; indx < argc; ++indx) {
@@ -2259,10 +1547,22 @@ syserr: run_err("%s: %s", name, strerror(errno));
run_err("%s: not a regular file", name);
goto next;
}
- if ((last = strrchr(name, '/')) == NULL)
+#ifdef WINDOWS
+ if ((lastf = strrchr(name, '/')) == NULL && (lastr = strrchr(name, '\\')) == NULL)
last = name;
- else
- ++last;
+ else {
+ if (lastf)
+ last = lastf;
+ if (lastr)
+ last = lastr;
+ ++last;
+ }
+#else
+ if ((last = strrchr(name, '/')) == NULL)
+ last = name;
+ else
+ ++last;
+#endif
curfile = last;
if (pflag) {
if (do_times(remout, verbose_mode, &stb) < 0)
@@ -2351,7 +1651,17 @@ rsource(char *name, struct stat *statp)
(void) snprintf(path, sizeof path, "D%04o %d %.1024s\n",
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
if (verbose_mode)
- fprintf(stderr, "Entering directory: %s", path);
+#ifdef WINDOWS
+ {
+ printf("Entering directory: ");
+ wchar_t* wtmp = utf8_to_utf16(path);
+ WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ free(wtmp);
+ }
+#else
+ fprintf(stderr, "Entering directory: %s", path);
+#endif
+
(void) atomicio(vwrite, remout, path, strlen(path));
if (response() < 0) {
closedir(dirp);
@@ -2426,8 +1736,16 @@ sink(int argc, char **argv)
} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
*cp = 0;
if (verbose_mode)
- fprintf(stderr, "Sink: %s", buf);
-
+#ifdef WINDOWS
+ {
+ printf("Sink: ");
+ wchar_t* wtmp = utf8_to_utf16(buf);
+ WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ free(wtmp);
+ }
+#else
+ fprintf(stderr, "Sink: %s", buf);
+#endif
if (buf[0] == '\01' || buf[0] == '\02') {
if (iamremote == 0)
(void) atomicio(vwrite, STDERR_FILENO,
@@ -2703,7 +2021,6 @@ response(void)
}
/* NOTREACHED */
}
-#endif
void
usage(void)
@@ -2739,7 +2056,7 @@ run_err(const char *fmt,...)
fprintf(stderr, "\n");
}
}
-#ifndef WIN32_FIXME
+
void
verifydir(char *cp)
{
@@ -2822,95 +2139,6 @@ lostconn(int signo)
else
exit(1);
}
-#else
-char *win32colon(char *cp)
-{
- int len=0;
- bool bSkip = false;
-
- if (*cp == ':') /* Leading colon is part of file name. */
- return (0);
-
- for (; *cp; ++cp) {
- len++;
-
- if (*cp == '[')
- bSkip = true;
-
- if (bSkip && *cp!= ']')
- continue;
-
- if (*cp == ']')
- bSkip = false;
-
- if (*cp == ':') {
- if ( len != 2 ) { // avoid x: format for drive letter in Windows
- return (cp);
- }
- }
- // if ( (*cp == '/') || (*cp == '\\') )
- // return (0);
- }
- return (0);
-}
-
-void verifydir(char *cp)
-{
- struct stat stb;
-
- if (!stat(cp, &stb)) {
- if (S_ISDIR(stb.st_mode))
- return;
- errno = ENOTDIR;
- }
- char buf[MAX_PATH];
- strerror_s(buf, sizeof(buf), errno);
- run_err("%s: %s", cp, buf);
- exit(1);
-}
-
-int okname(char *cp0)
-{
- return (1);
-}
-
-BUF *
-allocbuf(BUF *bp, int fd, int blksize)
-{
- size_t size;
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
- struct stat stb;
-
- if (fstat(fd, &stb) < 0) {
- run_err("fstat: %s", strerror(errno));
- return (0);
- }
- size = roundup(stb.st_blksize, blksize);
- if (size == 0)
- size = blksize;
-#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */
- size = blksize;
-#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
- if (bp->cnt >= size)
- return (bp);
- if (bp->buf == NULL)
- bp->buf = xmalloc(size);
- else
- bp->buf = xreallocarray(bp->buf, 1, size);
- memset(bp->buf, 0, size);
- bp->cnt = size;
- return (bp);
-}
-
-void lostconn(int signo)
-{
- if (!iamremote)
- fprintf(stderr, "lost connection\n");
- exit(1);
-}
-#endif
-
-#ifdef WIN32_FIXME
#ifdef WITH_SCP_STATS
void stats_fixlen(int bwritten)
@@ -2927,17 +2155,11 @@ void stats_fixlen(int bwritten)
fflush(SOME_STATS_FILE);
}
-
char *stat_eta_new(int msecs)
{
static char stat_result[32];
int hours = 0, mins = 0, secs = 0;
- // hours = msecs / 3600000;
- // msecs %= 3600000;
- // mins = msecs / 60000;
- // msecs %= 60000;
-
hours = msecs / 3600000;
msecs %= 3600000;
mins = msecs / 60000;
@@ -2954,7 +2176,7 @@ char *stat_eta_new(int msecs)
return(stat_result);
}
-char *stat_eta_old(int secs)
+char *stat_eta(int secs)
{
static char stat_result[20];
int hours, mins;
@@ -2964,83 +2186,12 @@ char *stat_eta_old(int secs)
mins = secs / 60;
secs %= 60;
- sprintf_s(stat_result, sizeof(stat_result), "%02d:%02d:%02d", hours, mins, secs);
+ sprintf(stat_result, "%02d:%02d:%02d", hours, mins, secs);
return(stat_result);
}
#endif /* WITH_SCP_STATS */
-
-char *TranslatePath(char *path, bool *bDirSpec)
-{
- char temp[MAX_PATH*2];
- char resolved[MAX_PATH];
- char * rootpath;
-
- if ( iamremote == 0)
- return path; // if we are scp client, nothing special to do, return path we got.
-
- char *s = NULL;
-
- if (g_RootMode == M_ADMIN){
- rootpath = g_FSRoot;
- }else{
- rootpath = g_HomeDir;
- }
-
- if (!_strnicmp(path, rootpath, strlen(g_HomeDir)))
- { // already set to home directory
- strcpy_s(temp, sizeof(temp), path); // absolute path
- }
- else
- {
- if (path[1] != ':')
- {
- if (path[0] == '\\' || path[0] == '/')
- sprintf_s(temp, sizeof(temp), "%s%s",rootpath,&path[1]);
- else
- sprintf_s(temp, sizeof(temp), "%s%s",rootpath,path);
- }
- else
- strcpy(temp,path);
-
- }
- fixslashes(temp);
- PathCanonicalizeA(resolved,temp);
-
-
- *bDirSpec = (resolved[strlen(temp)-1] == '\\');
- // Remove trailing slash unless it's a root spec (c:\ etc)
- if (strcmp(&(resolved[1]),":\\") && resolved[strlen(temp)-1] == '\\')
- resolved[strlen(temp)-1] = 0x00;
-
- if (strlen(resolved) == strlen(rootpath)-1)
- {
- // We specify a length of less than one because if we
- // resolve to the scp home directory (i.e. user specified
- // '.' for the target), then PathCanonicalize will strip
- // the trailing slash.
- if (_strnicmp(resolved, rootpath, strlen(g_HomeDir)-1))
- return NULL;
- }
- else if (!((g_RootMode == M_ADMIN) && resolved[1] == ':')){
- // if we are in admin mode and the user specified a drive, let it go through
- if (_strnicmp(resolved, rootpath, strlen(rootpath)))
- return NULL;
- }
-
- // if we reach this point, the path is fine. We can actually just return path
- // if the path doesn't begin with a slash
- if (path[0] != '/' && path[0] != '\\')
- return path;
-
-
- s = (char *)LocalAlloc(LPTR,strlen(resolved)+1);
- strcpy_s(s,strlen(resolved)+1,resolved);
- isRootedPath = 1;
-
- return s;
-}
-
+#ifdef WINDOWS
/* start_process_io()
input parameters:
exename - name of executable
@@ -3092,7 +2243,7 @@ int start_process_io(char *exename, char **argv, char **envv,
ctr++;
}
- ret = CreateProcess(
+ ret = CreateProcess(
exename, // given in form like "d:\\util\\cmd.exe"
cmdbuf, /* in "arg0 arg1 arg2" form command line */
NULL, /* process security */
diff --git a/sftp-client.c b/sftp-client.c
index 141234f..3034b77 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -109,30 +109,8 @@
}
}
- /** TODO - Move this to POSIX wrapper**/
- /* ??? What if fd is nonblocking ???*/
- int writev(int fd, struct iovec *iov, int iovcnt)
- {
- int written = 0;
-
- int i = 0;
-
- for (i = 0; i < iovcnt; i++)
- {
- int ret = write(fd, iov[i].iov_base, iov[i].iov_len);
-
- if (ret > 0)
- {
- written += ret;
- }
- }
-
- return written;
- }
-
#endif
-
extern volatile sig_atomic_t interrupted;
extern int showprogress;
@@ -776,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;
}
@@ -1502,15 +1481,19 @@ do_download(struct sftp_conn *conn, const char *remote_path,
error("Can't set times on \"%s\": %s",
local_path, strerror(errno));
}
-#ifndef WIN32_FIXME
-// PRAGMA:TODO
+
if (fsync_flag) {
debug("syncing \"%s\"", local_path);
+#ifdef WINDOWS
+ if(FlushFileBuffers(local_fd))
+ error("Couldn't sync file \"%s\": %s",
+ local_path, strerror(GetLastError()));
+#else
if (fsync(local_fd) == -1)
error("Couldn't sync file \"%s\": %s",
local_path, strerror(errno));
- }
#endif
+ }
}
close(local_fd);
sshbuf_free(msg);
@@ -1657,15 +1640,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
TAILQ_INIT(&acks);
- #if(0)//def WIN32_FIXME
-
- if ((local_fd = _open(local_path, O_RDONLY | O_BINARY, 0)) == -1) {
-
- #else
-
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
-
- #endif
error("Couldn't open local file \"%s\" for reading: %s",
local_path, strerror(errno));
return(-1);
@@ -1904,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-common.c b/sftp-common.c
index b7f974b..513e0aa 100644
--- a/sftp-common.c
+++ b/sftp-common.c
@@ -26,7 +26,7 @@
#include "includes.h"
-#ifdef WIN32_FIXME
+#ifdef WINDOWS
void strmode(mode_t mode, char *p);
void strmode_from_attrib(unsigned attrib, char *p);
#endif
@@ -225,38 +225,32 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
char sbuf[FMT_SCALED_STRSIZE];
time_t now;
-#ifndef WIN32_FIXME
- strmode(st->st_mode, mode);
-#else
- strmode(st->st_mode, mode);
+ strmode(st->st_mode, mode);
+#ifdef WINDOWS
strmode_from_attrib(remote, mode);
#endif
if (!remote) {
#ifndef WIN32_FIXME
- user = user_from_uid(st->st_uid, 0);
+ user = user_from_uid(st->st_uid, 0);
#else
- user = "\0";
- snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
- group = gbuf;
+ user = "\0";
+ snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
+ group = gbuf;
#endif
} else {
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
user = ubuf;
-#ifdef WIN32_FIXME
-
- snprintf(gbuf, sizeof gbuf, "%u", (u_int) st -> st_gid);
-
- group = gbuf;
-
+#ifdef WINDOWS
+ snprintf(gbuf, sizeof gbuf, "%u", (u_int) st -> st_gid);
+ group = gbuf;
#else
- if (!remote) {
- group = group_from_gid(st->st_gid, 0);
- } else {
- snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
- group = gbuf;
- }
+ if (!remote) {
+ group = group_from_gid(st->st_gid, 0);
+ } else {
+ snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
+ group = gbuf;
+ }
#endif
-
}
if (ltime != NULL) {
now = time(NULL);
@@ -283,7 +277,7 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
return xstrdup(buf);
}
-#ifdef WIN32_FIXME
+#ifdef WINDOWS
#include
#include
@@ -299,7 +293,6 @@ strmode_from_attrib(unsigned attrib, char *p)
*p = '-';
}
-
void
strmode(mode_t mode, char *p)
{
diff --git a/sftp-glob.c b/sftp-glob.c
index 5ba93f2..fbe3294 100644
--- a/sftp-glob.c
+++ b/sftp-glob.c
@@ -22,7 +22,7 @@
# include
#endif
-#ifdef WIN32_VS
+#ifdef WINDOWS
#include "win32_dirent.h"
#else
#include
@@ -37,10 +37,6 @@
#include "sftp-common.h"
#include "sftp-client.h"
-#ifdef WIN32_VS
-#include "win32_dirent.c"
-#endif
-
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *);
diff --git a/sftp-server.c b/sftp-server.c
index 72477d8..09633af 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -61,11 +61,8 @@
#include "sftp.h"
#include "sftp-common.h"
-#ifdef WIN32_VS
-#include "win32_dirent.c"
-#endif
-
#ifdef WIN32_FIXME
+#include
char * get_inside_path(char *, BOOL, BOOL);
int readlink(const char *path, char *link, int linklen);
@@ -75,6 +72,7 @@
* stat requires paths
* without slash at the end).
*/
+
char *realpathWin32(const char *path, char resolved[PATH_MAX]);
char *realpathWin32i(const char *path, char resolved[PATH_MAX]);
#define realpath realpathWin32
@@ -2166,55 +2164,55 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
#ifdef WIN32_FIXME
char *realpathWin32(const char *path, char resolved[PATH_MAX])
{
- char realpath[PATH_MAX];
+ char realpath[PATH_MAX];
- strlcpy(resolved, path + 1, sizeof(realpath));
- backslashconvert(resolved);
- PathCanonicalizeA(realpath, resolved);
- slashconvert(realpath);
+ strlcpy(resolved, path + 1, sizeof(realpath));
+ backslashconvert(resolved);
+ PathCanonicalizeA(realpath, resolved);
+ slashconvert(realpath);
- /*
- * Store terminating slash in 'X:/' on Windows.
- */
+ /*
+ * Store terminating slash in 'X:/' on Windows.
+ */
- if (realpath[1] == ':' && realpath[2] == 0)
- {
- realpath[2] = '/';
- realpath[3] = 0;
- }
+ if (realpath[1] == ':' && realpath[2] == 0)
+ {
+ realpath[2] = '/';
+ realpath[3] = 0;
+ }
- resolved[0] = *path; // will be our first slash in /x:/users/test1 format
- strncpy(resolved + 1, realpath, sizeof(realpath));
- return resolved;
+ resolved[0] = *path; // will be our first slash in /x:/users/test1 format
+ strncpy(resolved + 1, realpath, sizeof(realpath));
+ return resolved;
}
// like realpathWin32() but takes out the first slash so that windows systems can work on the actual file or directory
char *realpathWin32i(const char *path, char resolved[PATH_MAX])
{
- char realpath[PATH_MAX];
+ char realpath[PATH_MAX];
- if (path[0] != '/') {
- // absolute form x:/abc/def given, no first slash to take out
- strlcpy(resolved, path, sizeof(realpath));
- }
- else
- strlcpy(resolved, path + 1, sizeof(realpath));
+ if (path[0] != '/') {
+ // absolute form x:/abc/def given, no first slash to take out
+ strlcpy(resolved, path, sizeof(realpath));
+ }
+ else
+ strlcpy(resolved, path + 1, sizeof(realpath));
- backslashconvert(resolved);
- PathCanonicalizeA(realpath, resolved);
- slashconvert(realpath);
+ backslashconvert(resolved);
+ PathCanonicalizeA(realpath, resolved);
+ slashconvert(realpath);
- /*
- * Store terminating slash in 'X:/' on Windows.
- */
+ /*
+ * Store terminating slash in 'X:/' on Windows.
+ */
- if (realpath[1] == ':' && realpath[2] == 0)
- {
- realpath[2] = '/';
- realpath[3] = 0;
- }
+ if (realpath[1] == ':' && realpath[2] == 0)
+ {
+ realpath[2] = '/';
+ realpath[3] = 0;
+ }
- strncpy(resolved, realpath, sizeof(realpath));
- return resolved;
+ strncpy(resolved, realpath, sizeof(realpath));
+ return resolved;
}
#endif
diff --git a/sftp.c b/sftp.c
index 5e17179..3332fb4 100644
--- a/sftp.c
+++ b/sftp.c
@@ -72,10 +72,7 @@ typedef void EditLine;
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
-
-#ifdef WIN32_FIXME
- #define FAIL(X) if (X) goto fail
-#endif
+#define MAX_COMMAND_LINE 2048
#ifdef WIN32_VS
#include "win32_dirent.h"
@@ -290,17 +287,12 @@ help(void)
static void
local_do_shell(const char *args)
{
- #ifdef WIN32_FIXME
-
+ #ifdef WINDOWS
if (!*args) {
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
}
system(args); // execute the shell or cmd given
#else
-
- /*
- * Original OpenSSH code.
- */
int status;
char *shell;
pid_t pid;
@@ -663,10 +655,38 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
free(tmp);
resume |= global_aflag;
- if (!quiet && resume)
+ if (!quiet && resume)
+#ifdef WINDOWS
+ {
+ printf("Resuming ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ printf(" to ");
+ free(wtmp);
+ wtmp = utf8_to_utf16(abs_dst);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
- else if (!quiet && !resume)
- printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
+#endif
+ else if (!quiet && !resume)
+#ifdef WINDOWS
+ {
+ printf("Fetching ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ printf(" to ");
+ free(wtmp);
+ wtmp = utf8_to_utf16(abs_dst);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
+#endif
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
@@ -753,12 +773,40 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
}
free(tmp);
- resume |= global_aflag;
+ resume |= global_aflag;
if (!quiet && resume)
+#ifdef WINDOWS
+ {
+ printf("Resuming upload of ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ printf(" to ");
+ free(wtmp);
+ wtmp = utf8_to_utf16(abs_dst);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
abs_dst);
+#endif
else if (!quiet && !resume)
+#ifdef WINDOWS
+ {
+ printf("Uploading ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ printf(" to ");
+ free(wtmp);
+ wtmp = utf8_to_utf16(abs_dst);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
+#endif
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
@@ -823,13 +871,12 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
tmp = path_strip(path, strip_path);
m += strlen(tmp);
free(tmp);
-#ifndef WIN32_FIXME
+#ifdef WINDOWS
+ width = ConScreenSizeX();
+#else
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
#endif
-
-
-
columns = width / (m + 2);
columns = MAX(columns, 1);
colspace = width / columns;
@@ -862,12 +909,37 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
attrib_to_stat(&d[n]->a, &sb);
lname = ls_file(fname, &sb, 1,
(lflag & LS_SI_UNITS));
- printf("%s\n", lname);
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(lname);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+#else
+ printf("%s\n", lname);
+#endif
free(lname);
- } else
- printf("%s\n", d[n]->longname);
- } else {
- printf("%-*s", colspace, fname);
+ }
+ else {
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(d[n]->longname);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+#else
+ printf("%s\n", d[n]->longname);
+#endif
+ }
+ }
+ else {
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(fname);
+ // TODO: Deal with the sizing wprintf_s(L"%-*s", colspace, wtmp);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L" ", 1, 0, 0);
+ free(wtmp);
+#else
+ printf("%-*s", colspace, fname);
+#endif
if (c >= columns) {
printf("\n");
c = 1;
@@ -926,14 +998,13 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
return err;
}
-
-#ifndef WIN32_FIXME
+#ifdef WINDOWS
+ width = ConScreenSizeX();
+#else
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
#endif
-
-
if (!(lflag & LS_SHORT_VIEW)) {
/* Count entries for sort and find longest filename */
for (i = 0; g.gl_pathv[i]; i++)
@@ -953,11 +1024,26 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
}
lname = ls_file(fname, g.gl_statv[i], 1,
(lflag & LS_SI_UNITS));
- printf("%s\n", lname);
- free(lname);
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(lname);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+#else
+ printf("%s\n", lname);
+#endif
+ free(lname);
} else {
- printf("%-*s", colspace, fname);
- if (c >= columns) {
+#ifdef WINDOWS
+ wchar_t* wtmp = utf8_to_utf16(fname);
+ // TODO: Deal with the sizing wprintf_s(L"%-*s", colspace, wtmp);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L" ", 1, 0, 0);
+ free(wtmp);
+#else
+ printf("%-*s", colspace, fname);
+#endif
+ if (c >= columns) {
printf("\n");
c = 1;
} else
@@ -1436,6 +1522,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
glob_t g;
path1 = path2 = NULL;
+
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
if (ignore_errors != 0)
@@ -1483,8 +1570,18 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (!quiet)
- printf("Removing %s\n", g.gl_pathv[i]);
+ if (!quiet)
+#ifdef WINDOWS
+ {
+ printf("Removing ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Removing %s\n", g.gl_pathv[i]);
+#endif
err = do_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
@@ -1584,7 +1681,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
- printf("Changing mode on %s\n", g.gl_pathv[i]);
+#ifdef WINDOWS
+ {
+ printf("Changing mode on ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Changing mode on %s\n", g.gl_pathv[i]);
+#endif
err = do_setstat(conn, g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
@@ -1614,13 +1721,33 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
- printf("Changing owner on %s\n",
- g.gl_pathv[i]);
+#ifdef WINDOWS
+ {
+ printf("Changing owner on ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Changing owner on %s\n",
+ g.gl_pathv[i]);
+#endif
aa->uid = n_arg;
} else {
if (!quiet)
- printf("Changing group on %s\n",
- g.gl_pathv[i]);
+#ifdef WINDOWS
+ {
+ printf("Changing group on ");
+ wchar_t* wtmp = utf8_to_utf16(g.gl_pathv[i]);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Changing group on %s\n",
+ g.gl_pathv[i]);
+#endif
aa->gid = n_arg;
}
err = do_setstat(conn, g.gl_pathv[i], aa);
@@ -1629,7 +1756,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
}
break;
case I_PWD:
- printf("Remote working directory: %s\n", *pwd);
+#ifdef WINDOWS
+ printf("Remote working directory: ");
+ {
+ wchar_t* wtmp = utf8_to_utf16(*pwd);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Remote working directory: %s\n", *pwd);
+#endif
break;
case I_LPWD:
if (!getcwd(path_buf, sizeof(path_buf))) {
@@ -1637,7 +1774,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
err = -1;
break;
}
- printf("Local working directory: %s\n", path_buf);
+#ifdef WINDOWS
+ printf("Local working directory: ");
+ {
+ wchar_t* wtmp = utf8_to_utf16(path_buf);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Local working directory: %s\n", path_buf);
+#endif
break;
case I_QUIT:
/* Processed below */
@@ -2040,7 +2187,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
@@ -2090,7 +2237,17 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
if (remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
- printf("Changing to: %s\n", dir);
+#ifdef WINDOWS
+ {
+ printf("Changing to: ");
+ wchar_t* wtmp = utf8_to_utf16(dir);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
+ free(wtmp);
+ }
+#else
+ printf("Changing to: %s\n", dir);
+#endif
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
if (parse_dispatch_command(conn, cmd,
&remote_path, 1) != 0) {
@@ -2115,7 +2272,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
free(dir);
}
- #ifndef WIN32_VS
+ #ifndef WINDOWS
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
#endif
@@ -2128,13 +2285,36 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
signal(SIGINT, SIG_IGN);
if (el == NULL) {
- if (interactive)
- printf("sftp> ");
- if (fgets(cmd, sizeof(cmd), infile) == NULL) {
- if (interactive)
- printf("\n");
- break;
- }
+#ifdef WINDOWS
+ if (interactive) {
+ wchar_t wcmd[MAX_COMMAND_LINE];
+ printf("sftp> ");
+ if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
+ printf("\n");
+ break;
+ }
+ else {
+ char *pcmd = NULL;
+ if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
+ fatal("failed to convert input arguments");
+ strcpy(cmd, pcmd);
+ free(pcmd);
+ }
+ }
+ else {
+ if (fgets(cmd, sizeof(cmd), infile) == NULL) {
+ break;
+ }
+ }
+#else
+ if (interactive) {
+ printf("sftp> ");
+ if (fgets(cmd, sizeof(cmd), infile) == NULL) {
+ if (interactive)
+ printf("\n");
+ break;
+ }
+#endif
if (!interactive) { /* Echo command */
printf("sftp> %s", cmd);
if (strlen(cmd) > 0 &&
@@ -2187,9 +2367,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
static void
connect_to_server(char *path, char **args, int *in, int *out)
{
- /*
- * Original OpenSSH code.
- */
int c_in, c_out;
#ifdef USE_PIPES
@@ -2210,9 +2387,9 @@ connect_to_server(char *path, char **args, int *in, int *out)
c_in = c_out = inout[1];
#endif /* USE_PIPES */
-#ifdef WIN32_FIXME
+#ifdef WINDOWS
{
- int i;
+ int i = 0;
char fullCmd[MAX_PATH] = { 0 };
char ioArg[1024] = { 0 };
PROCESS_INFORMATION pi = { 0 };
@@ -2225,8 +2402,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
strncat(fullCmd, "\\", MAX_PATH);
}
strncat(fullCmd, path, MAX_PATH);
- for (i = 1; args[i]; i++)
- {
+ for (i = 1; args[i]; i++) {
strncat(fullCmd, " ", MAX_PATH);
strncat(fullCmd, args[i], MAX_PATH);
}
@@ -2337,36 +2513,36 @@ main(int argc, char **argv)
size_t num_requests = DEFAULT_NUM_REQUESTS;
long long limit_kbps = 0;
-#ifdef WIN32_FIXME
+#ifdef WINDOWS
+ /*
+ * Initialize I/O wrappers.
+ */
+ w32posix_initialize();
setvbuf(stdout, NULL, _IONBF, 0);
- #endif
+ ConInit(STD_OUTPUT_HANDLE, TRUE);
+
+ #endif
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
-#ifndef WIN32_FIXME
setlocale(LC_CTYPE, "");
-#endif
__progname = ssh_get_progname(argv[0]);
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "%s", ssh_program);
- #ifdef WIN32_FIXME
- addargs(&args, "-oForwardX11=no");
- addargs(&args, "-oForwardAgent=no");
- addargs(&args, "-oPermitLocalCommand=no");
- addargs(&args, "-oClearAllForwardings=yes");
-
- #else
- addargs(&args, "-oForwardX11 no");
- addargs(&args, "-oForwardAgent no");
- addargs(&args, "-oPermitLocalCommand no");
- addargs(&args, "-oClearAllForwardings yes");
-#endif
+ addargs(&args, "\"-oForwardX11 no\"");
+ addargs(&args, "\"-oForwardAgent no\"");
+ addargs(&args, "\"-oPermitLocalCommand no\"");
+ addargs(&args, "\"-oClearAllForwardings yes\"");
+
ll = SYSLOG_LEVEL_INFO;
- infile = stdin;
+#ifdef WINDOWS
+ _setmode(_fileno(stdin), O_U16TEXT);
+#endif
+ infile = stdin;
while ((ch = getopt(argc, argv,
"1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
@@ -2392,17 +2568,8 @@ main(int argc, char **argv)
addargs(&args, "-%c", ch);
break;
case 'P':
- #ifdef WIN32_FIXME
-
- addargs(&args, "-oPort=%s", optarg);
-
- #else
-
- addargs(&args, "-oPort %s", optarg);
-
- #endif
-
- break;
+ addargs(&args, "\"-oPort %s\"", optarg);
+ break;
case 'v':
if (debug_level < 3) {
addargs(&args, "-v");
@@ -2436,17 +2603,8 @@ main(int argc, char **argv)
fatal("%s (%s).", strerror(errno), optarg);
showprogress = 0;
quiet = batchmode = 1;
- #ifdef WIN32_FIXME
-
- addargs(&args, "-obatchmode=yes");
-
- #else
-
- addargs(&args, "-obatchmode yes");
-
- #endif
-
- break;
+ addargs(&args, "\"-obatchmode yes\"");
+ break;
case 'f':
global_fflag = 1;
break;
@@ -2519,16 +2677,7 @@ main(int argc, char **argv)
fprintf(stderr, "Missing hostname\n");
usage();
}
- #ifdef WIN32_FIXME
-
- addargs(&args, "-oProtocol=%d", sshver);
-
- #else
-
- addargs(&args, "-oProtocol %d", sshver);
-
- #endif
-
+ addargs(&args, "\"-oProtocol %d\"", sshver);
/* no subsystem if the server-spec contains a '/' */
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
diff --git a/win32_dirent.c b/win32_dirent.c
index 4036a8d..9812252 100644
--- a/win32_dirent.c
+++ b/win32_dirent.c
@@ -2,11 +2,11 @@
// directory entry functions in Windows platform like Ubix/Linux
// opendir(), readdir(), closedir().
+#include
#include
#include
#include
#include
-#include
#include "win32_dirent.h"
@@ -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, 0, c_file.name, -1, NULL, 0, NULL, NULL)) == 0 ||
+ WideCharToMultiByte(CP_UTF8, 0, 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,33 @@ 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;
+ char *tmp = NULL;
- 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 ((tmp = utf16_to_utf8(pdirentry->d_name)) == NULL)
+ fatal("failed to covert input arguments");
+ strcpy(c_file.name[0], tmp);
+ free(tmp);
+ tmp = NULL;
+
+ 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..3859889 100644
--- a/win32_dirent.h
+++ b/win32_dirent.h
@@ -8,7 +8,8 @@
#define __DIRENT_H__
#include
-#include
+#include
+#include
// Windows directory structure content
struct dirent {
@@ -18,11 +19,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);