From: Jo-Philipp Wich Date: Sun, 12 Feb 2017 20:43:11 +0000 (+0100) Subject: pkg: convert most other struct members into dynamic blob buffer fields X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=commitdiff_plain;h=98ce8c256f3c430bc0077a20cbd041b3f36c177a pkg: convert most other struct members into dynamic blob buffer fields Signed-off-by: Jo-Philipp Wich --- diff --git a/libopkg/opkg_cmd.c b/libopkg/opkg_cmd.c index 7f51ea9..c50d8f9 100644 --- a/libopkg/opkg_cmd.c +++ b/libopkg/opkg_cmd.c @@ -285,7 +285,6 @@ opkg_recurse_pkgs_in_order(pkg_t * pkg, pkg_vec_t * all, pkg_vec_t * visited, pkg_vec_t * ordered) { int j, k, l, m; - int count; pkg_t *dep; compound_depend_t *compound_depend; depend_t **possible_satisfiers; @@ -312,17 +311,13 @@ opkg_recurse_pkgs_in_order(pkg_t * pkg, pkg_vec_t * all, pkg_vec_insert(visited, pkg); - count = pkg->pre_depends_count + pkg->depends_count + - pkg->recommends_count + pkg->suggests_count; - opkg_msg(DEBUG, "pkg %s.\n", pkg->name); /* Iterate over all the dependencies of pkg. For each one, find a package that is either installed or unpacked and satisfies this dependency. (there should only be one such package per dependency installed or unpacked). Then recurse to the dependency package */ - for (j = 0; j < count; j++) { - compound_depend = &pkg->depends[j]; + for (compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS); compound_depend && compound_depend->type; compound_depend++) { possible_satisfiers = compound_depend->possibilities; for (k = 0; k < compound_depend->possibility_count; k++) { abpkg = possible_satisfiers[k]->pkg; @@ -633,6 +628,7 @@ static int opkg_list_changed_conffiles_cmd(int argc, char **argv) pkg_t *pkg; char *pkg_name = NULL; conffile_list_elt_t *iter; + conffile_list_t *cl; conffile_t *cf; if (argc > 0) { @@ -643,13 +639,14 @@ static int opkg_list_changed_conffiles_cmd(int argc, char **argv) pkg_vec_sort(available, pkg_compare_names); for (i = 0; i < available->len; i++) { pkg = available->pkgs[i]; + cl = pkg_get_ptr(pkg, PKG_CONFFILES); /* if we have package name or pattern and pkg does not match, then skip it */ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase)) continue; - if (nv_pair_list_empty(&pkg->conffiles)) + if (!cl || nv_pair_list_empty(cl)) continue; - 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)) { cf = (conffile_t *) iter->data; if (cf->name && cf->value && conffile_has_been_modified(cf)) @@ -690,6 +687,7 @@ static int opkg_info_status_cmd(int argc, char **argv, int installed_only) pkg_vec_t *available; pkg_t *pkg; char *pkg_name = NULL; + conffile_list_t *cl; if (argc > 0) { pkg_name = argv[0]; @@ -709,10 +707,12 @@ static int opkg_info_status_cmd(int argc, char **argv, int installed_only) pkg_formatted_info(stdout, pkg); - if (conf->verbosity >= NOTICE) { + cl = pkg_get_ptr(pkg, PKG_CONFFILES); + + if (conf->verbosity >= NOTICE && cl) { conffile_list_elt_t *iter; - 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)) { conffile_t *cf = (conffile_t *) iter->data; int modified = conffile_has_been_modified(cf); if (cf->value) @@ -897,7 +897,6 @@ static int opkg_files_cmd(int argc, char **argv) static int opkg_depends_cmd(int argc, char **argv) { int i, j, k; - int depends_count; pkg_vec_t *available_pkgs; compound_depend_t *cdep; pkg_t *pkg; @@ -918,15 +917,9 @@ static int opkg_depends_cmd(int argc, char **argv) if (fnmatch(argv[i], pkg->name, conf->nocase) != 0) continue; - depends_count = pkg->depends_count + - pkg->pre_depends_count + - pkg->recommends_count + pkg->suggests_count; - opkg_msg(NOTICE, "%s depends on:\n", pkg->name); - for (k = 0; k < depends_count; k++) { - cdep = &pkg->depends[k]; - + for (k = 0, cdep = pkg_get_ptr(pkg, PKG_DEPENDS); cdep && cdep->type; k++, cdep++) { if (cdep->type != DEPEND) continue; @@ -944,13 +937,15 @@ static int opkg_depends_cmd(int argc, char **argv) static int pkg_mark_provides(pkg_t * pkg) { - int provides_count = pkg->provides_count; - abstract_pkg_t **provides = pkg->provides; - int i; + abstract_pkg_t **provider = pkg_get_ptr(pkg, PKG_PROVIDES); + pkg->parent->state_flag |= SF_MARKED; - for (i = 0; i < provides_count; i++) { - provides[i]->state_flag |= SF_MARKED; + + while (provider && *provider) { + (*provider)->state_flag |= SF_MARKED; + provider++; } + return 0; } @@ -968,11 +963,11 @@ opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv) { depend_t *possibility; - compound_depend_t *cdep; + compound_depend_t *cdep, *deps; pkg_vec_t *available_pkgs; pkg_t *pkg; - int i, j, k, l; - int changed, count; + int i, j, l; + int changed; const char *rel_str = NULL; char *ver; @@ -1022,21 +1017,21 @@ opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, for (j = 0; j < available_pkgs->len; j++) { pkg = available_pkgs->pkgs[j]; + /* count = ((what_field_type == CONFLICTS) ? pkg->conflicts_count : pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count); + */ /* skip this package if it is already marked */ if (pkg->parent->state_flag & SF_MARKED) continue; - for (k = 0; k < count; k++) { - cdep = (what_field_type == CONFLICTS) - ? &pkg->conflicts[k] - : &pkg->depends[k]; + deps = pkg_get_ptr(pkg, (what_field_type == CONFLICTS) ? PKG_CONFLICTS : PKG_DEPENDS); + for (cdep = deps; cdep->type; cdep++) { if (what_field_type != cdep->type) continue; @@ -1115,6 +1110,7 @@ static int opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv) { + abstract_pkg_t *apkg, **abpkgs; if (argc > 0) { pkg_vec_t *available_pkgs = pkg_vec_alloc(); @@ -1135,33 +1131,22 @@ opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, opkg_msg(NOTICE, "What %s %s\n", rel_str, target); for (j = 0; j < available_pkgs->len; j++) { pkg_t *pkg = available_pkgs->pkgs[j]; - int k; - int count = - (what_field_type == - WHATPROVIDES) ? pkg->provides_count : pkg-> - replaces_count; - for (k = 0; k < count; k++) { - abstract_pkg_t *apkg = - ((what_field_type == WHATPROVIDES) - ? pkg->provides[k] - : pkg->replaces[k]); - if (fnmatch - (target, apkg->name, - conf->nocase) == 0) { - opkg_msg(NOTICE, " %s", - pkg->name); - if ((conf-> - nocase ? strcasecmp(target, - apkg-> - name) : - strcmp(target, - apkg->name)) != 0) - opkg_msg(NOTICE, - "\t%s %s\n", - rel_str, - apkg->name); - opkg_message(NOTICE, "\n"); - } + abpkgs = pkg_get_ptr(pkg, (what_field_type == WHATPROVIDES) ? PKG_PROVIDES : PKG_REPLACES); + + while (abpkgs && *abpkgs) { + apkg = *abpkgs; + + if (fnmatch(target, apkg->name, conf->nocase)) + continue; + + opkg_msg(NOTICE, " %s", pkg->name); + + if ((conf->nocase ? strcasecmp(target, apkg->name) + : strcmp(target, apkg->name))) + opkg_msg(NOTICE, "\t%s %s\n", rel_str, apkg->name); + + opkg_message(NOTICE, "\n"); + abpkgs++; } } } diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index 2d31905..55c124b 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -232,19 +232,23 @@ static int unpack_pkg_control_files(pkg_t * pkg) int err; char *conffiles_file_name; char *root_dir; + char *tmp_unpack_dir; FILE *conffiles_file; + conffile_list_t *cl; - sprintf_alloc(&pkg->tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir, + sprintf_alloc(&tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir, pkg->name); - pkg->tmp_unpack_dir = mkdtemp(pkg->tmp_unpack_dir); - if (pkg->tmp_unpack_dir == NULL) { + tmp_unpack_dir = mkdtemp(tmp_unpack_dir); + if (tmp_unpack_dir == NULL) { opkg_perror(ERROR, "Failed to create temporary directory '%s'", - pkg->tmp_unpack_dir); + tmp_unpack_dir); return -1; } - err = pkg_extract_control_files_to_dir(pkg, pkg->tmp_unpack_dir); + pkg_set_string(pkg, PKG_TMP_UNPACK_DIR, tmp_unpack_dir); + + err = pkg_extract_control_files_to_dir(pkg, tmp_unpack_dir); if (err) { return err; } @@ -255,12 +259,13 @@ static int unpack_pkg_control_files(pkg_t * pkg) move all of unpack_pkg_control_files to that function. */ /* Don't need to re-read conffiles if we already have it */ - if (!nv_pair_list_empty(&pkg->conffiles)) { + cl = pkg_get_ptr(pkg, PKG_CONFFILES); + if (cl && !nv_pair_list_empty(cl)) { return 0; } sprintf_alloc(&conffiles_file_name, "%s/conffiles", - pkg->tmp_unpack_dir); + tmp_unpack_dir); if (!file_exists(conffiles_file_name)) { free(conffiles_file_name); return 0; @@ -274,6 +279,9 @@ static int unpack_pkg_control_files(pkg_t * pkg) } free(conffiles_file_name); + cl = xcalloc(1, sizeof(*cl)); + conffile_list_init(cl); + while (1) { char *cf_name; char *cf_name_in_dest; @@ -304,12 +312,14 @@ static int unpack_pkg_control_files(pkg_t * pkg) /* Can't get an md5sum now, (file isn't extracted yet). We'll wait until resolve_conffiles */ - conffile_list_append(&pkg->conffiles, cf_name_in_dest, NULL); + conffile_list_append(cl, cf_name_in_dest, NULL); free(cf_name); free(cf_name_in_dest); } + pkg_set_ptr(pkg, PKG_CONFFILES, cl); + fclose(conffiles_file); return 0; @@ -321,28 +331,20 @@ static int unpack_pkg_control_files(pkg_t * pkg) */ static int pkg_remove_orphan_dependent(pkg_t * pkg, pkg_t * old_pkg) { - int i, j, k, l, found, r, err = 0; + int j, l, found, r, err = 0; int n_deps; pkg_t *p; struct compound_depend *cd0, *cd1; abstract_pkg_t **dependents; - int count0 = old_pkg->pre_depends_count + - old_pkg->depends_count + - old_pkg->recommends_count + old_pkg->suggests_count; - int count1 = pkg->pre_depends_count + - pkg->depends_count + pkg->recommends_count + pkg->suggests_count; - - for (i = 0; i < count0; i++) { - cd0 = &old_pkg->depends[i]; + for (cd0 = pkg_get_ptr(old_pkg, PKG_DEPENDS); cd0 && cd0->type; cd0++) { if (cd0->type != DEPEND) continue; for (j = 0; j < cd0->possibility_count; j++) { found = 0; - for (k = 0; k < count1; k++) { - cd1 = &pkg->depends[k]; + for (cd1 = pkg_get_ptr(pkg, PKG_DEPENDS); cd1 && cd1->type; cd1++) { if (cd1->type != DEPEND) continue; for (l = 0; l < cd1->possibility_count; l++) { @@ -402,11 +404,11 @@ static int pkg_remove_orphan_dependent(pkg_t * pkg, pkg_t * old_pkg) static int pkg_get_installed_replacees(pkg_t * pkg, pkg_vec_t * installed_replacees) { - abstract_pkg_t **replaces = pkg->replaces; - int replaces_count = pkg->replaces_count; - int i, j; - for (i = 0; i < replaces_count; i++) { - abstract_pkg_t *ab_pkg = replaces[i]; + abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES); + int j; + + while (replaces && *replaces) { + abstract_pkg_t *ab_pkg = *replaces++; pkg_vec_t *pkg_vec = ab_pkg->pkgs; if (pkg_vec) { for (j = 0; j < pkg_vec->len; j++) { @@ -420,6 +422,7 @@ pkg_get_installed_replacees(pkg_t * pkg, pkg_vec_t * installed_replacees) } } } + return installed_replacees->len; } @@ -692,14 +695,17 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg) int err; conffile_list_elt_t *iter; conffile_t *cf; + conffile_list_t *cl; if (conf->noaction) return 0; /* Backup all modified conffiles */ if (old_pkg) { - for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; - iter = nv_pair_list_next(&old_pkg->conffiles, iter)) { + cl = pkg_get_ptr(old_pkg, PKG_CONFFILES); + + for (iter = cl ? nv_pair_list_first(cl) : NULL; iter; + iter = nv_pair_list_next(cl, iter)) { char *cf_name; cf = iter->data; @@ -718,8 +724,10 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg) } /* Backup all conffiles that were not conffiles in old_pkg */ - 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)) { char *cf_name; cf = (conffile_t *) iter->data; cf_name = root_filename_alloc(cf->name); @@ -742,17 +750,22 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg) static int backup_modified_conffiles_unwind(pkg_t * pkg, pkg_t * old_pkg) { + conffile_list_t *cl; conffile_list_elt_t *iter; if (old_pkg) { - for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; - iter = nv_pair_list_next(&old_pkg->conffiles, iter)) { + cl = pkg_get_ptr(old_pkg, PKG_CONFFILES); + + for (iter = cl ? nv_pair_list_first(cl) : NULL; iter; + iter = nv_pair_list_next(cl, iter)) { backup_remove(((nv_pair_t *) iter->data)->name); } } - 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)) { backup_remove(((nv_pair_t *) iter->data)->name); } @@ -1108,6 +1121,7 @@ static int install_data_files(pkg_t * pkg) static int resolve_conffiles(pkg_t * pkg) { conffile_list_elt_t *iter; + conffile_list_t *cl; conffile_t *cf; char *cf_backup; char *chksum; @@ -1115,8 +1129,10 @@ static int resolve_conffiles(pkg_t * pkg) if (conf->noaction) return 0; - 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)) { char *root_filename; cf = (conffile_t *) iter->data; root_filename = root_filename_alloc(cf->name); @@ -1330,6 +1346,8 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade) pkg->name); return -1; } + + local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME); } /* check that the repository is valid */ @@ -1423,7 +1441,7 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade) return 0; } - if (pkg->tmp_unpack_dir == NULL) { + if (!pkg_get_string(pkg, PKG_TMP_UNPACK_DIR)) { if (unpack_pkg_control_files(pkg) == -1) { opkg_msg(ERROR, "Failed to unpack control files from %s.\n", diff --git a/libopkg/opkg_remove.c b/libopkg/opkg_remove.c index 41d98d9..694c3f3 100644 --- a/libopkg/opkg_remove.c +++ b/libopkg/opkg_remove.c @@ -32,12 +32,13 @@ */ int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents) { - int nprovides = pkg->provides_count; - abstract_pkg_t **provides = pkg->provides; - unsigned int n_installed_dependents = 0; - int i; - for (i = 0; i < nprovides; i++) { - abstract_pkg_t *providee = provides[i]; + abstract_pkg_t **provider, **provides = pkg_get_ptr(pkg, PKG_PROVIDES); + unsigned int i, n_installed_dependents = 0; + + provider = provides; + + while (provider && *provider) { + abstract_pkg_t *providee = *provider++; abstract_pkg_t **dependers = providee->depended_upon_by; abstract_pkg_t *dep_ab_pkg; if (dependers == NULL) @@ -47,8 +48,8 @@ int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents) n_installed_dependents++; } } - } + /* if caller requested the set of installed dependents */ if (pdependents) { int p = 0; @@ -56,9 +57,11 @@ int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents) xcalloc((n_installed_dependents + 1), sizeof(abstract_pkg_t *)); + provider = provides; *pdependents = dependents; - for (i = 0; i < nprovides; i++) { - abstract_pkg_t *providee = provides[i]; + + while (provider && *provider) { + abstract_pkg_t *providee = *provider++; abstract_pkg_t **dependers = providee->depended_upon_by; abstract_pkg_t *dep_ab_pkg; if (dependers == NULL) @@ -169,18 +172,14 @@ static void print_dependents_warning(pkg_t * pkg, abstract_pkg_t ** dependents) */ static int remove_autoinstalled(pkg_t * pkg) { - int i, j; + int j; int err = 0; int n_deps; pkg_t *p; struct compound_depend *cdep; abstract_pkg_t **dependents; - int count = pkg->pre_depends_count + - pkg->depends_count + pkg->recommends_count + pkg->suggests_count; - - for (i = 0; i < count; i++) { - cdep = &pkg->depends[i]; + for (cdep = pkg_get_ptr(pkg, PKG_DEPENDS); cdep && cdep->type; cdep++) { if (cdep->type != PREDEPEND && cdep->type != DEPEND && cdep->type != RECOMMEND) continue; diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 7b10c1a..2a393a7 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -79,29 +79,9 @@ 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; - conffile_list_init(&pkg->conffiles); pkg->installed_files = NULL; pkg->installed_files_ref_cnt = 0; pkg->essential = 0; @@ -194,7 +174,7 @@ static void compound_depend_deinit(compound_depend_t * depends) void pkg_deinit(pkg_t * pkg) { - int i; + compound_depend_t *deps, *dep; if (pkg->name) free(pkg->name); @@ -211,40 +191,27 @@ void pkg_deinit(pkg_t * pkg) active_list_clear(&pkg->list); - if (pkg->replaces) - free(pkg->replaces); - pkg->replaces = NULL; + deps = pkg_get_ptr(pkg, PKG_DEPENDS); - 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 (deps) { + for (dep = deps; dep->type; dep++) + compound_depend_deinit(dep); - if (pkg->conflicts) { - for (i = 0; i < pkg->conflicts_count; i++) - compound_depend_deinit(&pkg->conflicts[i]); - free(pkg->conflicts); + free(deps); + pkg_set_ptr(pkg, PKG_DEPENDS, NULL); } - if (pkg->provides) - free(pkg->provides); + deps = pkg_get_ptr(pkg, PKG_CONFLICTS); - pkg->pre_depends_count = 0; - pkg->provides_count = 0; + if (deps) { + for (dep = deps; dep->type; dep++) + compound_depend_deinit(dep); - /* 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; + free(deps); + pkg_set_ptr(pkg, PKG_CONFLICTS, NULL); + } - 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 @@ -253,7 +220,7 @@ void pkg_deinit(pkg_t * pkg) pkg_free_installed_files(pkg); pkg->essential = 0; - blob_buf_free(&pkg->blob); + //blob_buf_free(&pkg->blob); } int pkg_init_from_file(pkg_t * pkg, const char *filename) @@ -315,6 +282,9 @@ err0: /* Merge any new information in newpkg into oldpkg */ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) { + abstract_pkg_t **ab; + conffile_list_t *cf, head; + if (oldpkg == newpkg) { return 0; } @@ -328,8 +298,8 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) 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 (!pkg_get_int(oldpkg, PKG_ARCH_PRIORITY)) + pkg_set_int(oldpkg, PKG_ARCH_PRIORITY, pkg_get_int(newpkg, PKG_ARCH_PRIORITY)); 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)) @@ -337,56 +307,34 @@ 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 (!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); } - if (!oldpkg->replaces_count) { - oldpkg->replaces_count = newpkg->replaces_count; - newpkg->replaces_count = 0; - - 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_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)) @@ -400,9 +348,13 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) 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)) { + cf = pkg_get_ptr(newpkg, PKG_CONFFILES); + if (cf) { + conffile_list_init(&head); + list_splice_init(&cf->head, &head.head); + pkg_set_raw(oldpkg, PKG_CONFFILES, &head, sizeof(head)); + } } if (!oldpkg->installed_files) { @@ -585,8 +537,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; @@ -611,14 +563,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", @@ -630,11 +585,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) { @@ -653,10 +609,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 ? "" : ",", @@ -725,11 +682,13 @@ 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++) { - fprintf(fp, "%s %s", i == 1 ? "" : ",", - pkg->provides[i]->name); + for (i = 0, ab_pkg++; *ab_pkg; i++, ab_pkg++) { + fprintf(fp, "%s %s", i == 0 ? "" : ",", + (*ab_pkg)->name); + ab_pkg++; } fprintf(fp, "\n"); } @@ -740,19 +699,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 ? "" : ",", @@ -798,10 +759,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 ? "" : ",", @@ -949,8 +911,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; @@ -1012,6 +974,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); @@ -1024,15 +987,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_int(a, PKG_ARCH_PRIORITY); + arch_prio2 = pkg_get_int(b, PKG_ARCH_PRIORITY); + 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; } @@ -1055,7 +1020,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) { @@ -1242,14 +1207,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) { @@ -1265,6 +1233,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; @@ -1278,7 +1247,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) { @@ -1289,13 +1258,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); diff --git a/libopkg/pkg.h b/libopkg/pkg.h index 0931e6e..7fdbea2 100644 --- a/libopkg/pkg.h +++ b/libopkg/pkg.h @@ -90,12 +90,19 @@ enum pkg_fields { PKG_VERSION, PKG_REVISION, PKG_ARCHITECTURE, + PKG_ARCH_PRIORITY, PKG_DESCRIPTION, PKG_MD5SUM, PKG_SHA256SUM, PKG_SIZE, PKG_INSTALLED_SIZE, PKG_INSTALLED_TIME, + PKG_TMP_UNPACK_DIR, + PKG_REPLACES, + PKG_PROVIDES, + PKG_DEPENDS, + PKG_CONFLICTS, + PKG_CONFFILES, }; struct abstract_pkg { @@ -138,36 +145,13 @@ struct pkg { char *name; pkg_src_t *src; pkg_dest_t *dest; - pkg_state_want_t state_want; - pkg_state_flag_t state_flag; - pkg_state_status_t state_status; - char **depends_str; - unsigned int depends_count; - char **pre_depends_str; - unsigned int pre_depends_count; - char **recommends_str; - unsigned int recommends_count; - char **suggests_str; - unsigned int suggests_count; + pkg_state_want_t state_want:3; + pkg_state_flag_t state_flag:10; + pkg_state_status_t state_status:4; struct active_list list; /* Used for installing|upgrading */ - compound_depend_t *depends; - - char **conflicts_str; - compound_depend_t *conflicts; - unsigned int conflicts_count; - - char **replaces_str; - unsigned int replaces_count; - abstract_pkg_t **replaces; - - char **provides_str; - unsigned int provides_count; - abstract_pkg_t **provides; abstract_pkg_t *parent; - char *tmp_unpack_dir; - conffile_list_t conffiles; /* As pointer for lazy evaluation */ str_list_t *installed_files; /* XXX: CLEANUP: I'd like to perhaps come up with a better @@ -175,7 +159,6 @@ struct pkg { installed_files list was being freed from an inner loop while still being used within an outer loop. */ int installed_files_ref_cnt; - int arch_priority; int essential:1; /* Adding this flag, to "force" opkg to choose a "provided_by_hand" package, if there are multiple choice */ @@ -215,12 +198,13 @@ static inline char *pkg_get_string(const pkg_t *pkg, int id) static inline void * pkg_set_ptr(pkg_t *pkg, int id, void *ptr) { - return pkg_set_raw(pkg, id, ptr, sizeof(ptr)); + return ptr ? *(void **) pkg_set_raw(pkg, id, &ptr, sizeof(ptr)) : NULL; } static inline void * pkg_get_ptr(const pkg_t *pkg, int id) { - return pkg_get_raw(pkg, id); + void **ptr = pkg_get_raw(pkg, id); + return ptr ? *ptr : NULL; } abstract_pkg_t *abstract_pkg_new(void); diff --git a/libopkg/pkg_depends.c b/libopkg/pkg_depends.c index d741c4a..4ffe73a 100644 --- a/libopkg/pkg_depends.c +++ b/libopkg/pkg_depends.c @@ -59,9 +59,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied, { pkg_t *satisfier_entry_pkg; int i, j, k; - int count, found; + int found; char **the_lost; abstract_pkg_t *ab_pkg; + compound_depend_t *compound_depend; /* * this is a setup to check for redundant/cyclic dependency checks, @@ -78,11 +79,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied, } else { ab_pkg->dependencies_checked = 1; /* mark it for subsequent visits */ } - /**/ - count = - pkg->pre_depends_count + pkg->depends_count + - pkg->recommends_count + pkg->suggests_count; - if (!count) { + + compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS); + + if (!compound_depend || !compound_depend->type) { *unresolved = NULL; return 0; } @@ -90,8 +90,7 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied, the_lost = NULL; /* foreach dependency */ - for (i = 0; i < count; i++) { - compound_depend_t *compound_depend = &pkg->depends[i]; + for (; compound_depend && compound_depend->type; compound_depend++) { depend_t **possible_satisfiers = compound_depend->possibilities;; found = 0; @@ -322,34 +321,30 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied, */ static int is_pkg_a_replaces(pkg_t * pkg_scout, pkg_t * pkg) { - int i; - int replaces_count = pkg->replaces_count; - abstract_pkg_t **replaces; + abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES); - if (pkg->replaces_count == 0) // No replaces, it's surely a conflict + if (!replaces || !*replaces) return 0; - replaces = pkg->replaces; - - for (i = 0; i < replaces_count; i++) { - if (strcmp(pkg_scout->name, pkg->replaces[i]->name) == 0) { // Found + while (*replaces) { + if (strcmp(pkg_scout->name, (*replaces)->name) == 0) { // Found opkg_msg(DEBUG2, "Seems I've found a replace %s %s\n", - pkg_scout->name, pkg->replaces[i]->name); + pkg_scout->name, (*replaces)->name); return 1; } + replaces++; } - return 0; + return 0; } pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg) { pkg_vec_t *installed_conflicts, *test_vec; - compound_depend_t *conflicts; + compound_depend_t *conflicts, *conflict; depend_t **possible_satisfiers; depend_t *possible_satisfier; - int i, j, k; - int count; + int j, k; abstract_pkg_t *ab_pkg; pkg_t **pkg_scouts; pkg_t *pkg_scout; @@ -364,17 +359,14 @@ pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg) return (pkg_vec_t *) NULL; } - conflicts = pkg->conflicts; + conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS); if (!conflicts) { return (pkg_vec_t *) NULL; } installed_conflicts = pkg_vec_alloc(); - count = pkg->conflicts_count; - /* foreach conflict */ - for (i = 0; i < pkg->conflicts_count; i++) { - + for (conflict = conflicts; conflict->type; conflict++ ) { possible_satisfiers = conflicts->possibilities; /* foreach possible satisfier */ @@ -537,17 +529,15 @@ static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg) */ int pkg_replaces(pkg_t * pkg, pkg_t * replacee) { - abstract_pkg_t **replaces = pkg->replaces; - int replaces_count = pkg->replaces_count; - int replacee_provides_count = replacee->provides_count; - int i, j; - for (i = 0; i < replaces_count; i++) { - abstract_pkg_t *abstract_replacee = replaces[i]; - for (j = 0; j < replacee_provides_count; j++) { - if (replacee->provides[j] == abstract_replacee) + abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES); + abstract_pkg_t **provides = pkg_get_ptr(replacee, PKG_PROVIDES); + abstract_pkg_t **r, **p; + + for (r = replaces; r && *r; r++) + for (p = provides; p && *p; p++) + if (*r == *p) return 1; - } - } + return 0; } @@ -557,12 +547,14 @@ int pkg_replaces(pkg_t * pkg, pkg_t * replacee) */ int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee) { - compound_depend_t *conflicts = pkg->conflicts; - int conflicts_count = pkg->conflicts_count; - int i, j; - for (i = 0; i < conflicts_count; i++) { - int possibility_count = conflicts[i].possibility_count; - struct depend **possibilities = conflicts[i].possibilities; + compound_depend_t *conflicts, *conflict; + + conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS); + + int j; + for (conflict = conflicts; conflict->type; conflict++) { + int possibility_count = conflict->possibility_count; + struct depend **possibilities = conflict->possibilities; for (j = 0; j < possibility_count; j++) { if (possibilities[j]->pkg == conflictee) { return 1; @@ -578,22 +570,22 @@ int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee) */ int pkg_conflicts(pkg_t * pkg, pkg_t * conflictee) { - compound_depend_t *conflicts = pkg->conflicts; - int conflicts_count = pkg->conflicts_count; - abstract_pkg_t **conflictee_provides = conflictee->provides; - int conflictee_provides_count = conflictee->provides_count; - int i, j, k; + int j; int possibility_count; struct depend **possibilities; - abstract_pkg_t *possibility; + compound_depend_t *conflicts, *conflict; + abstract_pkg_t **conflictee_provides, **provider, *possibility; - for (i = 0; i < conflicts_count; i++) { - possibility_count = conflicts[i].possibility_count; - possibilities = conflicts[i].possibilities; + conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS); + conflictee_provides = pkg_get_ptr(conflictee, PKG_PROVIDES); + + for (conflict = conflicts; conflict->type; conflict++) { + possibility_count = conflict->possibility_count; + possibilities = conflict->possibilities; for (j = 0; j < possibility_count; j++) { possibility = possibilities[j]->pkg; - for (k = 0; k < conflictee_provides_count; k++) { - if (possibility == conflictee_provides[k]) { + for (provider = conflictee_provides; provider && *provider; provider++) { + if (possibility == *provider) { return 1; } } @@ -647,8 +639,123 @@ char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx) return resized; } +abstract_pkg_t **init_providelist(pkg_t *pkg, int *count) +{ + abstract_pkg_t *ab_pkg; + abstract_pkg_t **provides = pkg_get_ptr(pkg, PKG_PROVIDES); + + if (!provides) { + provides = calloc(2, sizeof(abstract_pkg_t *)); + + if (!provides) { + if (count) + *count = 0; + + return NULL; + } + + ab_pkg = ensure_abstract_pkg_by_name(pkg->name); + + if (!ab_pkg->pkgs) + ab_pkg->pkgs = pkg_vec_alloc(); + + abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg); + + provides[0] = ab_pkg; + provides[1] = NULL; + + if (count) + *count = 2; + + pkg_set_ptr(pkg, PKG_PROVIDES, provides); + } + else if (count) { + for (*count = 1; *provides; provides++) + (*count)++; + } + + return provides; +} + +void parse_providelist(pkg_t *pkg, char *list) +{ + int count = 0; + char *item, *tok; + abstract_pkg_t *ab_pkg, *provided_abpkg, **tmp, **provides; + + provides = init_providelist(pkg, &count); + ab_pkg = ensure_abstract_pkg_by_name(pkg->name); + + if (!provides || !ab_pkg) + return; + + for (item = strtok_r(list, ", ", &tok); item; + count++, item = strtok_r(NULL, ", ", &tok)) { + tmp = realloc(provides, sizeof(abstract_pkg_t *) * (count + 1)); + + if (!tmp) + break; + + provided_abpkg = ensure_abstract_pkg_by_name(item); + + abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg); + + provides = tmp; + provides[count - 1] = provided_abpkg; + } + + provides[count - 1] = NULL; + + pkg_set_ptr(pkg, PKG_PROVIDES, provides); +} + +void parse_replacelist(pkg_t *pkg, char *list) +{ + int count; + char *item, *tok; + abstract_pkg_t *ab_pkg, *old_abpkg, **tmp, **replaces = NULL; + + ab_pkg = ensure_abstract_pkg_by_name(pkg->name); + + if (!ab_pkg->pkgs) + ab_pkg->pkgs = pkg_vec_alloc(); + + abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg); + + for (count = 1, item = strtok_r(list, ", ", &tok); + item; + count++, item = strtok_r(NULL, ", ", &tok), count++) { + tmp = realloc(replaces, sizeof(abstract_pkg_t *) * (count + 1)); + + if (!tmp) + break; + + old_abpkg = ensure_abstract_pkg_by_name(item); + + if (!old_abpkg->replaced_by) + old_abpkg->replaced_by = abstract_pkg_vec_alloc(); + + /* if a package pkg both replaces and conflicts old_abpkg, + * then add it to the replaced_by vector so that old_abpkg + * will be upgraded to ab_pkg automatically */ + if (pkg_conflicts_abstract(pkg, old_abpkg)) + abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg); + + replaces = tmp; + replaces[count - 1] = old_abpkg; + } + + if (!replaces) + return; + + replaces[count - 1] = NULL; + + pkg_set_ptr(pkg, PKG_REPLACES, replaces); +} + void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg) { +#if 0 int i; /* every pkg provides itself */ @@ -668,12 +775,14 @@ void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg) } if (pkg->provides_str) free(pkg->provides_str); +#endif } void buildConflicts(pkg_t * pkg) { + /* int i; - compound_depend_t *conflicts; + compound_depend_t *conflicts, *conflict; if (!pkg->conflicts_count) return; @@ -688,10 +797,12 @@ void buildConflicts(pkg_t * pkg) } if (pkg->conflicts_str) free(pkg->conflicts_str); + */ } void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg) { +#if 0 int i; if (!pkg->replaces_count) @@ -717,10 +828,62 @@ void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg) if (pkg->replaces_str) free(pkg->replaces_str); +#endif +} + +void parse_deplist(pkg_t *pkg, enum depend_type type, char *list) +{ + int id, count; + char *item, *tok; + compound_depend_t *tmp, *deps; + + switch (type) + { + case DEPEND: + case PREDEPEND: + case RECOMMEND: + case SUGGEST: + case GREEDY_DEPEND: + id = PKG_DEPENDS; + break; + + case CONFLICTS: + id = PKG_CONFLICTS; + break; + + default: + return; + } + + deps = pkg_get_ptr(pkg, id); + + for (tmp = deps, count = 1; tmp && tmp->type; tmp++) + count++; + + for (item = strtok_r(list, ",", &tok); item; item = strtok_r(NULL, ",", &tok), count++) { + tmp = realloc(deps, sizeof(compound_depend_t) * (count + 1)); + + if (!tmp) + break; + + deps = tmp; + + memset(deps + count - 1, 0, sizeof(compound_depend_t)); + parseDepends(deps + count - 1, item); + + deps[count - 1].type = type; + } + + if (!deps) + return; + + memset(deps + count - 1, 0, sizeof(compound_depend_t)); + pkg_set_ptr(pkg, id, deps); } void buildDepends(pkg_t * pkg) { +#if 0 unsigned int count; int i; compound_depend_t *depends; @@ -767,6 +930,8 @@ void buildDepends(pkg_t * pkg) } if (pkg->suggests_str) free(pkg->suggests_str); + +#endif } const char *constraint_to_str(enum version_constraint c) @@ -798,11 +963,19 @@ char *pkg_depend_str(pkg_t * pkg, int idx) int i; unsigned int len; char *str; - compound_depend_t *cdep; + compound_depend_t *cdep = NULL, *p; depend_t *dep; + for (i = 0, p = pkg_get_ptr(pkg, PKG_DEPENDS); p && p->type; i++, p++) + if (i == idx) { + cdep = p; + break; + } + + if (!cdep) + return NULL; + len = 0; - cdep = &pkg->depends[idx]; /* calculate string length */ for (i = 0; i < cdep->possibility_count; i++) { @@ -846,16 +1019,12 @@ char *pkg_depend_str(pkg_t * pkg, int idx) void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg) { compound_depend_t *depends; - int count, othercount; - int i, j; + int othercount; + int j; abstract_pkg_t *ab_depend; abstract_pkg_t **temp; - count = pkg->pre_depends_count + - pkg->depends_count + pkg->recommends_count + pkg->suggests_count; - - for (i = 0; i < count; i++) { - depends = &pkg->depends[i]; + for (depends = pkg_get_ptr(pkg, PKG_DEPENDS); depends && depends->type; depends++) { if (depends->type != PREDEPEND && depends->type != DEPEND && depends->type != RECOMMEND) continue; @@ -898,97 +1067,77 @@ static depend_t *depend_init(void) static int parseDepends(compound_depend_t * compound_depend, char *depend_str) { - char *pkg_name, buffer[2048]; - unsigned int num_of_ors = 0; int i; - char *src, *dest; - depend_t **possibilities; - - /* first count the number of ored possibilities for satisfying dependency */ - src = depend_str; - while (*src) - if (*src++ == '|') - num_of_ors++; + char *depend, *name, *vstr, *rest, *tok = NULL; + depend_t **possibilities = NULL, **tmp; compound_depend->type = DEPEND; - compound_depend->possibility_count = num_of_ors + 1; - possibilities = xcalloc((num_of_ors + 1), sizeof(depend_t *)); - compound_depend->possibilities = possibilities; + for (i = 0, depend = strtok_r(depend_str, "|", &tok); depend; i++, depend = strtok_r(NULL, "|", &tok)) { + name = strtok(depend, " "); + rest = strtok(NULL, "\n"); + + tmp = realloc(possibilities, sizeof(tmp) * (i + 1)); - src = depend_str; - for (i = 0; i < num_of_ors + 1; i++) { + if (!tmp) + return -1; + + possibilities = tmp; possibilities[i] = depend_init(); - /* gobble up just the name first */ - dest = buffer; - while (*src && - !isspace(*src) && - (*src != '(') && (*src != '*') && (*src != '|')) - *dest++ = *src++; - *dest = '\0'; - pkg_name = trim_xstrdup(buffer); - - /* now look at possible version info */ - - /* skip to next chars */ - if (isspace(*src)) - while (*src && isspace(*src)) - src++; - - /* extract constraint and version */ - if (*src == '(') { - src++; - if (!strncmp(src, "<<", 2)) { + possibilities[i]->pkg = ensure_abstract_pkg_by_name(name); + + if (rest && *rest == '(') { + vstr = strtok(rest + 1, ")"); + + if (!strncmp(vstr, "<<", 2)) { possibilities[i]->constraint = EARLIER; - src += 2; - } else if (!strncmp(src, "<=", 2)) { + vstr += 2; + } else if (!strncmp(vstr, "<=", 2)) { possibilities[i]->constraint = EARLIER_EQUAL; - src += 2; - } else if (!strncmp(src, ">=", 2)) { + vstr += 2; + } else if (!strncmp(vstr, ">=", 2)) { possibilities[i]->constraint = LATER_EQUAL; - src += 2; - } else if (!strncmp(src, ">>", 2)) { + vstr += 2; + } else if (!strncmp(vstr, ">>", 2)) { possibilities[i]->constraint = LATER; - src += 2; - } else if (!strncmp(src, "=", 1)) { + vstr += 2; + } else if (!strncmp(vstr, "=", 1)) { possibilities[i]->constraint = EQUAL; - src++; + vstr++; } /* should these be here to support deprecated designations; dpkg does */ - else if (!strncmp(src, "<", 1)) { + else if (!strncmp(vstr, "<", 1)) { possibilities[i]->constraint = EARLIER_EQUAL; - src++; - } else if (!strncmp(src, ">", 1)) { + vstr++; + } else if (!strncmp(vstr, ">", 1)) { possibilities[i]->constraint = LATER_EQUAL; - src++; + vstr++; } - /* now we have any constraint, pass space to version string */ - while (isspace(*src)) - src++; - - /* this would be the version string */ - dest = buffer; - while (*src && *src != ')') - *dest++ = *src++; - *dest = '\0'; - - possibilities[i]->version = trim_xstrdup(buffer); + possibilities[i]->version = trim_xstrdup(vstr); + rest = strtok(NULL, " "); + } + else { + rest = strtok(rest, " "); } - /* hook up the dependency to its abstract pkg */ - possibilities[i]->pkg = ensure_abstract_pkg_by_name(pkg_name); - - free(pkg_name); - /* now get past the ) and any possible | chars */ - while (*src && - (isspace(*src) || (*src == ')') || (*src == '|'))) - src++; - if (*src == '*') { + if (rest && *rest == '*') compound_depend->type = GREEDY_DEPEND; - src++; - } } + compound_depend->possibility_count = i; + compound_depend->possibilities = possibilities; + return 0; } + +compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type) +{ + compound_depend_t *dep; + + for (dep = pkg_get_ptr(pkg, PKG_DEPENDS); dep && dep->type; dep++) + if (type == UNSPEC || dep->type == type) + return dep; + + return NULL; +} diff --git a/libopkg/pkg_depends.h b/libopkg/pkg_depends.h index c1f7aa8..eeaa5ff 100644 --- a/libopkg/pkg_depends.h +++ b/libopkg/pkg_depends.h @@ -22,6 +22,7 @@ #include "pkg_hash.h" enum depend_type { + UNSPEC, PREDEPEND, DEPEND, CONFLICTS, @@ -60,6 +61,11 @@ void buildConflicts(pkg_t * pkg); void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg); void buildDepends(pkg_t * pkg); +void parse_deplist(pkg_t *pkg, enum depend_type type, char *list); + +abstract_pkg_t **init_providelist(pkg_t *pkg, int *count); +void parse_providelist(pkg_t *pkg, char *list); + /** * pkg_replaces returns 1 if pkg->replaces contains one of replacee's provides and 0 * otherwise. @@ -88,4 +94,6 @@ int pkg_dependence_satisfiable(depend_t * depend); int pkg_dependence_satisfied(depend_t * depend); const char *constraint_to_str(enum version_constraint c); +compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type); + #endif diff --git a/libopkg/pkg_hash.c b/libopkg/pkg_hash.c index 1b3fd05..a8809a3 100644 --- a/libopkg/pkg_hash.c +++ b/libopkg/pkg_hash.c @@ -141,7 +141,8 @@ pkg_hash_add_from_file(const char *file_name, continue; } - if (!pkg_get_string(pkg, PKG_ARCHITECTURE) || !pkg->arch_priority) { + if (!pkg_get_string(pkg, PKG_ARCHITECTURE) || + !pkg_get_int(pkg, PKG_ARCH_PRIORITY)) { char *version_str = pkg_version_str_alloc(pkg); opkg_msg(NOTICE, "Package %s version %s has no " "valid architecture, ignoring.\n", @@ -237,6 +238,7 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg, int nprovides = 0; int nmatching = 0; int wrong_arch_found = 0; + int arch_priority; pkg_vec_t *matching_pkgs; abstract_pkg_vec_t *matching_apkgs; abstract_pkg_vec_t *provided_apkg_vec; @@ -317,13 +319,15 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg, /* count packages matching max arch priority and keep track of last one */ for (j = 0; j < vec->len; j++) { pkg_t *maybe = vec->pkgs[j]; + arch_priority = pkg_get_int(maybe, PKG_ARCH_PRIORITY); + opkg_msg(DEBUG, "%s arch=%s arch_priority=%d version=%s.\n", maybe->name, pkg_get_string(maybe, PKG_ARCHITECTURE), - maybe->arch_priority, pkg_get_string(maybe, PKG_VERSION)); + arch_priority, pkg_get_string(maybe, PKG_VERSION)); /* We make sure not to add the same package twice. Need to search for the reason why they show up twice sometimes. */ - if ((maybe->arch_priority > 0) + if ((arch_priority > 0) && (!pkg_vec_contains(matching_pkgs, maybe))) { max_count++; @@ -389,9 +393,10 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg, int prio = 0; for (i = 0; i < matching_pkgs->len; i++) { pkg_t *matching = matching_pkgs->pkgs[i]; - if (matching->arch_priority > prio) { + arch_priority = pkg_get_int(matching, PKG_ARCH_PRIORITY); + if (arch_priority > prio) { priorized_matching = matching; - prio = matching->arch_priority; + prio = arch_priority; opkg_msg(DEBUG, "Match %s with priority %i.\n", matching->name, prio); } @@ -648,6 +653,8 @@ void hash_insert_pkg(pkg_t * pkg, int set_status) buildProvides(ab_pkg, pkg); + init_providelist(pkg, NULL); + /* Need to build the conflicts graph before replaces for correct * calculation of replaced_by relation. */ diff --git a/libopkg/pkg_parse.c b/libopkg/pkg_parse.c index 4b2e902..cfa551e 100644 --- a/libopkg/pkg_parse.c +++ b/libopkg/pkg_parse.c @@ -25,6 +25,7 @@ #include "pkg.h" #include "opkg_utils.h" #include "pkg_parse.h" +#include "pkg_depends.h" #include "libbb/libbb.h" #include "parse_util.h" @@ -46,6 +47,7 @@ static void parse_status(pkg_t * pkg, const char *sstr) static void parse_conffiles(pkg_t * pkg, const char *cstr) { + conffile_list_t *cl; char file_name[1024], md5sum[85]; if (sscanf(cstr, "%1023s %84s", file_name, md5sum) != 2) { @@ -54,7 +56,10 @@ static void parse_conffiles(pkg_t * pkg, const char *cstr) return; } - conffile_list_append(&pkg->conffiles, file_name, md5sum); + cl = pkg_get_ptr(pkg, PKG_CONFFILES); + + if (cl) + conffile_list_append(cl, file_name, md5sum); } int parse_version(pkg_t * pkg, const char *vstr) @@ -77,13 +82,15 @@ int parse_version(pkg_t * pkg, const char *vstr) vstr = ++colon; } - rev = strrchr(pkg_set_string(pkg, PKG_VERSION, vstr), '-'); + rev = strrchr(vstr, '-'); if (rev) { *rev++ = '\0'; - pkg_set_ptr(pkg, PKG_REVISION, rev); + pkg_set_string(pkg, PKG_REVISION, rev); } + pkg_set_string(pkg, PKG_VERSION, vstr); + return 0; } @@ -102,6 +109,7 @@ static int get_arch_priority(const char *arch) int pkg_parse_line(void *ptr, const char *line, uint mask) { pkg_t *pkg = (pkg_t *) ptr; + abstract_pkg_t *ab_pkg = NULL; /* these flags are a bit hackish... */ static int reading_conffiles = 0, reading_description = 0; @@ -117,8 +125,8 @@ int pkg_parse_line(void *ptr, const char *line, uint mask) switch (*line) { case 'A': if ((mask & PFM_ARCHITECTURE) && is_field("Architecture", line)) { - pkg->arch_priority = get_arch_priority( - pkg_set_string(pkg, PKG_ARCHITECTURE, line + strlen("Architecture") + 1)); + pkg_set_int(pkg, PKG_ARCH_PRIORITY, get_arch_priority( + pkg_set_string(pkg, PKG_ARCHITECTURE, line + strlen("Architecture") + 1))); } else if ((mask & PFM_AUTO_INSTALLED) && is_field("Auto-Installed", line)) { @@ -136,8 +144,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask) goto dont_reset_flags; } else if ((mask & PFM_CONFLICTS) && is_field("Conflicts", line)) - pkg->conflicts_str = - parse_list(line, &pkg->conflicts_count, ',', 0); + parse_deplist(pkg, CONFLICTS, line + strlen("Conflicts") + 1); break; case 'D': @@ -147,8 +154,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask) reading_description = 1; goto dont_reset_flags; } else if ((mask & PFM_DEPENDS) && is_field("Depends", line)) - pkg->depends_str = - parse_list(line, &pkg->depends_count, ',', 0); + parse_deplist(pkg, DEPEND, line + strlen("Depends") + 1); break; case 'E': @@ -193,22 +199,17 @@ int pkg_parse_line(void *ptr, const char *line, uint mask) else if ((mask & PFM_PRIORITY) && is_field("Priority", line)) pkg_set_string(pkg, PKG_PRIORITY, line + strlen("Priority") + 1); else if ((mask & PFM_PROVIDES) && is_field("Provides", line)) - pkg->provides_str = - parse_list(line, &pkg->provides_count, ',', 0); + parse_providelist(pkg, line + strlen("Provides") + 1); else if ((mask & PFM_PRE_DEPENDS) && is_field("Pre-Depends", line)) - pkg->pre_depends_str = - parse_list(line, &pkg->pre_depends_count, ',', 0); + parse_deplist(pkg, PREDEPEND, line + strlen("Pre-Depends") + 1); break; case 'R': if ((mask & PFM_RECOMMENDS) && is_field("Recommends", line)) - pkg->recommends_str = - parse_list(line, &pkg->recommends_count, ',', 0); + parse_deplist(pkg, RECOMMEND, line + strlen("Recommends") + 1); else if ((mask & PFM_REPLACES) && is_field("Replaces", line)) - pkg->replaces_str = - parse_list(line, &pkg->replaces_count, ',', 0); - + parse_replacelist(pkg, line + strlen("Replaces") + 1); break; case 'S': @@ -225,8 +226,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask) else if ((mask & PFM_STATUS) && is_field("Status", line)) parse_status(pkg, line); else if ((mask & PFM_SUGGESTS) && is_field("Suggests", line)) - pkg->suggests_str = - parse_list(line, &pkg->suggests_count, ',', 0); + parse_deplist(pkg, SUGGEST, line + strlen("Suggests") + 1); break; case 'T':