about summary refs log tree commit diff
path: root/inet/getnameinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'inet/getnameinfo.c')
-rw-r--r--inet/getnameinfo.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index ce54fe42a8..0126f20326 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved.  */
 
-#include <alloca.h>
 #include <errno.h>
 #include <netdb.h>
 #include <stddef.h>
@@ -53,6 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sys/un.h>
 #include <sys/utsname.h>
 #include <bits/libc-lock.h>
+#include <scratch_buffer.h>
 
 #ifdef HAVE_LIBIDN
 # include <libidn/idna.h>
@@ -82,17 +82,21 @@ nrl_domainname (void)
 	{
 	  char *c;
 	  struct hostent *h, th;
-	  size_t tmpbuflen = 1024;
-	  char *tmpbuf = alloca (tmpbuflen);
 	  int herror;
+	  struct scratch_buffer tmpbuf;
 
+	  scratch_buffer_init (&tmpbuf);
 	  not_first = 1;
 
-	  while (__gethostbyname_r ("localhost", &th, tmpbuf, tmpbuflen, &h,
-				    &herror))
+	  while (__gethostbyname_r ("localhost", &th,
+				    tmpbuf.data, tmpbuf.length,
+				    &h, &herror))
 	    {
 	      if (herror == NETDB_INTERNAL && errno == ERANGE)
-		tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		{
+		  if (!scratch_buffer_grow (&tmpbuf))
+		    goto done;
+		}
 	      else
 		break;
 	    }
@@ -103,22 +107,26 @@ nrl_domainname (void)
 	    {
 	      /* The name contains no domain information.  Use the name
 		 now to get more information.  */
-	      while (__gethostname (tmpbuf, tmpbuflen))
-		tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+	      while (__gethostname (tmpbuf.data, tmpbuf.length))
+		if (!scratch_buffer_grow (&tmpbuf))
+		  goto done;
 
-	      if ((c = strchr (tmpbuf, '.')))
+	      if ((c = strchr (tmpbuf.data, '.')))
 		domain = __strdup (++c);
 	      else
 		{
 		  /* We need to preserve the hostname.  */
-		  const char *hstname = strdupa (tmpbuf);
+		  const char *hstname = strdupa (tmpbuf.data);
 
-		  while (__gethostbyname_r (hstname, &th, tmpbuf, tmpbuflen,
+		  while (__gethostbyname_r (hstname, &th,
+					    tmpbuf.data, tmpbuf.length,
 					    &h, &herror))
 		    {
 		      if (herror == NETDB_INTERNAL && errno == ERANGE)
-			tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
-						2 * tmpbuflen);
+			{
+			  if (!scratch_buffer_grow (&tmpbuf))
+			    goto done;
+			}
 		      else
 			break;
 		    }
@@ -133,12 +141,15 @@ nrl_domainname (void)
 
 		      while (__gethostbyaddr_r ((const char *) &in_addr,
 						sizeof (struct in_addr),
-						AF_INET, &th, tmpbuf,
-						tmpbuflen, &h, &herror))
+						AF_INET, &th,
+						tmpbuf.data, tmpbuf.length,
+						&h, &herror))
 			{
 			  if (herror == NETDB_INTERNAL && errno == ERANGE)
-			    tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
-						    2 * tmpbuflen);
+			    {
+			      if (!scratch_buffer_grow (&tmpbuf))
+				goto done;
+			    }
 			  else
 			    break;
 			}
@@ -148,6 +159,8 @@ nrl_domainname (void)
 		    }
 		}
 	    }
+	done:
+	  scratch_buffer_free (&tmpbuf);
 	}
 
       __libc_lock_unlock (lock);
@@ -163,11 +176,12 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	     int flags)
 {
   int serrno = errno;
-  int tmpbuflen = 1024;
   int herrno;
-  char *tmpbuf = alloca (tmpbuflen);
   struct hostent th;
   int ok = 0;
+  struct scratch_buffer tmpbuf;
+
+  scratch_buffer_init (&tmpbuf);
 
   if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM
 #ifdef HAVE_LIBIDN
@@ -212,21 +226,35 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	      {
 		while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
 					  sizeof(struct in6_addr),
-					  AF_INET6, &th, tmpbuf, tmpbuflen,
+					  AF_INET6, &th,
+					  tmpbuf.data, tmpbuf.length,
 					  &h, &herrno))
 		  if (herrno == NETDB_INTERNAL && errno == ERANGE)
-		    tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		    {
+		      if (!scratch_buffer_grow (&tmpbuf))
+			{
+			  __set_h_errno (herrno);
+			  return EAI_MEMORY;
+			}
+		    }
 		  else
 		    break;
 	      }
 	    else
 	      {
 		while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
-					  sizeof(struct in_addr), AF_INET,
-					  &th, tmpbuf, tmpbuflen,
+					  sizeof(struct in_addr),
+					  AF_INET, &th,
+					  tmpbuf.data, tmpbuf.length,
 					  &h, &herrno))
 		  if (herrno == NETDB_INTERNAL && errno == ERANGE)
-		    tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		    {
+		      if (!scratch_buffer_grow (&tmpbuf))
+			{
+			  __set_h_errno (herrno);
+			  return EAI_MEMORY;
+			}
+		    }
 		  else
 		    break;
 	      }
@@ -401,11 +429,14 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	    int e;
 	    while ((e = __getservbyport_r (((const struct sockaddr_in *) sa)->sin_port,
 					   ((flags & NI_DGRAM)
-					    ? "udp" : "tcp"),
-					   &ts, tmpbuf, tmpbuflen, &s)))
+					    ? "udp" : "tcp"), &ts,
+					   tmpbuf.data, tmpbuf.length, &s)))
 	      {
 		if (e == ERANGE)
-		  tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+		  {
+		    if (!scratch_buffer_grow (&tmpbuf))
+		      return EAI_MEMORY;
+		  }
 		else
 		  break;
 	      }