libopkg: fix printing provides in pkg_formatted_field()
[oweals/opkg-lede.git] / libopkg / pkg.c
index 30602bf87f6850f05a6b4ddcb46a66b96150cc6a..023cf75c466797960dfe9483fc2dcff1e702f486 100644 (file)
@@ -79,36 +79,14 @@ static void pkg_init(pkg_t * pkg)
        pkg->state_want = SW_UNKNOWN;
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
-       pkg->depends_str = NULL;
-       pkg->provides_str = NULL;
-       pkg->depends_count = 0;
-       pkg->depends = NULL;
-       pkg->suggests_str = NULL;
-       pkg->recommends_str = NULL;
-       pkg->suggests_count = 0;
-       pkg->recommends_count = 0;
-
-       active_list_init(&pkg->list);
-
-       pkg->conflicts = NULL;
-       pkg->conflicts_count = 0;
-
-       pkg->replaces = NULL;
-       pkg->replaces_count = 0;
-
-       pkg->pre_depends_count = 0;
-       pkg->pre_depends_str = NULL;
-       pkg->provides_count = 0;
-       pkg->provides = NULL;
-       pkg->tmp_unpack_dir = NULL;
-       pkg->size = 0;
-       pkg->installed_size = 0;
-       conffile_list_init(&pkg->conffiles);
+
        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);
 }
 
