Hack for mswindows without getnameinfo

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25923 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2008-01-10 16:05:41 +00:00
parent 08c85d9f2e
commit b9a02a2c3e
7 changed files with 264 additions and 77 deletions

View file

@ -1,3 +1,14 @@
2008-01-10 Richard Frith-Macdonald <rfm@gnu.org>
* Source/inet_pton.c:
* Source/inet_ntop.c:
* Source/GSNetwork.h:
* Source/GNUmakefile:
* configure.ac:
* configure:
Avoid using mswindows getnameinfo function as it doesn't work for
Riccardo for some reason ... perhaps older mingw32 doesn't have it.
2008-01-10 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSPathUtilities.m: Allow '../' to indicate a relocatable

View file

@ -405,6 +405,9 @@ $(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h
ifeq ($(HAVE_INET_PTON), no)
GNU_CFILES += inet_pton.c
endif
ifeq ($(HAVE_INET_NTOP), no)
GNU_CFILES += inet_ntop.c
endif
# The Objective-C source files to be compiled
libgnustep-base_OBJC_FILES = $(GNU_MFILES) \

View file

@ -77,6 +77,10 @@
#define INADDRSZ 4
#endif
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16
#endif
#ifndef socklen_t
#define socklen_t uint32_t
#endif

220
Source/inet_ntop.c Normal file
View file

@ -0,0 +1,220 @@
/* from NetBSD: inet_pton.c,v 1.16 2000/02/07 18:51:02 itojun Exp */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include "config.h"
#include <ctype.h>
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <errno.h>
#include "GSNetwork.h"
#if HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
#ifndef INT16SZ
#define INT16SZ 2 /* for systems without 16-bit ints */
#endif
/*
* WARNING: 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.
*/
static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
/* 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 *
inet_ntop(af, src, dst, size)
int af;
const void *src;
char *dst;
size_t size;
{
switch (af) {
case AF_INET:
return (inet_ntop4(src, dst, size));
case AF_INET6:
return (inet_ntop6(src, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
/* NOTREACHED */
}
/* 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(src, dst, size)
const u_char *src;
char *dst;
size_t size;
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
int l;
l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
if (l <= 0 || l >= size) {
errno = ENOSPC;
return (NULL);
}
strncpy(dst, tmp, size);
dst[size-1] = '\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(src, dst, size)
const u_char *src;
char *dst;
size_t 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"];
char *tp, *ep;
struct { int base, len; } best, cur;
u_int words[IN6ADDRSZ / INT16SZ];
int i;
int advance;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
if (words[i] == 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;
}
}
}
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;
ep = tmp + sizeof(tmp);
for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base) {
if (tp + 1 >= ep)
return (NULL);
*tp++ = ':';
}
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0) {
if (tp + 1 >= ep)
return (NULL);
*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, (size_t)(ep - tp)))
return (NULL);
tp += strlen(tp);
break;
}
advance = snprintf(tp, ep - tp, "%x", words[i]);
if (advance <= 0 || advance >= ep - tp)
return (NULL);
tp += advance;
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
if (tp + 1 >= ep)
return (NULL);
*tp++ = ':';
}
if (tp + 1 >= ep)
return (NULL);
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size) {
errno = ENOSPC;
return (NULL);
}
strncpy(dst, tmp, size);
dst[size-1] = '\0';
return (dst);
}

View file

@ -27,28 +27,13 @@
#endif
#include <errno.h>
#if defined(__MINGW32__)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wininet.h>
#if !defined(EAFNOSUPPORT)
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "GSNetwork.h"
#if HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
/*
* WARNING: 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.
@ -71,7 +56,7 @@ static int inet_pton6(const char *src, uint8_t *dst);
* Paul Vixie, 1996.
*/
int
inet_pton(int af, const char *src, void *dst)
GSPrivate_pton(int af, const char *src, void *dst)
{
switch (af) {
@ -308,62 +293,3 @@ inet_pton6(const char *src, uint8_t *dst)
#endif
/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by: Richard Frith-Macdoanld <rfm@gnu.org>
Date: January 2008
This is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
The remainder of this file is compatibility code for use under
mswindows (which does not have inet_ntop()).
*/
#if defined(__MINGW32__)
const char *
inet_ntop(int af, const void *src, char *dst, socklen_t len)
{
if (af == AF_INET)
{
struct sockaddr_in in;
memset(&in, '\0', sizeof(in));
in.sin_family = AF_INET;
memcpy(&in.sin_addr, src, sizeof(struct in_addr));
getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in),
dst, len, 0, 0, NI_NUMERICHOST);
return dst;
}
#ifdef AF_INET6
else if (af == AF_INET6)
{
struct sockaddr_in6 in;
memset(&in, '\0', sizeof(in));
in.sin6_family = AF_INET6;
memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6),
dst, len, 0, 0, NI_NUMERICHOST);
return dst;
}
#endif
return 0;
}
#endif

