Skip to content

Commit 4d95292

Browse files
committed
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.
1 parent 71cca6e commit 4d95292

File tree

8 files changed

+173
-3
lines changed

8 files changed

+173
-3
lines changed

contrib/win32/openssh/config.h.vs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,9 @@ struct iovec
17031703

17041704

17051705

1706-
#define __attribute__(A)
1706+
#define __attribute__(A)
1707+
1708+
// define building with MS Visual Studio Compiler and runtime and not with MingW/gcc compiler
1709+
#define WIN32_VS 1
17071710

17081711

sftp-client.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@
3636
#endif
3737
#include <sys/uio.h>
3838

39+
#ifdef WIN32_VS
40+
#include "win32_dirent.h"
41+
#else
3942
#include <dirent.h>
43+
#endif
44+
4045
#include <errno.h>
4146
#include <fcntl.h>
4247
#include <signal.h>
@@ -1502,9 +1507,11 @@ do_download(struct sftp_conn *conn, const char *remote_path,
15021507
"server reordered requests", local_path);
15031508
}
15041509
debug("truncating at %llu", (unsigned long long)highwater);
1510+
#ifndef WIN32_VS
15051511
if (ftruncate(local_fd, highwater) == -1)
15061512
error("ftruncate \"%s\": %s", local_path,
15071513
strerror(errno));
1514+
#endif
15081515
}
15091516
if (read_error) {
15101517
error("Couldn't read from remote file \"%s\" : %s",

sftp-common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
234234
#endif
235235
if (!remote) {
236236
user = user_from_uid(st->st_uid, 0);
237+
#ifdef WIN32_FIXME
238+
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
239+
group = gbuf;
240+
#endif
237241
} else {
238242
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
239243
user = ubuf;

sftp-glob.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@
2222
# include <sys/stat.h>
2323
#endif
2424

25+
#ifdef WIN32_VS
26+
#include "win32_dirent.h"
27+
#else
2528
#include <dirent.h>
29+
#endif
30+
2631
#include <stdlib.h>
2732
#include <string.h>
2833
#include <stdlib.h>
@@ -32,6 +37,10 @@
3237
#include "sftp-common.h"
3338
#include "sftp-client.h"
3439

40+
#ifdef WIN32_VS
41+
#include "win32_dirent.c"
42+
#endif
43+
3544
int remote_glob(struct sftp_conn *, const char *, int,
3645
int (*)(const char *, int), glob_t *);
3746

@@ -147,4 +156,4 @@ remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
147156
cur.conn = conn;
148157

149158
return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
150-
}
159+
}

sftp-server.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@
4242
#include <sys/prctl.h>
4343
#endif
4444

45+
#ifdef WIN32_VS
46+
#include "win32_dirent.h"
47+
#else
4548
#include <dirent.h>
49+
#endif
50+
4651
#include <errno.h>
4752
#include <fcntl.h>
4853
#include <pwd.h>
@@ -64,6 +69,10 @@
6469
#include "sftp.h"
6570
#include "sftp-common.h"
6671

72+
#ifdef WIN32_VS
73+
#include "win32_dirent.c"
74+
#endif
75+
6776
#ifdef WIN32_FIXME
6877

6978
#undef select
@@ -738,6 +747,9 @@ process_init(void)
738747
sshbuf_free(msg);
739748
}
740749

750+
#ifdef WIN32_VS
751+
#define O_ACCMODE 0x3
752+
#endif
741753
static void
742754
process_open(u_int32_t id)
743755
{
@@ -1180,8 +1192,11 @@ process_readdir(u_int32_t id)
11801192
/*
11811193
* Convert names to UTF8 before send to network.
11821194
*/
1183-
1195+
#ifdef WIN32_VS
1196+
stats[count].name = xstrdup(dp->d_name);
1197+
#else
11841198
stats[count].name = ConvertLocal8ToUtf8(dp -> d_name, -1, NULL);
1199+
#endif
11851200
stats[count].long_name = ls_file(dp -> d_name, &st, 0, 0);
11861201

11871202
/*

sftp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ typedef void EditLine;
8383

8484
#endif
8585

86+
#ifdef WIN32_VS
87+
#include "win32_dirent.h"
88+
#endif
89+
8690
/* File to read commands from */
8791
FILE* infile;
8892

@@ -2117,8 +2121,10 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
21172121
free(dir);
21182122
}
21192123

