diff --git a/config/c-library.m4 b/config/c-library.m4
index d301b0155cf428e56b025ed5416001136e0833f3..d6acd8c98b69cc0c3dcabe600e129716edf8bbb4 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -1,5 +1,5 @@
 # Macros that test various C library quirks
-# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.22 2003/06/23 23:51:59 momjian Exp $
+# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.23 2003/07/23 23:30:39 tgl Exp $
 
 
 # PGAC_VAR_INT_TIMEZONE
@@ -100,8 +100,8 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN],
 
 # PGAC_STRUCT_SOCKADDR_STORAGE
 # ----------------------------
-# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. If
-# it is missing then one could define it.
+# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE.
+# If it is missing then one could define it.
 AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE],
 [AC_CHECK_TYPES([struct sockaddr_storage], [], [],
 [#include <sys/types.h>
@@ -110,18 +110,24 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE],
 #endif
 ])])# PGAC_STRUCT_SOCKADDR_STORAGE
 
-# PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 # --------------------------------------
-# This checks if the struct sockaddr has a proper ss_family and not an
-# __ss_family as rfc2553 defined.
-AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY],
+# Check the members of `struct sockaddr_storage'.  We need to know about
+# ss_family and ss_len.  (Some platforms follow RFC 2553 and call them
+# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len;
+# if we have to define our own `struct sockaddr_storage', this tells us
+# whether we need to provide an ss_len field.
+AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
 [AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family,
-	struct sockaddr_storage.__ss_family], [], [],
+		   struct sockaddr_storage.__ss_family,
+		   struct sockaddr_storage.ss_len,
+		   struct sockaddr_storage.__ss_len,
+		   struct sockaddr.sa_len], [], [],
 [#include <sys/types.h>
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
-])])# PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 
 
 # PGAC_STRUCT_ADDRINFO
diff --git a/configure b/configure
index 99bce0c0410ae1f6c8f2768daa359ab7e0ac95a5..24066b6fac363cc9e79db6245beff6649f33a1bb 100755
--- a/configure
+++ b/configure
@@ -9990,6 +9990,186 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+fi
+echo "$as_me:$LINENO: checking for struct sockaddr_storage.ss_len" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.ss_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage_ss_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.ss_len)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage_ss_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_member_struct_sockaddr_storage_ss_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_len" >&6
+if test $ac_cv_member_struct_sockaddr_storage_ss_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_len" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.__ss_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage___ss_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.__ss_len)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage___ss_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_member_struct_sockaddr_storage___ss_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_len" >&6
+if test $ac_cv_member_struct_sockaddr_storage___ss_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5
+echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_sa_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+#ifdef F77_DUMMY_MAIN
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (ac_aggr.sa_len)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_sa_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_cv_member_struct_sockaddr_sa_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6
+if test $ac_cv_member_struct_sockaddr_sa_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 1
+_ACEOF
+
+
 fi
 
 echo "$as_me:$LINENO: checking for struct addrinfo" >&5
diff --git a/configure.in b/configure.in
index 515d53c183a46ec9df9f64e3cc73979956fc9d73..d189a5ffdb39279f86fe6edd608d6164fca2d64e 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $Header: /cvsroot/pgsql/configure.in,v 1.269 2003/07/23 17:27:28 momjian Exp $
+dnl $Header: /cvsroot/pgsql/configure.in,v 1.270 2003/07/23 23:30:40 tgl Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -778,7 +778,7 @@ PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 PGAC_STRUCT_SOCKADDR_UN
 PGAC_STRUCT_SOCKADDR_STORAGE
-PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 PGAC_STRUCT_ADDRINFO
 
 AC_CHECK_TYPES([struct cmsgcred, struct fcred, struct sockcred], [], [],
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index ca6bfcf4d7ee3ba10cb981605abab2598851590a..a24f0978466a126510b41053399fac4d62c58184 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.104 2003/07/22 19:00:10 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.105 2003/07/23 23:30:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -434,11 +434,10 @@ ClientAuthentication(Port *port)
 			{
 				char	hostinfo[NI_MAXHOST];
 
-				getnameinfo((struct sockaddr *) &port->raddr.addr,
-							port->raddr.salen,
-							hostinfo, sizeof(hostinfo),
-							NULL, 0,
-							NI_NUMERICHOST);
+				getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+								hostinfo, sizeof(hostinfo),
+								NULL, 0,
+								NI_NUMERICHOST);
 
 				ereport(FATAL,
 						(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index f0bd0b8515497117c2a9140fb8a04d13d609f874..0d98e729a40eb4e60cacd03a6636ef8e8b2a79fe 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.106 2003/07/22 21:19:22 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.107 2003/07/23 23:30:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -648,31 +648,33 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 		hints.ai_next = NULL;
 
 		/* Get the IP address either way */
-		ret = getaddrinfo2(token, NULL, &hints, &file_ip_addr);
+		ret = getaddrinfo_all(token, NULL, &hints, &file_ip_addr);
 		if (ret || !file_ip_addr)
 		{
 			ereport(LOG,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-					 errmsg("failed to interpret IP address \"%s\" in config file: %s",
+					 errmsg("could not interpret IP address \"%s\" in config file: %s",
 							token, gai_strerror(ret))));
 			if (cidr_slash)
 				*cidr_slash = '/';
 			goto hba_syntax;
 		}
 
+		if (cidr_slash)
+			*cidr_slash = '/';
+
 		if (file_ip_addr->ai_family != port->raddr.addr.ss_family)
 		{
 			/* Wrong address family. */
-			freeaddrinfo2(hints.ai_family, file_ip_addr);
+			freeaddrinfo_all(hints.ai_family, file_ip_addr);
 			return;
 		}
 
 		/* Get the netmask */
 		if (cidr_slash)
 		{
-			*cidr_slash = '/';
 			if (SockAddr_cidr_mask(&mask, cidr_slash + 1,
-				file_ip_addr->ai_family) < 0)
+								   file_ip_addr->ai_family) < 0)
 				goto hba_syntax;
 		}
 		else
@@ -683,13 +685,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 				goto hba_syntax;
 			token = lfirst(line);
 
-			ret = getaddrinfo2(token, NULL, &hints, &file_ip_mask);
+			ret = getaddrinfo_all(token, NULL, &hints, &file_ip_mask);
 			if (ret || !file_ip_mask)
 				goto hba_syntax;
 
 			mask = (struct sockaddr_storage *)file_ip_mask->ai_addr;
 
-			if(file_ip_addr->ai_family != mask->ss_family)
+			if (file_ip_addr->ai_family != mask->ss_family)
 				goto hba_syntax;
 		}
 
