You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/05/04 15:34:13 UTC

svn commit: r1099442 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.msc.in Makefile.unx.in configure include/acr/netapi.h include/acr/netdefs.h include/acr/string.h os/win32/config.hw shared/netaddr.c shared/string.c

Author: mturk
Date: Wed May  4 13:34:13 2011
New Revision: 1099442

URL: http://svn.apache.org/viewvc?rev=1099442&view=rev
Log:
APR's socladdr

Added:
    commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h   (with props)
    commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h   (with props)
    commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
    commons/sandbox/runtime/trunk/src/main/native/configure
    commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw
    commons/sandbox/runtime/trunk/src/main/native/shared/string.c

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Wed May  4 13:34:13 2011
@@ -118,6 +118,7 @@ LIBSOURCES=\
 	$(TOPDIR)\shared\iofd.c \
 	$(TOPDIR)\shared\memory.c \
 	$(TOPDIR)\shared\native.c \
+	$(TOPDIR)\shared\netaddr.c \
 	$(TOPDIR)\shared\pointer.c \
 	$(TOPDIR)\shared\psock.c \
 	$(TOPDIR)\shared\psockimpl.c \

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in Wed May  4 13:34:13 2011
@@ -111,6 +111,7 @@ LIBSOURCES=\
 	$(TOPDIR)/shared/iofd.c \
 	$(TOPDIR)/shared/memory.c \
 	$(TOPDIR)/shared/native.c \
+	$(TOPDIR)/shared/netaddr.c \
 	$(TOPDIR)/shared/pointer.c \
 	$(TOPDIR)/shared/psock.c \
 	$(TOPDIR)/shared/psockimpl.c \

Modified: commons/sandbox/runtime/trunk/src/main/native/configure
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/configure (original)
+++ commons/sandbox/runtime/trunk/src/main/native/configure Wed May  4 13:34:13 2011
@@ -1086,6 +1086,35 @@ EOF
     echo $rc
 }
 
