diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs index e68ebfe..b673805 100644 --- a/contrib/win32/openssh/config.h.vs +++ b/contrib/win32/openssh/config.h.vs @@ -1703,6 +1703,9 @@ struct iovec -#define __attribute__(A) +#define __attribute__(A) + +// define building with MS Visual Studio Compiler and runtime and not with MingW/gcc compiler +#define WIN32_VS 1 diff --git a/sftp-client.c b/sftp-client.c index 582fb5f..70cf0d0 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -36,7 +36,12 @@ #endif #include +#ifdef WIN32_VS +#include "win32_dirent.h" +#else #include +#endif + #include #include #include @@ -1502,9 +1507,11 @@ do_download(struct sftp_conn *conn, const char *remote_path, "server reordered requests", local_path); } debug("truncating at %llu", (unsigned long long)highwater); + #ifndef WIN32_VS if (ftruncate(local_fd, highwater) == -1) error("ftruncate \"%s\": %s", local_path, strerror(errno)); + #endif } if (read_error) { error("Couldn't read from remote file \"%s\" : %s", diff --git a/sftp-common.c b/sftp-common.c index 22e1218..9fea144 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -234,6 +234,10 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units) #endif if (!remote) { user = user_from_uid(st->st_uid, 0); + #ifdef WIN32_FIXME + 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; diff --git a/sftp-glob.c b/sftp-glob.c index 43a1beb..5ba93f2 100644 --- a/sftp-glob.c +++ b/sftp-glob.c @@ -22,7 +22,12 @@ # include #endif +#ifdef WIN32_VS +#include "win32_dirent.h" +#else #include +#endif + #include #include #include @@ -32,6 +37,10 @@ #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 *); @@ -147,4 +156,4 @@ remote_glob(struct sftp_conn *conn, const char *pattern, int flags, cur.conn = conn; return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); -} +} \ No newline at end of file diff --git a/sftp-server.c b/sftp-server.c index 1f0b510..88bf5b9 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -42,7 +42,12 @@ #include #endif +#ifdef WIN32_VS +#include "win32_dirent.h" +#else #include +#endif + #include #include #include @@ -64,6 +69,10 @@ #include "sftp.h" #include "sftp-common.h" +#ifdef WIN32_VS +#include "win32_dirent.c" +#endif + #ifdef WIN32_FIXME #undef select @@ -738,6 +747,9 @@ process_init(void) sshbuf_free(msg); } +#ifdef WIN32_VS +#define O_ACCMODE 0x3 +#endif static void process_open(u_int32_t id) { @@ -1180,8 +1192,11 @@ process_readdir(u_int32_t id) /* * Convert names to UTF8 before send to network. */ - + #ifdef WIN32_VS + stats[count].name = xstrdup(dp->d_name); + #else stats[count].name = ConvertLocal8ToUtf8(dp -> d_name, -1, NULL); + #endif stats[count].long_name = ls_file(dp -> d_name, &st, 0, 0); /* diff --git a/sftp.c b/sftp.c index 2f7a277..7d5e0e2 100644 --- a/sftp.c +++ b/sftp.c @@ -83,6 +83,10 @@ typedef void EditLine; #endif +#ifdef WIN32_VS +#include "win32_dirent.h" +#endif + /* File to read commands from */ FILE* infile; @@ -2117,8 +2121,10 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) free(dir); } + #ifndef WIN32_VS setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(infile, NULL, _IOLBF, 0); + #endif interactive = !batchmode && isatty(STDIN_FILENO); err = 0; diff --git a/win32_dirent.c b/win32_dirent.c new file mode 100644 index 0000000..024e677 --- /dev/null +++ b/win32_dirent.c @@ -0,0 +1,93 @@ +// win32_dirent.c +// directory entry functions in Windows platform like Ubix/Linux +// opendir(), readdir(), closedir(). + +#include +#include +#include +#include +#include + +#include "win32_dirent.h" + +/* Open a directory stream on NAME. + 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]; + + sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name); // add *.* to it for NT + + 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 ; + + 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); + } + + return 0; +} + +/* Read a directory entry from DIRP. + Return a pointer to a `struct dirent' describing the entry, + or NULL for EOF or error. The storage returned may be overwritten + by a later readdir call on the same DIR stream. */ +struct dirent *readdir(void *avp) +{ + struct dirent *pdirentry; + DIR *dirp = (DIR *)avp; + + for (;;) { + if ( _findnext( dirp->hFile, &(dirp->c_file) ) == 0 ) { + if ( ( strcmp (dirp->c_file.name,".") == 0 ) || + ( strcmp (dirp->c_file.name,"..") == 0 ) ) { + continue ; + } + pdirentry = (struct dirent *) malloc( sizeof(struct dirent) ); + pdirentry->d_name = dirp->c_file.name ; + pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero + return pdirentry ; + } + else { + return (struct dirent *) NULL; + } + } +} + +// return last part of a path. The last path being a filename. +char *basename(char *path) +{ + char *pdest; + + if (!path) + return "."; + pdest = strrchr(path, '/'); + if (pdest) + return (pdest+1); + pdest = strrchr(path, '\\'); + if (pdest) + return (pdest+1); + + return path; // path does not have a slash +} +// end of dirent functions in Windows diff --git a/win32_dirent.h b/win32_dirent.h new file mode 100644 index 0000000..29a3323 --- /dev/null +++ b/win32_dirent.h @@ -0,0 +1,33 @@ +// direntry functions in Windows platform like Ubix/Linux +// opendir(), readdir(), closedir(). +// NT_DIR * nt_opendir(char *name) ; +// struct nt_dirent *nt_readdir(NT_DIR *dirp); +// int nt_closedir(NT_DIR *dirp) ; + +#ifndef __DIRENT_H__ +#define __DIRENT_H__ + +#include +#include + +// Windows directory structure content +struct dirent { + char *d_name ; // name of the directory entry + int d_ino; // UNIX inode + //unsigned attrib ; // its attributes +}; + +typedef struct { + intptr_t hFile; + struct _finddata_t c_file; + int bRoot; + int bDrive; + char initName[260]; +} DIR; + +DIR * opendir(char *name); +int closedir(DIR *dirp); +struct dirent *readdir(void *avp); +char *basename(char *path); + +#endif \ No newline at end of file