#include "win32_compat.h"
#include <errno.h>
#include <stdio.h>
+#include < time.h >
+
#undef poll
#undef socket
#undef connect
int win32_inet_pton(int af, const char * src, void * dst)
{
- int temp = sizeof(struct sockaddr_in);
- int ret = -1;
- int len = strlen(src) + 1;
- wchar_t *srcNonConst = (wchar_t *)malloc(len);
- memset(srcNonConst, 0, len);
- MultiByteToWideChar(CP_ACP, NULL, src, -1, srcNonConst, len);
-
- if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)dst,&temp) == 0 )
- {
- ret = 1;
- }
- else
- {
- if( WSAGetLastError() == WSAEINVAL )
- {
- ret = -1;
- }
- }
- //free(srcNonConst);
- return ret;
-}
-
-/*
- * Check whether "cp" is a valid ascii representation of an Internet address
- * and convert to a binary address. Returns 1 if the address is valid, 0 if
- * not. This replaces inet_addr, the return value from which cannot
- * distinguish between failure and a local broadcast address.
- *
- * This implementation of the standard inet_aton() function was copied
- * (with trivial modifications) from the OpenBSD project.
- */
-int
-win32_inet_aton(const char *cp, struct in_addr *addr)
-{
- register unsigned int val;
- register int base, n;
- register char c;
- unsigned int parts[4];
- register unsigned int *pp = parts;
-
- assert(sizeof(val) == 4);
-
- c = *cp;
- while(1) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, isdigit=decimal.
- */
- if(!isdigit(c))
- return (0);
- val = 0; base = 10;
- if(c == '0') {
- c = *++cp;
- if(c == 'x' || c == 'X')
- base = 16, c = *++cp;
- else
- base = 8;
- }
- while(1) {
- if(isascii(c) && isdigit(c)) {
- val = (val * base) + (c - '0');
- c = *++cp;
- } else if(base == 16 && isascii(c) && isxdigit(c)) {
- val = (val << 4) |
- (c + 10 - (islower(c) ? 'a' : 'A'));
- c = *++cp;
- } else
- break;
- }
- if(c == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16 bits)
- * a.b (with b treated as 24 bits)
- */
- if(pp >= parts + 3)
- return (0);
- *pp++ = val;
- c = *++cp;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if(c != '\0' && (!isascii(c) || !isspace(c)))
- return (0);
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- n = pp - parts + 1;
- switch(n) {
-
- case 0:
- return (0); /* initial nondigit */
-
- case 1: /* a -- 32 bits */
- break;
-
- case 2: /* a.b -- 8.24 bits */
- if((val > 0xffffff) || (parts[0] > 0xff))
- return (0);
- val |= parts[0] << 24;
- break;
-
- case 3: /* a.b.c -- 8.8.16 bits */
- if((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16);
- break;
-
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
- if((val > 0xff) || (parts[0] > 0xff) ||
- (parts[1] > 0xff) || (parts[2] > 0xff))
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
- break;
- }
- if(addr)
- addr->s_addr = htonl(val);
- return (1);
-}
-
-unsigned int
-win32_sleep(unsigned int seconds)
-{
- Sleep(seconds * 1000);
- return 0;
-}
-
-int win32_poll(struct pollfd *fds, int nfsd, int timeout)
-{
- fd_set rfds, wfds, efds;
- int ret;
+ struct sockaddr_in sa;
+ int len = sizeof(SOCKADDR);
+ int ret = -1;
+ int strLen = strlen(src) + 1;
+#ifdef UNICODE
+ wchar_t *srcNonConst = (wchar_t *)malloc(strLen*sizeof(wchar_t));
+ memset(srcNonConst, 0, strLen);
+ MultiByteToWideChar(CP_ACP, 0, src, -1, srcNonConst, strLen);
+#else
+ char *srcNonConst = (char *)malloc(strLen);
+ memset(srcNonConst, 0, strLen);
+ strncpy(srcNonConst, src, strLen);
+#endif
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&efds);
- if (fds->events & POLLIN)
- {
- FD_SET(fds->fd, &rfds);
- }
- if (fds->events & POLLOUT)
- {
- FD_SET(fds->fd, &wfds);
- }
- FD_SET(fds->fd, &efds);
- ret = select(fds->fd + 1, &rfds, &wfds, &efds, NULL);
- fds->revents = 0;
-
- if (FD_ISSET(fds->fd, &rfds))
- {
- fds->revents |= POLLIN;
- }
-
- if (FD_ISSET(fds->fd, &wfds))
+ if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0 )
{
- fds->revents |= POLLOUT;
+ ret = 1;
}
-
- if (FD_ISSET(fds->fd, &efds))
+ else
{
- fds->revents |= POLLHUP;
+ if( WSAGetLastError() == WSAEINVAL )
+ {
+ ret = -1;
+ }
}
+ free(srcNonConst);
+ memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));
return ret;
}
-/*int win32_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;
- int i, rc;
-
- // Set up the file-descriptor sets in ifds, ofds and efds.
- FD_ZERO(&ifds);
- FD_ZERO(&ofds);
- FD_ZERO(&efds);
- for (i = 0, op = ip = 0; i < nfds; ++i) {
- fds[i].revents = 0;
- if(fds[i].events & (POLLIN|POLLPRI)) {
- ip = &ifds;
- FD_SET(fds[i].fd, ip);
- }
- if(fds[i].events & POLLOUT) {
- op = &ofds;
- FD_SET(fds[i].fd, op);
- }
- FD_SET(fds[i].fd, &efds);
- }
-
- // Set up the timeval structure for the timeout parameter
- if(timo < 0) {
- toptr = 0;
- } else {
- toptr = &timeout;
- timeout.tv_sec = timo / 1000;
- timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
+ struct timeval timeout, *toptr;
+ fd_set ifds, ofds, efds, *ip, *op;
+ unsigned int i;
+ int rc;
+
+ // Set up the file-descriptor sets in ifds, ofds and efds.
+ FD_ZERO(&ifds);
+ FD_ZERO(&ofds);
+ FD_ZERO(&efds);
+ for (i = 0, op = ip = 0; i < nfds; ++i)
+ {
+ fds[i].revents = 0;
+ if(fds[i].events & (POLLIN|POLLPRI))
+ {
+ ip = &ifds;
+ FD_SET(fds[i].fd, ip);
+ }
+ if(fds[i].events & POLLOUT)
+ {
+ op = &ofds;
+ FD_SET(fds[i].fd, op);
}
+ FD_SET(fds[i].fd, &efds);
+ }
+
+ // Set up the timeval structure for the timeout parameter
+ if(timo < 0)
+ {
+ toptr = 0;
+ }
+ else
+ {
+ toptr = &timeout;
+ timeout.tv_sec = timo / 1000;
+ timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
+ }
#ifdef DEBUG_POLL
- printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
- (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
+ printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
+ (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
#endif
- rc = select(0, ip, op, &efds, toptr);
+ rc = select(0, ip, op, &efds, toptr);
#ifdef DEBUG_POLL
- printf("Exiting select rc=%d\n", rc);
+ printf("Exiting select rc=%d\n", rc);
#endif
- if(rc <= 0)
- return rc;
+ if(rc <= 0)
+ return rc;
- if(rc > 0) {
- for (i = 0; i < nfds; ++i) {
- int fd = fds[i].fd;
- if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
- fds[i].revents |= POLLIN;
- if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
- fds[i].revents |= POLLOUT;
- if(FD_ISSET(fd, &efds))
- // Some error was detected ... should be some way to know.
- fds[i].revents |= POLLHUP;
+ if(rc > 0)
+ {
+ for (i = 0; i < nfds; ++i)
+ {
+ int fd = fds[i].fd;
+ if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
+ fds[i].revents |= POLLIN;
+ if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
+ fds[i].revents |= POLLOUT;
+ if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know.
+ fds[i].revents |= POLLHUP;
#ifdef DEBUG_POLL
- printf("%d %d %d revent = %x\n",
- FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
- fds[i].revents
- );
+ printf("%d %d %d revent = %x\n",
+ FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
+ fds[i].revents
+ );
#endif
- }
}
- return rc;
+ }
+ return rc;
}
-*/
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+#else
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif
+
+struct timezone
+{
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+int win32_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ FILETIME ft;
+ unsigned __int64 tmpres = 0;
+ static int tzflag;
+
+ if (NULL != tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+ /*converting file time to unix epoch*/
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+ tmpres /= 10; /*convert into microseconds*/
+ tv->tv_sec = (long)(tmpres / 1000000UL);
+ tv->tv_usec = (long)(tmpres % 1000000UL);
+ }
+
+ if (NULL != tz)
+ {
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
+ return 0;
+}
+
#endif