@@ -181,6 +159,101 @@ char *pkg_set_string(pkg_t *pkg, int id, const char *s)
        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)
 {
@@ -196,7 +269,10 @@ static void compound_depend_deinit(compound_depend_t * depends)
 
 void pkg_deinit(pkg_t * pkg)
 {
-       int i;
+       int rem;
+       struct blob_attr *cur;
+       compound_depend_t *deps, *dep;
+       void *ptr;
 
        if (pkg->name)
                free(pkg->name);
@@ -211,42 +287,46 @@ void pkg_deinit(pkg_t * pkg)
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
-       active_list_clear(&pkg->list);
+       blob_for_each_attr(cur, pkg->blob.head, rem) {
+               switch (blob_id(cur)) {
+               case PKG_DEPENDS:
+               case PKG_CONFLICTS:
+                       deps = pkg_get_ptr(pkg, blob_id(cur));
 
-       if (pkg->replaces)
-               free(pkg->replaces);
-       pkg->replaces = NULL;
+                       if (deps) {
+                               for (dep = deps; dep->type; dep++)
+                                       compound_depend_deinit(dep);
 
-       if (pkg->depends) {
-               int count = pkg->pre_depends_count
-                   + pkg->depends_count
-                   + pkg->recommends_count + pkg->suggests_count;
+                               free(deps);
+                       }
 
-               for (i = 0; i < count; i++)
-                       compound_depend_deinit(&pkg->depends[i]);
-               free(pkg->depends);
-       }
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
 
-       if (pkg->conflicts) {
-               for (i = 0; i < pkg->conflicts_count; i++)
-                       compound_depend_deinit(&pkg->conflicts[i]);
-               free(pkg->conflicts);
-       }
+               case PKG_REPLACES:
+               case PKG_PROVIDES:
+                       ptr = pkg_get_ptr(pkg, blob_id(cur));
 
-       if (pkg->provides)
-               free(pkg->provides);
+                       if (ptr)
+                               free(ptr);
 
-       pkg->pre_depends_count = 0;
-       pkg->provides_count = 0;
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
 
-       /* CLEANUP: It'd be nice to pullin the cleanup function from
-          opkg_install.c here. See comment in
-          opkg_install.c:cleanup_temporary_files */
-       if (pkg->tmp_unpack_dir)
-               free(pkg->tmp_unpack_dir);
-       pkg->tmp_unpack_dir = NULL;
+               case PKG_CONFFILES:
+                       ptr = pkg_get_ptr(pkg, blob_id(cur));
 
-       conffile_list_deinit(&pkg->conffiles);
+                       if (ptr) {
+                               conffile_list_deinit(ptr);
+                               free(ptr);
+                       }
+
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
+               }
+       }
+
+       //conffile_list_deinit(&pkg->conffiles);
 
        /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
           since if they are calling deinit, they should know. Maybe do an
@@ -317,6 +397,8 @@ err0:
 /* Merge any new information in newpkg into oldpkg */
 int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
 {
+       abstract_pkg_t **ab;
+
        if (oldpkg == newpkg) {
                return 0;
        }
@@ -328,10 +410,8 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                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 (!oldpkg->arch_priority)
-               oldpkg->arch_priority = newpkg->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))
@@ -339,72 +419,53 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
        if (!pkg_get_string(oldpkg, PKG_DESCRIPTION))
                pkg_set_string(oldpkg, PKG_DESCRIPTION, pkg_get_string(newpkg, PKG_DESCRIPTION));
 
-       if (!oldpkg->depends_count && !oldpkg->pre_depends_count
-           && !oldpkg->recommends_count && !oldpkg->suggests_count) {
-               oldpkg->depends_count = newpkg->depends_count;
-               newpkg->depends_count = 0;
-
-               oldpkg->depends = newpkg->depends;
-               newpkg->depends = NULL;
-
-               oldpkg->pre_depends_count = newpkg->pre_depends_count;
-               newpkg->pre_depends_count = 0;
-
-               oldpkg->recommends_count = newpkg->recommends_count;
-               newpkg->recommends_count = 0;
-
-               oldpkg->suggests_count = newpkg->suggests_count;
-               newpkg->suggests_count = 0;
+       if (!pkg_get_ptr(oldpkg, PKG_DEPENDS)) {
+               pkg_set_ptr(oldpkg, PKG_DEPENDS, pkg_get_ptr(newpkg, PKG_DEPENDS));
+               pkg_set_ptr(newpkg, PKG_DEPENDS, NULL);
        }
 
-       if (oldpkg->provides_count <= 1) {
-               oldpkg->provides_count = newpkg->provides_count;
-               newpkg->provides_count = 0;
+       ab = pkg_get_ptr(oldpkg, PKG_PROVIDES);
 
-               if (!oldpkg->provides) {
-                       oldpkg->provides = newpkg->provides;
-                       newpkg->provides = NULL;
-               }
-       }
+       if (!ab || !ab[0] || !ab[1]) {
+               pkg_set_ptr(oldpkg, PKG_PROVIDES, pkg_get_ptr(newpkg, PKG_PROVIDES));
+               pkg_set_ptr(newpkg, PKG_PROVIDES, NULL);
 
-       if (!oldpkg->conflicts_count) {
-               oldpkg->conflicts_count = newpkg->conflicts_count;
-               newpkg->conflicts_count = 0;
-
-               oldpkg->conflicts = newpkg->conflicts;
-               newpkg->conflicts = NULL;
+               if (ab)
+                       free(ab);
        }
 
-       if (!oldpkg->replaces_count) {
-               oldpkg->replaces_count = newpkg->replaces_count;
-               newpkg->replaces_count = 0;
+       if (!pkg_get_ptr(oldpkg, PKG_CONFLICTS)) {
+               pkg_set_ptr(oldpkg, PKG_CONFLICTS, pkg_get_ptr(newpkg, PKG_CONFLICTS));
+               pkg_set_ptr(newpkg, PKG_CONFLICTS, NULL);
+       }
 
-               oldpkg->replaces = newpkg->replaces;
-               newpkg->replaces = NULL;
+       if (!pkg_get_ptr(oldpkg, PKG_REPLACES)) {
+               pkg_set_ptr(oldpkg, PKG_REPLACES, pkg_get_ptr(newpkg, PKG_REPLACES));
+               pkg_set_ptr(newpkg, PKG_REPLACES, NULL);
        }
 
        if (!pkg_get_string(oldpkg, PKG_FILENAME))
                pkg_set_string(oldpkg, PKG_FILENAME, pkg_get_string(newpkg, PKG_FILENAME));
        if (!pkg_get_string(oldpkg, PKG_LOCAL_FILENAME))
                pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
-       if (!oldpkg->tmp_unpack_dir)
-               oldpkg->tmp_unpack_dir = xstrdup(newpkg->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 (!oldpkg->size)
-               oldpkg->size = newpkg->size;
-       if (!oldpkg->installed_size)
-               oldpkg->installed_size = newpkg->installed_size;
+       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_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))
+               pkg_set_int(oldpkg, PKG_INSTALLED_SIZE, pkg_get_int(newpkg, PKG_INSTALLED_SIZE));
        if (!pkg_get_string(oldpkg, PKG_PRIORITY))
                pkg_set_string(oldpkg, PKG_PRIORITY, pkg_get_string(newpkg, PKG_PRIORITY));
        if (!pkg_get_string(oldpkg, PKG_SOURCE))
                pkg_set_string(oldpkg, PKG_SOURCE, pkg_get_string(newpkg, PKG_SOURCE));
 
-       if (nv_pair_list_empty(&oldpkg->conffiles)) {
-               list_splice_init(&newpkg->conffiles.head,
-                                &oldpkg->conffiles.head);
+       if (!pkg_get_ptr(oldpkg, PKG_CONFFILES)) {
+               pkg_set_ptr(oldpkg, PKG_CONFFILES, pkg_get_ptr(newpkg, PKG_CONFFILES));
+               pkg_set_ptr(newpkg, PKG_CONFFILES, NULL);
        }
 
        if (!oldpkg->installed_files) {
@@ -587,8 +648,8 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        int i, j;
        char *str;
        const char *p;
-       int depends_count = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
+       compound_depend_t *dep;
+       abstract_pkg_t **ab_pkg;
 
        if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
                goto UNKNOWN_FMT_FIELD;
@@ -598,7 +659,7 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        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);
@@ -613,14 +674,17 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'c':
        case 'C':
                if (strcasecmp(field, "Conffiles") == 0) {
+                       conffile_list_t *cl;
                        conffile_list_elt_t *iter;
 
-                       if (nv_pair_list_empty(&pkg->conffiles))
+                       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+                       if (!cl || nv_pair_list_empty(cl))
                                return;
 
                        fprintf(fp, "Conffiles:\n");
-                       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-                            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+                       for (iter = nv_pair_list_first(cl); iter;
+                            iter = nv_pair_list_next(cl, iter)) {
                                if (((conffile_t *) iter->data)->name
                                    && ((conffile_t *) iter->data)->value) {
                                        fprintf(fp, " %s %s\n",
@@ -632,11 +696,12 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                        }
                } else if (strcasecmp(field, "Conflicts") == 0) {
                        struct depend *cdep;
-                       if (pkg->conflicts_count) {
+                       compound_depend_t *deps, *dep;
+                       deps = pkg_get_ptr(pkg, PKG_CONFLICTS);
+                       if (deps) {
                                fprintf(fp, "Conflicts:");
-                               for (i = 0; i < pkg->conflicts_count; i++) {
-                                       cdep =
-                                           pkg->conflicts[i].possibilities[0];
+                               for (i = 0, dep = deps; dep->type; dep++, i++) {
+                                       cdep = dep->possibilities[0];
                                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
                                                cdep->pkg->name);
                                        if (cdep->version) {
@@ -655,10 +720,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'd':
        case 'D':
                if (strcasecmp(field, "Depends") == 0) {
-                       if (pkg->depends_count) {
+                       dep = pkg_get_depends(pkg, DEPEND);
+                       if (dep) {
                                fprintf(fp, "Depends:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != DEPEND)
+                               for (i = 0, j = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != DEPEND)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -694,12 +760,14 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'i':
        case 'I':
                if (strcasecmp(field, "Installed-Size") == 0) {
-                       fprintf(fp, "Installed-Size: %ld\n",
-                               pkg->installed_size);
-               } else if (strcasecmp(field, "Installed-Time") == 0
-                          && pkg->installed_time) {
-                       fprintf(fp, "Installed-Time: %lu\n",
-                               pkg->installed_time);
+                       fprintf(fp, "Installed-Size: %lu\n",
+                               (unsigned long) pkg_get_int(pkg, PKG_INSTALLED_SIZE));
+               } else if (strcasecmp(field, "Installed-Time") == 0) {
+                       i = pkg_get_int(pkg, PKG_INSTALLED_TIME);
+                       if (i) {
+                               fprintf(fp, "Installed-Time: %lu\n",
+                                       (unsigned long) i);
+                       }
                }
                break;
        case 'm':
@@ -710,7 +778,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) {
-                       p = pkg_get_string(pkg, PKG_MD5SUM);
+                       p = pkg_get_md5(pkg);
                        if (p) {
                                fprintf(fp, "MD5Sum: %s\n", p);
                        }
@@ -725,11 +793,12 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                } else if (strcasecmp(field, "Priority") == 0) {
                        fprintf(fp, "Priority: %s\n", pkg_get_string(pkg, PKG_PRIORITY));
                } else if (strcasecmp(field, "Provides") == 0) {
-                       if (pkg->provides_count > 1) {
+                       ab_pkg = pkg_get_ptr(pkg, PKG_PROVIDES);
+                       if (ab_pkg && ab_pkg[0] && ab_pkg[1]) {
                                fprintf(fp, "Provides:");
-                               for (i = 1; i < pkg->provides_count; i++) {
+                               for (i = 1; ab_pkg[i]; i++) {
                                        fprintf(fp, "%s %s", i == 1 ? "" : ",",
-                                               pkg->provides[i]->name);
+                                               ab_pkg[i]->name);
                                }
                                fprintf(fp, "\n");
                        }
@@ -740,19 +809,21 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'r':
        case 'R':
                if (strcasecmp(field, "Replaces") == 0) {
-                       if (pkg->replaces_count) {
+                       ab_pkg = pkg_get_ptr(pkg, PKG_REPLACES);
+                       if (ab_pkg && *ab_pkg) {
                                fprintf(fp, "Replaces:");
-                               for (i = 0; i < pkg->replaces_count; i++) {
+                               for (i = 0; *ab_pkg; i++, ab_pkg++) {
                                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
-                                               pkg->replaces[i]->name);
+                                               (*ab_pkg)->name);
                                }
                                fprintf(fp, "\n");
                        }
                } else if (strcasecmp(field, "Recommends") == 0) {
-                       if (pkg->recommends_count) {
+                       dep = pkg_get_depends(pkg, RECOMMEND);
+                       if (dep) {
                                fprintf(fp, "Recommends:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != RECOMMEND)
+                               for (j = 0, i = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != RECOMMEND)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -781,8 +852,9 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                        }
 #endif
                } else if (strcasecmp(field, "Size") == 0) {
-                       if (pkg->size) {
-                               fprintf(fp, "Size: %ld\n", pkg->size);
+                       i = pkg_get_int(pkg, PKG_SIZE);
+                       if (i) {
+                               fprintf(fp, "Size: %lu\n", (unsigned long) i);
                        }
                } else if (strcasecmp(field, "Source") == 0) {
                        p = pkg_get_string(pkg, PKG_SOURCE);
@@ -797,10 +869,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                                pkg_state_status_to_str(pkg->state_status));
                        free(pflag);
                } else if (strcasecmp(field, "Suggests") == 0) {
-                       if (pkg->suggests_count) {
+                       dep = pkg_get_depends(pkg, SUGGEST);
+                       if (dep) {
                                fprintf(fp, "Suggests:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != SUGGEST)
+                               for (j = 0, i = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != SUGGEST)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -948,8 +1021,8 @@ int pkg_compare_versions(const pkg_t * pkg, const pkg_t * ref_pkg)
 {
        unsigned int epoch1 = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
        unsigned int epoch2 = (unsigned int) pkg_get_int(ref_pkg, PKG_EPOCH);
-       char *revision1 = pkg_get_ptr(pkg, PKG_REVISION);
-       char *revision2 = pkg_get_ptr(ref_pkg, PKG_REVISION);
+       char *revision1 = pkg_get_string(pkg, PKG_REVISION);
+       char *revision2 = pkg_get_string(ref_pkg, PKG_REVISION);
        const char *version1 = pkg_get_string(pkg, PKG_VERSION);
        const char *version2 = pkg_get_string(ref_pkg, PKG_VERSION);
        int r;
@@ -1011,6 +1084,7 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
        const pkg_t * b = *(const pkg_t **)p2;
        int namecmp;
        int vercmp;
+       int arch_prio1, arch_prio2;
        if (!a->name || !b->name) {
                opkg_msg(ERROR, "Internal error: a->name=%p, b->name=%p.\n",
                         a->name, b->name);
@@ -1023,15 +1097,17 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
        vercmp = pkg_compare_versions(a, b);
        if (vercmp)
                return vercmp;
-       if (!a->arch_priority || !b->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",
-                        a->arch_priority, b->arch_priority);
+                        arch_prio1, arch_prio2);
                return 0;
        }
-       if (a->arch_priority > b->arch_priority)
+       if (arch_prio1 > arch_prio2)
                return 1;
-       if (a->arch_priority < b->arch_priority)
+       if (arch_prio1 < arch_prio2)
                return -1;
        return 0;
 }
@@ -1054,7 +1130,7 @@ char *pkg_version_str_alloc(pkg_t * pkg)
        char *version, *revptr;
        unsigned int epoch = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
 
-       revptr = pkg_get_ptr(pkg, PKG_REVISION);
+       revptr = pkg_get_string(pkg, PKG_REVISION);
        verstr = pkg_get_string(pkg, PKG_VERSION);
 
        if (epoch) {
@@ -1241,14 +1317,17 @@ void pkg_remove_installed_files_list(pkg_t * pkg)
 conffile_t *pkg_get_conffile(pkg_t * pkg, const char *file_name)
 {
        conffile_list_elt_t *iter;
+       conffile_list_t *cl;
        conffile_t *conffile;
 
        if (pkg == NULL) {
                return NULL;
        }
 
-       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+            iter = nv_pair_list_next(cl, iter)) {
                conffile = (conffile_t *) iter->data;
 
                if (strcmp(conffile->name, file_name) == 0) {
@@ -1264,6 +1343,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        int err;
        char *path;
        char *cmd;
+       char *tmp_unpack_dir;
 
        if (conf->noaction)
                return 0;
@@ -1277,7 +1357,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        }
 
        /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
-          have scripts in pkg->tmp_unpack_dir. */
+          have scripts in tmp_unpack_dir. */
        if (pkg->state_status == SS_INSTALLED
            || pkg->state_status == SS_UNPACKED) {
                if (pkg->dest == NULL) {
@@ -1288,13 +1368,14 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
                sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name,
                              script);
        } else {
-               if (pkg->tmp_unpack_dir == NULL) {
+               tmp_unpack_dir = pkg_get_string(pkg, PKG_TMP_UNPACK_DIR);
+               if (tmp_unpack_dir == NULL) {
                        opkg_msg(ERROR,
                                 "Internal error: %s has a NULL tmp_unpack_dir.\n",
                                 pkg->name);
                        return -1;
                }
-               sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
+               sprintf_alloc(&path, "%s/%s", tmp_unpack_dir, script);
        }
 
        opkg_msg(INFO, "Running script %s.\n", path);
@@ -1334,7 +1415,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;
-       char *architecture = pkg_get_string(pkg, PKG_ARCHITECTURE);
+       char *architecture = pkg_get_architecture(pkg);
 
        if (!architecture)
                return 1;