libopkg: fix hex encoding/decoding, add checksum getter/setter
[oweals/opkg-lede.git] / libopkg / pkg.c
index 2a393a7e7736cec894ad44e87f809f6d947ea92a..1a3eda8167bcaf3700cf2940fcff44627a62a4cc 100644 (file)
@@ -80,13 +80,13 @@ static void pkg_init(pkg_t * pkg)
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
-       active_list_init(&pkg->list);
-
        pkg->installed_files = NULL;
        pkg->installed_files_ref_cnt = 0;
        pkg->essential = 0;
        pkg->provided_by_hand = 0;
 
        pkg->installed_files = NULL;
        pkg->installed_files_ref_cnt = 0;
        pkg->essential = 0;
        pkg->provided_by_hand = 0;
 
+       pkg->arch_index = 0;
+
        blob_buf_init(&pkg->blob, 0);
 }
 
        blob_buf_init(&pkg->blob, 0);
 }
 
@@ -159,6 +159,101 @@ char *pkg_set_string(pkg_t *pkg, int id, const char *s)
        return p;
 }
 
        return p;
 }
 
+char *pkg_get_architecture(const pkg_t *pkg)
+{
+       nv_pair_list_elt_t *l;
+       int n = 1;
+
+       list_for_each_entry(l, &conf->arch_list.head, node) {
+               nv_pair_t *nv = (nv_pair_t *) l->data;
+               if (n++ == pkg->arch_index)
+                       return nv->name;
+       }
+
+       return NULL;
+}
+
+char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len)
+{
+       nv_pair_list_elt_t *l;
+       int n = 1;
+
+       list_for_each_entry(l, &conf->arch_list.head, node) {
+               nv_pair_t *nv = (nv_pair_t *) l->data;
+
+               if (!strncmp(nv->name, architecture, len) && nv->name[len] == '\0') {
+                       if (n >= 8) {
+                               opkg_msg(ERROR, "Internal error: too many different architectures\n");
+                               break;
+                       }
+
+                       pkg->arch_index = n;
+                       return nv->name;
+               }
+
+               n++;
+       }
+
+       pkg->arch_index = 0;
+       return NULL;
+}
+
+int pkg_get_arch_priority(const pkg_t *pkg)
+{
+       nv_pair_list_elt_t *l;
+       int n = 1;
+
+       list_for_each_entry(l, &conf->arch_list.head, node) {
+               nv_pair_t *nv = (nv_pair_t *) l->data;
+               if (n++ == pkg->arch_index)
+                       return strtol(nv->value, NULL, 0);
+       }
+
+       return 0;
+}
+
+char *pkg_get_md5(const pkg_t *pkg)
+{
+       char *p = pkg_get_raw(pkg, PKG_MD5SUM);
+
+       if (!p)
+               return NULL;
+
+       return checksum_bin2hex(p, 16);
+}
+
+char *pkg_set_md5(pkg_t *pkg, const char *cksum)
+{
+       size_t len;
+       char *p = checksum_hex2bin(cksum, &len);
+
+       if (!p || len != 16)
+               return NULL;
+
+       return pkg_set_raw(pkg, PKG_MD5SUM, p, len);
+}
+
+char *pkg_get_sha256(const pkg_t *pkg)
+{
+       char *p = pkg_get_raw(pkg, PKG_SHA256SUM);
+
+       if (!p)
+               return NULL;
+
+       return checksum_bin2hex(p, 32);
+}
+
+char *pkg_set_sha256(pkg_t *pkg, const char *cksum)
+{
+       size_t len;
+       char *p = checksum_hex2bin(cksum, &len);
+
+       if (!p || len != 32)
+               return NULL;
+
+       return pkg_set_raw(pkg, PKG_SHA256SUM, p, len);
+}
+
 
 static void compound_depend_deinit(compound_depend_t * depends)
 {
 
 static void compound_depend_deinit(compound_depend_t * depends)
 {
@@ -189,8 +284,6 @@ void pkg_deinit(pkg_t * pkg)
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
-       active_list_clear(&pkg->list);
-
        deps = pkg_get_ptr(pkg, PKG_DEPENDS);
 
        if (deps) {
        deps = pkg_get_ptr(pkg, PKG_DEPENDS);
 
        if (deps) {
@@ -296,10 +389,8 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                oldpkg->src = newpkg->src;
        if (!oldpkg->dest)
                oldpkg->dest = newpkg->dest;
                oldpkg->src = newpkg->src;
        if (!oldpkg->dest)
                oldpkg->dest = newpkg->dest;
-       if (!pkg_get_string(oldpkg, PKG_ARCHITECTURE))
-               pkg_set_string(oldpkg, PKG_ARCHITECTURE, pkg_get_string(newpkg, PKG_ARCHITECTURE));
-       if (!pkg_get_int(oldpkg, PKG_ARCH_PRIORITY))
-               pkg_set_int(oldpkg, PKG_ARCH_PRIORITY, pkg_get_int(newpkg, PKG_ARCH_PRIORITY));
+       if (!oldpkg->arch_index)
+               oldpkg->arch_index = newpkg->arch_index;
        if (!pkg_get_string(oldpkg, PKG_SECTION))
                pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION));
        if (!pkg_get_string(oldpkg, PKG_MAINTAINER))
        if (!pkg_get_string(oldpkg, PKG_SECTION))
                pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION));
        if (!pkg_get_string(oldpkg, PKG_MAINTAINER))
