diff --git a/configure.ac b/configure.ac index 120082f..f1754dd 100644 --- a/configure.ac +++ b/configure.ac @@ -42,9 +42,14 @@ AC_MSG_CHECKING(for WIN32) if test "$MINGW32" = yes; then bwin32=true + LIB_WS32=-lws2_32 + AC_SUBST(LIB_WS32) AC_MSG_RESULT(compile in mingw32) fi +AM_CONDITIONAL([WIN32], [test "$MINGW32" = "yes"]) +AC_SUBST(WIN32) + dnl if test "$bwin32" = true; then LIB_PYTHON=-lpython26 @@ -84,6 +89,11 @@ AC_SUBST(JSON_GLIB_LIBS) # conditinally check python and subst if test x${compile_python} = xyes; then AM_PATH_PYTHON([2.4]) + if test "$bwin32" = true; then + if test x$PYTHON_DIR != x; then + pyexecdir=$PYTHON_DIR/Lib/site-packages + fi + fi AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)]) PKG_CHECK_MODULES(PYGOBJECT, [pygobject-2.0 >= $PYGOBJECT_REQUIRED]) AC_SUBST(PYGOBJECT_CFLAGS) diff --git a/demo/Makefile.am b/demo/Makefile.am index 6558a76..f1dc5fa 100644 --- a/demo/Makefile.am +++ b/demo/Makefile.am @@ -4,14 +4,14 @@ noinst_PROGRAMS = searpc-demo-server searpc-demo-client searpc-async-client searpc_demo_server_SOURCES = searpc-demo-server.c searpc-demo-packet.h -searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la +searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ searpc_demo_client_SOURCES = searpc-demo-client.c searpc-demo-packet.h -searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la +searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ searpc_async_client_SOURCES = demo-async-client.c searpc-demo-packet.h -searpc_async_client_LDADD = ${top_builddir}/lib/libsearpc.la +searpc_async_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ diff --git a/demo/demo-async-client.c b/demo/demo-async-client.c index 76a983f..612879c 100644 --- a/demo/demo-async-client.c +++ b/demo/demo-async-client.c @@ -3,17 +3,24 @@ #include #include -#include -#include #include -#include -#include #include #include "searpc-client.h" #include "searpc-demo-packet.h" +#ifdef WIN32 + #include + #include + typedef int socklen_t; +#else + #include + #include + #include + #include +#endif + #define BUFLEN 256 #define MAGIC_STRING "ABCD" @@ -95,6 +102,11 @@ main(int argc, char *argv[]) g_type_init(); +#ifdef WIN32 + WSADATA wsadata; + WSAStartup(0x0101, &wsadata); +#endif + ret = sockfd = socket(AF_INET, SOCK_STREAM, 0); if (ret < 0) { fprintf(stderr, "socket failed: %s\n", strerror(errno)); @@ -102,7 +114,7 @@ main(int argc, char *argv[]) } int on = 1; - if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) { fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno)); exit(-1); } diff --git a/demo/searpc-demo-client.c b/demo/searpc-demo-client.c index 7d71ee6..496cbb7 100644 --- a/demo/searpc-demo-client.c +++ b/demo/searpc-demo-client.c @@ -3,11 +3,8 @@ #include #include -#include -#include + #include -#include -#include #include @@ -17,6 +14,17 @@ #define BUFLEN 256 #define MAGIC_STRING "ABCD" +#ifdef WIN32 + #include + #include + typedef int socklen_t; +#else + #include + #include + #include + #include +#endif + /* define the client-side function */ SEARPC_CLIENT_DEFUN_INT__STRING(searpc_strlen); @@ -49,7 +57,7 @@ static char *transport_callback(void *arg, const char *fcall_str, *ret_len = ntohs(pac_ret->length); - return strndup(pac_ret->data, *ret_len); + return g_strndup(pac_ret->data, *ret_len); } int @@ -63,6 +71,11 @@ main(int argc, char *argv[]) g_type_init(); +#ifdef WIN32 + WSADATA wsadata; + WSAStartup(0x0101, &wsadata); +#endif + ret = sockfd = socket(AF_INET, SOCK_STREAM, 0); if (ret < 0) { fprintf(stderr, "socket failed: %s\n", strerror(errno)); @@ -70,7 +83,7 @@ main(int argc, char *argv[]) } int on = 1; - if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) { fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno)); exit(-1); } diff --git a/demo/searpc-demo-packet.h b/demo/searpc-demo-packet.h index bac4619..4f755cd 100644 --- a/demo/searpc-demo-packet.h +++ b/demo/searpc-demo-packet.h @@ -6,6 +6,15 @@ #include #include +#ifdef WIN32 + #include + #include + #include + #include + #include + #define UNUSED +#endif + typedef struct packet { uint16_t length; char data[0]; @@ -23,7 +32,11 @@ writen(int fd, const void *vptr, size_t n) ptr = vptr; nleft = n; while (nleft > 0) { +#ifdef WIN32 + if ( (nwritten = send(fd, ptr, nleft,0)) <= 0) { +#else if ( (nwritten = write(fd, ptr, nleft)) <= 0) { +#endif if (nwritten < 0 && errno == EINTR) nwritten = 0; /* and call write() again */ else @@ -44,7 +57,11 @@ readn(int fd, char *buf, size_t n) nleft = n; while (nleft > 0) { +#ifdef WIN32 + if ( (nread = recv(fd, buf, nleft, 0)) < 0) { +#else if ( (nread = read(fd, buf, nleft)) < 0) { +#endif if (errno == EINTR) nread = 0; /* and call read() again */ else @@ -85,3 +102,267 @@ read_packet(int sockfd, char *buf) #endif +#ifdef WIN32 + + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 +#endif + +#ifndef INT16SZ +#define INT16SZ 2 +#endif + +#ifndef INADDRSZ +#define INADDRSZ 4 +#endif + +/* + * Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +/* int + * inet_pton4(src, dst, pton) + * when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand. + * when last arg is 1: inet_pton(). decimal dotted-quad only. + * return: + * 1 if `src' is a valid input, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +int inet_pton4(const char *src, u_char *dst, int pton) +{ + u_int val; + u_int digit; + int base, n; + unsigned char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *src; + for (;;) { + /* + * 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 = *++src; + if (c == 'x' || c == 'X') + base = 16, c = *++src; + else if (isdigit(c) && c != '9') + base = 8; + } + /* inet_pton() takes decimal only */ + if (pton && base != 10) + return (0); + for (;;) { + if (isdigit(c)) { + digit = c - '0'; + if (digit >= base) + break; + val = (val * base) + digit; + c = *++src; + } else if (base == 16 && isxdigit(c)) { + digit = c + 10 - (islower(c) ? 'a' : 'A'); + if (digit >= 16) + break; + val = (val << 4) | digit; + c = *++src; + } 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) + * a (with a treated as 32 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++src; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + /* inet_pton() takes dotted-quad only. it does not take shorthand. */ + if (pton && n != 4) + return (0); + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (parts[0] > 0xff || val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((parts[0] | parts[1]) > 0xff || val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((parts[0] | parts[1] | parts[2] | val) > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (dst) { + val = htonl(val); + memcpy(dst, &val, INADDRSZ); + } + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +int inet_pton6(const char *src, u_char *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), '\0', IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } else if (*src == '\0') + return (0); + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp, 1) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + if (tp == endp) + return (0); + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int inet_pton(int af, const char *src, void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst, 1)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} +#endif /* WIN32 */ diff --git a/demo/searpc-demo-server.c b/demo/searpc-demo-server.c index adb9902..588b16c 100644 --- a/demo/searpc-demo-server.c +++ b/demo/searpc-demo-server.c @@ -4,10 +4,7 @@ #include #include -#include -#include -#include -#include + #include #include @@ -16,6 +13,17 @@ #include "searpc-demo-packet.h" #define BUFLEN 256 +#ifdef WIN32 + #include + #include + typedef int socklen_t; +#else + #include + #include + #include + #include +#endif + static int searpc_strlen(const char *str) { @@ -55,6 +63,11 @@ main(int argc, char *argv[]) g_type_init(); +#ifdef WIN32 + WSADATA wsadata; + WSAStartup(0x0101, &wsadata); +#endif + start_rpc_service(); listenfd = socket(AF_INET, SOCK_STREAM, 0); @@ -64,7 +77,7 @@ main(int argc, char *argv[]) } int on = 1; - if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) { fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno)); exit(-1); } diff --git a/pysearpc/Makefile.am b/pysearpc/Makefile.am index 986a102..31265d5 100644 --- a/pysearpc/Makefile.am +++ b/pysearpc/Makefile.am @@ -8,6 +8,7 @@ AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ -I${top_builddir}/lib \ -I${top_srcdir}/lib + pysearpcdir=${pyexecdir}/pysearpc pysearpc_PYTHON = __init__.py client.py