@@ -703,12 +705,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 
 		/* Must meet network restrictions */
 		if (!rangeSockAddr(&port->raddr.addr,
-			(struct sockaddr_storage *)file_ip_addr->ai_addr, mask))
+						   (struct sockaddr_storage *)file_ip_addr->ai_addr,
+						   mask))
 			goto hba_freeaddr;
 
-		freeaddrinfo2(hints.ai_family, file_ip_addr);
+		freeaddrinfo_all(hints.ai_family, file_ip_addr);
 		if (file_ip_mask)
-			freeaddrinfo2(hints.ai_family, file_ip_mask);
+			freeaddrinfo_all(hints.ai_family, file_ip_mask);
 	}
 	else
 		goto hba_syntax;
@@ -731,16 +734,16 @@ hba_syntax:
 	else
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("missing entry in pg_hba.conf file at end of line %d",
+				 errmsg("missing field in pg_hba.conf file at end of line %d",
 						line_number)));
 
 	*error_p = true;
 
 hba_freeaddr:
 	if (file_ip_addr)
-		freeaddrinfo2(hints.ai_family, file_ip_addr);
+		freeaddrinfo_all(hints.ai_family, file_ip_addr);
 	if (file_ip_mask)
-		freeaddrinfo2(hints.ai_family, file_ip_mask);
+		freeaddrinfo_all(hints.ai_family, file_ip_mask);
 }
 
 
