symbian-qemu-0.9.1-12/python-2.6.1/Modules/getnameinfo.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Modules/getnameinfo.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked
+ * - Return values.  There seems to be no standard for return value (RFC2133)
+ *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+#if 0
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "addrinfo.h"
+#endif
+
+#define SUCCESS 0
+#define YES 1
+#define NO  0
+
+static struct gni_afd {
+	int a_af;
+	int a_addrlen;
+	int a_socklen;
+	int a_off;
+} gni_afdl [] = {
+#ifdef ENABLE_IPV6
+	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+		offsetof(struct sockaddr_in6, sin6_addr)},
+#endif
+	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+		offsetof(struct sockaddr_in, sin_addr)},
+	{0, 0, 0},
+};
+
+struct gni_sockinet {
+	u_char	si_len;
+	u_char	si_family;
+	u_short	si_port;
+};
+
+#define ENI_NOSOCKET 	0
+#define ENI_NOSERVNAME	1
+#define ENI_NOHOSTNAME	2
+#define ENI_MEMORY	3
+#define ENI_SYSTEM	4
+#define ENI_FAMILY	5
+#define ENI_SALEN	6
+
+/* forward declaration to make gcc happy */
+int getnameinfo Py_PROTO((const struct sockaddr *, size_t, char *, size_t,
+			  char *, size_t, int));
+
+int
+getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+	const struct sockaddr *sa;
+	size_t salen;
+	char *host;
+	size_t hostlen;
+	char *serv;
+	size_t servlen;
+	int flags;
+{
+	struct gni_afd *gni_afd;
+	struct servent *sp;
+	struct hostent *hp;
+	u_short port;
+	int family, len, i;
+	char *addr, *p;
+	u_long v4a;
+#ifdef ENABLE_IPV6
+	u_char pfx;
+#endif
+	int h_error;
+	char numserv[512];
+	char numaddr[512];
+
+	if (sa == NULL)
+		return ENI_NOSOCKET;
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+	len = sa->sa_len;
+	if (len != salen) return ENI_SALEN;
+#else
+	len = salen;
+#endif
+	
+	family = sa->sa_family;
+	for (i = 0; gni_afdl[i].a_af; i++)
+		if (gni_afdl[i].a_af == family) {
+			gni_afd = &gni_afdl[i];
+			goto found;
+		}
+	return ENI_FAMILY;
+	
+ found:
+	if (len != gni_afd->a_socklen) return ENI_SALEN;
+	
+	port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */
+	addr = (char *)sa + gni_afd->a_off;
+
+	if (serv == NULL || servlen == 0) {
+		/* what we should do? */
+	} else if (flags & NI_NUMERICSERV) {
+		sprintf(numserv, "%d", ntohs(port));
+		if (strlen(numserv) > servlen)
+			return ENI_MEMORY;
+		strcpy(serv, numserv);
+	} else {
+		sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
+		if (sp) {
+			if (strlen(sp->s_name) > servlen)
+				return ENI_MEMORY;
+			strcpy(serv, sp->s_name);
+		} else
+			return ENI_NOSERVNAME;
+	}
+
+	switch (sa->sa_family) {
+	case AF_INET:
+		v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+			flags |= NI_NUMERICHOST;
+		v4a >>= IN_CLASSA_NSHIFT;
+		if (v4a == 0 || v4a == IN_LOOPBACKNET)
+			flags |= NI_NUMERICHOST;			
+		break;
+#ifdef ENABLE_IPV6
+	case AF_INET6:
+		pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
+		if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+			flags |= NI_NUMERICHOST;
+		break;
+#endif
+	}
+	if (host == NULL || hostlen == 0) {
+		/* what should we do? */
+	} else if (flags & NI_NUMERICHOST) {
+		if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+		    == NULL)
+			return ENI_SYSTEM;
+		if (strlen(numaddr) > hostlen)
+			return ENI_MEMORY;
+		strcpy(host, numaddr);
+	} else {
+#ifdef ENABLE_IPV6
+		hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error);
+#else
+		hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af);
+		h_error = h_errno;
+#endif
+
+		if (hp) {
+			if (flags & NI_NOFQDN) {
+				p = strchr(hp->h_name, '.');
+				if (p) *p = '\0';
+			}
+			if (strlen(hp->h_name) > hostlen) {
+#ifdef ENABLE_IPV6
+				freehostent(hp);
+#endif
+				return ENI_MEMORY;
+			}
+			strcpy(host, hp->h_name);
+#ifdef ENABLE_IPV6
+			freehostent(hp);
+#endif
+		} else {
+			if (flags & NI_NAMEREQD)
+				return ENI_NOHOSTNAME;
+			if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+			    == NULL)
+				return ENI_NOHOSTNAME;
+			if (strlen(numaddr) > hostlen)
+				return ENI_MEMORY;
+			strcpy(host, numaddr);
+		}
+	}
+	return SUCCESS;
+}