From 6d2b2e4a529b8ad32222cc3d4b8acae59dec94b8 Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:46:37 +0800
Subject: [PATCH 1/7] change from MINGW to WIN32

---
 chunk.c      |    2 +-
 fts_compat.c |    2 +-
 io.c         |    2 +-
 mingw.c      |    2 +-
 mingw.h      |    2 +-
 polipo.h     |    6 ++++--
 util.c       |    2 +-
 7 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/chunk.c b/chunk.c
index f7bb6d2..0a7ed16 100644
--- a/chunk.c
+++ b/chunk.c
@@ -184,7 +184,7 @@ totalChunkArenaSize()
 }
 #else
 
-#ifdef MINGW
+#ifdef WIN32 /*MINGW*/
 #define MAP_FAILED NULL
 #define getpagesize() (64 * 1024)
 static void *
diff --git a/fts_compat.c b/fts_compat.c
index 7451e81..c42c3eb 100644
--- a/fts_compat.c
+++ b/fts_compat.c
@@ -127,7 +127,7 @@ dirfd(DIR *dir)
 /*
  * Make the directory identified by the argument the current directory.
  */
-#ifdef MINGW
+#ifdef WIN32 /*MINGW*/
 int
 change_to_dir(DIR *dir)
 {
diff --git a/io.c b/io.c
index 95de1a5..a61db56 100644
--- a/io.c
+++ b/io.c
@@ -799,7 +799,7 @@ create_listener(char *address, int port,
 int
 setNonblocking(int fd, int nonblocking)
 {
-#ifdef MINGW
+#ifdef WIN32 /*MINGW*/
     return mingw_setnonblocking(fd, nonblocking);
 #else
     int rc;
diff --git a/mingw.c b/mingw.c
index a33d2cc..226347a 100644
--- a/mingw.c
+++ b/mingw.c
@@ -23,7 +23,7 @@ THE SOFTWARE.
 
 #include "polipo.h"
 
-#ifndef MINGW
+#ifndef WIN32 /*MINGW*/
 
 static int dummy ATTRIBUTE((unused));
 
diff --git a/mingw.h b/mingw.h
index baca6fb..8801368 100644
--- a/mingw.h
+++ b/mingw.h
@@ -32,7 +32,7 @@ THE SOFTWARE.
  * symbol. For Unix or Unix-like systems, leave it undefined.
  */
 
-#ifdef MINGW
+#ifdef WIN32 /*MINGW*/
 
 /* Unfortunately, there's no hiding it. */
 #define HAVE_WINSOCK 1
diff --git a/polipo.h b/polipo.h
index b0481b8..ff97101 100644
--- a/polipo.h
+++ b/polipo.h
@@ -24,7 +24,9 @@ THE SOFTWARE.
 #define _GNU_SOURCE
 #endif
 
+#ifndef WIN32
 #include <sys/param.h>
+#endif
 
 #ifdef __MINGW32_VERSION
 #define MINGW
@@ -43,7 +45,7 @@ THE SOFTWARE.
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <dirent.h>
-#ifndef MINGW
+#ifndef WIN32 /*MINGW*/
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -165,7 +167,7 @@ THE SOFTWARE.
 #define UNALIGNED_ACCESS
 #endif
 
-#ifndef MINGW
+#ifndef WIN32 /*MINGW*/
 #define HAVE_FORK
 #ifndef NO_SYSLOG
 #define HAVE_SYSLOG
diff --git a/util.c b/util.c
index e6494ed..727fc4e 100644
--- a/util.c
+++ b/util.c
@@ -426,7 +426,7 @@ pstrerror(int e)
     default: s = NULL; break;
     }
     if(!s) s = strerror(e);
-#ifdef MINGW
+#ifdef WIN32 /*MINGW*/
     if(!s) {
         if(e >= WSABASEERR && e <= WSABASEERR + 2000) {
             /* This should be okay, as long as the caller discards the
-- 
1.6.5.1.msysgit.1


From 31c5bbbd4d85c3e71f45a5b39d02effad4c5cfae Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:48:56 +0800
Subject: [PATCH 2/7] change func from mingw_* to win32_*

---
 io.c    |    2 +-
 mingw.c |   30 +++++++++++++++---------------
 mingw.h |   54 +++++++++++++++++++++++++++---------------------------
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/io.c b/io.c
index a61db56..957c6b9 100644
--- a/io.c
+++ b/io.c
@@ -800,7 +800,7 @@ int
 setNonblocking(int fd, int nonblocking)
 {
 #ifdef WIN32 /*MINGW*/
-    return mingw_setnonblocking(fd, nonblocking);
+    return win32_setnonblocking(fd, nonblocking);
 #else
     int rc;
     rc = fcntl(fd, F_GETFL, 0);
diff --git a/mingw.c b/mingw.c
index 226347a..5b8f08c 100644
--- a/mingw.c
+++ b/mingw.c
@@ -53,7 +53,7 @@ static int dummy ATTRIBUTE((unused));
  * (with trivial modifications) from the OpenBSD project.
  */
 int
-mingw_inet_aton(const char *cp, struct in_addr *addr)
+win32_inet_aton(const char *cp, struct in_addr *addr)
 {
     register unsigned int val;
     register int base, n;
@@ -148,14 +148,14 @@ mingw_inet_aton(const char *cp, struct in_addr *addr)
 }
 
 unsigned int
-mingw_sleep(unsigned int seconds)
+win32_sleep(unsigned int seconds)
 {
     Sleep(seconds * 1000);
     return 0;
 }
 
 int
-mingw_gettimeofday(struct timeval *tv, char *tz)
+win32_gettimeofday(struct timeval *tv, char *tz)
 {
     const long long EPOCHFILETIME = (116444736000000000LL);
     FILETIME        ft;
@@ -183,7 +183,7 @@ mingw_gettimeofday(struct timeval *tv, char *tz)
     return 0;
 }
 
-int mingw_poll(struct pollfd *fds, unsigned int nfds, int timo)
+int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
 {
     struct timeval timeout, *toptr;
     fd_set ifds, ofds, efds, *ip, *op;
@@ -248,7 +248,7 @@ int mingw_poll(struct pollfd *fds, unsigned int nfds, int timo)
     return rc;
 }
 
-int mingw_close_socket(SOCKET fd) {
+int win32_close_socket(SOCKET fd) {
     int rc;
 
     rc = closesocket(fd);
@@ -268,7 +268,7 @@ set_errno(int winsock_err)
     }
 }
 
-int mingw_write_socket(SOCKET fd, void *buf, int n)
+int win32_write_socket(SOCKET fd, void *buf, int n)
 {
     int rc = send(fd, buf, n, 0);
     if(rc == SOCKET_ERROR) {
@@ -277,7 +277,7 @@ int mingw_write_socket(SOCKET fd, void *buf, int n)
     return rc;
 }
 
-int mingw_read_socket(SOCKET fd, void *buf, int n)
+int win32_read_socket(SOCKET fd, void *buf, int n)
 {
     int rc = recv(fd, buf, n, 0);
     if(rc == SOCKET_ERROR) {
@@ -294,7 +294,7 @@ int mingw_read_socket(SOCKET fd, void *buf, int n)
  * is successful, other -1.
  */
 int
-mingw_setnonblocking(SOCKET fd, int nonblocking)
+win32_setnonblocking(SOCKET fd, int nonblocking)
 {
     int rc;
 
@@ -312,7 +312,7 @@ mingw_setnonblocking(SOCKET fd, int nonblocking)
  * even if we are using winsock.
  */
 SOCKET
-mingw_socket(int domain, int type, int protocol)
+win32_socket(int domain, int type, int protocol)
 {
     SOCKET fd = socket(domain, type, protocol);
     if(fd == INVALID_SOCKET) {
@@ -342,7 +342,7 @@ set_connect_errno(int winsock_err)
  * even if we are using winsock.
  */
 int
-mingw_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
+win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
 {
     int rc = connect(fd, addr, addr_len);
     assert(rc == 0 || rc == SOCKET_ERROR);
@@ -358,7 +358,7 @@ mingw_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
  * even if we are using winsock.
  */
 SOCKET
-mingw_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
+win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
 {
     SOCKET newfd = accept(fd, addr, addr_len);
     if(newfd == INVALID_SOCKET) {
@@ -374,7 +374,7 @@ mingw_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
  * even if we are using winsock.
  */
 int
-mingw_shutdown(SOCKET fd, int mode)
+win32_shutdown(SOCKET fd, int mode)
 {
     int rc = shutdown(fd, mode);
     assert(rc == 0 || rc == SOCKET_ERROR);
@@ -390,7 +390,7 @@ mingw_shutdown(SOCKET fd, int mode)
  * even if we are using winsock.
  */
 int
-mingw_getpeername(SOCKET fd, struct sockaddr *name, socklen_t *namelen)
+win32_getpeername(SOCKET fd, struct sockaddr *name, socklen_t *namelen)
 {
     int rc = getpeername(fd, name, namelen);
     assert(rc == 0 || rc == SOCKET_ERROR);
@@ -403,7 +403,7 @@ mingw_getpeername(SOCKET fd, struct sockaddr *name, socklen_t *namelen)
 /* Stat doesn't work on directories if the name ends in a slash. */
 
 int
-mingw_stat(const char *filename, struct stat *ss)
+win32_stat(const char *filename, struct stat *ss)
 {
     int len, rc, saved_errno;
     char *noslash;
@@ -425,7 +425,7 @@ mingw_stat(const char *filename, struct stat *ss)
     errno = saved_errno;
     return rc;
 }
-#endif /* #ifdef MINGW */
+#endif /* #ifdef WIN32 MINGW */
 
 #ifndef HAVE_READV_WRITEV
 
diff --git a/mingw.h b/mingw.h
index 8801368..4b2ec77 100644
--- a/mingw.h
+++ b/mingw.h
@@ -74,7 +74,7 @@ struct pollfd {
     short events;     /* requested events */
     short revents;    /* returned events */
 };
-#define poll(x, y, z)        mingw_poll(x, y, z)
+#define poll(x, y, z)        win32_poll(x, y, z)
 
 /* These wrappers do nothing special except set the global errno variable if
  * an error occurs (winsock doesn't do this by default). They set errno
@@ -82,17 +82,17 @@ struct pollfd {
  * outside of this file "shouldn't" have to worry about winsock specific error
  * handling.
  */
-#define socket(x, y, z)      mingw_socket(x, y, z)
-#define connect(x, y, z)     mingw_connect(x, y, z)
-#define accept(x, y, z)      mingw_accept(x, y, z)
-#define shutdown(x, y)       mingw_shutdown(x, y)
-#define getpeername(x, y, z) mingw_getpeername(x, y, z)
+#define socket(x, y, z)      win32_socket(x, y, z)
+#define connect(x, y, z)     win32_connect(x, y, z)
+#define accept(x, y, z)      win32_accept(x, y, z)
+#define shutdown(x, y)       win32_shutdown(x, y)
+#define getpeername(x, y, z) win32_getpeername(x, y, z)
 
 /* Wrapper macros to call misc. functions mingw is missing */
-#define sleep(x)             mingw_sleep(x)
-#define inet_aton(x, y)      mingw_inet_aton(x, y)
-#define gettimeofday(x, y)   mingw_gettimeofday(x, y)
-#define stat(x, y)           mingw_stat(x, y)
+#define sleep(x)             win32_sleep(x)
+#define inet_aton(x, y)      win32_inet_aton(x, y)
+#define gettimeofday(x, y)   win32_gettimeofday(x, y)
+#define stat(x, y)           win32_stat(x, y)
 
 #define mkdir(x, y) mkdir(x)
 
@@ -100,27 +100,27 @@ struct pollfd {
 typedef int socklen_t;
 
 /* Function prototypes for functions in mingw.c */
-unsigned int mingw_sleep(unsigned int);
-int     mingw_inet_aton(const char *, struct in_addr *);
-int     mingw_gettimeofday(struct timeval *, char *);
-int     mingw_poll(struct pollfd *, unsigned int, int);
-SOCKET  mingw_socket(int, int, int);
-int     mingw_connect(SOCKET, struct sockaddr*, socklen_t);
-SOCKET  mingw_accept(SOCKET, struct sockaddr*, socklen_t *);
-int     mingw_shutdown(SOCKET, int);
-int     mingw_getpeername(SOCKET, struct sockaddr*, socklen_t *);
+unsigned int win32_sleep(unsigned int);
+int     win32_inet_aton(const char *, struct in_addr *);
+int     win32_gettimeofday(struct timeval *, char *);
+int     win32_poll(struct pollfd *, unsigned int, int);
+SOCKET  win32_socket(int, int, int);
+int     win32_connect(SOCKET, struct sockaddr*, socklen_t);
+SOCKET  win32_accept(SOCKET, struct sockaddr*, socklen_t *);
+int     win32_shutdown(SOCKET, int);
+int     win32_getpeername(SOCKET, struct sockaddr*, socklen_t *);
 
 /* Three socket specific macros */
-#define READ(x, y, z)  mingw_read_socket(x, y, z)
-#define WRITE(x, y, z) mingw_write_socket(x, y, z)
-#define CLOSE(x)       mingw_close_socket(x)
+#define READ(x, y, z)  win32_read_socket(x, y, z)
+#define WRITE(x, y, z) win32_write_socket(x, y, z)
+#define CLOSE(x)       win32_close_socket(x)
 
-int mingw_read_socket(SOCKET, void *, int);
-int mingw_write_socket(SOCKET, void *, int);
-int mingw_close_socket(SOCKET);
+int win32_read_socket(SOCKET, void *, int);
+int win32_write_socket(SOCKET, void *, int);
+int win32_close_socket(SOCKET);
 
-int mingw_setnonblocking(SOCKET, int);
-int mingw_stat(const char*, struct stat*);
+int win32_setnonblocking(SOCKET, int);
+int win32_stat(const char*, struct stat*);
 #endif
 
 #ifndef HAVE_READV_WRITEV
-- 
1.6.5.1.msysgit.1


From 2e1b4a5865cbe2eadbae755c1d763b5b70d0c4d9 Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:51:00 +0800
Subject: [PATCH 3/7] move va_copy from log.c/util.c to polipo.h

---
 log.c    |    4 ----
 polipo.h |    8 ++++++++
 util.c   |    6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/log.c b/log.c
index ec5c545..31aa15e 100644
--- a/log.c
+++ b/log.c
@@ -304,10 +304,6 @@ maybeFlushSyslog(int type)
     }
 }
 
-#ifndef va_copy
-#define va_copy(a, b) do { a = b; } while(0)
-#endif
-
 static void
 accumulateSyslogV(int type, const char *f, va_list args)
 {
diff --git a/polipo.h b/polipo.h
index ff97101..4c87484 100644
--- a/polipo.h
+++ b/polipo.h
@@ -60,6 +60,14 @@ THE SOFTWARE.
 #include <signal.h>
 #endif
 
+#if defined(va_copy)
+#elif defined(__va_copy)
+#  define va_copy(dst, src) __va_copy((dst), (src))
+#else
+/* #  define va_copy(dst, src) (memcpy(&(dst), &(src), sizeof (va_list))) */
+#  define va_copy(dst, src) do{((dst) = (src)) ;} while(0) 
+#endif
+
 #ifndef MAP_ANONYMOUS
 #define MAP_ANONYMOUS MAP_ANON
 #endif
diff --git a/util.c b/util.c
index 727fc4e..008c6e6 100644
--- a/util.c
+++ b/util.c
@@ -311,11 +311,13 @@ vsprintf_a(const char *f, va_list args)
 
 #else
 
-/* This is not going to work if va_list is interesting.  But then, if you
+/*** This is not going to work if va_list is interesting.  But then, if you
    have a non-trivial implementation of va_list, you should have va_copy. */
+/*
 #ifndef va_copy
 #define va_copy(a, b) do { a = b; } while(0)
-#endif
+#endif 
+*/
 
 char*
 vsprintf_a(const char *f, va_list args)
-- 
1.6.5.1.msysgit.1


From 834ba63d1e0a4688237c1761d626efec311c4002 Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:51:54 +0800
Subject: [PATCH 4/7] write a new mktime_gmt for VC

---
 util.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/util.c b/util.c
index 008c6e6..9960f8b 100644
--- a/util.c
+++ b/util.c
@@ -487,6 +487,22 @@ mktime_gmt(struct tm *tm)
     tzset();
     return t;
 }
+#elif defined(_MSC_VER)
+ time_t
+mktime_gmt(struct tm *tm)
+{
+    time_t t;
+    static int bias = -1;
+    if(bias == -1){
+        time_t   curr = time(NULL);
+        struct   tm *p = gmtime(&curr);
+        time_t   gmtcurr = mktime(p);
+        bias = curr-gmtcurr ;
+    }
+    t = mktime(tm)+bias;
+    /* printf("mktime_gmt2: %d\n", t ); */
+    return t;
+}
 #else
 time_t
 mktime_gmt(struct tm *tm)
-- 
1.6.5.1.msysgit.1


From 5c279171043ee30b01427fbff491698b5efe3747 Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:53:04 +0800
Subject: [PATCH 5/7] add HAVE_FORK in event.h

---
 event.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/event.h b/event.h
index 05575d6..c94aa3c 100644
--- a/event.h
+++ b/event.h
@@ -52,7 +52,9 @@ typedef struct _Condition {
 
 void initEvents(void);
 void uninitEvents(void);
+#ifdef HAVE_FORK
 void interestingSignals(sigset_t *ss);
+#endif
 
 TimeEventHandlerPtr scheduleTimeEvent(int seconds,
                                       int (*handler)(TimeEventHandlerPtr),
-- 
1.6.5.1.msysgit.1


From 2d655c4d01eaa9aa6cb97827c02d1ee8b70dd48b Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 20:56:59 +0800
Subject: [PATCH 6/7] some port of func  for VC

---
 local.h  |    5 +++++
 polipo.h |   15 +++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/local.h b/local.h
index 24dde5a..10bc422 100644
--- a/local.h
+++ b/local.h
@@ -20,6 +20,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
+#ifdef _MSC_VER
+  typedef int pid_t;
+#endif
+
+
 typedef struct _SpecialRequest {
     ObjectPtr object;
     int fd;
diff --git a/polipo.h b/polipo.h
index 4c87484..6ea9d95 100644
--- a/polipo.h
+++ b/polipo.h
@@ -39,12 +39,14 @@ THE SOFTWARE.
 #include <errno.h>
 #include <string.h>
 #include <assert.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include <time.h>
-#include <sys/time.h>
 #include <sys/stat.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#include <sys/time.h>
 #include <dirent.h>
+#endif
 #ifndef WIN32 /*MINGW*/
 #include <sys/mman.h>
 #include <sys/socket.h>
@@ -191,6 +193,15 @@ THE SOFTWARE.
 #endif
 #endif
 
+#ifdef _MSC_VER
+
+#define F_OK 00
+#define snprintf _snprintf
+#define S_ISDIR(x) (S_IFDIR&(x))
+#define S_ISREG(x) (S_IFREG&(x))
+
+#endif
+
 #ifdef HAVE_READV_WRITEV
 #define WRITEV(x, y, z) writev(x, y, z)
 #define READV(x, y, z)  readv(x, y, z)
-- 
1.6.5.1.msysgit.1


From c67fff81b713ae874ae5c3ed8dc922ec94885081 Mon Sep 17 00:00:00 2001
From: honglei jiang <jhonglei@gmail.com>
Date: Thu, 28 Jan 2010 21:03:54 +0800
Subject: [PATCH 7/7] win_direct.h/c for VC

---
 fts_compat.c |   12 +++-
 fts_compat.h |    6 ++
 win_dirent.c |  221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 win_dirent.h |   61 ++++++++++++++++
 4 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 win_dirent.c
 create mode 100644 win_dirent.h

diff --git a/fts_compat.c b/fts_compat.c
index c42c3eb..6fb74cb 100644
--- a/fts_compat.c
+++ b/fts_compat.c
@@ -25,9 +25,17 @@ THE SOFTWARE.
 
 #include <stdlib.h>
 #include <errno.h>
-#include <unistd.h>
+
+#ifdef _MSC_VER
+ #include "polipo.h"
+ #include <direct.h>
+#else
+ #include <unistd.h>
+ #include <dirent.h>
+#endif
+
 #include <sys/types.h>
-#include <dirent.h>
+
 #include <sys/stat.h>
 #include <errno.h>
 #include <string.h>
diff --git a/fts_compat.h b/fts_compat.h
index c23d405..30714b8 100644
--- a/fts_compat.h
+++ b/fts_compat.h
@@ -50,6 +50,12 @@ struct _FTSENT {
 
 typedef struct _FTSENT FTSENT;
 
+#ifdef _MSC_VER
+#include "win_dirent.h"
+#else
+#include <dirent.h>
+#endif
+
 struct _FTS {
     int depth;
     DIR *dir[FTS_MAX_DEPTH];
diff --git a/win_dirent.c b/win_dirent.c
new file mode 100644
index 0000000..cab822a
--- /dev/null
+++ b/win_dirent.c
@@ -0,0 +1,221 @@
+/* This software is distributed under the conditions of the BSD style license.
+
+ Copyright (c)
+ 1995-2002
+ Petar Marinov
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** dirent.c: emulates POSIX directory readin functions: opendir(), readdir(),
+ *           etc. under Win32   
+ */
+
+#include <windows.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <malloc.h>
+#include "win_dirent.h"
+
+/*--------------------------------------------------------------------------
+ Name         countslashes
+
+ Description  
+ --------------------------------------------------------------------------*/
+
+static int countslashes(const char *dirname) {
+    const char *p;
+    int n;
+
+    n = 0;
+    p = dirname;
+
+    while (*p)
+        if (*p++ == '\\')
+            ++n;
+
+    return n;
+}
+
+/*--------------------------------------------------------------------------
+ * Name         opendir
+ *
+ * Description
+ --------------------------------------------------------------------------*/
+DIR * opendir(const char * dirname) {
+    DIR * dir;
+    int nameLen;
+    struct stat st;
+    unsigned char flagNetPath;
+    unsigned char flagRootOnly;
+
+    if (dirname == NULL || *dirname == 0) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    nameLen = strlen(dirname);
+    flagNetPath = 0;
+    if (dirname[0] == '\\' && dirname[1] == '\\')
+        flagNetPath = 1;
+    /* we have to check for root-dir-only case */
+    flagRootOnly = 0;
+    if (flagNetPath) {
+        if (countslashes(&dirname[2]) == 2) /* only the separation for server_name and the root*/
+            flagRootOnly = 1;
+    }
+
+    if ((dirname[nameLen - 1] == '/' || dirname[nameLen - 1] == '\\')
+            && (nameLen != 3 || dirname[1] != ':') && nameLen != 1
+            && !flagRootOnly) {
+        char * t = alloca( nameLen );
+        memcpy(t, dirname, nameLen);
+        t[nameLen - 1] = 0;
+        dirname = t;
+        --nameLen;
+    }
+
+    if (stat(dirname, &st))
+        return NULL;
+
+    if ((st.st_mode & S_IFDIR) == 0) {
+        /* this is not a DIR */
+        errno = ENOTDIR;
+        return NULL;
+    }
+
+    if ((dir = malloc(sizeof(DIR) + nameLen + 2)) == NULL) {
+        errno = ENOMEM;
+        return NULL;
+    }
+
+    dir->hFind = INVALID_HANDLE_VALUE;
+
+    memcpy(dir->szDirName, dirname, nameLen);
+    if (nameLen && dirname[nameLen - 1] != ':' && dirname[nameLen - 1] != '\\'
+            && dirname[nameLen - 1] != '/') {
+        dir->szDirName[nameLen++] = '\\';
+    }
+    dir->szDirName[nameLen] = '*';
+    dir->szDirName[nameLen + 1] = 0;
+
+    return dir;
+}
+;
+
+/*--------------------------------------------------------------------------
+ * Name         readdir
+ *
+ * Description  
+ --------------------------------------------------------------------------*/
+struct dirent * readdir(DIR * dir) {
+    static WIN32_FIND_DATA fData;
+
+    if (dir == NULL) {
+        errno = EBADF;
+        return NULL;
+    }
+
+    do {
+        int ok = 1;
+
+        if (dir->hFind == INVALID_HANDLE_VALUE) {
+            dir->hFind = FindFirstFile(dir->szDirName, &fData);
+            if (dir->hFind == INVALID_HANDLE_VALUE)
+                ok = 0;
+        } else if (!FindNextFile(dir->hFind, &fData))
+            ok = 0;
+
+        if (!ok) {
+            switch (GetLastError()) {
+            case ERROR_NO_MORE_FILES:
+            case ERROR_FILE_NOT_FOUND:
+            case ERROR_PATH_NOT_FOUND:
+                errno = ENOENT;
+                break;
+
+            case ERROR_NOT_ENOUGH_MEMORY:
+                errno = ENOMEM;
+                break;
+
+            default:
+                errno = EINVAL;
+                break;
+            }
+            return NULL;
+        }
+    } while (fData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
+
+    return (struct dirent *) &fData.cFileName;
+}
+;
+
+/*--------------------------------------------------------------------------
+ * Name         closedir
+ --------------------------------------------------------------------------*/
+int closedir(DIR * dir) {
+    if (dir == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+    if (dir->hFind != INVALID_HANDLE_VALUE)
+        FindClose(dir->hFind);
+    free(dir);
+    return 0;
+}
+;
+
+/*--------------------------------------------------------------------------
+ Name         rewinddir
+ Description  
+ --------------------------------------------------------------------------*/
+void rewinddir(DIR * dir) {
+    if (dir) {
+        if (dir->hFind != INVALID_HANDLE_VALUE)
+            FindClose(dir->hFind);
+        dir->hFind = INVALID_HANDLE_VALUE;
+    }
+}
+;
+
+/*
+ int main(int argc, char ** argv) {
+    DIR * dir;
+    struct dirent * de;
+    char * arg;
+
+    arg = argc > 1 ? argv[1] : ".";
+
+    if (dir = opendir(arg)) {
+        while (de = readdir(dir)) {
+            puts(de->d_name);
+        }
+        closedir(dir);
+    }
+    return 0;
+}
+;
+*/
+
diff --git a/win_dirent.h b/win_dirent.h
new file mode 100644
index 0000000..82d5433
--- /dev/null
+++ b/win_dirent.h
@@ -0,0 +1,61 @@
+/* This software is distributed under the conditions of the BSD style license.
+
+ Copyright (c)
+ 1995-2002
+ Petar Marinov
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#include <stdio.h>
+
+struct dirent {
+    char d_name[FILENAME_MAX + 1]; /* File name. */
+};
+struct DIR {
+    HANDLE hFind; /* File search handle */
+    char szDirName[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
+};
+#ifdef  __cplusplus
+extern "C" {
+#endif
+typedef struct DIR DIR;
+
+DIR * opendir(const char * dirname);
+struct dirent * readdir(DIR * dir);
+int closedir(DIR * dir);
+void rewinddir(DIR * dir);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* DIRENT_H */
-- 
1.6.5.1.msysgit.1