19
configure vendored
View file

@ -719,6 +719,7 @@ DEFINE_INTPTR_T
DEFINE_UINTPTR_T
USE_ZLIB
HAVE_INET_PTON
HAVE_INET_NTOP
GS_PASS_ARGUMENTS
GS_FAKE_MAIN
WITH_FFI
@ -2318,6 +2319,15 @@ case "$target_os" in
GNUSTEP_NETWORK_USERS_DIR="C:\Documents and Settings"
GNUSTEP_LOCAL_USERS_DIR="C:\Documents and Settings"
# TODO: It would be nice to use the 'short' output of
# relative_path.sh, but older versions of relative_path.sh
# did not support specifying the type of output and
# would abort if they were given more than 2 parameters,
# so we can not use the 'short' option if we want gnustep-base
# to work with older versions of gnustep-make.
# Once everyone has upgraded to gnustep-make >= 2.0.5 (I'd say
# two years after it has been released ?), we could switch to the
# 'short' output though.
GNUSTEP_SYSTEM_APPS=`$GNUSTEP_MAKEFILES/relative_path.sh $GNUSTEP_BASE_PATH $GNUSTEP_SYSTEM_APPS`
GNUSTEP_SYSTEM_ADMIN_APPS=`$GNUSTEP_MAKEFILES/relative_path.sh $GNUSTEP_BASE_PATH $GNUSTEP_SYSTEM_ADMIN_APPS`
GNUSTEP_SYSTEM_WEB_APPS=`$GNUSTEP_MAKEFILES/relative_path.sh $GNUSTEP_BASE_PATH $GNUSTEP_SYSTEM_WEB_APPS`
@ -13995,6 +14005,12 @@ if test $ac_cv_func_inet_pton = yes ; then
fi
HAVE_INET_NTOP=no
if test $ac_cv_func_inet_ntop = yes ; then
HAVE_INET_NTOP=yes
fi
#--------------------------------------------------------------------
# One of these function needed by NSThread.m
#--------------------------------------------------------------------
@ -19346,6 +19362,7 @@ DEFINE_INTPTR_T!$DEFINE_INTPTR_T$ac_delim
DEFINE_UINTPTR_T!$DEFINE_UINTPTR_T$ac_delim
USE_ZLIB!$USE_ZLIB$ac_delim
HAVE_INET_PTON!$HAVE_INET_PTON$ac_delim
HAVE_INET_NTOP!$HAVE_INET_NTOP$ac_delim
GS_PASS_ARGUMENTS!$GS_PASS_ARGUMENTS$ac_delim
GS_FAKE_MAIN!$GS_FAKE_MAIN$ac_delim
WITH_FFI!$WITH_FFI$ac_delim
@ -19373,7 +19390,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 34; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 35; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View file

@ -1572,6 +1572,12 @@ if test $ac_cv_func_inet_pton = yes ; then
fi
AC_SUBST(HAVE_INET_PTON)
HAVE_INET_NTOP=no
if test $ac_cv_func_inet_ntop = yes ; then
HAVE_INET_NTOP=yes
fi
AC_SUBST(HAVE_INET_NTOP)
#--------------------------------------------------------------------
# One of these function needed by NSThread.m
#--------------------------------------------------------------------