about summary refs log tree commit diff
path: root/inet
diff options
context:
space:
mode:
Diffstat (limited to 'inet')
-rw-r--r--inet/getnameinfo.c99
1 files changed, 51 insertions, 48 deletions
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index 6beeba0a19..119def2f83 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -175,25 +175,28 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
   struct hostent th;
   int ok = 0;
 
+  if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM))
+    return EAI_BADFLAGS;
+
   if (sa == NULL || addrlen < sizeof (sa_family_t))
-    return -1;
+    return EAI_FAMILY;
 
   switch (sa->sa_family)
     {
     case AF_LOCAL:
       if (addrlen < (socklen_t) (((struct sockaddr_un *) NULL)->sun_path))
-	return -1;
+	return EAI_FAMILY;
       break;
     case AF_INET:
       if (addrlen < sizeof (struct sockaddr_in))
-	return -1;
+	return EAI_FAMILY;
       break;
     case AF_INET6:
       if (addrlen < sizeof (struct sockaddr_in6))
-	return -1;
+	return EAI_FAMILY;
       break;
     default:
-      return -1;
+      return EAI_FAMILY;
     }
 
   if (host != NULL && hostlen > 0)
@@ -224,7 +227,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 			      {
 				__set_h_errno (herrno);
 				__set_errno (serrno);
-				return -1;
+				return EAI_SYSTEM;
 			      }
 			  }
 			else
@@ -255,26 +258,23 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 
 	    if (h)
 	      {
-		if (flags & NI_NOFQDN)
+		char *c;
+		if ((flags & NI_NOFQDN) == 0
+		    && (c = nrl_domainname ())
+		    && (c = strstr (h->h_name, c))
+		    && (c != h->h_name) && (*(--c) == '.'))
 		  {
-		    char *c;
-		    if ((c = nrl_domainname ()) && (c = strstr(h->h_name, c))
-			&& (c != h->h_name) && (*(--c) == '.'))
-		      {
-			strncpy (host, h->h_name,
-				 min(hostlen, (size_t) (c - h->h_name)));
-			host[min(hostlen - 1, (size_t) (c - h->h_name))]
-			  = '\0';
-			ok = 1;
-		      }
-		    else
-		      {
-			strncpy (host, h->h_name, hostlen);
-			ok = 1;
-		      }
+		    strncpy (host, h->h_name,
+			     min(hostlen, (size_t) (c - h->h_name)));
+		    host[min(hostlen - 1, (size_t) (c - h->h_name))]
+		      = '\0';
+		    ok = 1;
+		  }
+		else
+		  {
+		    strncpy (host, h->h_name, hostlen);
+		    ok = 1;
 		  }
-		strncpy (host, h->h_name, hostlen);
-		ok = 1;
 	      }
 	  }
 
@@ -283,7 +283,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	    if (flags & NI_NAMEREQD)
 	      {
 		__set_errno (serrno);
-		return -1;
+		return EAI_NONAME;
 	      }
 	    else
 	      {
@@ -295,40 +295,43 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 
 		    c = inet_ntop (AF_INET6,
 				   (void *) &sin6p->sin6_addr, host, hostlen);
-		    if (addrlen > sizeof (struct sockaddr_in6)
-			&& (scopeid = sin6p->sin6_scope_id))
+		    scopeid = sin6p->sin6_scope_id;
+		    if (scopeid != 0)
 		      {
 			/* Buffer is >= IFNAMSIZ+1.  */
 			char scopebuf[IFNAMSIZ + 1];
+			char *scopeptr;
 			int ni_numericscope = 0;
+			size_t real_hostlen = __strnlen (host, hostlen);
+			size_t scopelen = 0;
+
+			scopebuf[0] = SCOPE_DELIMITER;
+			scopebuf[1] = '\0';
+			scopeptr = &scopebuf[1];
 
 			if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
 			    || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
 			  {
 			    if (if_indextoname (scopeid, scopebuf) == NULL)
 			      ++ni_numericscope;
+			    else
+			      scopelen = strlen (scopebuf);
 			  }
 			else
 			  ++ni_numericscope;
 
 			if (ni_numericscope)
-			  {
-			    char *scopeptr = &scopebuf[1];
-			    size_t real_hostlen;
-			    size_t scopelen;
-
-			    scopebuf[0] = SCOPE_DELIMITER;
-			    scopelen = 1 + __snprintf (scopeptr,
-						       (scopebuf
-							+ sizeof scopebuf
-							- scopeptr),
-						       "%u", scopeid);
-
-			    real_hostlen = __strnlen (host, hostlen);
-			    if (real_hostlen + scopelen + 1 > hostlen)
-			      return -1;
-			    memcpy (host + real_hostlen, scopebuf, scopelen);
-			  }
+			  scopelen = 1 + __snprintf (scopeptr,
+						     (scopebuf
+						      + sizeof scopebuf
+						      - scopeptr),
+						     "%u", scopeid);
+
+			if (real_hostlen + scopelen + 1 > hostlen)
+			  /* XXX We should not fail here.  Simply enlarge
+			     the buffer or return with out of memory.  */
+			  return EAI_SYSTEM;
+			memcpy (host + real_hostlen, scopebuf, scopelen + 1);
 		      }
 		  }
 		else
@@ -338,7 +341,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 		if (c == NULL)
 		  {
 		    __set_errno (serrno);
-		    return -1;
+		    return EAI_SYSTEM;
 		  }
 	      }
 	    ok = 1;
@@ -360,14 +363,14 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	if (flags & NI_NAMEREQD)
 	   {
 	    __set_errno (serrno);
-	    return -1;
+	    return EAI_NONAME;
 	  }
 
 	strncpy (host, "localhost", hostlen);
 	break;
 
       default:
-        return -1;
+        return EAI_FAMILY;
     }
 
   if (serv && (servlen > 0))
@@ -392,7 +395,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 		    else
 		      {
 			__set_errno (serrno);
-			return -1;
+			return EAI_SYSTEM;
 		      }
 		  }
 		else