(getanswer_r): Correctly track usage of user-provided buffer.
[kopensolaris-gnu/glibc.git] / resolv / inet_pton.c
index 385dc25..e1419b9 100644 (file)
@@ -24,20 +24,21 @@ static char rcsid[] = "$Id$";
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
+#include <ctype.h>
 #include <string.h>
 #include <errno.h>
 #include <string.h>
 #include <errno.h>
-#include "../conf/portability.h"
+#include <conf/portability.h>
 
 /*
  * WARNING: Don't even consider trying to compile this on a system where
  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  */
 
 
 /*
  * WARNING: Don't even consider trying to compile this on a system where
  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  */
 
-static int     inet_pton4 __P((const char *src, u_char *dst));
-static int     inet_pton6 __P((const char *src, u_char *dst));
+static int inet_pton4 __P((const char *src, u_char *dst)) internal_function;
+static int inet_pton6 __P((const char *src, u_char *dst)) internal_function;
 
 /* int
 
 /* int
- * inet_pton(af, src, dst, size)
+ * inet_pton(af, src, dst)
  *     convert from presentation format (which usually means ASCII printable)
  *     to network format (which is usually some kind of binary format).
  * return:
  *     convert from presentation format (which usually means ASCII printable)
  *     to network format (which is usually some kind of binary format).
  * return:
@@ -48,27 +49,18 @@ static int  inet_pton6 __P((const char *src, u_char *dst));
  *     Paul Vixie, 1996.
  */
 int
  *     Paul Vixie, 1996.
  */
 int
-inet_pton(af, src, dst, size)
+inet_pton(af, src, dst)
        int af;
        const char *src;
        void *dst;
        int af;
        const char *src;
        void *dst;
-       size_t size;
 {
        switch (af) {
        case AF_INET:
 {
        switch (af) {
        case AF_INET:
-               if (size < INADDRSZ) {
-                       errno = ENOSPC;
-                       return (-1);
-               }
                return (inet_pton4(src, dst));
        case AF_INET6:
                return (inet_pton4(src, dst));
        case AF_INET6:
-               if (size < IN6ADDRSZ) {
-                       errno = ENOSPC;
-                       return (-1);
-               }
                return (inet_pton6(src, dst));
        default:
                return (inet_pton6(src, dst));
        default:
-               errno = EINVAL;
+               __set_errno (EAFNOSUPPORT);
                return (-1);
        }
        /* NOTREACHED */
                return (-1);
        }
        /* NOTREACHED */
@@ -76,7 +68,7 @@ inet_pton(af, src, dst, size)
 
 /* int
  * inet_pton4(src, dst)
 
 /* int
  * inet_pton4(src, dst)
- *     like inet_pton() but without all the hexadecimal and shorthand.
+ *     like inet_aton() but without all the hexadecimal and shorthand.
  * return:
  *     1 if `src' is a valid dotted quad, else 0.
  * notice:
  * return:
  *     1 if `src' is a valid dotted quad, else 0.
  * notice:
@@ -85,11 +77,11 @@ inet_pton(af, src, dst, size)
  *     Paul Vixie, 1996.
  */
 static int
  *     Paul Vixie, 1996.
  */
 static int
+internal_function
 inet_pton4(src, dst)
        const char *src;
        u_char *dst;
 {
 inet_pton4(src, dst)
        const char *src;
        u_char *dst;
 {
-       static const char digits[] = "0123456789";
        int saw_digit, octets, ch;
        u_char tmp[INADDRSZ], *tp;
 
        int saw_digit, octets, ch;
        u_char tmp[INADDRSZ], *tp;
 
@@ -97,10 +89,9 @@ inet_pton4(src, dst)
        octets = 0;
        *(tp = tmp) = 0;
        while ((ch = *src++) != '\0') {
        octets = 0;
        *(tp = tmp) = 0;
        while ((ch = *src++) != '\0') {
-               const char *pch;
 
 
-               if ((pch = strchr(digits, ch)) != NULL) {
-                       u_int new = *tp * 10 + (pch - digits);
+               if (ch >= '0' && ch <= '9') {
+                       u_int new = *tp * 10 + (ch - '0');
 
                        if (new > 255)
                                return (0);
 
                        if (new > 255)
                                return (0);
@@ -120,7 +111,8 @@ inet_pton4(src, dst)
        }
        if (octets < 4)
                return (0);
        }
        if (octets < 4)
                return (0);
-       bcopy(tmp, dst, INADDRSZ);
+
+       memcpy(dst, tmp, INADDRSZ);
        return (1);
 }
 
        return (1);
 }
 
@@ -138,18 +130,18 @@ inet_pton4(src, dst)
  *     Paul Vixie, 1996.
  */
 static int
  *     Paul Vixie, 1996.
  */
 static int
+internal_function
 inet_pton6(src, dst)
        const char *src;
        u_char *dst;
 {
 inet_pton6(src, dst)
        const char *src;
        u_char *dst;
 {
-       static const char xdigits_l[] = "0123456789abcdef",
-                         xdigits_u[] = "0123456789ABCDEF";
+       static const char xdigits[] = "0123456789abcdef";
        u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
        u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
-       const char *xdigits, *curtok;
+       const char *curtok;
        int ch, saw_xdigit;
        u_int val;
 
        int ch, saw_xdigit;
        u_int val;
 
-       bzero((tp = tmp), IN6ADDRSZ);
+       tp = memset(tmp, '\0', IN6ADDRSZ);
        endp = tp + IN6ADDRSZ;
        colonp = NULL;
        /* Leading :: requires some special handling. */
        endp = tp + IN6ADDRSZ;
        colonp = NULL;
        /* Leading :: requires some special handling. */
@@ -159,11 +151,10 @@ inet_pton6(src, dst)
        curtok = src;
        saw_xdigit = 0;
        val = 0;
        curtok = src;
        saw_xdigit = 0;
        val = 0;
-       while ((ch = *src++) != '\0') {
+       while ((ch = tolower (*src++)) != '\0') {
                const char *pch;
 
                const char *pch;
 
-               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-                       pch = strchr((xdigits = xdigits_u), ch);
+               pch = strchr(xdigits, ch);
                if (pch != NULL) {
                        val <<= 4;
                        val |= (pch - xdigits);
                if (pch != NULL) {
                        val <<= 4;
                        val |= (pch - xdigits);
@@ -207,17 +198,17 @@ inet_pton6(src, dst)
                 * Since some memmove()'s erroneously fail to handle
                 * overlapping regions, we'll do the shift by hand.
                 */
                 * Since some memmove()'s erroneously fail to handle
                 * overlapping regions, we'll do the shift by hand.
                 */
-               const howmany = tp - colonp;
+               const int n = tp - colonp;
                int i;
 
                int i;
 
-               for (i = 1; i <= howmany; i++) {
-                       endp[- i] = colonp[howmany - i];
-                       colonp[howmany - i] = 0;
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
                }
                tp = endp;
        }
        if (tp != endp)
                return (0);
                }
                tp = endp;
        }
        if (tp != endp)
                return (0);
-       bcopy(tmp, dst, IN6ADDRSZ);
+       memcpy(dst, tmp, IN6ADDRSZ);
        return (1);
 }
        return (1);
 }