file_util: consolidate hex/unhex routines
[oweals/opkg-lede.git] / libopkg / file_util.c
index 1a98df6a102bc0a9d9495b57328a16a9cac02b85..759c21b3ae76d206f717022c38dc8538fecf0d52 100644 (file)
 
 #include "sprintf_alloc.h"
 #include "file_util.h"
-#ifdef HAVE_MD5
-#include "md5.h"
-#endif
+#include <libubox/md5.h>
 #include "libbb/libbb.h"
 
-#if defined HAVE_SHA256
 #include "sha256.h"
-#endif
 
 int file_exists(const char *file_name)
 {
@@ -129,42 +125,43 @@ int file_mkdir_hier(const char *path, long mode)
        return make_directory(path, mode, FILEUTILS_RECUR);
 }
 
-#ifdef HAVE_MD5
+
+static int hex2bin(unsigned char x)
+{
+       if (x >= 'a' && x <= 'f')
+               return x - 'a' + 10;
+       else if (x >= 'A' && x <= 'F')
+               return x - 'A' + 10;
+       else if (x >= '0' && x <= '9')
+               return x - '0';
+       else
+               return 0;
+}
+
+static const unsigned char bin2hex[16] = {
+       '0', '1', '2', '3',
+       '4', '5', '6', '7',
+       '8', '9', 'a', 'b',
+       'c', 'd', 'e', 'f'
+};
+
 char *file_md5sum_alloc(const char *file_name)
 {
        static const int md5sum_bin_len = 16;
        static const int md5sum_hex_len = 32;
 
-       static const unsigned char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
-       int i, err;
-       FILE *file;
+       int i, len;
        char *md5sum_hex;
        unsigned char md5sum_bin[md5sum_bin_len];
 
-       md5sum_hex = xcalloc(1, md5sum_hex_len + 1);
+       len = md5sum(file_name, md5sum_bin);
 
-       file = fopen(file_name, "r");
-       if (file == NULL) {
-               opkg_perror(ERROR, "Failed to open file %s", file_name);
-               free(md5sum_hex);
-               return NULL;
-       }
-
-       err = md5_stream(file, md5sum_bin);
-       if (err) {
+       if (len) {
                opkg_msg(ERROR, "Could't compute md5sum for %s.\n", file_name);
-               fclose(file);
-               free(md5sum_hex);
                return NULL;
        }
 
-       fclose(file);
+       md5sum_hex = xcalloc(1, md5sum_hex_len + 1);
 
        for (i = 0; i < md5sum_bin_len; i++) {
                md5sum_hex[i * 2] = bin2hex[md5sum_bin[i] >> 4];
@@ -175,21 +172,12 @@ char *file_md5sum_alloc(const char *file_name)
 
        return md5sum_hex;
 }
-#endif
 
-#ifdef HAVE_SHA256
 char *file_sha256sum_alloc(const char *file_name)
 {
        static const int sha256sum_bin_len = 32;
        static const int sha256sum_hex_len = 64;
 
-       static const unsigned char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        int i, err;
        FILE *file;
        char *sha256sum_hex;
@@ -225,20 +213,11 @@ char *file_sha256sum_alloc(const char *file_name)
        return sha256sum_hex;
 }
 
-#endif
-
 char *checksum_bin2hex(const char *src, size_t len)
 {
        unsigned char *p;
        static unsigned char buf[65];
        const unsigned char *s = (unsigned char *)src;
-       static const unsigned char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        if (!s || len > 32)
                return NULL;
 
@@ -274,13 +253,10 @@ char *checksum_hex2bin(const char *src, size_t *len)
                return NULL;
        }
 
-#define hex(c) \
-       (c >= 'a' ? (c - 'a') : (c >= 'A' ? (c - 'A') : (c - '0')))
-
        for (p = buf, *len = 0;
             slen > 0 && isxdigit(s[0]) && isxdigit(s[1]);
             slen--, s += 2, (*len)++)
-               *p++ = hex(s[0]) * 16 + hex(s[1]);
+               *p++ = hex2bin(s[0]) * 16 + hex2bin(s[1]);
 
        return (char *)buf;
 }
@@ -366,3 +342,56 @@ int rm_r(const char *path)
 
        return ret;
 }
+
+static int urlencode_is_specialchar(char c)
+{
+       switch (c) {
+       case ':':
+       case '?':
+       case '#':
+       case '[':
+       case ']':
+       case '@':
+       case '!':
+       case '$':
+       case '&':
+       case '\'':
+       case '(':
+       case ')':
+       case '*':
+       case '+':
+       case ',':
+       case ';':
+       case '=':
+       case '%':
+               return 1;
+
+       default:
+               return 0;
+       }
+}
+
+char *urlencode_path(const char *filename)
+{
+       size_t len = 0;
+       const unsigned char *in;
+       unsigned char *copy, *out;
+
+       for (in = (unsigned char *)filename; *in != 0; in++)
+               len += urlencode_is_specialchar(*in) ? 3 : 1;
+
+       copy = xcalloc(1, len + 1);
+
+       for (in = (unsigned char *)filename, out = copy; *in != 0; in++) {
+               if (urlencode_is_specialchar(*in)) {
+                       *out++ = '%';
+                       *out++ = bin2hex[*in / 16];
+                       *out++ = bin2hex[*in % 16];
+               }
+               else {
+                       *out++ = *in;
+               }
+       }
+
+       return (char *)copy;
+}