X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=libopkg%2Fpkg.c;h=c0de884bfe8916cd9048e1d035a359b560732c21;hb=52c31c1c7a6f228bc36da56ce1ed76f4f1c64e47;hp=41aaff889c650bd578878eabef0489ccc11a4051;hpb=4ea955bc7e5575bc1d8b34c364591c47653f2cfd;p=oweals%2Fopkg-lede.git diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 41aaff8..c0de884 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -15,8 +15,6 @@ General Public License for more details. */ -#include "config.h" - #include #include #include @@ -74,55 +72,20 @@ static const enum_map_t pkg_state_status_map[] = { static void pkg_init(pkg_t * pkg) { pkg->name = NULL; - pkg->epoch = 0; - pkg->version = NULL; - pkg->revision = NULL; pkg->dest = NULL; pkg->src = NULL; - pkg->architecture = NULL; - pkg->maintainer = NULL; - pkg->section = NULL; - pkg->description = NULL; 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->filename = NULL; - pkg->local_filename = NULL; - pkg->tmp_unpack_dir = NULL; - pkg->md5sum = NULL; -#if defined HAVE_SHA256 - pkg->sha256sum = NULL; -#endif - pkg->size = 0; - pkg->installed_size = 0; - pkg->priority = NULL; - pkg->source = NULL; - 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); } pkg_t *pkg_new(void) @@ -135,6 +98,161 @@ pkg_t *pkg_new(void) return pkg; } +void *pkg_set_raw(pkg_t *pkg, int id, const void *val, size_t len) +{ + int rem; + struct blob_attr *cur; + + blob_for_each_attr(cur, pkg->blob.head, rem) { + if (blob_id(cur) == id) { + if (blob_len(cur) < len) { + fprintf(stderr, "ERROR: truncating field %d <%p> to %d byte", + id, val, blob_len(cur)); + } + memcpy(blob_data(cur), val, blob_len(cur)); + return blob_data(cur); + } + } + + cur = blob_put(&pkg->blob, id, val, len); + return cur ? blob_data(cur) : NULL; +} + +void *pkg_get_raw(const pkg_t * pkg, int id) +{ + int rem; + struct blob_attr *cur; + + blob_for_each_attr(cur, pkg->blob.head, rem) + if (blob_id(cur) == id) + return blob_data(cur); + + return NULL; +} + +char *pkg_set_string(pkg_t *pkg, int id, const char *s) +{ + size_t len; + char *p; + + if (!s) + return NULL; + + len = strlen(s); + + while (isspace(*s)) { + s++; + len--; + } + + while (len > 0 && isspace(s[len - 1])) + len--; + + if (!len) + return NULL; + + p = pkg_set_raw(pkg, id, s, len + 1); + p[len] = 0; + + 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) { int i; @@ -149,107 +267,64 @@ 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); pkg->name = NULL; - pkg->epoch = 0; - - if (pkg->version) - free(pkg->version); - pkg->version = NULL; - /* revision shares storage with version, so don't free */ - pkg->revision = NULL; - /* owned by opkg_conf_t */ pkg->dest = NULL; /* owned by opkg_conf_t */ pkg->src = NULL; - if (pkg->architecture) - free(pkg->architecture); - pkg->architecture = NULL; - - if (pkg->maintainer) - free(pkg->maintainer); - pkg->maintainer = NULL; - - if (pkg->section) - free(pkg->section); - pkg->section = NULL; - - if (pkg->description) - free(pkg->description); - pkg->description = NULL; - pkg->state_want = SW_UNKNOWN; pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; - active_list_clear(&pkg->list); - - if (pkg->replaces) - free(pkg->replaces); - pkg->replaces = NULL; - - if (pkg->depends) { - int count = pkg->pre_depends_count - + pkg->depends_count - + pkg->recommends_count + pkg->suggests_count; - - for (i = 0; i < count; i++) - compound_depend_deinit(&pkg->depends[i]); - free(pkg->depends); - } - - if (pkg->conflicts) { - for (i = 0; i < pkg->conflicts_count; i++) - compound_depend_deinit(&pkg->conflicts[i]); - free(pkg->conflicts); - } + 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->provides) - free(pkg->provides); + if (deps) { + for (dep = deps; dep->type; dep++) + compound_depend_deinit(dep); - pkg->pre_depends_count = 0; - pkg->provides_count = 0; + free(deps); + } - if (pkg->filename) - free(pkg->filename); - pkg->filename = NULL; + pkg_set_ptr(pkg, blob_id(cur), NULL); + break; - if (pkg->local_filename) - free(pkg->local_filename); - pkg->local_filename = NULL; + case PKG_REPLACES: + case PKG_PROVIDES: + ptr = pkg_get_ptr(pkg, blob_id(cur)); - /* 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; + if (ptr) + free(ptr); - if (pkg->md5sum) - free(pkg->md5sum); - pkg->md5sum = NULL; + pkg_set_ptr(pkg, blob_id(cur), NULL); + break; -#if defined HAVE_SHA256 - if (pkg->sha256sum) - free(pkg->sha256sum); - pkg->sha256sum = NULL; -#endif + case PKG_CONFFILES: + ptr = pkg_get_ptr(pkg, blob_id(cur)); - if (pkg->priority) - free(pkg->priority); - pkg->priority = NULL; + if (ptr) { + conffile_list_deinit(ptr); + free(ptr); + } - if (pkg->source) - free(pkg->source); - pkg->source = NULL; + pkg_set_ptr(pkg, blob_id(cur), NULL); + break; + } + } - conffile_list_deinit(&pkg->conffiles); + //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 @@ -258,9 +333,7 @@ void pkg_deinit(pkg_t * pkg) pkg_free_installed_files(pkg); pkg->essential = 0; - if (pkg->tags) - free(pkg->tags); - pkg->tags = NULL; + blob_buf_free(&pkg->blob); } int pkg_init_from_file(pkg_t * pkg, const char *filename) @@ -271,7 +344,12 @@ int pkg_init_from_file(pkg_t * pkg, const char *filename) pkg_init(pkg); - pkg->local_filename = xstrdup(filename); + if (!(pkg->state_flag & SF_NEED_DETAIL)) { + opkg_msg(DEBUG, "applying abpkg flag to %s\n", filename); + pkg->state_flag |= SF_NEED_DETAIL; + } + + pkg_set_string(pkg, PKG_LOCAL_FILENAME, filename); tmp = xstrdup(filename); sprintf_alloc(&control_path, "%s/%s.control.XXXXXX", @@ -322,6 +400,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; } @@ -333,85 +413,62 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) oldpkg->src = newpkg->src; if (!oldpkg->dest) oldpkg->dest = newpkg->dest; - if (!oldpkg->architecture) - oldpkg->architecture = xstrdup(newpkg->architecture); - if (!oldpkg->arch_priority) - oldpkg->arch_priority = newpkg->arch_priority; - if (!oldpkg->section) - oldpkg->section = xstrdup(newpkg->section); - if (!oldpkg->maintainer) - oldpkg->maintainer = xstrdup(newpkg->maintainer); - if (!oldpkg->description) - oldpkg->description = xstrdup(newpkg->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 (!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)) + pkg_set_string(oldpkg, PKG_MAINTAINER, pkg_get_string(newpkg, PKG_MAINTAINER)); + if (!pkg_get_string(oldpkg, PKG_DESCRIPTION)) + pkg_set_string(oldpkg, PKG_DESCRIPTION, pkg_get_string(newpkg, PKG_DESCRIPTION)); + + 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; - - if (!oldpkg->provides) { - oldpkg->provides = newpkg->provides; - newpkg->provides = NULL; - } - } + ab = pkg_get_ptr(oldpkg, PKG_PROVIDES); - if (!oldpkg->conflicts_count) { - oldpkg->conflicts_count = newpkg->conflicts_count; - newpkg->conflicts_count = 0; + 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); - 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 (!oldpkg->filename) - oldpkg->filename = xstrdup(newpkg->filename); - if (!oldpkg->local_filename) - oldpkg->local_filename = xstrdup(newpkg->local_filename); - if (!oldpkg->tmp_unpack_dir) - oldpkg->tmp_unpack_dir = xstrdup(newpkg->tmp_unpack_dir); - if (!oldpkg->md5sum) - oldpkg->md5sum = xstrdup(newpkg->md5sum); -#if defined HAVE_SHA256 - if (!oldpkg->sha256sum) - oldpkg->sha256sum = xstrdup(newpkg->sha256sum); -#endif - if (!oldpkg->size) - oldpkg->size = newpkg->size; - if (!oldpkg->installed_size) - oldpkg->installed_size = newpkg->installed_size; - if (!oldpkg->priority) - oldpkg->priority = xstrdup(newpkg->priority); - if (!oldpkg->source) - oldpkg->source = xstrdup(newpkg->source); - - if (nv_pair_list_empty(&oldpkg->conffiles)) { - list_splice_init(&newpkg->conffiles.head, - &oldpkg->conffiles.head); + 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 (!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 (!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) { @@ -424,6 +481,9 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) if (!oldpkg->essential) oldpkg->essential = newpkg->essential; + if (!oldpkg->provided_by_hand) + oldpkg->provided_by_hand = newpkg->provided_by_hand; + return 0; } @@ -444,34 +504,6 @@ abstract_pkg_t *abstract_pkg_new(void) return ab_pkg; } -void set_flags_from_control(pkg_t * pkg) -{ - char *file_name; - FILE *fp; - - sprintf_alloc(&file_name, "%s/%s.control", pkg->dest->info_dir, - pkg->name); - - fp = fopen(file_name, "r"); - if (fp == NULL) { - opkg_perror(ERROR, "Failed to open %s", file_name); - free(file_name); - return; - } - - free(file_name); - - if (pkg_parse_from_stream(pkg, fp, PFM_ALL ^ PFM_ESSENTIAL)) { - opkg_msg(DEBUG, - "Unable to read control file for %s. May be empty.\n", - pkg->name); - } - - fclose(fp); - - return; -} - static const char *pkg_state_want_to_str(pkg_state_want_t sw) { int i; @@ -593,8 +625,9 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) { int i, j; char *str; - int depends_count = pkg->pre_depends_count + - pkg->depends_count + pkg->recommends_count + pkg->suggests_count; + const char *p; + compound_depend_t *dep; + abstract_pkg_t **ab_pkg; if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) { goto UNKNOWN_FMT_FIELD; @@ -604,9 +637,10 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) case 'a': case 'A': if (strcasecmp(field, "Architecture") == 0) { - if (pkg->architecture) { + p = pkg_get_architecture(pkg); + if (p) { fprintf(fp, "Architecture: %s\n", - pkg->architecture); + p); } } else if (strcasecmp(field, "Auto-Installed") == 0) { if (pkg->auto_installed) @@ -618,14 +652,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", @@ -637,11 +674,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) { @@ -660,10 +698,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 ? "" : ",", @@ -674,9 +713,10 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) fprintf(fp, "\n"); } } else if (strcasecmp(field, "Description") == 0) { - if (pkg->description) { + p = pkg_get_string(pkg, PKG_DESCRIPTION); + if (p) { fprintf(fp, "Description: %s\n", - pkg->description); + p); } } else { goto UNKNOWN_FMT_FIELD; @@ -690,31 +730,35 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) break; case 'f': case 'F': - if (pkg->filename) { - fprintf(fp, "Filename: %s\n", pkg->filename); + p = pkg_get_string(pkg, PKG_FILENAME); + if (p) { + fprintf(fp, "Filename: %s\n", p); } break; 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': case 'M': if (strcasecmp(field, "Maintainer") == 0) { - if (pkg->maintainer) { - fprintf(fp, "Maintainer: %s\n", - pkg->maintainer); + p = pkg_get_string(pkg, PKG_MAINTAINER); + if (p) { + fprintf(fp, "Maintainer: %s\n", p); } } else if (strcasecmp(field, "MD5sum") == 0) { - if (pkg->md5sum) { - fprintf(fp, "MD5Sum: %s\n", pkg->md5sum); + p = pkg_get_md5(pkg); + if (p) { + fprintf(fp, "MD5Sum: %s\n", p); } } else { goto UNKNOWN_FMT_FIELD; @@ -725,13 +769,14 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) if (strcasecmp(field, "Package") == 0) { fprintf(fp, "Package: %s\n", pkg->name); } else if (strcasecmp(field, "Priority") == 0) { - fprintf(fp, "Priority: %s\n", pkg->priority); + 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"); } @@ -742,19 +787,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 ? "" : ",", @@ -771,22 +818,24 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) case 's': case 'S': if (strcasecmp(field, "Section") == 0) { - if (pkg->section) { - fprintf(fp, "Section: %s\n", pkg->section); + p = pkg_get_string(pkg, PKG_SECTION); + if (p) { + fprintf(fp, "Section: %s\n", p); } -#if defined HAVE_SHA256 } else if (strcasecmp(field, "SHA256sum") == 0) { - if (pkg->sha256sum) { - fprintf(fp, "SHA256sum: %s\n", pkg->sha256sum); + p = pkg_get_string(pkg, PKG_SHA256SUM); + if (p) { + fprintf(fp, "SHA256sum: %s\n", p); } -#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) { - if (pkg->source) { - fprintf(fp, "Source: %s\n", pkg->source); + p = pkg_get_string(pkg, PKG_SOURCE); + if (p) { + fprintf(fp, "Source: %s\n", p); } } else if (strcasecmp(field, "Status") == 0) { char *pflag = pkg_state_flag_to_str(pkg->state_flag); @@ -796,10 +845,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 ? "" : ",", @@ -816,8 +866,9 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) case 't': case 'T': if (strcasecmp(field, "Tags") == 0) { - if (pkg->tags) { - fprintf(fp, "Tags: %s\n", pkg->tags); + p = pkg_get_string(pkg, PKG_TAGS); + if (p) { + fprintf(fp, "Tags: %s\n", p); } } break; @@ -944,22 +995,28 @@ static int verrevcmp(const char *val, const char *ref) 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_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; - if (pkg->epoch > ref_pkg->epoch) { + if (epoch1 > epoch2) { return 1; } - if (pkg->epoch < ref_pkg->epoch) { + if (epoch1 < epoch2) { return -1; } - r = verrevcmp(pkg->version, ref_pkg->version); + r = verrevcmp(version1, version2); if (r) { return r; } - r = verrevcmp(pkg->revision, ref_pkg->revision); + r = verrevcmp(revision1, revision2); if (r) { return r; } @@ -999,10 +1056,11 @@ int pkg_version_satisfied(pkg_t * it, pkg_t * ref, const char *op) int pkg_name_version_and_architecture_compare(const void *p1, const void *p2) { - const pkg_t *a = *(const pkg_t **)p1; - const pkg_t *b = *(const pkg_t **)p2; + const pkg_t * a = *(const pkg_t **)p1; + 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); @@ -1015,15 +1073,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; } @@ -1042,21 +1102,26 @@ int abstract_pkg_name_compare(const void *p1, const void *p2) char *pkg_version_str_alloc(pkg_t * pkg) { - char *version; + const char *verstr; + char *version, *revptr; + unsigned int epoch = (unsigned int) pkg_get_int(pkg, PKG_EPOCH); + + revptr = pkg_get_string(pkg, PKG_REVISION); + verstr = pkg_get_string(pkg, PKG_VERSION); - if (pkg->epoch) { - if (pkg->revision) + if (epoch) { + if (revptr) sprintf_alloc(&version, "%d:%s-%s", - pkg->epoch, pkg->version, pkg->revision); + epoch, verstr, revptr); else sprintf_alloc(&version, "%d:%s", - pkg->epoch, pkg->version); + epoch, verstr); } else { - if (pkg->revision) + if (revptr) sprintf_alloc(&version, "%s-%s", - pkg->version, pkg->revision); + verstr, revptr); else - version = xstrdup(pkg->version); + version = xstrdup(verstr); } return version; @@ -1074,6 +1139,7 @@ str_list_t *pkg_get_installed_files(pkg_t * pkg) char *installed_file_name; unsigned int rootdirlen = 0; int list_from_package; + const char *local_filename; pkg->installed_files_ref_cnt++; @@ -1093,7 +1159,9 @@ str_list_t *pkg_get_installed_files(pkg_t * pkg) list_from_package = 0; if (list_from_package) { - if (pkg->local_filename == NULL) { + local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME); + + if (!local_filename) { return pkg->installed_files; } /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary @@ -1121,7 +1189,7 @@ str_list_t *pkg_get_installed_files(pkg_t * pkg) err = pkg_extract_data_file_names_to_stream(pkg, list_file); if (err) { opkg_msg(ERROR, "Error extracting file list from %s.\n", - pkg->local_filename); + local_filename); fclose(list_file); unlink(list_file_name); free(list_file_name); @@ -1225,14 +1293,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) { @@ -1248,6 +1319,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; @@ -1261,7 +1333,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) { @@ -1272,13 +1344,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); @@ -1300,7 +1373,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args) sprintf_alloc(&cmd, "%s %s", path, args); free(path); { - const char *argv[] = { "sh", "-c", cmd, NULL }; + const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; err = xsystem(argv); } free(cmd); @@ -1318,13 +1391,14 @@ 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_architecture(pkg); - if (!pkg->architecture) + if (!architecture) return 1; list_for_each_entry(l, &conf->arch_list.head, node) { nv_pair_t *nv = (nv_pair_t *) l->data; - if (strcmp(nv->name, pkg->architecture) == 0) { + if (strcmp(nv->name, architecture) == 0) { opkg_msg(DEBUG, "Arch %s (priority %s) supported for pkg %s.\n", nv->name, nv->value, pkg->name); @@ -1333,7 +1407,7 @@ int pkg_arch_supported(pkg_t * pkg) } opkg_msg(DEBUG, "Arch %s unsupported for pkg %s.\n", - pkg->architecture, pkg->name); + architecture, pkg->name); return 0; }