sftp client and server code changed to build & work with MS Visual Studio

Use new compile flag WIN32_VS to add/change logic of sftp client and
sftp server codes so that MS Visual Studio 2015 compiler and runtime can
be used. opendir(), readdir(), closedir() directory APIs and basename()
API of Unix/Linux are implemented in Windows as they are not available
in Windows/VisualStudio C-runtime. win32_dirent.c and win32_dirent.h
files added as dirent.c and dirent.h are not available in Windows and we
do not want to affect mingW/gcc builds for Windows which have those
files available.
This commit is contained in:
quamrulmina 2015-11-06 03:02:51 -06:00
parent 71cca6edc4
commit 4d952924e1
8 changed files with 173 additions and 3 deletions

View File

@ -1705,4 +1705,7 @@ struct iovec
#define __attribute__(A)
// define building with MS Visual Studio Compiler and runtime and not with MingW/gcc compiler
#define WIN32_VS 1

View File

@ -36,7 +36,12 @@
#endif
#include <sys/uio.h>
#ifdef WIN32_VS
#include "win32_dirent.h"
#else
#include <dirent.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@ -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",

View File

@ -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;

View File

@ -22,7 +22,12 @@
# include <sys/stat.h>
#endif
#ifdef WIN32_VS
#include "win32_dirent.h"
#else
#include <dirent.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
@ -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 *);

View File

@ -42,7 +42,12 @@
#include <sys/prctl.h>
#endif
#ifdef WIN32_VS
#include "win32_dirent.h"
#else
#include <dirent.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
@ -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);
/*

6
sftp.c
View File

@ -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;

93
win32_dirent.c Normal file
View File

@ -0,0 +1,93 @@
// win32_dirent.c
// directory entry functions in Windows platform like Ubix/Linux
// opendir(), readdir(), closedir().
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>
#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

33
win32_dirent.h Normal file
View File

@ -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 <direct.h>
#include <io.h>
// 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