summaryrefslogtreecommitdiff
path: root/src/port
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2009-03-29 16:46:46 +0200
committerAndreas Baumann <abaumann@yahoo.com>2009-03-29 16:46:46 +0200
commit0b6f512e8e37935481de1d11b90c739070cb2565 (patch)
treea7499b355003f3f6d081fe6d7cc1132bc0fe96f7 /src/port
parentcb1119666a3a4273fa53743837b2e13f6730bc10 (diff)
downloadwolfbones-0b6f512e8e37935481de1d11b90c739070cb2565.tar.gz
wolfbones-0b6f512e8e37935481de1d11b90c739070cb2565.tar.bz2
added stub implementation of getaddrinfo on Cygwin
Diffstat (limited to 'src/port')
-rwxr-xr-xsrc/port/getaddrinfo.c165
-rwxr-xr-xsrc/port/getaddrinfo.h247
-rw-r--r--src/port/netdb.c3
3 files changed, 413 insertions, 2 deletions
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
new file mode 100755
index 0000000..558cb9e
--- /dev/null
+++ b/src/port/getaddrinfo.c
@@ -0,0 +1,165 @@
+/*
+ Copyright (C) 2008 Andreas Baumann <abaumann@yahoo.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "port/getaddrinfo.h"
+
+#if !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO
+
+#include "port/string.h" /* for memset, memcpy */
+#include "port/stdlib.h" /* for atoi, malloc, free, NULL */
+
+#include <netinet/in.h> /* for struct sockaddr_in */
+
+int wolf_port_getaddrinfo( const char *host_name,
+ const char *service_name,
+ const struct wolf_port_addrinfo *hintp,
+ struct wolf_port_addrinfo **result ) {
+ struct wolf_port_addrinfo *ai;
+ struct sockaddr_in sin,
+ *psin;
+ struct wolf_port_addrinfo hints;
+
+ if( hintp == NULL ) {
+ memset( &hints, 0, sizeof( struct wolf_port_addrinfo ) );
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ } else {
+ memcpy( &hints, hintp, sizeof( struct wolf_port_addrinfo ) );
+ }
+
+ if( hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC ) {
+ return EAI_FAMILY;
+ }
+
+ if( hints.ai_socktype == 0 ) {
+ hints.ai_socktype = SOCK_STREAM;
+ }
+
+ if( ( host_name == NULL ) && ( service_name == NULL ) ) {
+ return EAI_NONAME;
+ }
+
+ memset( &sin, 0, sizeof( struct sockaddr_in) );
+
+ sin.sin_family = AF_INET;
+
+ if( host_name != NULL ) {
+ if( host_name[0] == '\0' ) {
+ sin.sin_addr.s_addr = htonl( INADDR_ANY );
+ } else if( hints.ai_flags & AI_NUMERICHOST ) {
+ if( !inet_aton( host_name, &sin.sin_addr ) ) {
+ return EAI_FAIL;
+ }
+ } else {
+ struct hostent *hp;
+
+ hp = gethostbyname( host_name );
+
+ if( hp == NULL ) {
+ switch( h_errno ) {
+ case HOST_NOT_FOUND:
+ case NO_DATA:
+ return EAI_NONAME;
+
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+
+ case NO_RECOVERY:
+ default:
+ return EAI_FAIL;
+ }
+ }
+
+ if( hp->h_addrtype != AF_INET ) {
+ return EAI_FAIL;
+ }
+
+ memcpy( &(sin.sin_addr), hp->h_addr, hp->h_length );
+ }
+ } else {
+ if( hints.ai_flags & AI_PASSIVE ) {
+ sin.sin_addr.s_addr = htonl( INADDR_ANY );
+ } else {
+ sin.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
+ }
+ }
+
+ if( service_name != NULL ) {
+ sin.sin_port = htons( (unsigned short)atoi( service_name ) );
+ }
+
+ ai = (struct wolf_port_addrinfo *)malloc( sizeof( struct wolf_port_addrinfo ) );
+ if( ai == NULL ) {
+ return EAI_MEMORY;
+ }
+
+ psin = (struct sockaddr_in *)malloc( sizeof( struct sockaddr_in ) );
+ if (!psin)
+ {
+ free(ai);
+ return EAI_MEMORY;
+ }
+
+ memcpy( psin, &sin, sizeof( struct sockaddr_in ) );
+
+ ai->ai_flags = 0;
+ ai->ai_family = AF_INET;
+ ai->ai_socktype = hints.ai_socktype;
+ ai->ai_protocol = hints.ai_protocol;
+ ai->ai_addrlen = sizeof(*psin);
+ ai->ai_addr = (struct sockaddr *) psin;
+ ai->ai_canonname = NULL;
+ ai->ai_next = NULL;
+
+ *result = ai;
+
+ return 0;
+}
+
+void wolf_port_freeaddrinfo( struct wolf_port_addrinfo *result ) {
+ /* stub doesn't have more than one element in list, adapt if you change that! */
+ if( result != NULL ) {
+ if( result->ai_addr != NULL ) {
+ free( result->ai_addr );
+ }
+ free( result );
+ }
+}
+
+const char *wolf_port_gai_strerror( int errcode ) {
+ switch( errcode ) {
+ case EAI_NONAME:
+ return "host nor service provided, or not known";
+
+ case EAI_AGAIN:
+ return "temporary failure in name resolution";
+
+ case EAI_FAIL:
+ return "non-recoverable failure in name resultion";
+
+ case EAI_FAMILY:
+ return "socket family not supported";
+
+ case EAI_MEMORY:
+ return "memory allocation failure";
+
+ default:
+ return "Unknown GAI error";
+ }
+}
+
+#endif /* !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO */
diff --git a/src/port/getaddrinfo.h b/src/port/getaddrinfo.h
new file mode 100755
index 0000000..2177afa
--- /dev/null
+++ b/src/port/getaddrinfo.h
@@ -0,0 +1,247 @@
+/*
+ Copyright (C) 2008 Andreas Baumann <abaumann@yahoo.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Bases on ideas found in:
+ *
+ * Postgres src/port/getaddrinfo.c, Copyright (c) 2003-2008, PostgreSQL Global Development Group
+ * Unix Stevens Network Programming, libgai implementation in unpv12e
+ *
+ * At least Windows 2000 and Cygwin don't know getaddrinfo..
+ */
+
+#ifndef __GETADDRINFO_H
+#define __GETADDRINFO_H
+
+#include "port/sys_internal.h"
+
+/* for errors returned by getaddrinfo */
+#if !defined EAI_NONAME
+#define EAI_NONAME -2 /**< NAME or SERVICE is unknown */
+#define EAI_AGAIN -3 /**< temporary failure in name resolution */
+#define EAI_FAIL -4 /**< non-recoverable failure in name resultion */
+#define EAI_FAMILY -6 /**< socket family not supported */
+#define EAI_MEMORY -10 /**< memory allocation failure */
+#endif
+
+/* for ai_flags */
+#if !defined AI_PASSIVE
+#define AI_PASSIVE 1 /**< socket is intended for bind() + listen() */
+#define AI_CANONNAME 2 /**< return canonical name */
+#define AI_NUMERICHOST 4 /**< don't use name resolution */
+#endif
+
+#if !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO
+struct wolf_port_addrinfo
+{
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct wolf_port_addrinfo *ai_next;
+};
+
+extern int wolf_port_getaddrinfo( const char *host_name,
+ const char *service_name,
+ const struct wolf_port_addrinfo *hints,
+ struct wolf_port_addrinfo **result );
+
+extern void wolf_port_freeaddrinfo( struct wolf_port_addrinfo *result );
+extern const char *wolf_port_gai_strerror( int errcode );
+
+#if !defined HAVE_GETADDRINFO
+#define addrinfo wolf_port_addrinfo
+#define getaddrinfo( host_name, service_name, hints, result ) wolf_port_getaddrinfo( host_name, service_name, hints, result )
+#define freeaddrinfo( result ) wolf_port_freeaddrinfo( result )
+#define gai_strerror( errcode ) wolf_port_gai_strerror( errcode )
+#endif
+
+#endif /* !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO */
+
+#endif /* ifndef __GETADDRINFO_H */
+
+#if 0
+
+/*-------------------------------------------------------------------------
+ *
+ * getaddrinfo.h
+ * Support getaddrinfo() on platforms that don't have it.
+ *
+ * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
+ * whether or not the library routine getaddrinfo() can be found. This
+ * policy is needed because on some platforms a manually installed libbind.a
+ * may provide getaddrinfo(), yet the system headers may not provide the
+ * struct definitions needed to call it. To avoid conflict with the libbind
+ * definition in such cases, we rename our routines to pg_xxx() via macros.
+ *
+ * This code will also work on platforms where struct addrinfo is defined
+ * in the system headers but no getaddrinfo() can be located.
+ *
+ * Copyright (c) 2003-2008, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/getaddrinfo.h,v 1.25 2008/01/01 19:45:56 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef GETADDRINFO_H
+#define GETADDRINFO_H
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+
+/* Various macros that ought to be in <netdb.h>, but might not be */
+
+#ifndef EAI_FAIL
+#ifndef WIN32
+#define EAI_BADFLAGS (-1)
+#define EAI_NONAME (-2)
+#define EAI_AGAIN (-3)
+#define EAI_FAIL (-4)
+#define EAI_FAMILY (-6)
+#define EAI_SOCKTYPE (-7)
+#define EAI_SERVICE (-8)
+#define EAI_MEMORY (-10)
+#define EAI_SYSTEM (-11)
+#else /* WIN32 */
+#ifdef WIN32_ONLY_COMPILER
+#ifndef WSA_NOT_ENOUGH_MEMORY
+#define WSA_NOT_ENOUGH_MEMORY (WSAENOBUFS)
+#endif
+#ifndef __BORLANDC__
+#define WSATYPE_NOT_FOUND (WSABASEERR+109)
+#endif
+#endif
+#define EAI_AGAIN WSATRY_AGAIN
+#define EAI_BADFLAGS WSAEINVAL
+#define EAI_FAIL WSANO_RECOVERY
+#define EAI_FAMILY WSAEAFNOSUPPORT
+#define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
+#define EAI_NODATA WSANO_DATA
+#define EAI_NONAME WSAHOST_NOT_FOUND
+#define EAI_SERVICE WSATYPE_NOT_FOUND
+#define EAI_SOCKTYPE WSAESOCKTNOSUPPORT
+#endif /* !WIN32 */
+#endif /* !EAI_FAIL */
+
+#ifndef AI_PASSIVE
+#define AI_PASSIVE 0x0001
+#endif
+
+#ifndef AI_NUMERICHOST
+/*
+ * some platforms don't support AI_NUMERICHOST; define as zero if using
+ * the system version of getaddrinfo...
+ */
+#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
+#define AI_NUMERICHOST 0
+#else
+#define AI_NUMERICHOST 0x0004
+#endif
+#endif
+
+#ifndef NI_NUMERICHOST
+#define NI_NUMERICHOST 1
+#endif
+#ifndef NI_NUMERICSERV
+#define NI_NUMERICSERV 2
+#endif
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+#ifndef NI_MAXSERV
+#define NI_MAXSERV 32
+#endif
+
+
+#ifndef HAVE_STRUCT_ADDRINFO
+
+#ifndef WIN32
+struct addrinfo
+{
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct addrinfo *ai_next;
+};
+#else
+/*
+ * The order of the structure elements on Win32 doesn't match the
+ * order specified in the standard, but we have to match it for
+ * IPv6 to work.
+ */
+struct addrinfo
+{
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfo *ai_next;
+};
+#endif
+#endif /* HAVE_STRUCT_ADDRINFO */
+
+
+#ifndef HAVE_GETADDRINFO
+
+#if 0
+/* Rename private copies per comments above */
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo pg_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo pg_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror pg_gai_strerror
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo pg_getnameinfo
+#endif
+
+
+extern int getaddrinfo(const char *node, const char *service,
+ const struct addrinfo * hints, struct addrinfo ** res);
+extern void freeaddrinfo(struct addrinfo * res);
+extern const char *gai_strerror(int errcode);
+extern int getnameinfo(const struct sockaddr * sa, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen, int flags);
+#endif /* HAVE_GETADDRINFO */
+
+#endif /* GETADDRINFO_H */
+
+#endif
diff --git a/src/port/netdb.c b/src/port/netdb.c
index 3995c5a..1e5b2eb 100644
--- a/src/port/netdb.c
+++ b/src/port/netdb.c
@@ -19,7 +19,6 @@
#if !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO
-void wolf_port_getaddrinfo( void ) {
-}
+#include "port/getaddrinfo.c"
#endif /* !defined HAVE_GETADDRINFO || defined TEST_GETADDRINFO */