+have_working_getnameinfo()
+{
+    do_printf 'Checking for %-32s' "working getnameinfo"
+    cat > $cccsrc.c << EOF
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+int rc = 0;
+int main(void) {
+    struct sockaddr_in sa;
+    char hbuf[256];
+    int error;
+    sa.sin_family = AF_INET;
+    sa.sin_port = 0;
+    sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+#ifdef SIN6_LEN
+    sa.sin_len = sizeof(sa);
+#endif
+    if (getnameinfo((const struct sockaddr *)&sa, sizeof(sa),
+                    hbuf, 256, NULL, 0, NI_NUMERICHOST) == 0) rc=1;
+    printf("%d", rc);return 0;
+}
+EOF
+    rc=`test_compile z 0`
+    echo $rc
+}
+
 check_sizeof()
 {
     do_printf 'Checking for sizeof %-25s' "$1"
@@ -1258,6 +1287,7 @@ extern "C" {
 #define HAVE_SYS_SIGNALFD_H     `have_include sys/signalfd`
 #define HAVE_SYS_INOTIFY_H      `have_include sys/inotify`
 #define HAVE_SYS_TIME_H         `have_include sys/time`
+#define HAVE_SYS_UN_H           `have_include sys/un`
 #define HAVE_LIMITS_H           `have_include limits`
 #define HAVE_NETDB_H            `have_include netdb`
 #define HAVE_NETINET_IN_H       `have_include netinet/in`
@@ -1340,6 +1370,7 @@ extern "C" {
 #define HAVE_STRTOULL           `have_function x strtoull`
 #define HAVE_STRTONUM           `have_function x strtonum`
 #define HAVE_SHM_OPEN           `have_function x shm_open`
+#define HAVE_GETNAMEINFO        `have_working_getnameinfo`
 #define HAVE_GETHOSTBYADDR_R    `have_function x gethostbyaddr_r`
 #define HAVE_GETHOSTBYNAME2     `have_function x gethostbyname2`
 #define HAVE_GETHOSTBYNAME_R    `have_function x gethostbyname_r`
@@ -1363,6 +1394,7 @@ extern "C" {
 #define HAVE_INTPTR_T           `have_typedef intptr_t`
 #define HAVE_UINTPTR_T          `have_typedef uintptr_t`
 #define HAVE_UNION_SEMUN        `have_typedef 'union semun' sys/sem`
+#define HAVE_SOCKADDR_STORAGE   `have_typedef 'struct sockaddr_storage' netinet/in`
 #define HAVE_PRETTY_FUNCTION    `have_defined __PRETTY_FUNCTION__`
 #define HAVE_FUNCTION           `have_defined __FUNCTION__`
 #define HAVE_FUNCSIG            `have_defined __FUNCSIG__`

Added: commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h?rev=1099442&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h Wed May  4 13:34:13 2011
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011 The MyoMake Project <http://www.myomake.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _ACR_NETAPI_H_
+#define _ACR_NETAPI_H_
+
+#include "acr/stdtypes.h"
+#include "acr/netdefs.h"
+
+typedef struct acr_sockaddr_t acr_sockaddr_t;
+struct acr_sockaddr_t {
+    /** The hostname */
+    char       hostname[256];
+    /** Either a string of the port number or the service name for the port */
+    char       servname[256];
+    /** The numeric port */
+    int         port;
+    /** The family */
+    int         family;
+    /** How big is the sockaddr we're using? */
+    int         salen;
+    /** How big is the ip address structure we're using? */
+    int         iplen;
+    /** How big should the address buffer be?  16 for v4 or 46 for v6
+     *  used in inet_ntop... */
+    int         addrlen;
+    /** This points to the IP address structure within the appropriate
+     *  sockaddr structure.  */
+    void       *ipaddr;
+    /** If multiple addresses were found by AcrGetSockaddrInfo(), this
+     *  points to a representation of the next address. */
+    acr_sockaddr_t *next;
+    /** Union of either IPv4 or IPv6 sockaddr. */
+    union {
+        /** IPv4 sockaddr structure */
+        struct sockaddr_in      sin;
+        /** IPv6 sockaddr structure */
+        struct sockaddr_in6     sin6;
+#if HAVE_SOCKADDR_STORAGE
+        /** Placeholder to ensure that the size of this union is not
+         * dependent on whether APR_HAVE_IPV6 is defined. */
+        struct sockaddr_storage sas;
+#endif
+#if HAVE_SYS_UN_H
+        /** Unix domain socket sockaddr structure */
+        struct sockaddr_un      unx;
+#endif
+    } sa;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ACR_NETAPI_H_ */

Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h?rev=1099442&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h Wed May  4 13:34:13 2011
@@ -0,0 +1,58 @@
+/* Copyright (c) 2011 The MyoMake Project <http://www.myomake.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _ACR_NETDEFS_H_
+#define _ACR_NETDEFS_H_
+
+#if HAVE_SYS_UN_H
+# if !defined(AF_LOCAL)
+#  if defined(AF_UNIX)
+#   define AF_LOCAL      AF_UNIX
+#  else
+#   error "Neither AF_UNIX nor AF_LOCAL is defined"
+#  endif
+# endif
+#else
+# define AF_LOCAL        127
+#endif
+
+#if !defined(AF_UNSPEC)
+# define AF_UNSPEC   0
+#endif
+
+#if !defined(INADDR_NONE)
+# define INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ   16
+#endif
+#ifndef INADDRSZ
+#define INADDRSZ     4
+#endif
+#ifndef INT16SZ
+#define INT16SZ      2
+#endif
+
+#if !defined(EAFNOSUPPORT) && defined(WSAEAFNOSUPPORT)
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#endif
+
+#define ACR_IPV4_ADDR_OK  0x01
+#define ACR_IPV6_ADDR_OK  0x02
+
+
+#endif /* _ACR_IODEFS_H */

Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h Wed May  4 13:34:13 2011
@@ -225,6 +225,11 @@ wchar_t *
 AcrGetNativePathW(JNI_STDENV, jstring str, wchar_t *b);
 #endif
 
+/** Convert n to string
+ * buf must be of size 16
+ */
+char *AcrItoa(char *buf, int n);
+
 #ifdef __cplusplus
 }
 #endif

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw Wed May  4 13:34:13 2011
@@ -28,6 +28,7 @@
 #define HAVE_SYS_SIGNALFD_H     0
 #define HAVE_SYS_INOTIFY_H      0
 #define HAVE_SYS_TIME_H         0
+#define HAVE_SYS_UN_H           0
 #define HAVE_LIMITS_H           1
 #define HAVE_NETDB_H            0
 #define HAVE_NETINET_IN_H       0
@@ -131,6 +132,7 @@
 #define HAVE_INTPTR_T           1
 #define HAVE_UINTPTR_T          1
 #define HAVE_UNION_SEMUN        0
+#define HAVE_SOCKADDR_STORAGE   1
 #define HAVE_PRETTY_FUNCTION    0
 #define HAVE_FUNCTION           1
 #define HAVE_FUNC               0

Added: commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c?rev=1099442&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Wed May  4 13:34:13 2011
@@ -0,0 +1,721 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *
+ * @author Mladen Turk
+ */
+
+#include "acr/netapi.h"
+#include "acr/memory.h"
+#include "acr/string.h"
+#include "acr/port.h"
+
+#define V4MAPPED_EQUAL(a,b)                                             \
+    ((a)->sa.sin.sin_family == AF_INET &&                               \
+     (b)->sa.sin.sin_family == AF_INET6 &&                              \
+     IN6_IS_ADDR_V4MAPPED((struct in6_addr *)(b)->ipaddr) &&            \
+     memcmp((a)->ipaddr,                                                \
+            &((struct in6_addr *)(b)->ipaddr)->s6_addr[12],             \
+            (a)->iplen) == 0)
+
+#if !defined(WINDOWS)
+# if defined(HAVE_SET_H_ERRNO)
+#  define SET_H_ERRNO(newval) set_h_errno(newval)
+# else
+#  define SET_H_ERRNO(newval) h_errno = (newval)
+# endif
+#else
+# define SET_H_ERRNO(newval)
+#endif
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *      format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *      `dst' (as a const)
+ * notes:
+ *      (1) uses no statics
+ *      (2) takes a u_char* not an in_addr as input
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, int size)
+{
+    int MIN_SIZE = 16; /* space for 255.255.255.255\0 */
+    int n = 0;
+    char *next = dst;
+
+    if (size < MIN_SIZE) {
+        ACR_SET_OS_ERROR(ACR_ENOSPC);
+        return 0;
+    }
+    do {
+        unsigned char u = *src++;
+        if (u > 99) {
+            *next++ = '0' + u/100;
+            u %= 100;
+            *next++ = '0' + u/10;
+            u %= 10;
+        }
+        else if (u > 9) {
+            *next++ = '0' + u/10;
+            u %= 10;
+        }
+        *next++ = '0' + u;
+        *next++ = '.';
+        n++;
+    } while (n < 4);
+    *--next = 0;
+    return dst;
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *      convert IPv6 binary address into presentation (printable) format
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, int size)
+{
+    /*
+     * Note that int32_t and int16_t need only be "at least" large enough
+     * to contain a value of the specified size.  On some systems, like
+     * Crays, there is no such thing as an integer variable with 16 bits.
+     * Keep this in mind if you think this function should have been coded
+     * to use pointer overlays.  All the world's not a VAX.
+     */
+    char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
+    struct { int base, len; } best = {-1, 0}, cur = {-1, 0};
+    unsigned int words[IN6ADDRSZ / INT16SZ];
+    int i;
+    const unsigned char *next_src, *src_end;
+    unsigned int *next_dest;
+
+    /*
+     * Preprocess:
+     *  Copy the input (bytewise) array into a wordwise array.
+     *  Find the longest run of 0x00's in src[] for :: shorthanding.
+     */
+    next_src = src;
+    src_end = src + IN6ADDRSZ;
+    next_dest = words;
+    i = 0;
+    do {
+        unsigned int next_word = (unsigned int)*next_src++;
+        next_word <<= 8;
+        next_word |= (unsigned int)*next_src++;
+        *next_dest++ = next_word;
+
+        if (next_word == 0) {
+            if (cur.base == -1) {
+                cur.base = i;
+                cur.len = 1;
+            }
+            else {
+                cur.len++;
+            }
+        } else {
+            if (cur.base != -1) {
+                if (best.base == -1 || cur.len > best.len) {
+                    best = cur;
+                }
+                cur.base = -1;
+            }
+        }
+
+        i++;
+    } while (next_src < src_end);
+
+    if (cur.base != -1) {
+        if (best.base == -1 || cur.len > best.len) {
+            best = cur;
+        }
+    }
+    if (best.base != -1 && best.len < 2) {
+        best.base = -1;
+    }
+
+    /*
+     * Format the result.
+     */
+    tp = tmp;
+    for (i = 0; i < (IN6ADDRSZ / INT16SZ);) {
+        /* Are we inside the best run of 0x00's? */
+        if (i == best.base) {
+            *tp++ = ':';
+            i += best.len;
+            continue;
+        }
+        /* Are we following an initial run of 0x00s or any real hex? */
+        if (i != 0) {
+            *tp++ = ':';
+        }
+        /* Is this address an encapsulated IPv4? */
+        if (i == 6 && best.base == 0 &&
+            (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+            if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
+                return 0;
+            }
+            tp += strlen(tp);
+            break;
+        }
+        tp += snprintf(tp, sizeof(tmp) - (tp - tmp), "%x", words[i]);
+        i++;
+    }
+    /* Was it a trailing run of 0x00's? */
+    if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
+        *tp++ = ':';
+    }
+    *tp++ = '\0';
+
+    /*
+     * Check for overflow, copy, and we're done.
+     */
+    if ((int)(tp - tmp) > size) {
+        ACR_SET_OS_ERROR(ACR_ENOSPC);
+        return 0;
+    }
+    strcpy(dst, tmp);
+    return dst;
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *      like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *      1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *      does not touch `dst' unless it's returning 1.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst)
+{
+    static const char digits[] = "0123456789";
+    int saw_digit, octets, ch;
+    unsigned char tmp[INADDRSZ], *tp;
+
+    saw_digit = 0;
+    octets = 0;
+    *(tp = tmp) = 0;
+    while ((ch = *src++) != '\0') {
+        const char *pch;
+
+        if ((pch = strchr(digits, ch)) != 0) {
+            unsigned int new = *tp * 10 + (unsigned int)(pch - digits);
+
+            if (new > 255)
+                return 0;
+            *tp = new;
+            if (! saw_digit) {
+                if (++octets > 4)
+                    return 0;
+                saw_digit = 1;
+            }
+        } else if (ch == '.' && saw_digit) {
+            if (octets == 4)
+                return 0;
+            *++tp = 0;
+            saw_digit = 0;
+        } else
+                return 0;
+    }
+    if (octets < 4)
+        return 0;
+
+    memcpy(dst, tmp, 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.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst)
+{
+    static const char xdigits_l[] = "0123456789abcdef",
+                        xdigits_u[] = "0123456789ABCDEF";
+    unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+    const char *xdigits, *curtok;
+    int ch, saw_xdigit;
+    unsigned int val;
+
+    memset((tp = tmp), '\0', IN6ADDRSZ);
+    endp   = tp + IN6ADDRSZ;
+    colonp = 0;
+    /* 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)) == 0)
+            pch = strchr((xdigits = xdigits_u), ch);
+        if (pch != 0) {
+            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;
+            }
+            if (tp + INT16SZ > endp)
+                return 0;
+            *tp++ = (unsigned char) (val >> 8) & 0xff;
+            *tp++ = (unsigned char) val & 0xff;
+            saw_xdigit = 0;
+            val = 0;
+            continue;
+        }
+        if (ch == '.' && ((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 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++ = (unsigned char) (val >> 8) & 0xff;
+        *tp++ = (unsigned char) val & 0xff;
+    }
+    if (colonp != 0) {
+        /*
+         * Since some memmove()'s erroneously fail to handle
+         * overlapping regions, we'll do the shift by hand.
+         */
+        int n = (int)(tp - colonp);
+        int i;
+
+        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;
+}
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ *      convert a network format address to presentation format.
+ * return:
+ *      pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *      Paul Vixie, 1996.
+ */
+const char *
+AcrInetNtop(int af, const void *src, char *dst, int size)
+{
+    switch (af) {
+        case AF_INET:
+            return inet_ntop4(src, dst, size);
+        case AF_INET6:
+            return inet_ntop6(src, dst, size);
+        default:
+            ACR_SET_OS_ERROR(EAFNOSUPPORT);
+            return 0;
+    }
+    /* NOTREACHED */
+}
+
+int
+AcrInetPton(int af, const char *src, void *dst)
+{
+    switch (af) {
+        case AF_INET:
+            return inet_pton4(src, dst);
+        case AF_INET6:
+            return inet_pton6(src, dst);
+        default:
+            ACR_SET_OS_ERROR(EAFNOSUPPORT);
+            return -1;
+    }
+    /* NOTREACHED */
+}
+
+
+static void
+sockaddr_vars_set(acr_sockaddr_t *addr, int family, int port)
+{
+    addr->family            = family;
+    addr->sa.sin.sin_family = family;
+
+    if (port > 0) {
+        /* XXX IPv6: assumes sin_port and sin6_port at same offset */
+        addr->sa.sin.sin_port = htons(port);
+        addr->port = port;
+    }
+    if (family == AF_INET) {
+        addr->salen   = ISIZEOF(struct sockaddr_in);
+        addr->addrlen = 16;
+        addr->ipaddr  = &(addr->sa.sin.sin_addr);
+        addr->iplen   = sizeof(struct in_addr);
+    }
+    else if (family == AF_INET6) {
+        addr->salen   = ISIZEOF(struct sockaddr_in6);
+        addr->addrlen = 46;
+        addr->ipaddr  = &(addr->sa.sin6.sin6_addr);
+        addr->iplen   = sizeof(struct in6_addr);
+    }
+#if HAVE_SYS_UN_H
+    else if (family == AF_LOCAL) {
+        addr->salen   = ISIZEOF(struct sockaddr_un);
+        addr->addrlen = ISIZEOF(addr->sa.unx.sun_path);;
+        addr->ipaddr  = &(addr->sa.unx.sun_path);
+        addr->iplen   = addr->addrlen;
+    }
+#endif
+}
+
+static int
+call_resolver(acr_sockaddr_t **sa, const char *hostname,
+              int family, int port, int flags)
+{
+    struct addrinfo hints, *ai, *ai_list;
+    acr_sockaddr_t *prev_sa;
+    int error;
+    char *servname = 0;
+    char buf[16];
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = family;
+    hints.ai_socktype = SOCK_STREAM;
+#if defined(AI_ADDRCONFIG)
+    if (family == AF_UNSPEC) {
+        /* By default, only look up addresses using address types for
+         * which a local interface is configured, i.e. no IPv6 if no
+         * IPv6 interfaces configured. */
+        hints.ai_flags = AI_ADDRCONFIG;
+    }
+#endif
+    if(hostname == 0) {
+#if defined(AI_PASSIVE)
+        /* If hostname is NULL, assume we are trying to bind to all
+         * interfaces. */
+        hints.ai_flags |= AI_PASSIVE;
+#endif
+        /* getaddrinfo according to RFC 2553 must have either hostname
+         * or servname non-NULL.
+         */
+        servname = AcrItoa(buf, port);
+    }
+    error = getaddrinfo(hostname, servname, &hints, &ai_list);
+#if defined(AI_ADDRCONFIG)
+    if (error == EAI_BADFLAGS && family == AF_UNSPEC) {
+        /* Retry with no flags if AI_ADDRCONFIG was rejected. */
+        hints.ai_flags = 0;
+        error = getaddrinfo(hostname, servname, &hints, &ai_list);
+    }
+#endif
+    if (error) {
+#if defined(WINDOWS)
+        return ACR_GET_NETOS_ERROR();
+#else
+        if (error == EAI_SYSTEM) {
+            return errno;
+        }
+        else
+        {
+            /* issues with representing this with APR's error scheme:
+             * glibc uses negative values for these numbers, perhaps so
+             * they don't conflict with h_errno values...  Tru64 uses
+             * positive values which conflict with h_errno values
+             */
+#if defined(NEGATIVE_EAI)
+            error = -error;
+#endif
+            return error + ACR_OS_START_EAIERR;
+        }
+#endif /* WIN32 */
+    }
+
+    prev_sa = NULL;
+    ai = ai_list;
+
+    while (ai) { /* while more addresses to report */
+        acr_sockaddr_t *new_sa;
+
+        /* Ignore anything bogus: getaddrinfo in some old versions of
+         * glibc will return AF_LOCAL entries for APR_UNSPEC+AI_PASSIVE
+         * lookups. */
+        if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
+            ai = ai->ai_next;
+            continue;
+        }
+
+        new_sa = calloc(1, sizeof(acr_sockaddr_t));
+        if (new_sa == 0)
+            return ACR_ENOMEM;
+        memcpy(&new_sa->sa, ai->ai_addr, ai->ai_addrlen);
+        sockaddr_vars_set(new_sa, ai->ai_family, port);
+
+        if (!prev_sa) { /* first element in new list */
+            if (hostname != 0)
+                strlcpy(new_sa->hostname, hostname, 256);
+            *sa = new_sa;
+        }
+        else {
+            strlcpy(new_sa->hostname, prev_sa->hostname, 256);
+            prev_sa->next = new_sa;
+        }
+
+        prev_sa = new_sa;
+        ai = ai->ai_next;
+    }
+    freeaddrinfo(ai_list);
+    return 0;
+}
+
+static int
+find_addresses(acr_sockaddr_t **sa, const char *hostname,
+               int family, int port, int flags)
+{
+    if (flags & ACR_IPV4_ADDR_OK) {
+        int rc = call_resolver(sa, hostname, AF_INET, port, flags);
+        if (rc != 0)
+            family = AF_INET6; /* try again */
+        else
+            return 0;
+    }
+    else if (flags & ACR_IPV6_ADDR_OK) {
+        int rc = call_resolver(sa, hostname, AF_INET6, port, flags);
+        if (rc != 0)
+            family = AF_INET;  /* try again */
+        else
+            return 0;
+    }
+    return call_resolver(sa, hostname, family, port, flags);
+}
+
+int
+AcrGetSockaddrInfo(acr_sockaddr_t **sa, const char *hostname,
+                   int family, int port, int flags)
+{
+    int masked;
+    *sa = 0;
+
+    if ((masked = flags & (ACR_IPV4_ADDR_OK | ACR_IPV6_ADDR_OK))) {
+        if (hostname == 0 || family != AF_UNSPEC ||
+            masked == (ACR_IPV4_ADDR_OK | ACR_IPV6_ADDR_OK)) {
+            return ACR_EINVAL;
+        }
+    }
+    if (family == AF_UNSPEC && hostname != 0 && *hostname == '/')
+        family = AF_LOCAL;
+    if (family == AF_LOCAL) {
+        if (hostname != 0) {
+#if HAVE_SYS_UN_H
+            *sa = calloc(1, sizeof(acr_sockaddr_t));
+            if (*sa == 0)
+                return ACR_ENOMEM;
+            strlcpy((*sa)->sa.unx.sun_path, hostname, sizeof((*sa)->sa.unx.sun_path));
+            strlcpy((*sa)->hostname, hostname, sizeof((*sa)->hostname));
+            (*sa)->sa.unx.sun_family = AF_LOCAL;
+            (*sa)->family  = AF_LOCAL;
+            (*sa)->salen   = ISIZEOF(struct sockaddr_un);
+            (*sa)->addrlen = ISIZEOF((*sa)->sa.unx.sun_path);
+            (*sa)->ipaddr  = &((*sa)->sa.unx.sun_path);
+            (*sa)->iplen   = (*sa)->addrlen;
+            return 0;
+#elif defined(WINDOWS)
+            *sa = calloc(1, sizeof(acr_sockaddr_t));
+            if (*sa == 0)
+                return ACR_ENOMEM;
+            strlcpy((*sa)->hostname, hostname, sizeof((*sa)->hostname));
+            (*sa)->family  = AF_LOCAL;
+            (*sa)->addrlen = ISIZEOF((*sa)->hostname);
+            (*sa)->ipaddr  = &((*sa)->hostname);
+            (*sa)->iplen   = (*sa)->addrlen;
+            return 0;
+#else
+            *sa = 0;
+            return ACR_ENOTIMPL;
+#endif
+        }
+        else {
+            *sa = 0;
+            return ACR_EINVAL;
+        }
+    }
+    return find_addresses(sa, hostname, family, port, flags);
+}
+
+int
+AcrIsSockaddrEqual(const acr_sockaddr_t *addr1,
+                   const acr_sockaddr_t *addr2)
+{
+    if (addr1->iplen == addr2->iplen &&
+        !memcmp(addr1->ipaddr, addr2->ipaddr, addr1->iplen)) {
+        return 1;
+    }
+    if (V4MAPPED_EQUAL(addr1, addr2))
+        return 1;
+    if (V4MAPPED_EQUAL(addr2, addr1))
+        return 1;
+    return 0; /* not equal */
+}
+
+#define GETHOSTBYNAME_BUFLEN 512
+
+int
+AcrGetNameInfo(char **hostname, acr_sockaddr_t *sockaddr, int flags)
+{
+#if defined(HAVE_GETNAMEINFO)
+    int rc;
+#if !defined(NI_MAXHOST)
+# define NI_MAXHOST 256
+#endif
+    char tmphostname[NI_MAXHOST];
+
+    /* don't know if it is portable for getnameinfo() to set h_errno;
+     * clear it then see if it was set */
+    SET_H_ERRNO(0);
+
+    /* default flags are NI_NAMREQD; otherwise, getnameinfo() will return
+     * a numeric address string if it fails to resolve the host name;
+     * that is *not* what we want here
+     *
+     * For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling
+     * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc).
+     */
+    if (sockaddr->family == AF_INET6 &&
+        IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
+        struct sockaddr_in tmpsa;
+        tmpsa.sin_family = AF_INET;
+        tmpsa.sin_port   = 0;
+        tmpsa.sin_addr.s_addr = ((acr_u32_t *)sockaddr->ipaddr)[3];
+#ifdef SIN6_LEN
+        tmpsa.sin_len    = sizeof(tmpsa);
+#endif
+
+        rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
+                         tmphostname, NI_MAXHOST, NULL, 0,
+                         flags != 0 ? flags : NI_NAMEREQD);
+    }
+    else if (sockaddr->family == AF_UNIX) {
+        *hostname = sockaddr->hostname;
+        return 0;
+    }
+    else
+        rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
+                         tmphostname, NI_MAXHOST, NULL, 0,
+                         flags != 0 ? flags : NI_NAMEREQD);
+    if (rc != 0) {
+        *hostname = 0;
+
+#if !defined(WINDOWS)
+        /* something went wrong. Look at the EAI_ error code */
+        if (rc == EAI_SYSTEM) {
+            /* EAI_SYSTEM      System error returned in errno. */
+            /* IMHO, Implementations that set h_errno a simply broken. */
+            if (h_errno) /* for broken implementations which set h_errno */
+                return h_errno + ACR_OS_START_SYSERR;
+            else /* "normal" case */
+                return errno + ACR_OS_START_SYSERR;
+        }
+        else
+#endif
+        {
+#if defined(NEGATIVE_EAI)
+            if (rc < 0) rc = -rc;
+#endif
+            return rc + ACR_OS_START_EAIERR; /* return the EAI_ error */
+        }
+    }
+    strlcpy(sockaddr->hostname, tmphostname, 256);
+    *hostname = sockaddr->hostname;
+    return 0;
+#else
+/* XXX: Do we need the following block
+ */
+#if HAVE_GETHOSTBYADDR_R
+    char tmp[GETHOSTBYNAME_BUFLEN];
+    int hosterror;
+    struct hostent hs, *hptr;
+
+#if defined(HPUX) || defined(AIX)
+    /* AIX, HP/UX, D/UX et alia */
+    gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+                  sizeof(struct in_addr), AF_INET, &hs, &hd);
+    hptr = &hs;
+#else
+#if defined(LINUX)
+    /* Linux glibc2+ */
+    gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+                    sizeof(struct in_addr), AF_INET,
+                    &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hptr, &hosterror);
+#else
+    /* Solaris, Irix et alia */
+    hptr = gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+                           sizeof(struct in_addr), AF_INET,
+                           &hs, tmp, GETHOSTBYNAME_BUFLEN, &hosterror);
+#endif
+    if (!hptr) {
+        *hostname = 0;
+        return hosterror + ACR_OS_START_SYSERR;
+    }
+#endif
+#else
+    struct hostent *hptr;
+    hptr = gethostbyaddr((char *)&sockaddr->sa.sin.sin_addr,
+                         sizeof(struct in_addr), AF_INET);
+#endif
+
+    if (hptr) {
+        strlcpy(sockaddr->hostname, hptr->h_name, 256);
+        *hostname = sockaddr->hostname;
+        return 0;
+    }
+    *hostname = 0;
+#if defined(WINDOWS)
+    return ACR_GET_NETOS_ERROR();
+#else
+    return h_errno + ACR_OS_START_SYSERR;
+#endif
+#endif
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/string.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/string.c?rev=1099442&r1=1099441&r2=1099442&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Wed May  4 13:34:13 2011
@@ -18,6 +18,25 @@
 #include "acr/clazz.h"
 #include "acr/unsafe.h"
 
+#define NCONVSETN()                         \
+    start = buf + BUFFER_SIZE - 1;          \
+    if (n < 0) {                            \
+        negative = 1;                       \
+        n = -n;                             \
+    }                                       \
+    else                                    \
+        negative = 0
+
+#define NCONVSETU()                         \
+    start = buf + BUFFER_SIZE - 1           \
+
+#define NCONVLOOP()                         \
+    *start = '\0';                          \
+    do {                                    \
+        *--start = (char)('0' + (n % 10));  \
+        n /= 10;                            \
+    } while (n)
+
 J_DECLARE_CLAZZ = {
     INVALID_FIELD_BASE,
     0,
@@ -1244,6 +1263,20 @@ ACR_JNI_EXPORT(jcharArray, Unsafe, getch
     return 0;
 }
 
+char *AcrItoa(char *buf, int n)
+{
+#define BUFFER_SIZE 16
+    char *start;
+    int   negative;
+
+    NCONVSETN();
+    NCONVLOOP();
+    if (negative)
+        *--start = '-';
+    return start;
+#undef BUFFER_SIZE
+}
+
 #if defined(ENABLE_TEST_PRIVATE)
 
 ACR_JNI_EXPORT(jint, TestString, test0)(JNI_STDARGS, jstring s)