2124+
#ifndef WIN32_VS
21202125
setvbuf(stdout, NULL, _IOLBF, 0);
21212126
setvbuf(infile, NULL, _IOLBF, 0);
2127+
#endif
21222128

21232129
interactive = !batchmode && isatty(STDIN_FILENO);
21242130
err = 0;

win32_dirent.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// win32_dirent.c
2+
// directory entry functions in Windows platform like Ubix/Linux
3+
// opendir(), readdir(), closedir().
4+
5+
#include <stdlib.h>
6+
#include <stdio.h>
7+
#include <ctype.h>
8+
#include <string.h>
9+
#include <windows.h>
10+
11+
#include "win32_dirent.h"
12+
13+
/* Open a directory stream on NAME.
14+
Return a DIR stream on the directory, or NULL if it could not be opened. */
15+
DIR * opendir(char *name)
16+
{
17+
struct _finddata_t c_file;
18+
intptr_t hFile;
19+
DIR *pdir;
20+
char searchstr[256];
21+
22+
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name); // add *.* to it for NT
23+
24+
if( (hFile = _findfirst( searchstr, &c_file )) == -1L ) {
25+
if (1) // verbose
26+
printf( "No files found for %s search.\n", name );
27+
return (DIR *) NULL;
28+
}
29+
else {
30+
pdir = (DIR *) malloc( sizeof(DIR) );
31+
pdir->hFile = hFile ;
32+
pdir->c_file = c_file ;
33+
34+
return pdir ;
35+
}
36+
}
37+
38+
/* Close the directory stream DIRP.
39+
Return 0 if successful, -1 if not. */
40+
int closedir(DIR *dirp)
41+
{
42+
if ( dirp && (dirp->hFile) ) {
43+
_findclose( dirp->hFile );
44+
dirp->hFile = 0;
45+
free (dirp);
46+
}
47+
48+
return 0;
49+
}
50+
51+
/* Read a directory entry from DIRP.
52+
Return a pointer to a `struct dirent' describing the entry,
53+
or NULL for EOF or error. The storage returned may be overwritten
54+
by a later readdir call on the same DIR stream. */
55+
struct dirent *readdir(void *avp)
56+
{
57+
struct dirent *pdirentry;
58+
DIR *dirp = (DIR *)avp;
59+
60+
for (;;) {
61+
if ( _findnext( dirp->hFile, &(dirp->c_file) ) == 0 ) {
62+
if ( ( strcmp (dirp->c_file.name,".") == 0 ) ||
63+
( strcmp (dirp->c_file.name,"..") == 0 ) ) {
64+
continue ;
65+
}
66+
pdirentry = (struct dirent *) malloc( sizeof(struct dirent) );
67+
pdirentry->d_name = dirp->c_file.name ;
68+
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
69+
return pdirentry ;
70+
}
71+
else {
72+
return (struct dirent *) NULL;
73+
}
74+
}
75+
}
76+
77+
// return last part of a path. The last path being a filename.
78+
char *basename(char *path)
79+
{
80+
char *pdest;
81+
82+
if (!path)
83+
return ".";
84+
pdest = strrchr(path, '/');
85+
if (pdest)
86+
return (pdest+1);
87+
pdest = strrchr(path, '\\');
88+
if (pdest)
89+
return (pdest+1);
90+
91+
return path; // path does not have a slash
92+
}
93+
// end of dirent functions in Windows

win32_dirent.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// direntry functions in Windows platform like Ubix/Linux
2+
// opendir(), readdir(), closedir().
3+
// NT_DIR * nt_opendir(char *name) ;
4+
// struct nt_dirent *nt_readdir(NT_DIR *dirp);
5+
// int nt_closedir(NT_DIR *dirp) ;
6+
7+
#ifndef __DIRENT_H__
8+
#define __DIRENT_H__
9+
10+
#include <direct.h>
11+
#include <io.h>
12+
13+
// Windows directory structure content
14+
struct dirent {
15+
char *d_name ; // name of the directory entry
16+
int d_ino; // UNIX inode
17+
//unsigned attrib ; // its attributes
18+
};
19+
20+
typedef struct {
21+
intptr_t hFile;
22+
struct _finddata_t c_file;
23+
int bRoot;
24+
int bDrive;
25+
char initName[260];
26+
} DIR;
27+
28+
DIR * opendir(char *name);
29+
int closedir(DIR *dirp);
30+
struct dirent *readdir(void *avp);
31+
char *basename(char *path);
32+
33+
#endif

0 commit comments

Comments
 (0)