Tom Lane wrote:
> Bruce Momjian <br...@momjian.us> writes:
> > I assume you are suggesting to use our inet_net_ntop() even if the
> > system has inet_ntop().
> 
> If you're going to have code to do the former, it doesn't seem to be
> worth the trouble to also have code that does the latter ...

OK, we will not call inet_ntop() at all.  I moved the CIDR part of
adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining
"net" part to /port/inet_net_ntop.c.

I then changed all uses of inet_ntoa to use inet_net_ntop().  While this
churn would perhaps not be warranted just to allow for better error
messages, I found pg_getaddrinfo_all() being called from
libpq::connectDBStart(), which makes it not thread-safe.  I am not
excited about backpatching it but it is a threading bug.

The output is as expected:

        $ psql -h localhost test
        psql: could not connect to server: Connection refused
                Is the server running on host "localhost" (127.0.0.1) and 
accepting
                TCP/IP connections on port 5432?
        $ psql -h 127.0.0.1 test
        psql: could not connect to server: Connection refused
                Is the server running on host "127.0.0.1" and accepting
                TCP/IP connections on port 5432?

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a911c50..814c27a 100644
*** /tmp/pgrevert.8208/Z2NPcb_libpq.sgml	Sat Nov 20 18:06:46 2010
--- doc/src/sgml/libpq.sgml	Sat Nov 20 17:11:04 2010
*************** PGconn *PQconnectdbParams(const char **k
*** 170,180 ****
             If <literal>host</> is specified without <literal>hostaddr</>,
             a host name lookup occurs.
             If <literal>hostaddr</> is specified without <literal>host</>,
!            the value for <literal>hostaddr</> gives the server address.
             The connection attempt will fail in any of the cases where a
             host name is required.
             If both <literal>host</> and <literal>hostaddr</> are specified,
!            the value for <literal>hostaddr</> gives the server address.
             The value for <literal>host</> is ignored unless needed for
             authentication or verification purposes, in which case it will be
             used as the host name.  Note that authentication is likely to fail
--- 170,180 ----
             If <literal>host</> is specified without <literal>hostaddr</>,
             a host name lookup occurs.
             If <literal>hostaddr</> is specified without <literal>host</>,
!            the value for <literal>hostaddr</> gives the server network address.
             The connection attempt will fail in any of the cases where a
             host name is required.
             If both <literal>host</> and <literal>hostaddr</> are specified,
!            the value for <literal>hostaddr</> gives the server network address.
             The value for <literal>host</> is ignored unless needed for
             authentication or verification purposes, in which case it will be
             used as the host name.  Note that authentication is likely to fail
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index be272b5..ce28abd 100644
*** /tmp/pgrevert.8208/zxOcga_Makefile	Sat Nov 20 18:06:46 2010
--- src/backend/utils/adt/Makefile	Sat Nov 20 17:11:04 2010
*************** OBJS = acl.o arrayfuncs.o array_userfunc
*** 23,29 ****
  	oid.o oracle_compat.o pseudotypes.o rowtypes.o \
  	regexp.o regproc.o ruleutils.o selfuncs.o \
  	tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
! 	network.o mac.o inet_net_ntop.o inet_net_pton.o \
  	ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
  	ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o trigfuncs.o \
  	tsginidx.o tsgistidx.o tsquery.o tsquery_cleanup.o tsquery_gist.o \
--- 23,29 ----
  	oid.o oracle_compat.o pseudotypes.o rowtypes.o \
  	regexp.o regproc.o ruleutils.o selfuncs.o \
  	tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
! 	network.o mac.o inet_cidr_ntop.o inet_net_pton.o \
  	ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
  	ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o trigfuncs.o \
  	tsginidx.o tsgistidx.o tsquery.o tsquery_cleanup.o tsquery_gist.o \
diff --git a/src/include/port.h b/src/include/port.h
index 2048768..0cfbed8 100644
*** /tmp/pgrevert.8208/DZNlKd_port.h	Sat Nov 20 18:06:46 2010
--- src/include/port.h	Sat Nov 20 17:11:42 2010
*************** extern void qsort_arg(void *base, size_t
*** 437,440 ****
--- 437,444 ----
  /* port/chklocale.c */
  extern int	pg_get_encoding_from_locale(const char *ctype);
  
+ /* port/inet_net_ntop.c */
+ extern char *inet_net_ntop(int af, const void *src, int bits,
+ 			  char *dst, size_t size);
+ 
  #endif   /* PG_PORT_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index ae267ab..88eac70 100644
*** /tmp/pgrevert.8208/1NPEOc_builtins.h	Sat Nov 20 18:06:46 2010
--- src/include/utils/builtins.h	Sat Nov 20 17:11:42 2010
*************** extern Datum chr (PG_FUNCTION_ARGS);
*** 793,801 ****
  extern Datum repeat(PG_FUNCTION_ARGS);
  extern Datum ascii(PG_FUNCTION_ARGS);
  
! /* inet_net_ntop.c */
! extern char *inet_net_ntop(int af, const void *src, int bits,
! 			  char *dst, size_t size);
  extern char *inet_cidr_ntop(int af, const void *src, int bits,
  			   char *dst, size_t size);
  
--- 793,799 ----
  extern Datum repeat(PG_FUNCTION_ARGS);
  extern Datum ascii(PG_FUNCTION_ARGS);
  
! /* inet_cidr_ntop.c */
  extern char *inet_cidr_ntop(int af, const void *src, int bits,
  			   char *dst, size_t size);
  
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8f318a1..8011604 100644
*** /tmp/pgrevert.8208/7EVSqc_fe-connect.c	Sat Nov 20 18:06:46 2010
--- src/interfaces/libpq/fe-connect.c	Sat Nov 20 17:42:54 2010
*************** connectFailureMessage(PGconn *conn, int 
*** 960,968 ****
  	else
  #endif   /* HAVE_UNIX_SOCKETS */
  	{
  		appendPQExpBuffer(&conn->errorMessage,
  						  libpq_gettext("could not connect to server: %s\n"
! 					 "\tIs the server running on host \"%s\" and accepting\n"
  										"\tTCP/IP connections on port %s?\n"),
  						  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
  						  conn->pghostaddr
--- 960,987 ----
  	else
  #endif   /* HAVE_UNIX_SOCKETS */
  	{
+ 		char	host_addr[NI_MAXHOST];
+ 		bool 	display_host_addr;
+ 		struct sockaddr_in *host_addr_struct = (struct sockaddr_in *)
+ 												&conn->raddr.addr;
+ 
+ 		/*
+ 		 *	Optionally display the network address with the hostname.
+ 		 *	This is useful to distinguish between IPv4 and IPv6 connections.
+ 		 */
+ 		if (conn->pghostaddr != NULL)
+ 			strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST);
+ 		else if (inet_net_ntop(conn->addr_cur->ai_family, &host_addr_struct->sin_addr,
+ 				 host_addr_struct->sin_family == AF_INET ? 32 : 128,
+ 				 host_addr, sizeof(host_addr)) == NULL)
+ 			strcpy(host_addr, "???");
+ 
+ 		display_host_addr = !conn->pghostaddr &&
+ 							strcmp(conn->pghost, host_addr) != 0;
+ 		
  		appendPQExpBuffer(&conn->errorMessage,
  						  libpq_gettext("could not connect to server: %s\n"
! 					 "\tIs the server running on host \"%s\" %s%s%sand accepting\n"
  										"\tTCP/IP connections on port %s?\n"),
  						  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
  						  conn->pghostaddr
*************** connectFailureMessage(PGconn *conn, int 
*** 970,975 ****
--- 989,998 ----
  						  : (conn->pghost
  							 ? conn->pghost
  							 : "???"),
+ 						  /* display the IP address only if not already output */
+ 						  display_host_addr ? "(" : "",
+ 						  display_host_addr ? host_addr : "",
+ 						  display_host_addr ? ") " : "",
  						  conn->pgport);
  	}
  }
diff --git a/src/port/Makefile b/src/port/Makefile
index 327ec72..711f633 100644
*** /tmp/pgrevert.8208/9HEr9d_Makefile	Sat Nov 20 18:06:46 2010
--- src/port/Makefile	Sat Nov 20 17:11:04 2010
*************** include $(top_builddir)/src/Makefile.glo
*** 30,36 ****
  override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
  LIBS += $(PTHREAD_LIBS)
  
! OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o noblock.o path.o \
  	pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o
  ifneq (,$(filter $(PORTNAME),cygwin win32))
  OBJS += pipe.o
--- 30,36 ----
  override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
  LIBS += $(PTHREAD_LIBS)
  
! OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o path.o \
  	pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o
  ifneq (,$(filter $(PORTNAME),cygwin win32))
  OBJS += pipe.o
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index f867744..807f5bd 100644
*** /tmp/pgrevert.8208/vneSVc_getaddrinfo.c	Sat Nov 20 18:06:46 2010
--- src/port/getaddrinfo.c	Sat Nov 20 17:21:02 2010
*************** getnameinfo(const struct sockaddr * sa, 
*** 388,403 ****
  
  	if (node)
  	{
- 		int			ret = -1;
- 
  		if (sa->sa_family == AF_INET)
  		{
! 			char	   *p;
! 
! 			p = inet_ntoa(((struct sockaddr_in *) sa)->sin_addr);
! 			ret = snprintf(node, nodelen, "%s", p);
  		}
! 		if (ret == -1 || ret > nodelen)
  			return EAI_MEMORY;
  	}
  
--- 388,401 ----
  
  	if (node)
  	{
  		if (sa->sa_family == AF_INET)
  		{
! 			if (inet_net_ntop(AF_INET, ((struct sockaddr_in *) sa)->sin_addr,
! 				sa->sa_family == AF_INET ? 32 : 128,
! 				node, nodelen) == NULL)
! 			return EAI_MEMORY;
  		}
! 		else
  			return EAI_MEMORY;
  	}
  
diff --git a/src/backend/utils/adt/inet_cidr_ntop.c b/src/backend/utils/adt/inet_cidr_ntop.c
index ...5f2a3d3 .
*** /dev/null	Sat Nov 20 18:04:30 2010
--- src/backend/utils/adt/inet_cidr_ntop.c	Sat Nov 20 17:16:32 2010
***************
*** 0 ****
--- 1,295 ----
+ /*
+  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+  * Copyright (c) 1996,1999 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 ISC DISCLAIMS ALL WARRANTIES
+  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
+  *
+  *	  src/backend/utils/adt/inet_net_ntop.c
+  */
+ 
+ #if defined(LIBC_SCCS) && !defined(lint)
+ static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $";
+ #endif
+ 
+ #include "postgres.h"
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+ #include "utils/builtins.h"
+ #include "utils/inet.h"
+ 
+ 
+ #ifdef SPRINTF_CHAR
+ #define SPRINTF(x) strlen(sprintf/**/x)
+ #else
+ #define SPRINTF(x) ((size_t)sprintf x)
+ #endif
+ 
+ static char *inet_cidr_ntop_ipv4(const u_char *src, int bits,
+ 					char *dst, size_t size);
+ static char *inet_cidr_ntop_ipv6(const u_char *src, int bits,
+ 					char *dst, size_t size);
+ 
+ /*
+  * char *
+  * inet_cidr_ntop(af, src, bits, dst, size)
+  *	convert network number from network to presentation format.
+  *	generates CIDR style result always.
+  * return:
+  *	pointer to dst, or NULL if an error occurred (check errno).
+  * author:
+  *	Paul Vixie (ISC), July 1996
+  */
+ char *
+ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
+ {
+ 	switch (af)
+ 	{
+ 		case PGSQL_AF_INET:
+ 			return (inet_cidr_ntop_ipv4(src, bits, dst, size));
+ 		case PGSQL_AF_INET6:
+ 			return (inet_cidr_ntop_ipv6(src, bits, dst, size));
+ 		default:
+ 			errno = EAFNOSUPPORT;
+ 			return (NULL);
+ 	}
+ }
+ 
+ 
+ /*
+  * static char *
+  * inet_cidr_ntop_ipv4(src, bits, dst, size)
+  *	convert IPv4 network number from network to presentation format.
+  *	generates CIDR style result always.
+  * return:
+  *	pointer to dst, or NULL if an error occurred (check errno).
+  * note:
+  *	network byte order assumed.  this means 192.5.5.240/28 has
+  *	0b11110000 in its fourth octet.
+  * author:
+  *	Paul Vixie (ISC), July 1996
+  */
+ static char *
+ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
+ {
+ 	char	   *odst = dst;
+ 	char	   *t;
+ 	u_int		m;
+ 	int			b;
+ 
+ 	if (bits < 0 || bits > 32)
+ 	{
+ 		errno = EINVAL;
+ 		return (NULL);
+ 	}
+ 
+ 	if (bits == 0)
+ 	{
+ 		if (size < sizeof "0")
+ 			goto emsgsize;
+ 		*dst++ = '0';
+ 		size--;
+ 		*dst = '\0';
+ 	}
+ 
+ 	/* Format whole octets. */
+ 	for (b = bits / 8; b > 0; b--)
+ 	{
+ 		if (size <= sizeof "255.")
+ 			goto emsgsize;
+ 		t = dst;
+ 		dst += SPRINTF((dst, "%u", *src++));
+ 		if (b > 1)
+ 		{
+ 			*dst++ = '.';
+ 			*dst = '\0';
+ 		}
+ 		size -= (size_t) (dst - t);
+ 	}
+ 
+ 	/* Format partial octet. */
+ 	b = bits % 8;
+ 	if (b > 0)
+ 	{
+ 		if (size <= sizeof ".255")
+ 			goto emsgsize;
+ 		t = dst;
+ 		if (dst != odst)
+ 			*dst++ = '.';
+ 		m = ((1 << b) - 1) << (8 - b);
+ 		dst += SPRINTF((dst, "%u", *src & m));
+ 		size -= (size_t) (dst - t);
+ 	}
+ 
+ 	/* Format CIDR /width. */
+ 	if (size <= sizeof "/32")
+ 		goto emsgsize;
+ 	dst += SPRINTF((dst, "/%u", bits));
+ 	return (odst);
+ 
+ emsgsize:
+ 	errno = EMSGSIZE;
+ 	return (NULL);
+ }
+ 
+ /*
+  * static char *
+  * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size)
+  *	convert IPv6 network number from network to presentation format.
+  *	generates CIDR style result always. Picks the shortest representation
+  *	unless the IP is really IPv4.
+  *	always prints specified number of bits (bits).
+  * return:
+  *	pointer to dst, or NULL if an error occurred (check errno).
+  * note:
+  *	network byte order assumed.  this means 192.5.5.240/28 has
+  *	0x11110000 in its fourth octet.
+  * author:
+  *	Vadim Kogan (UCB), June 2001
+  *	Original version (IPv4) by Paul Vixie (ISC), July 1996
+  */
+ 
+ static char *
+ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
+ {
+ 	u_int		m;
+ 	int			b;
+ 	int			p;
+ 	int			zero_s,
+ 				zero_l,
+ 				tmp_zero_s,
+ 				tmp_zero_l;
+ 	int			i;
+ 	int			is_ipv4 = 0;
+ 	unsigned char inbuf[16];
+ 	char		outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
+ 	char	   *cp;
+ 	int			words;
+ 	u_char	   *s;
+ 
+ 	if (bits < 0 || bits > 128)
+ 	{
+ 		errno = EINVAL;
+ 		return (NULL);
+ 	}
+ 
+ 	cp = outbuf;
+ 
+ 	if (bits == 0)
+ 	{
+ 		*cp++ = ':';
+ 		*cp++ = ':';
+ 		*cp = '\0';
+ 	}
+ 	else
+ 	{
+ 		/* Copy src to private buffer.	Zero host part. */
+ 		p = (bits + 7) / 8;
+ 		memcpy(inbuf, src, p);
+ 		memset(inbuf + p, 0, 16 - p);
+ 		b = bits % 8;
+ 		if (b != 0)
+ 		{
+ 			m = ~0 << (8 - b);
+ 			inbuf[p - 1] &= m;
+ 		}
+ 
+ 		s = inbuf;
+ 
+ 		/* how many words need to be displayed in output */
+ 		words = (bits + 15) / 16;
+ 		if (words == 1)
+ 			words = 2;
+ 
+ 		/* Find the longest substring of zero's */
+ 		zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
+ 		for (i = 0; i < (words * 2); i += 2)
+ 		{
+ 			if ((s[i] | s[i + 1]) == 0)
+ 			{
+ 				if (tmp_zero_l == 0)
+ 					tmp_zero_s = i / 2;
+ 				tmp_zero_l++;
+ 			}
+ 			else
+ 			{
+ 				if (tmp_zero_l && zero_l < tmp_zero_l)
+ 				{
+ 					zero_s = tmp_zero_s;
+ 					zero_l = tmp_zero_l;
+ 					tmp_zero_l = 0;
+ 				}
+ 			}
+ 		}
+ 
+ 		if (tmp_zero_l && zero_l < tmp_zero_l)
+ 		{
+ 			zero_s = tmp_zero_s;
+ 			zero_l = tmp_zero_l;
+ 		}
+ 
+ 		if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
+ 						  ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
+ 						   ((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
+ 			is_ipv4 = 1;
+ 
+ 		/* Format whole words. */
+ 		for (p = 0; p < words; p++)
+ 		{
+ 			if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l)
+ 			{
+ 				/* Time to skip some zeros */
+ 				if (p == zero_s)
+ 					*cp++ = ':';
+ 				if (p == words - 1)
+ 					*cp++ = ':';
+ 				s++;
+ 				s++;
+ 				continue;
+ 			}
+ 
+ 			if (is_ipv4 && p > 5)
+ 			{
+ 				*cp++ = (p == 6) ? ':' : '.';
+ 				cp += SPRINTF((cp, "%u", *s++));
+ 				/* we can potentially drop the last octet */
+ 				if (p != 7 || bits > 120)
+ 				{
+ 					*cp++ = '.';
+ 					cp += SPRINTF((cp, "%u", *s++));
+ 				}
+ 			}
+ 			else
+ 			{
+ 				if (cp != outbuf)
+ 					*cp++ = ':';
+ 				cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
+ 				s += 2;
+ 			}
+ 		}
+ 	}
+ 	/* Format CIDR /width. */
+ 	(void) SPRINTF((cp, "/%u", bits));
+ 	if (strlen(outbuf) + 1 > size)
+ 		goto emsgsize;
+ 	strcpy(dst, outbuf);
+ 
+ 	return (dst);
+ 
+ emsgsize:
+ 	errno = EMSGSIZE;
+ 	return (NULL);
+ }
diff --git a/src/backend/utils/adt/inet_net_ntop.c b/src/backend/utils/adt/inet_net_ntop.c
index 3d7fb65..e69de29 100644
*** /tmp/pgrevert.8208/zi7lid_inet_net_ntop.c	Sat Nov 20 18:06:46 2010
--- /dev/null	Sat Nov 20 18:04:30 2010
***************
*** 1,530 ****
- /*
-  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-  * Copyright (c) 1996,1999 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 ISC DISCLAIMS ALL WARRANTIES
-  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
-  *
-  *	  src/backend/utils/adt/inet_net_ntop.c
-  */
- 
- #if defined(LIBC_SCCS) && !defined(lint)
- static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $";
- #endif
- 
- #include "postgres.h"
- 
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- 
- #include "utils/builtins.h"
- #include "utils/inet.h"
- 
- 
- #define NS_IN6ADDRSZ 16
- #define NS_INT16SZ 2
- 
- #ifdef SPRINTF_CHAR
- #define SPRINTF(x) strlen(sprintf/**/x)
- #else
- #define SPRINTF(x) ((size_t)sprintf x)
- #endif
- 
- static char *inet_net_ntop_ipv4(const u_char *src, int bits,
- 				   char *dst, size_t size);
- static char *inet_cidr_ntop_ipv4(const u_char *src, int bits,
- 					char *dst, size_t size);
- static char *inet_net_ntop_ipv6(const u_char *src, int bits,
- 				   char *dst, size_t size);
- static char *inet_cidr_ntop_ipv6(const u_char *src, int bits,
- 					char *dst, size_t size);
- 
- /*
-  * char *
-  * inet_cidr_ntop(af, src, bits, dst, size)
-  *	convert network number from network to presentation format.
-  *	generates CIDR style result always.
-  * return:
-  *	pointer to dst, or NULL if an error occurred (check errno).
-  * author:
-  *	Paul Vixie (ISC), July 1996
-  */
- char *
- inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
- {
- 	switch (af)
- 	{
- 		case PGSQL_AF_INET:
- 			return (inet_cidr_ntop_ipv4(src, bits, dst, size));
- 		case PGSQL_AF_INET6:
- 			return (inet_cidr_ntop_ipv6(src, bits, dst, size));
- 		default:
- 			errno = EAFNOSUPPORT;
- 			return (NULL);
- 	}
- }
- 
- 
- /*
-  * static char *
-  * inet_cidr_ntop_ipv4(src, bits, dst, size)
-  *	convert IPv4 network number from network to presentation format.
-  *	generates CIDR style result always.
-  * return:
-  *	pointer to dst, or NULL if an error occurred (check errno).
-  * note:
-  *	network byte order assumed.  this means 192.5.5.240/28 has
-  *	0b11110000 in its fourth octet.
-  * author:
-  *	Paul Vixie (ISC), July 1996
-  */
- static char *
- inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
- {
- 	char	   *odst = dst;
- 	char	   *t;
- 	u_int		m;
- 	int			b;
- 
- 	if (bits < 0 || bits > 32)
- 	{
- 		errno = EINVAL;
- 		return (NULL);
- 	}
- 
- 	if (bits == 0)
- 	{
- 		if (size < sizeof "0")
- 			goto emsgsize;
- 		*dst++ = '0';
- 		size--;
- 		*dst = '\0';
- 	}
- 
- 	/* Format whole octets. */
- 	for (b = bits / 8; b > 0; b--)
- 	{
- 		if (size <= sizeof "255.")
- 			goto emsgsize;
- 		t = dst;
- 		dst += SPRINTF((dst, "%u", *src++));
- 		if (b > 1)
- 		{
- 			*dst++ = '.';
- 			*dst = '\0';
- 		}
- 		size -= (size_t) (dst - t);
- 	}
- 
- 	/* Format partial octet. */
- 	b = bits % 8;
- 	if (b > 0)
- 	{
- 		if (size <= sizeof ".255")
- 			goto emsgsize;
- 		t = dst;
- 		if (dst != odst)
- 			*dst++ = '.';
- 		m = ((1 << b) - 1) << (8 - b);
- 		dst += SPRINTF((dst, "%u", *src & m));
- 		size -= (size_t) (dst - t);
- 	}
- 
- 	/* Format CIDR /width. */
- 	if (size <= sizeof "/32")
- 		goto emsgsize;
- 	dst += SPRINTF((dst, "/%u", bits));
- 	return (odst);
- 
- emsgsize:
- 	errno = EMSGSIZE;
- 	return (NULL);
- }
- 
- /*
-  * static char *
-  * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size)
-  *	convert IPv6 network number from network to presentation format.
-  *	generates CIDR style result always. Picks the shortest representation
-  *	unless the IP is really IPv4.
-  *	always prints specified number of bits (bits).
-  * return:
-  *	pointer to dst, or NULL if an error occurred (check errno).
-  * note:
-  *	network byte order assumed.  this means 192.5.5.240/28 has
-  *	0x11110000 in its fourth octet.
-  * author:
-  *	Vadim Kogan (UCB), June 2001
-  *	Original version (IPv4) by Paul Vixie (ISC), July 1996
-  */
- 
- static char *
- inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
- {
- 	u_int		m;
- 	int			b;
- 	int			p;
- 	int			zero_s,
- 				zero_l,
- 				tmp_zero_s,
- 				tmp_zero_l;
- 	int			i;
- 	int			is_ipv4 = 0;
- 	unsigned char inbuf[16];
- 	char		outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
- 	char	   *cp;
- 	int			words;
- 	u_char	   *s;
- 
- 	if (bits < 0 || bits > 128)
- 	{
- 		errno = EINVAL;
- 		return (NULL);
- 	}
- 
- 	cp = outbuf;
- 
- 	if (bits == 0)
- 	{
- 		*cp++ = ':';
- 		*cp++ = ':';
- 		*cp = '\0';
- 	}
- 	else
- 	{
- 		/* Copy src to private buffer.	Zero host part. */
- 		p = (bits + 7) / 8;
- 		memcpy(inbuf, src, p);
- 		memset(inbuf + p, 0, 16 - p);
- 		b = bits % 8;
- 		if (b != 0)
- 		{
- 			m = ~0 << (8 - b);
- 			inbuf[p - 1] &= m;
- 		}
- 
- 		s = inbuf;
- 
- 		/* how many words need to be displayed in output */
- 		words = (bits + 15) / 16;
- 		if (words == 1)
- 			words = 2;
- 
- 		/* Find the longest substring of zero's */
- 		zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
- 		for (i = 0; i < (words * 2); i += 2)
- 		{
- 			if ((s[i] | s[i + 1]) == 0)
- 			{
- 				if (tmp_zero_l == 0)
- 					tmp_zero_s = i / 2;
- 				tmp_zero_l++;
- 			}
- 			else
- 			{
- 				if (tmp_zero_l && zero_l < tmp_zero_l)
- 				{
- 					zero_s = tmp_zero_s;
- 					zero_l = tmp_zero_l;
- 					tmp_zero_l = 0;
- 				}
- 			}
- 		}
- 
- 		if (tmp_zero_l && zero_l < tmp_zero_l)
- 		{
- 			zero_s = tmp_zero_s;
- 			zero_l = tmp_zero_l;
- 		}
- 
- 		if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
- 						  ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
- 						   ((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
- 			is_ipv4 = 1;
- 
- 		/* Format whole words. */
- 		for (p = 0; p < words; p++)
- 		{
- 			if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l)
- 			{
- 				/* Time to skip some zeros */
- 				if (p == zero_s)
- 					*cp++ = ':';
- 				if (p == words - 1)
- 					*cp++ = ':';
- 				s++;
- 				s++;
- 				continue;
- 			}
- 
- 			if (is_ipv4 && p > 5)
- 			{
- 				*cp++ = (p == 6) ? ':' : '.';
- 				cp += SPRINTF((cp, "%u", *s++));
- 				/* we can potentially drop the last octet */
- 				if (p != 7 || bits > 120)
- 				{
- 					*cp++ = '.';
- 					cp += SPRINTF((cp, "%u", *s++));
- 				}
- 			}
- 			else
- 			{
- 				if (cp != outbuf)
- 					*cp++ = ':';
- 				cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
- 				s += 2;
- 			}
- 		}
- 	}
- 	/* Format CIDR /width. */
- 	(void) SPRINTF((cp, "/%u", bits));
- 	if (strlen(outbuf) + 1 > size)
- 		goto emsgsize;
- 	strcpy(dst, outbuf);
- 
- 	return (dst);
- 
- emsgsize:
- 	errno = EMSGSIZE;
- 	return (NULL);
- }
- 
- 
- /*
-  * char *
-  * inet_net_ntop(af, src, bits, dst, size)
-  *	convert host/network address from network to presentation format.
-  *	"src"'s size is determined from its "af".
-  * return:
-  *	pointer to dst, or NULL if an error occurred (check errno).
-  * note:
-  *	192.5.5.1/28 has a nonzero host part, which means it isn't a network
-  *	as called for by inet_net_pton() but it can be a host address with
-  *	an included netmask.
-  * author:
-  *	Paul Vixie (ISC), October 1998
-  */
- char *
- inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
- {
- 	switch (af)
- 	{
- 		case PGSQL_AF_INET:
- 			return (inet_net_ntop_ipv4(src, bits, dst, size));
- 		case PGSQL_AF_INET6:
- 			return (inet_net_ntop_ipv6(src, bits, dst, size));
- 		default:
- 			errno = EAFNOSUPPORT;
- 			return (NULL);
- 	}
- }
- 
- /*
-  * static char *
-  * inet_net_ntop_ipv4(src, bits, dst, size)
-  *	convert IPv4 network address from network to presentation format.
-  *	"src"'s size is determined from its "af".
-  * return:
-  *	pointer to dst, or NULL if an error occurred (check errno).
-  * note:
-  *	network byte order assumed.  this means 192.5.5.240/28 has
-  *	0b11110000 in its fourth octet.
-  * author:
-  *	Paul Vixie (ISC), October 1998
-  */
- static char *
- inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
- {
- 	char	   *odst = dst;
- 	char	   *t;
- 	int			len = 4;
- 	int			b;
- 
- 	if (bits < 0 || bits > 32)
- 	{
- 		errno = EINVAL;
- 		return (NULL);
- 	}
- 
- 	/* Always format all four octets, regardless of mask length. */
- 	for (b = len; b > 0; b--)
- 	{
- 		if (size <= sizeof ".255")
- 			goto emsgsize;
- 		t = dst;
- 		if (dst != odst)
- 			*dst++ = '.';
- 		dst += SPRINTF((dst, "%u", *src++));
- 		size -= (size_t) (dst - t);
- 	}
- 
- 	/* don't print masklen if 32 bits */
- 	if (bits != 32)
- 	{
- 		if (size <= sizeof "/32")
- 			goto emsgsize;
- 		dst += SPRINTF((dst, "/%u", bits));
- 	}
- 
- 	return (odst);
- 
- emsgsize:
- 	errno = EMSGSIZE;
- 	return (NULL);
- }
- 
- static int
- decoct(const u_char *src, int bytes, char *dst, size_t size)
- {
- 	char	   *odst = dst;
- 	char	   *t;
- 	int			b;
- 
- 	for (b = 1; b <= bytes; b++)
- 	{
- 		if (size <= sizeof "255.")
- 			return (0);
- 		t = dst;
- 		dst += SPRINTF((dst, "%u", *src++));
- 		if (b != bytes)
- 		{
- 			*dst++ = '.';
- 			*dst = '\0';
- 		}
- 		size -= (size_t) (dst - t);
- 	}
- 	return (dst - odst);
- }
- 
- static char *
- inet_net_ntop_ipv6(const u_char *src, int bits, 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/128"];
- 	char	   *tp;
- 	struct
- 	{
- 		int			base,
- 					len;
- 	}			best, cur;
- 	u_int		words[NS_IN6ADDRSZ / NS_INT16SZ];
- 	int			i;
- 
- 	if ((bits < -1) || (bits > 128))
- 	{
- 		errno = EINVAL;
- 		return (NULL);
- 	}
- 
- 	/*
- 	 * 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 < NS_IN6ADDRSZ; i++)
- 		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
- 	best.base = -1;
- 	cur.base = -1;
- 	best.len = 0;
- 	cur.len = 0;
- 	for (i = 0; i < (NS_IN6ADDRSZ / NS_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;
- 	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); 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)
- 				*tp++ = ':';
- 			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 == 7 && words[7] != 0x0001) ||
- 									  (best.len == 5 && words[5] == 0xffff)))
- 		{
- 			int			n;
- 
- 			n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp));
- 			if (n == 0)
- 			{
- 				errno = EMSGSIZE;
- 				return (NULL);
- 			}
- 			tp += strlen(tp);
- 			break;
- 		}
- 		tp += SPRINTF((tp, "%x", words[i]));
- 	}
- 
- 	/* Was it a trailing run of 0x00's? */
- 	if (best.base != -1 && (best.base + best.len) ==
- 		(NS_IN6ADDRSZ / NS_INT16SZ))
- 		*tp++ = ':';
- 	*tp = '\0';
- 
- 	if (bits != -1 && bits != 128)
- 		tp += SPRINTF((tp, "/%u", bits));
- 
- 	/*
- 	 * Check for overflow, copy, and we're done.
- 	 */
- 	if ((size_t) (tp - tmp) > size)
- 	{
- 		errno = EMSGSIZE;
- 		return (NULL);
- 	}
- 	strcpy(dst, tmp);
- 	return (dst);
- }
--- 0 ----
diff --git a/src/port/inet_net_ntop.c b/src/port/inet_net_ntop.c
index ...02d3a7c .
*** /dev/null	Sat Nov 20 18:04:30 2010
--- src/port/inet_net_ntop.c	Sat Nov 20 17:14:44 2010
***************
*** 0 ****
--- 1,275 ----
+ /*
+  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+  * Copyright (c) 1996,1999 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 ISC DISCLAIMS ALL WARRANTIES
+  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
+  *
+  *	  src/backend/utils/adt/inet_net_ntop.c
+  */
+ 
+ #if defined(LIBC_SCCS) && !defined(lint)
+ static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $";
+ #endif
+ 
+ #include "postgres.h"
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+ #include "utils/inet.h"
+ 
+ 
+ #define NS_IN6ADDRSZ 16
+ #define NS_INT16SZ 2
+ 
+ #ifdef SPRINTF_CHAR
+ #define SPRINTF(x) strlen(sprintf/**/x)
+ #else
+ #define SPRINTF(x) ((size_t)sprintf x)
+ #endif
+ 
+ static char *inet_net_ntop_ipv4(const u_char *src, int bits,
+ 				   char *dst, size_t size);
+ static char *inet_net_ntop_ipv6(const u_char *src, int bits,
+ 				   char *dst, size_t size);
+ 
+ 
+ /*
+  * char *
+  * inet_net_ntop(af, src, bits, dst, size)
+  *	convert host/network address from network to presentation format.
+  *	"src"'s size is determined from its "af".
+  * return:
+  *	pointer to dst, or NULL if an error occurred (check errno).
+  * note:
+  *	192.5.5.1/28 has a nonzero host part, which means it isn't a network
+  *	as called for by inet_net_pton() but it can be a host address with
+  *	an included netmask.
+  * author:
+  *	Paul Vixie (ISC), October 1998
+  */
+ char *
+ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
+ {
+ 	switch (af)
+ 	{
+ 		case PGSQL_AF_INET:
+ 			return (inet_net_ntop_ipv4(src, bits, dst, size));
+ 		case PGSQL_AF_INET6:
+ 			return (inet_net_ntop_ipv6(src, bits, dst, size));
+ 		default:
+ 			errno = EAFNOSUPPORT;
+ 			return (NULL);
+ 	}
+ }
+ 
+ /*
+  * static char *
+  * inet_net_ntop_ipv4(src, bits, dst, size)
+  *	convert IPv4 network address from network to presentation format.
+  *	"src"'s size is determined from its "af".
+  * return:
+  *	pointer to dst, or NULL if an error occurred (check errno).
+  * note:
+  *	network byte order assumed.  this means 192.5.5.240/28 has
+  *	0b11110000 in its fourth octet.
+  * author:
+  *	Paul Vixie (ISC), October 1998
+  */
+ static char *
+ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
+ {
+ 	char	   *odst = dst;
+ 	char	   *t;
+ 	int			len = 4;
+ 	int			b;
+ 
+ 	if (bits < 0 || bits > 32)
+ 	{
+ 		errno = EINVAL;
+ 		return (NULL);
+ 	}
+ 
+ 	/* Always format all four octets, regardless of mask length. */
+ 	for (b = len; b > 0; b--)
+ 	{
+ 		if (size <= sizeof ".255")
+ 			goto emsgsize;
+ 		t = dst;
+ 		if (dst != odst)
+ 			*dst++ = '.';
+ 		dst += SPRINTF((dst, "%u", *src++));
+ 		size -= (size_t) (dst - t);
+ 	}
+ 
+ 	/* don't print masklen if 32 bits */
+ 	if (bits != 32)
+ 	{
+ 		if (size <= sizeof "/32")
+ 			goto emsgsize;
+ 		dst += SPRINTF((dst, "/%u", bits));
+ 	}
+ 
+ 	return (odst);
+ 
+ emsgsize:
+ 	errno = EMSGSIZE;
+ 	return (NULL);
+ }
+ 
+ static int
+ decoct(const u_char *src, int bytes, char *dst, size_t size)
+ {
+ 	char	   *odst = dst;
+ 	char	   *t;
+ 	int			b;
+ 
+ 	for (b = 1; b <= bytes; b++)
+ 	{
+ 		if (size <= sizeof "255.")
+ 			return (0);
+ 		t = dst;
+ 		dst += SPRINTF((dst, "%u", *src++));
+ 		if (b != bytes)
+ 		{
+ 			*dst++ = '.';
+ 			*dst = '\0';
+ 		}
+ 		size -= (size_t) (dst - t);
+ 	}
+ 	return (dst - odst);
+ }
+ 
+ static char *
+ inet_net_ntop_ipv6(const u_char *src, int bits, 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/128"];
+ 	char	   *tp;
+ 	struct
+ 	{
+ 		int			base,
+ 					len;
+ 	}			best, cur;
+ 	u_int		words[NS_IN6ADDRSZ / NS_INT16SZ];
+ 	int			i;
+ 
+ 	if ((bits < -1) || (bits > 128))
+ 	{
+ 		errno = EINVAL;
+ 		return (NULL);
+ 	}
+ 
+ 	/*
+ 	 * 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 < NS_IN6ADDRSZ; i++)
+ 		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ 	best.base = -1;
+ 	cur.base = -1;
+ 	best.len = 0;
+ 	cur.len = 0;
+ 	for (i = 0; i < (NS_IN6ADDRSZ / NS_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;
+ 	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); 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)
+ 				*tp++ = ':';
+ 			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 == 7 && words[7] != 0x0001) ||
+ 									  (best.len == 5 && words[5] == 0xffff)))
+ 		{
+ 			int			n;
+ 
+ 			n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp));
+ 			if (n == 0)
+ 			{
+ 				errno = EMSGSIZE;
+ 				return (NULL);
+ 			}
+ 			tp += strlen(tp);
+ 			break;
+ 		}
+ 		tp += SPRINTF((tp, "%x", words[i]));
+ 	}
+ 
+ 	/* Was it a trailing run of 0x00's? */
+ 	if (best.base != -1 && (best.base + best.len) ==
+ 		(NS_IN6ADDRSZ / NS_INT16SZ))
+ 		*tp++ = ':';
+ 	*tp = '\0';
+ 
+ 	if (bits != -1 && bits != 128)
+ 		tp += SPRINTF((tp, "/%u", bits));
+ 
+ 	/*
+ 	 * Check for overflow, copy, and we're done.
+ 	 */
+ 	if ((size_t) (tp - tmp) > size)
+ 	{
+ 		errno = EMSGSIZE;
+ 		return (NULL);
+ 	}
+ 	strcpy(dst, tmp);
+ 	return (dst);
+ }
+ 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to