@@ -335,10 +426,10 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
        if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR))
                pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR));
                pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
        if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR))
                pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR));
-       if (!pkg_get_string(oldpkg, PKG_MD5SUM))
-               pkg_set_string(oldpkg, PKG_MD5SUM, pkg_get_string(newpkg, PKG_MD5SUM));
-       if (!pkg_get_string(oldpkg, PKG_SHA256SUM))
-               pkg_set_string(oldpkg, PKG_SHA256SUM, pkg_get_string(newpkg, PKG_SHA256SUM));
+       if (!pkg_get_md5(oldpkg))
+               pkg_set_md5(oldpkg, pkg_get_md5(newpkg));
+       if (!pkg_get_sha256(oldpkg))
+               pkg_set_sha256(oldpkg, pkg_get_sha256(newpkg));
        if (!pkg_get_int(oldpkg, PKG_SIZE))
                pkg_set_int(oldpkg, PKG_SIZE, pkg_get_int(newpkg, PKG_SIZE));
        if (!pkg_get_int(oldpkg, PKG_INSTALLED_SIZE))
        if (!pkg_get_int(oldpkg, PKG_SIZE))
                pkg_set_int(oldpkg, PKG_SIZE, pkg_get_int(newpkg, PKG_SIZE));
        if (!pkg_get_int(oldpkg, PKG_INSTALLED_SIZE))
@@ -548,7 +639,7 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'a':
        case 'A':
                if (strcasecmp(field, "Architecture") == 0) {
        case 'a':
        case 'A':
                if (strcasecmp(field, "Architecture") == 0) {
-                       p = pkg_get_string(pkg, PKG_ARCHITECTURE);
+                       p = pkg_get_architecture(pkg);
                        if (p) {
                                fprintf(fp, "Architecture: %s\n",
                                        p);
                        if (p) {
                                fprintf(fp, "Architecture: %s\n",
                                        p);
@@ -667,7 +758,7 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                                fprintf(fp, "Maintainer: %s\n", p);
                        }
                } else if (strcasecmp(field, "MD5sum") == 0) {
                                fprintf(fp, "Maintainer: %s\n", p);
                        }
                } else if (strcasecmp(field, "MD5sum") == 0) {
-                       p = pkg_get_string(pkg, PKG_MD5SUM);
+                       p = pkg_get_md5(pkg);
                        if (p) {
                                fprintf(fp, "MD5Sum: %s\n", p);
                        }
                        if (p) {
                                fprintf(fp, "MD5Sum: %s\n", p);
                        }
@@ -987,8 +1078,8 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
        vercmp = pkg_compare_versions(a, b);
        if (vercmp)
                return vercmp;
        vercmp = pkg_compare_versions(a, b);
        if (vercmp)
                return vercmp;
-       arch_prio1 = pkg_get_int(a, PKG_ARCH_PRIORITY);
-       arch_prio2 = pkg_get_int(b, PKG_ARCH_PRIORITY);
+       arch_prio1 = pkg_get_arch_priority(a);
+       arch_prio2 = pkg_get_arch_priority(b);
        if (!arch_prio1 || !arch_prio2) {
                opkg_msg(ERROR,
                         "Internal error: a->arch_priority=%i b->arch_priority=%i.\n",
        if (!arch_prio1 || !arch_prio2) {
                opkg_msg(ERROR,
                         "Internal error: a->arch_priority=%i b->arch_priority=%i.\n",
@@ -1305,7 +1396,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
 int pkg_arch_supported(pkg_t * pkg)
 {
        nv_pair_list_elt_t *l;
 int pkg_arch_supported(pkg_t * pkg)
 {
        nv_pair_list_elt_t *l;
-       char *architecture = pkg_get_string(pkg, PKG_ARCHITECTURE);
+       char *architecture = pkg_get_architecture(pkg);
 
        if (!architecture)
                return 1;
 
        if (!architecture)
                return 1;