@@ -1209,14 +1212,14 @@ ident_inet(const SockAddr remote_addr,
 	 * Might look a little weird to first convert it to text and
 	 * then back to sockaddr, but it's protocol independent.
 	 */
-	getnameinfo((struct sockaddr *)&remote_addr.addr, remote_addr.salen,
-				remote_addr_s, sizeof(remote_addr_s),
-				remote_port, sizeof(remote_port),
-				NI_NUMERICHOST | NI_NUMERICSERV);
-	getnameinfo((struct sockaddr *)&local_addr.addr, local_addr.salen,
-				local_addr_s, sizeof(local_addr_s),
-				local_port, sizeof(local_port),
-				NI_NUMERICHOST | NI_NUMERICSERV);
+	getnameinfo_all(&remote_addr.addr, remote_addr.salen,
+					remote_addr_s, sizeof(remote_addr_s),
+					remote_port, sizeof(remote_port),
+					NI_NUMERICHOST | NI_NUMERICSERV);
+	getnameinfo_all(&local_addr.addr, local_addr.salen,
+					local_addr_s, sizeof(local_addr_s),
+					local_port, sizeof(local_port),
+					NI_NUMERICHOST | NI_NUMERICSERV);
 
 	snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
 	hints.ai_flags = AI_NUMERICHOST;
@@ -1227,7 +1230,7 @@ ident_inet(const SockAddr remote_addr,
 	hints.ai_canonname = NULL;
 	hints.ai_addr = NULL;
 	hints.ai_next = NULL;
-	rc = getaddrinfo2(remote_addr_s, ident_port, &hints, &ident_serv);
+	rc = getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
 	if (rc || !ident_serv)
 		return false;			/* we don't expect this to happen */
 
@@ -1239,7 +1242,7 @@ ident_inet(const SockAddr remote_addr,
 	hints.ai_canonname = NULL;
 	hints.ai_addr = NULL;
 	hints.ai_next = NULL;
-	rc = getaddrinfo2(local_addr_s, NULL, &hints, &la);
+	rc = getaddrinfo_all(local_addr_s, NULL, &hints, &la);
 	if (rc || !la)
 		return false;			/* we don't expect this to happen */
 	
@@ -1323,8 +1326,8 @@ ident_inet(const SockAddr remote_addr,
 ident_inet_done:
 	if (sock_fd >= 0)
 		closesocket(sock_fd);
-	freeaddrinfo2(remote_addr.addr.ss_family, ident_serv);
-	freeaddrinfo2(local_addr.addr.ss_family, la);
+	freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
+	freeaddrinfo_all(local_addr.addr.ss_family, la);
 	return ident_return;
 }
 
diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index 091b381ec179f9d9b5a63594519e59864d08ddfd..c5a0a485ef5c852b2a0d311aafedd89823127a6c 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.15 2003/06/12 08:15:28 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.16 2003/07/23 23:30:40 tgl Exp $
  *
  * This file and the IPV6 implementation were initially provided by
  * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -53,15 +53,20 @@ static int	rangeSockAddrAF_INET6(const struct sockaddr_in6 *addr,
 static int	getaddrinfo_unix(const char *path,
 			const struct addrinfo *hintsp,
 			struct addrinfo **result);
+
+static int	getnameinfo_unix(const struct sockaddr_un *sa, int salen,
+							 char *node, int nodelen,
+							 char *service, int servicelen,
+							 int flags);
 #endif
 
 
 /*
- *	getaddrinfo2 - get address info for Unix, IPv4 and IPv6 sockets
+ *	getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets
  */
 int
-getaddrinfo2(const char *hostname, const char *servname,
-			 const struct addrinfo *hintp, struct addrinfo **result)
+getaddrinfo_all(const char *hostname, const char *servname,
+				const struct addrinfo *hintp, struct addrinfo **result)
 {
 #ifdef HAVE_UNIX_SOCKETS
 	if (hintp != NULL && hintp->ai_family == AF_UNIX)
@@ -75,7 +80,7 @@ getaddrinfo2(const char *hostname, const char *servname,
 
 
 /*
- *	freeaddrinfo2 - free addrinfo structures for IPv4, IPv6, or Unix
+ *	freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix
  *
  * Note: the ai_family field of the original hint structure must be passed
  * so that we can tell whether the addrinfo struct was built by the system's
@@ -84,12 +89,12 @@ getaddrinfo2(const char *hostname, const char *servname,
  * not safe to look at ai_family in the addrinfo itself.
  */
 void
-freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
+freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 {
 #ifdef HAVE_UNIX_SOCKETS
 	if (hint_ai_family == AF_UNIX)
 	{
-		/* struct was built by getaddrinfo_unix (see getaddrinfo2) */
+		/* struct was built by getaddrinfo_unix (see getaddrinfo_all) */
 		while (ai != NULL)
 		{
 			struct addrinfo *p = ai;
@@ -109,11 +114,53 @@ freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
 }
 
 
+/*
+ *	getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets
+ *
+ * The API of this routine differs from the standard getnameinfo() definition
+ * in two ways: first, the addr parameter is declared as sockaddr_storage
+ * rather than struct sockaddr, and second, the node and service fields are
+ * guaranteed to be filled with something even on failure return.
+ */
+int
+getnameinfo_all(const struct sockaddr_storage *addr, int salen,
+				char *node, int nodelen,
+				char *service, int servicelen,
+				int flags)
+{
+	int		rc;
+
+#ifdef HAVE_UNIX_SOCKETS
+	if (addr && addr->ss_family == AF_UNIX)
+		rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
+							  node, nodelen,
+							  service, servicelen,
+							  flags);
+	else
+#endif
+		rc = getnameinfo((const struct sockaddr *) addr, salen,
+						 node, nodelen,
+						 service, servicelen,
+						 flags);
+
+	if (rc != 0)
+	{
+		if (node)
+			StrNCpy(node, "???", nodelen);
+		if (service)
+			StrNCpy(service, "???", servicelen);
+	}
+
+	return rc;
+}
+
+
 #if defined(HAVE_UNIX_SOCKETS)
+
 /* -------
  *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
  *
- *	Bug:  only one addrinfo is set even though hintsp is NULL or
+ *	Bugs: only one addrinfo is set even though hintsp is NULL or
  *		  ai_socktype is 0
  *		  AI_CANONNAME is not supported.
  * -------
@@ -176,12 +223,59 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
 
 	strcpy(unp->sun_path, path);
 
-#if SALEN
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
 	unp->sun_len = sizeof(struct sockaddr_un);
-#endif   /* SALEN */
+#endif
+
+	return 0;
+}
+
+/*
+ * Convert an address to a hostname.
+ */
+static int
+getnameinfo_unix(const struct sockaddr_un *sa, int salen,
+				 char *node, int nodelen,
+				 char *service, int servicelen,
+				 int flags)
+{
+	int		ret = -1;
+
+	/* Invalid arguments. */
+	if (sa == NULL || sa->sun_family != AF_UNIX ||
+		(node == NULL && service == NULL))
+	{
+		return EAI_FAIL;
+	}
+
+	/* We don't support those. */
+	if ((node && !(flags & NI_NUMERICHOST))
+		|| (service && !(flags & NI_NUMERICSERV)))
+	{
+		return EAI_FAIL;
+	}
+
+	if (node)
+	{
+		ret = snprintf(node, nodelen, "%s", "localhost");
+		if (ret == -1 || ret > nodelen)
+		{
+			return EAI_MEMORY;
+		}
+	}
+
+	if (service)
+	{
+		ret = snprintf(service, servicelen, "%s", sa->sun_path);
+		if (ret == -1 || ret > servicelen)
+		{
+			return EAI_MEMORY;
+		}
+	}
 
 	return 0;
 }
+
 #endif   /* HAVE_UNIX_SOCKETS */
 
 
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 7f3013925aea91ce4e348fd1871526f5a3647c25..7cd9e23f32cc9752007b316b9fd4975728364788 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -30,7 +30,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.158 2003/07/22 19:00:10 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.159 2003/07/23 23:30:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -190,16 +190,18 @@ StreamDoUnlink(void)
 #endif   /* HAVE_UNIX_SOCKETS */
 
 /*
- * StreamServerPort -- open a sock stream "listening" port.
+ * StreamServerPort -- open a "listening" port to accept connections.
  *
- * This initializes the Postmaster's connection-accepting port *fdP.
+ * Successfully opened sockets are added to the ListenSocket[] array,
+ * at the first position that isn't -1.
  *
  * RETURNS: STATUS_OK or STATUS_ERROR
  */
 
 int
 StreamServerPort(int family, char *hostName, unsigned short portNumber,
-	 char *unixSocketName, int ListenSocket[], int MaxListen)
+				 char *unixSocketName,
+				 int ListenSocket[], int MaxListen)
 {
 	int			fd,
 				err;
@@ -216,7 +218,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 	/* Initialize hint structure */
 	MemSet(&hint, 0, sizeof(hint));
 	hint.ai_family = family;
-	hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+	hint.ai_flags = AI_PASSIVE;
 	hint.ai_socktype = SOCK_STREAM;
 
 #ifdef HAVE_UNIX_SOCKETS
@@ -234,13 +236,18 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 		service = portNumberStr;
 	}
 
-	ret = getaddrinfo2(hostName, service, &hint, &addrs);
-	if (ret || addrs == NULL)
+	ret = getaddrinfo_all(hostName, service, &hint, &addrs);
+	if (ret || !addrs)
 	{
-		ereport(LOG,
-				(errmsg("failed to translate hostname to address: %s",
-						gai_strerror(ret))));
-		freeaddrinfo2(hint.ai_family, addrs);
+		if (hostName)
+			ereport(LOG,
+					(errmsg("could not translate hostname \"%s\", service \"%s\" to address: %s",
+							hostName, service, gai_strerror(ret))));
+		else
+			ereport(LOG,
+					(errmsg("could not translate service \"%s\" to address: %s",
+							service, gai_strerror(ret))));
+		freeaddrinfo_all(hint.ai_family, addrs);
 		return STATUS_ERROR;
 	}
 
@@ -250,7 +257,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 		{
 			/* Only set up a unix domain socket when
 			 * they really asked for it.  The service/port
-			 * is different in that case. */
+			 * is different in that case.
+			 */
 			continue;
 		}
 
@@ -258,17 +266,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 		for (; listen_index < MaxListen; listen_index++)
 		{
 			if (ListenSocket[listen_index] == -1)
-			{
 				break;
-			}
 		}
-		if (listen_index == MaxListen)
+		if (listen_index >= MaxListen)
 		{
 			/* Nothing found. */
 			break;
 		}
-		if ((fd = socket(addr->ai_family, addr->ai_socktype,
-			addr->ai_protocol)) < 0)
+
+		if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
 		{
 			ereport(LOG,
 					(errcode_for_socket_access(),
@@ -276,8 +282,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-
-
 		if (!IS_AF_UNIX(addr->ai_family))
 		{
 			if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
@@ -363,12 +367,11 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
 		added++;
 	}
 
-	freeaddrinfo(addrs);
+	freeaddrinfo_all(hint.ai_family, addrs);
 
 	if (!added)
-	{
 		return STATUS_ERROR;
-	}
+
 	return STATUS_OK;
 }
 
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 5ed1247e9519fe4f37a414cfa71e16e46782bcf5..f8882737eeed5f611f2ada4df0f39d183c32c1a2 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
  *
  *	Copyright (c) 2001-2003, PostgreSQL Global Development Group
  *
- *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.39 2003/07/22 19:13:19 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.40 2003/07/23 23:30:40 tgl Exp $
  * ----------
  */
 #include "postgres.h"
@@ -147,7 +147,7 @@ void
 pgstat_init(void)
 {
 	ACCEPT_TYPE_ARG3	alen;
-	struct	addrinfo	*addr = NULL, hints;
+	struct	addrinfo	*addrs = NULL, *addr, hints;
 	int			ret;
 
 	/*
@@ -189,17 +189,27 @@ pgstat_init(void)
 	hints.ai_addr = NULL;
 	hints.ai_canonname = NULL;
 	hints.ai_next = NULL;
-	ret = getaddrinfo2("localhost", NULL, &hints, &addr);
-	if (ret || !addr)
+	ret = getaddrinfo_all("localhost", NULL, &hints, &addrs);
+	if (ret || !addrs)
 	{
 		ereport(LOG,
-				(errmsg("getaddrinfo2(\"localhost\") failed: %s",
+				(errmsg("could not resolve \"localhost\": %s",
 						gai_strerror(ret))));
 		goto startup_failed;
 	}
 	
-	if ((pgStatSock = socket(addr->ai_family,
-							 addr->ai_socktype, addr->ai_protocol)) < 0)
+	for (addr = addrs; addr; addr = addr->ai_next)
+	{
+#ifdef HAVE_UNIX_SOCKETS
+		/* Ignore AF_UNIX sockets, if any are returned. */
+		if (addr->ai_family == AF_UNIX)
+			continue;
+#endif
+		if ((pgStatSock = socket(addr->ai_family, SOCK_DGRAM, 0)) >= 0)
+			break;
+	}
+
+	if (!addr || pgStatSock < 0)
 	{
 		ereport(LOG,
 				(errcode_for_socket_access(),
@@ -218,8 +228,9 @@ pgstat_init(void)
 				 errmsg("could not bind socket for statistics: %m")));
 		goto startup_failed;
 	}
-	freeaddrinfo2(hints.ai_family, addr);
-	addr = NULL;
+
+	freeaddrinfo_all(hints.ai_family, addrs);
+	addrs = NULL;
 
 	alen = sizeof(pgStatAddr);
 	if (getsockname(pgStatSock, (struct sockaddr *)&pgStatAddr, &alen) < 0)
@@ -272,8 +283,8 @@ pgstat_init(void)
 	return;
 
 startup_failed:
-	if (addr)
-		freeaddrinfo2(hints.ai_family, addr);
+	if (addrs)
+		freeaddrinfo_all(hints.ai_family, addrs);
 
 	if (pgStatSock >= 0)
 		closesocket(pgStatSock);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 614c76e64eeff63e7c7f4eca1a9c04f1a0dc91ed..fb64781bf8c09f0ba70506b70f973306875df076 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.335 2003/07/22 20:29:13 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.336 2003/07/23 23:30:40 tgl Exp $
  *
  * NOTES
  *
@@ -168,9 +168,9 @@ int			ReservedBackends;
 
 static char *progname = (char *) NULL;
 
-/* The sockets we're listening to. */
+/* The socket(s) we're listening to. */
 #define	MAXLISTEN	10
-int	ListenSocket[MAXLISTEN];
+static int	ListenSocket[MAXLISTEN];
 
 /* Used to reduce macros tests */
 #ifdef EXEC_BACKEND
@@ -277,7 +277,7 @@ static int	ServerLoop(void);
 static int	BackendStartup(Port *port);
 static int	ProcessStartupPacket(Port *port, bool SSLdone);
 static void processCancelRequest(Port *port, void *pkt);
-static int	initMasks(fd_set *rmask, fd_set *wmask);
+static int	initMasks(fd_set *rmask);
 static void report_fork_failure_to_client(Port *port, int errnum);
 enum CAC_state
 {
@@ -727,73 +727,80 @@ PostmasterMain(int argc, char *argv[])
 	 * Establish input sockets.
 	 */
 	for (i = 0; i < MAXLISTEN; i++)
-	{
 		ListenSocket[i] = -1;
-	}
+
 	if (NetServer)
 	{
 		if (VirtualHost && VirtualHost[0])
 		{
-			char	*p, *q;
+			char	*curhost, *endptr;
 			char	c = 0;
 
-			q = VirtualHost;
-			do
+			curhost = VirtualHost;
+			for (;;)
 			{
-				p = strchr(q, ' ');
-				if (p)
+				while (*curhost == ' ')	/* skip any extra spaces */
+					curhost++;
+				if (*curhost == '\0')
+					break;
+				endptr = strchr(curhost, ' ');
+				if (endptr)
 				{
-					c = *p;
-					*p = '\0';
+					c = *endptr;
+					*endptr = '\0';
 				}
-				status = StreamServerPort(AF_UNSPEC, q,
-					(unsigned short) PostPortNumber,
-					UnixSocketDir, ListenSocket, MAXLISTEN);
+				status = StreamServerPort(AF_UNSPEC, curhost,
+										  (unsigned short) PostPortNumber,
+										  UnixSocketDir,
+										  ListenSocket, MAXLISTEN);
 				if (status != STATUS_OK)
 				{
-					postmaster_error("cannot create tcpip "
-						"listen socket for: %s", p);
+					postmaster_error("could not create listen socket for \"%s\"",
+									 curhost);
 				}
-				if (p)
+				if (endptr)
 				{
-					*p = c;
-					q = p + 1;
+					*endptr = c;
+					curhost = endptr + 1;
 				}
+				else
+					break;
 			}
-			while (p);
 		}
 		else
 		{
 			status = StreamServerPort(AF_UNSPEC, NULL,
-				(unsigned short) PostPortNumber,
-				UnixSocketDir, ListenSocket, MAXLISTEN);
+									  (unsigned short) PostPortNumber,
+									  UnixSocketDir,
+									  ListenSocket, MAXLISTEN);
 			if (status != STATUS_OK)
 			{
-				postmaster_error("cannot create tcpip listen "
-					"socket.");
+				postmaster_error("could not create TCP/IP listen socket");
 			}
 		}
+
 #ifdef USE_RENDEZVOUS					 
-				if (rendezvous_name != NULL)
-				{
-						DNSServiceRegistrationCreate(rendezvous_name,
-													 "_postgresql._tcp.",
-													 "",
-													 htonl(PostPortNumber),
-													 "",
-													 (DNSServiceRegistrationReply)reg_reply,
-													 NULL);
-				}
+		if (rendezvous_name != NULL)
+		{
+			DNSServiceRegistrationCreate(rendezvous_name,
+										 "_postgresql._tcp.",
+										 "",
+										 htonl(PostPortNumber),
+										 "",
+										 (DNSServiceRegistrationReply)reg_reply,
+										 NULL);
+		}
 #endif
 	}
 
 #ifdef HAVE_UNIX_SOCKETS
 	status = StreamServerPort(AF_UNIX, NULL,
-			(unsigned short) PostPortNumber,
-			UnixSocketDir, ListenSocket, MAXLISTEN);
+							  (unsigned short) PostPortNumber,
+							  UnixSocketDir,
+							  ListenSocket, MAXLISTEN);
 	if (status != STATUS_OK)
 	{
-		postmaster_error("cannot create UNIX stream port");
+		postmaster_error("could not create UNIX stream port");
 		ExitPostmaster(1);
 	}
 #endif
@@ -994,7 +1001,7 @@ usage(const char *progname)
 static int
 ServerLoop(void)
 {
-	fd_set			readmask, writemask;
+	fd_set			readmask;
 	int			nSockets;
 	struct timeval		now, later;
 	struct timezone		tz;
@@ -1002,13 +1009,12 @@ ServerLoop(void)
 
 	gettimeofday(&now, &tz);
 
-	nSockets = initMasks(&readmask, &writemask);
+	nSockets = initMasks(&readmask);
 
 	for (;;)
 	{
 		Port	   *port;
-		fd_set		rmask,
-					wmask;
+		fd_set		rmask;
 		struct timeval timeout;
 
 		/*
@@ -1057,11 +1063,11 @@ ServerLoop(void)
 		 * Wait for something to happen.
 		 */
 		memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set));
-		memcpy((char *) &wmask, (char *) &writemask, sizeof(fd_set));
 
 		PG_SETMASK(&UnBlockSig);
 
-		if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, &timeout) < 0)
+		if (select(nSockets, &rmask, (fd_set *) NULL,
+				   (fd_set *) NULL, &timeout) < 0)
 		{
 			PG_SETMASK(&BlockSig);
 			if (errno == EINTR || errno == EWOULDBLOCK)
@@ -1096,12 +1102,14 @@ ServerLoop(void)
 		}
 
 		/*
-		 * New connection pending on our well-known port's socket? If so,
+		 * New connection pending on any of our sockets? If so,
 		 * fork a child process to deal with it.
 		 */
 		for (i = 0; i < MAXLISTEN; i++)
 		{
-			if (ListenSocket[i] != -1 && FD_ISSET(ListenSocket[i], &rmask))
+			if (ListenSocket[i] == -1)
+				break;
+			if (FD_ISSET(ListenSocket[i], &rmask))
 			{
 				port = ConnCreate(ListenSocket[i]);
 				if (port)
@@ -1126,28 +1134,27 @@ ServerLoop(void)
 
 
 /*
- * Initialise the read and write masks for select() for the well-known ports
+ * Initialise the masks for select() for the ports
  * we are listening on.  Return the number of sockets to listen on.
  */
 
 static int
-initMasks(fd_set *rmask, fd_set *wmask)
+initMasks(fd_set *rmask)
 {
 	int			nsocks = -1;
 	int			i;
 
 	FD_ZERO(rmask);
-	FD_ZERO(wmask);
 
 	for (i = 0; i < MAXLISTEN; i++)
 	{
 		int	fd = ListenSocket[i];
-		if (fd != -1)
-		{
-			FD_SET(fd, rmask);
-			if (fd > nsocks)
-				nsocks = fd;
-		}
+
+		if (fd == -1)
+			break;
+		FD_SET(fd, rmask);
+		if (fd > nsocks)
+			nsocks = fd;
 	}
 
 	return nsocks + 1;
@@ -2352,17 +2359,15 @@ BackendFork(Port *port)
 	 */
 	remote_host[0] = '\0';
 	remote_port[0] = '\0';
-	if (!getnameinfo((struct sockaddr *)&port->raddr.addr,
-					 port->raddr.salen,
-					 remote_host, sizeof(remote_host),
-					 remote_port, sizeof(remote_host),
-					 (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV))
-	{
-		getnameinfo((struct sockaddr *)&port->raddr.addr,
-			port->raddr.salen,
-			remote_host, sizeof(remote_host),
-			remote_port, sizeof(remote_host),
-			NI_NUMERICHOST | NI_NUMERICSERV);
+	if (getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+						remote_host, sizeof(remote_host),
+						remote_port, sizeof(remote_port),
+						(log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV))
+	{
+		getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+						remote_host, sizeof(remote_host),
+						remote_port, sizeof(remote_port),
+						NI_NUMERICHOST | NI_NUMERICSERV);
 	}
 
 	if (Log_connections)
@@ -2373,7 +2378,7 @@ BackendFork(Port *port)
 	if (LogSourcePort)
 	{
 		/* modify remote_host for use in ps status */
-		char	tmphost[sizeof(remote_host) + 10];
+		char	tmphost[NI_MAXHOST];
 
 		snprintf(tmphost, sizeof(tmphost), "%s:%s", remote_host, remote_port);
 		StrNCpy(remote_host, tmphost, sizeof(remote_host));
diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h
index ced6df07e9a6e441b58ae753b9653d824316153c..6312482a7a9b1444d975eab756664b63a81222fd 100644
--- a/src/include/getaddrinfo.h
+++ b/src/include/getaddrinfo.h
@@ -3,7 +3,6 @@
  * 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
@@ -16,7 +15,7 @@
  *
  * Copyright (c) 2003, PostgreSQL Global Development Group
  *
- * $Id: getaddrinfo.h,v 1.6 2003/06/12 08:15:29 momjian Exp $
+ * $Id: getaddrinfo.h,v 1.7 2003/07/23 23:30:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
diff --git a/src/include/libpq/ip.h b/src/include/libpq/ip.h
index b770d33bfe391274d0c74614811b12f5bd8f8228..5c614b168153aa82797d736440b27a1e989a5f6e 100644
--- a/src/include/libpq/ip.h
+++ b/src/include/libpq/ip.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2003, PostgreSQL Global Development Group
  *
- * $Id: ip.h,v 1.8 2003/06/12 07:36:51 momjian Exp $
+ * $Id: ip.h,v 1.9 2003/07/23 23:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,10 +16,15 @@
 #include "libpq/pqcomm.h"
 
 
-extern int   getaddrinfo2(const char *hostname, const char *servname,
-						  const struct addrinfo *hintp,
-						  struct addrinfo **result);
-extern void  freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
+extern int   getaddrinfo_all(const char *hostname, const char *servname,
+							 const struct addrinfo *hintp,
+							 struct addrinfo **result);
+extern void  freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai);
+
+extern int getnameinfo_all(const struct sockaddr_storage *addr, int salen,
+						   char *node, int nodelen,
+						   char *service, int servicelen,
+						   int flags);
 
 extern int   rangeSockAddr(const struct sockaddr_storage *addr,
 			const struct sockaddr_storage *netaddr,
@@ -29,7 +34,7 @@ extern int SockAddr_cidr_mask(struct sockaddr_storage **mask,
 				char *numbits, int family);
 
 #ifdef	HAVE_UNIX_SOCKETS
-#define	IS_AF_UNIX(fam)	(fam == AF_UNIX)
+#define	IS_AF_UNIX(fam)	((fam) == AF_UNIX)
 #else
 #define	IS_AF_UNIX(fam) (0)
 #endif
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 0cabdc24c1177d3ae97369d605a67e8f99444d01..caa186b8320f015154ac837d413174358d19a7b7 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqcomm.h,v 1.89 2003/07/15 17:54:34 tgl Exp $
+ * $Id: pqcomm.h,v 1.90 2003/07/23 23:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,56 +32,47 @@
 #include <netinet/in.h>
 #endif   /* not WIN32 */
 
-#ifndef	HAVE_STRUCT_SOCKADDR_STORAGE
-/* Define a struct sockaddr_storage if we don't have one. */
-
-#define _SS_MAXSIZE    128		/* Implementation specific max size */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
 
-#ifdef __CYGWIN__
-typedef unsigned short sa_family_t;
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
+#  define ss_family __ss_family
+# else
+#  error struct sockaddr_storage does not provide an ss_family member
+# endif
 #endif
 
-/* This must exactly match the non-padding fields of sockaddr_storage! */
-struct nopad_sockaddr_storage {
-#ifdef SALEN
-    uint8	__ss_len;			/* address length */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+#define ss_len __ss_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
 #endif
-    sa_family_t	ss_family;		/* address family */
-
-    int64	__ss_align;			/* ensures struct is properly aligned */
-};
 
-struct sockaddr_storage {
-#ifdef SALEN
-    uint8	__ss_len;			/* address length */
-#endif
-    sa_family_t	ss_family;		/* address family */
+#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */
 
-    int64	__ss_align;			/* ensures struct is properly aligned */
+/* Define a struct sockaddr_storage if we don't have one. */
 
-    char	__ss_pad[_SS_MAXSIZE - sizeof(struct nopad_sockaddr_storage)];
-								/* ensures struct has desired size */
+struct sockaddr_storage {
+	union {
+		struct sockaddr sa;		/* get the system-dependent fields */
+		int64	ss_align;		/* ensures struct is properly aligned */
+		char	ss_pad[128];	/* ensures struct has desired size */
+	} ss_stuff;
 };
 
-#elif !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)
-# ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
-#  define ss_family __ss_family
-# else
-#  error struct sockaddr_storage does not provide an ss_family member
-# endif
+#define ss_family	ss_stuff.sa.sa_family
+/* It should have an ss_len field if sockaddr has sa_len. */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+#define ss_len		ss_stuff.sa.sa_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
 #endif
 
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+
 typedef struct {
 	struct sockaddr_storage	addr;
 	ACCEPT_TYPE_ARG3	salen;
 } SockAddr;
 
-/* Some systems don't have it, so default it to 0 so it doesn't
- * have any effect on those systems. */
-#ifndef	AI_ADDRCONFIG
-#define	AI_ADDRCONFIG 0
-#endif
-
 /* Configure the UNIX socket location for the well known port. */
 
 #define UNIXSOCK_PATH(path,port,defpath) \
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 41806fe8fb2a7bc8ca57ab854b5ba44dc8f85533..2fe4cd3ea1280c47b0a5f8feb1799a0f9b6d8e7f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -420,15 +420,24 @@
 /* Define to 1 if the system has the type `struct fcred'. */
 #undef HAVE_STRUCT_FCRED
 
+/* Define to 1 if `sa_len' is member of `struct sockaddr'. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
 /* Define to 1 if the system has the type `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE
 
 /* Define to 1 if `ss_family' is member of `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
 
+/* Define to 1 if `ss_len' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+
 /* Define to 1 if `__ss_family' is member of `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
 
+/* Define to 1 if `__ss_len' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+
 /* Define to 1 if the system has the type `struct sockaddr_un'. */
 #undef HAVE_STRUCT_SOCKADDR_UN
 
@@ -594,7 +603,8 @@
 /* Define to select SysV-style shared memory. */
 #undef USE_SYSV_SHARED_MEMORY
 
-/* Define to 1 to build libpq and ecpg to be thread-safe. (--with-threads) */
+/* Define to 1 to build libpq and ecpg to be thread-safe.
+   (--enable-thread-safeness) */
 #undef USE_THREADS
 
 /* Define to select unnamed POSIX semaphores. */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a931fe9fa24bd14c266a4dde44f0122da9e89920..0518cd21b4c75c070731a54e766f0ce72fb7afeb 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.252 2003/06/23 19:20:24 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.253 2003/07/23 23:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -759,26 +759,33 @@ connectNoDelay(PGconn *conn)
 static void
 connectFailureMessage(PGconn *conn, int errorno)
 {
-	char	hostname[NI_MAXHOST];
-	char	service[NI_MAXHOST];
 	char	sebuf[256];
 
-	getnameinfo((struct sockaddr *)&conn->raddr.addr, conn->raddr.salen,
-		hostname, sizeof(hostname), service, sizeof(service),
-		NI_NUMERICHOST | NI_NUMERICSERV);
-	if (conn->raddr.addr.ss_family == AF_UNIX)
+#ifdef HAVE_UNIX_SOCKETS
+	if (IS_AF_UNIX(conn->raddr.addr.ss_family))
+	{
+		char	service[NI_MAXHOST];
+
+		getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
+						NULL, 0,
+						service, sizeof(service),
+						NI_NUMERICSERV);
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext(
 									  "could not connect to server: %s\n"
 						"\tIs the server running locally and accepting\n"
 						  "\tconnections on Unix domain socket \"%s\"?\n"
 										),
-			SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), service);
+						  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
+						  service);
+	}
 	else
+#endif   /* HAVE_UNIX_SOCKETS */
+	{
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext(
 									  "could not connect to server: %s\n"
-					 "\tIs the server running on host %s and accepting\n"
+					 "\tIs the server running on host \"%s\" and accepting\n"
 									 "\tTCP/IP connections on port %s?\n"
 										),
 						  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
@@ -788,6 +795,7 @@ connectFailureMessage(PGconn *conn, int errorno)
 							 ? conn->pghost
 							 : "???"),
 						  conn->pgport);
+	}
 }
 
 
@@ -802,7 +810,7 @@ static int
 connectDBStart(PGconn *conn)
 {
 	int			portnum;
-	char			portstr[64];
+	char			portstr[128];
 	struct addrinfo		*addrs = NULL;
 	struct addrinfo		hint;
 	const char		*node = NULL;
@@ -816,7 +824,7 @@ connectDBStart(PGconn *conn)
 	conn->outCount = 0;
 
 	/*
-	 * Determine the parameters to pass to getaddrinfo2.
+	 * Determine the parameters to pass to getaddrinfo_all.
 	 */
 
 	/* Initialize hint structure */
@@ -854,14 +862,19 @@ connectDBStart(PGconn *conn)
 	}
 #endif   /* HAVE_UNIX_SOCKETS */
 
-	/* Use getaddrinfo2() to resolve the address */
-	ret = getaddrinfo2(node, portstr, &hint, &addrs);
-	if (ret || addrs == NULL)
+	/* Use getaddrinfo_all() to resolve the address */
+	ret = getaddrinfo_all(node, portstr, &hint, &addrs);
+	if (ret || !addrs)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("getaddrinfo() failed: %s\n"),
-						  gai_strerror(ret));
-		freeaddrinfo2(hint.ai_family, addrs);
+		if (node)
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("could not translate hostname \"%s\" to address: %s\n"),
+							  node, gai_strerror(ret));
+		else
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("could not translate local service to address: %s\n"),
+							  gai_strerror(ret));
+		freeaddrinfo_all(hint.ai_family, addrs);
 		goto connect_errReturn;
 	}
 
