libbb: factor out hex2bin() for infiniband address parser
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 4 Apr 2010 13:29:32 +0000 (15:29 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 4 Apr 2010 13:29:32 +0000 (15:29 +0200)
function                                             old     new   delta
hex2bin                                                -     149    +149
in_ib                                                172      27    -145

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
libbb/xfuncs.c
networking/interface.c
networking/wget.c

index 794e4388984f2fd85c77d21f9499cc67781fdf3d..e674e4aeabf701b194d823246e69e5d1e4aecc5d 100644 (file)
@@ -734,6 +734,8 @@ const char *make_human_readable_str(unsigned long long size,
                unsigned long block_size, unsigned long display_unit) FAST_FUNC;
 /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
 char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC;
+/* Reverse */
+char* hex2bin(char *dst, const char *str, int count) FAST_FUNC;
 
 /* Generate a UUID */
 void generate_uuid(uint8_t *buf) FAST_FUNC;
index aac46f414ff7f28e895db30a98422fcae7f3eba2..aec165f0612dd86fb9052d7f408afb5128d43fad 100644 (file)
@@ -122,6 +122,41 @@ char* FAST_FUNC bin2hex(char *p, const char *cp, int count)
        return p;
 }
 
+/* Convert "[x]x[:][x]x[:][x]x[:][x]x" hex string to binary, no more than COUNT bytes */
+char* FAST_FUNC hex2bin(char *dst, const char *str, int count)
+{
+       errno = EINVAL;
+       while (*str && count) {
+               uint8_t val;
+               uint8_t c = *str++;
+               if (isdigit(c))
+                       val = c - '0';
+               else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
+                       val = (c|0x20) - ('a' - 10);
+               else
+                       return NULL;
+               val <<= 4;
+               c = *str;
+               if (isdigit(c))
+                       val |= c - '0';
+               else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
+                       val |= (c|0x20) - ('a' - 10);
+               else if (c == ':' || c == '\0')
+                       val >>= 4;
+               else
+                       return NULL;
+
+               *dst++ = val;
+               if (c != '\0')
+                       str++;
+               if (*str == ':')
+                       str++;
+               count--;
+       }
+       errno = (*str ? ERANGE : 0);
+       return dst;
+}
+
 /* Return how long the file at fd is, if there's any way to determine it. */
 #ifdef UNUSED
 off_t FAST_FUNC fdlength(int fd)
index b59a61de4d4903aa757c1582b73ec4d241aa95a2..a59f310a6abb9e7cef59aa15fc5f9aa87bda3501 100644 (file)
@@ -30,7 +30,6 @@
  *         20001008 - Bernd Eckenfels, Patch from RH for setting mtu
  *                     (default AF was wrong)
  */
-
 #include <net/if.h>
 #include <net/if_arp.h>
 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION)
@@ -1215,53 +1214,12 @@ static int if_print(char *ifname)
 /* Input an Infiniband address and convert to binary. */
 int FAST_FUNC in_ib(const char *bufp, struct sockaddr *sap)
 {
-       unsigned char *ptr;
-       char c;
-       const char *orig;
-       int i;
-       unsigned val;
-
        sap->sa_family = ib_hwtype.type;
-       ptr = (unsigned char *) sap->sa_data;
-
-       i = 0;
-       orig = bufp;
-       while ((*bufp != '\0') && (i < INFINIBAND_ALEN)) {
-               val = 0;
-               c = *bufp++;
-               if (isdigit(c))
-                       val = c - '0';
-               else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
-                       val = (c|0x20) - ('a' - 10);
-               else {
-                       errno = EINVAL;
-                       return -1;
-               }
-               val <<= 4;
-               c = *bufp;
-               if (isdigit(c))
-                       val |= c - '0';
-               else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
-                       val |= (c|0x20) - ('a' - 10);
-               else if (c == ':' || c == '\0')
-                       val >>= 4;
-               else {
-                       errno = EINVAL;
-                       return -1;
-               }
-               if (c != '\0')
-                       bufp++;
-               *ptr++ = (unsigned char) (val & 0377);
-               i++;
-
-               /* We might get a semicolon here - not required. */
-               if (*bufp == ':') {
-                       bufp++;
-               }
-       }
-#ifdef DEBUG
-       fprintf(stderr, "in_ib(%s): %s\n", orig, UNSPEC_print(sap->sa_data));
-#endif
+//TODO: error check?
+       hex2bin((char*)sap->sa_data, bufp, INFINIBAND_ALEN);
+# ifdef HWIB_DEBUG
+       fprintf(stderr, "in_ib(%s): %s\n", bufp, UNSPEC_print(sap->sa_data));
+# endif
        return 0;
 }
 #endif
index 5b73b933b7ffbef16e70ee983f2bebabd92db663..97f4a8f6e7b7d711b7bbfd10d65408721f2c8038 100644 (file)
@@ -282,8 +282,10 @@ static char *gethdr(char *buf, size_t bufsiz, FILE *fp /*, int *istrunc*/)
                return NULL;
 
        /* convert the header name to lower case */
-       for (s = buf; isalnum(*s) || *s == '-' || *s == '.'; ++s)
-               *s = tolower(*s);
+       for (s = buf; isalnum(*s) || *s == '-' || *s == '.'; ++s) {
+               /* tolower for "A-Z", no-op for "0-9a-z-." */
+               *s = (*s | 0x20);
+       }
 
        /* verify we are at the end of the header name */
        if (*s != ':')