@@ -1068,7 +1081,7 @@ keep_going:						/* We will come back to here until there
 			{
 				/*
 				 * Try to initiate a connection to one of the addresses
-				 * returned by getaddrinfo2().  conn->addr_cur is the
+				 * returned by getaddrinfo_all().  conn->addr_cur is the
 				 * next one to try.  We fail when we run out of addresses
 				 * (reporting the error returned for the *last* alternative,
 				 * which may not be what users expect :-().
@@ -1083,9 +1096,7 @@ keep_going:						/* We will come back to here until there
 					conn->raddr.salen = addr_cur->ai_addrlen;
 
 					/* Open a socket */
-					conn->sock = socket(addr_cur->ai_family,
-							addr_cur->ai_socktype,
-							addr_cur->ai_protocol);
+					conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
 					if (conn->sock < 0)
 					{
 						/*
@@ -1263,15 +1274,12 @@ retry_connect:
 				 * If SSL is enabled and we haven't already got it running,
 				 * request it instead of sending the startup message.
 				 */
-
-#ifdef HAVE_UNIX_SOCKETS
-				if (conn->raddr.addr.ss_family == AF_UNIX)
+				if (IS_AF_UNIX(conn->raddr.addr.ss_family))
 				{
 					/* Don't bother requesting SSL over a Unix socket */
 					conn->allow_ssl_try = false;
 					conn->require_ssl = false;
 				}
-#endif
 				if (conn->allow_ssl_try && conn->ssl == NULL)
 				{
 					ProtocolVersion pv;
@@ -1712,7 +1720,7 @@ retry_ssl_read:
 				}
 
 				/* We can release the address list now. */
-				freeaddrinfo2(conn->addrlist_family, conn->addrlist);
+				freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
 				conn->addrlist = NULL;
 				conn->addr_cur = NULL;
 
@@ -1886,7 +1894,7 @@ freePGconn(PGconn *conn)
 	/* Note that conn->Pfdebug is not ours to close or free */
 	if (conn->notifyList)
 		DLFreeList(conn->notifyList);
-	freeaddrinfo2(conn->addrlist_family, conn->addrlist);
+	freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
 	if (conn->lobjfuncs)
 		free(conn->lobjfuncs);
 	if (conn->inBuffer)
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index cc584a2209a85077a217941126929cfdaecb5242..011437bb9b7bd2dcf52d4115894b275feddd76f1 100644
--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -3,12 +3,16 @@
  * getaddrinfo.c
  *	  Support getaddrinfo() on platforms that don't have it.
  *
+ * We also supply getnameinfo() here, assuming that the platform will have
+ * it if and only if it has getaddrinfo().  If this proves false on some
+ * platform, we'll need to split this file and provide a separate configure
+ * test for getnameinfo().
  *
- * Copyright (c) 2003, PostgreSQL Global Development Group
  *
+ * Copyright (c) 2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.9 2003/06/23 23:52:00 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.10 2003/07/23 23:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,9 +26,6 @@
 #include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#ifdef	HAVE_UNIX_SOCKETS
-#include <sys/un.h>
-#endif
 #endif
 
 #include "getaddrinfo.h"
@@ -124,8 +125,9 @@ getaddrinfo(const char *node, const char *service,
 
 	if (service)
 		sin.sin_port = htons((unsigned short) atoi(service));
-#if SALEN
-        sin.sin_len = sizeof(sin);
+
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+	sin.sin_len = sizeof(sin);
 #endif
 
 	ai = malloc(sizeof(*ai));
@@ -209,7 +211,7 @@ gai_strerror(int errcode)
 }
 
 /*
- * Convert an address to a hostname.
+ * Convert an ipv4 address to a hostname.
  * 
  * Bugs:	- Only supports NI_NUMERICHOST and NI_NUMERICSERV
  *		  It will never resolv a hostname.
@@ -217,11 +219,9 @@ gai_strerror(int errcode)
  */
 int
 getnameinfo(const struct sockaddr *sa, int salen,
-		char *node, int nodelen,
-		char *service, int servicelen, int flags)
+			char *node, int nodelen,
+			char *service, int servicelen, int flags)
 {
-	int		ret = -1;
-
 	/* Invalid arguments. */
 	if (sa == NULL || (node == NULL && service == NULL))
 	{
@@ -242,41 +242,32 @@ getnameinfo(const struct sockaddr *sa, int salen,
 	}
 #endif
 
-	if (service)
+	if (node)
 	{
+		int		ret = -1;
+
 		if (sa->sa_family == AF_INET)
 		{
-			ret = snprintf(service, servicelen, "%d",
-				ntohs(((struct sockaddr_in *)sa)->sin_port));
-		}
-#ifdef	HAVE_UNIX_SOCKETS
-		else if (sa->sa_family == AF_UNIX)
-		{
-			ret = snprintf(service, servicelen, "%s",
-				((struct sockaddr_un *)sa)->sun_path);
+			char	*p;
+			p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
+			ret = snprintf(node, nodelen, "%s", p);
 		}
-#endif
-		if (ret == -1 || ret > servicelen)
+		if (ret == -1 || ret > nodelen)
 		{
 			return EAI_MEMORY;
 		}
 	}
 
-	if (node)
+	if (service)
 	{
+		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);
-		}
-#ifdef	HAVE_UNIX_SOCKETS
-		else if (sa->sa_family == AF_UNIX)
-		{
-			ret = snprintf(node, nodelen, "%s", "localhost");
+			ret = snprintf(service, servicelen, "%d",
+						   ntohs(((struct sockaddr_in *)sa)->sin_port));
 		}
-#endif
-		if (ret == -1 || ret > nodelen)
+		if (ret == -1 || ret > servicelen)
 		{
 			return EAI_MEMORY;
 		}