#include "hash_table.h"
#include "libbb/libbb.h"
-static int parseDepends(compound_depend_t * compound_depend, char *depend_str);
+static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type);
static depend_t *depend_init(void);
static char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx);
static char **merge_unresolved(char **oldstuff, char **newstuff);
/* foreach possible satisfier */
for (j = 0; j < compound_depend->possibility_count; j++) {
/* foreach provided_by, which includes the abstract_pkg itself */
- abstract_pkg_t *abpkg =
- possible_satisfiers[j]->pkg;
- abstract_pkg_vec_t *ab_provider_vec =
- abpkg->provided_by;
+ abstract_pkg_t *abpkg = possible_satisfiers[j]->pkg;
+ abstract_pkg_vec_t *ab_provider_vec = abpkg->provided_by;
int nposs = ab_provider_vec->len;
- abstract_pkg_t **ab_providers =
- ab_provider_vec->pkgs;
+ abstract_pkg_t **ab_providers = ab_provider_vec->pkgs;
int l;
for (l = 0; l < nposs; l++) {
- pkg_vec_t *test_vec =
- ab_providers[l]->pkgs;
+ pkg_vec_t *test_vec = ab_providers[l]->pkgs;
/* if no depends on this one, try the first package that Provides this one */
if (!test_vec) { /* no pkg_vec hooked up to the abstract_pkg! (need another feed?) */
continue;
/* cruise this possiblity's pkg_vec looking for an installed version */
for (k = 0; k < test_vec->len; k++) {
- pkg_t *pkg_scout =
- test_vec->pkgs[k];
+ pkg_t *pkg_scout = test_vec->pkgs[k];
/* not installed, and not already known about? */
- if ((pkg_scout->state_want !=
- SW_INSTALL)
- && !pkg_scout->parent->
- dependencies_checked
- &&
- !is_pkg_in_pkg_vec
- (unsatisfied, pkg_scout)) {
+ if ((pkg_scout->state_want != SW_INSTALL)
+ && !pkg_scout->parent->dependencies_checked
+ && !is_pkg_in_pkg_vec(unsatisfied, pkg_scout)) {
char **newstuff = NULL;
int rc;
- pkg_vec_t *tmp_vec =
- pkg_vec_alloc();
+ pkg_vec_t *tmp_vec = pkg_vec_alloc();
/* check for not-already-installed dependencies */
- rc = pkg_hash_fetch_unsatisfied_dependencies(pkg_scout, tmp_vec, &newstuff);
+ rc = pkg_hash_fetch_unsatisfied_dependencies(
+ pkg_scout, tmp_vec, &newstuff);
if (newstuff == NULL) {
int m;
int ok = 1;
- for (m = 0;
- m < rc;
- m++) {
- pkg_t *p
- =
- tmp_vec->
- pkgs
- [m];
- if (p->
- state_want
- ==
- SW_INSTALL)
+ for (m = 0; m < rc; m++) {
+ pkg_t *p = tmp_vec->pkgs[m];
+ if (p->state_want == SW_INSTALL)
continue;
- opkg_msg
- (DEBUG,
+ opkg_msg(DEBUG,
"Not installing %s due"
" to requirement for %s.\n",
- pkg_scout->
- name,
- p->
- name);
+ pkg_scout->name, p->name);
ok = 0;
break;
}
- pkg_vec_free
- (tmp_vec);
+ pkg_vec_free(tmp_vec);
if (ok) {
/* mark this one for installation */
- opkg_msg
- (NOTICE,
+ opkg_msg(NOTICE,
"Adding satisfier for greedy"
" dependence %s.\n",
- pkg_scout->
- name);
- pkg_vec_insert
- (unsatisfied,
- pkg_scout);
+ pkg_scout->name);
+ pkg_vec_insert(unsatisfied, pkg_scout);
}
} else {
opkg_msg(DEBUG,
"Not installing %s due to "
"broken depends.\n",
- pkg_scout->
- name);
+ pkg_scout->name);
free(newstuff);
}
}
/* foreach possible satisfier, look for installed package */
for (j = 0; j < compound_depend->possibility_count; j++) {
/* foreach provided_by, which includes the abstract_pkg itself */
- depend_t *dependence_to_satisfy =
- possible_satisfiers[j];
- abstract_pkg_t *satisfying_apkg =
- possible_satisfiers[j]->pkg;
+ depend_t *dependence_to_satisfy = possible_satisfiers[j];
+ abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;
pkg_t *satisfying_pkg =
- pkg_hash_fetch_best_installation_candidate
- (satisfying_apkg,
- pkg_installed_and_constraint_satisfied,
- dependence_to_satisfy, 1);
+ pkg_hash_fetch_best_installation_candidate(satisfying_apkg,
+ pkg_installed_and_constraint_satisfied,
+ dependence_to_satisfy, 1);
/* Being that I can't test constraing in pkg_hash, I will test it here */
if (satisfying_pkg != NULL) {
if (!pkg_installed_and_constraint_satisfied
/* foreach possible satisfier, look for installed package */
for (j = 0; j < compound_depend->possibility_count; j++) {
/* foreach provided_by, which includes the abstract_pkg itself */
- depend_t *dependence_to_satisfy =
- possible_satisfiers[j];
- abstract_pkg_t *satisfying_apkg =
- possible_satisfiers[j]->pkg;
+ depend_t *dependence_to_satisfy = possible_satisfiers[j];
+ abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;
pkg_t *satisfying_pkg =
- pkg_hash_fetch_best_installation_candidate
- (satisfying_apkg,
- pkg_constraint_satisfied,
- dependence_to_satisfy, 1);
+ pkg_hash_fetch_best_installation_candidate(satisfying_apkg,
+ pkg_constraint_satisfied, dependence_to_satisfy, 1);
/* Being that I can't test constraing in pkg_hash, I will test it here too */
if (satisfying_pkg != NULL) {
- if (!pkg_constraint_satisfied
- (satisfying_pkg,
- dependence_to_satisfy)) {
+ if (!pkg_constraint_satisfied(satisfying_pkg,
+ dependence_to_satisfy)) {
satisfying_pkg = NULL;
}
}
/* user request overrides package recommendation */
if (satisfying_pkg != NULL
&& (compound_depend->type == RECOMMEND
- || compound_depend->type == SUGGEST)
- && (satisfying_pkg->state_want ==
- SW_DEINSTALL
- || satisfying_pkg->state_want ==
- SW_PURGE)) {
+ || compound_depend->type == SUGGEST)
+ && (satisfying_pkg->state_want == SW_DEINSTALL
+ || satisfying_pkg->state_want == SW_PURGE)) {
opkg_msg(NOTICE,
"%s: ignoring recommendation for "
"%s at user request\n",
- pkg->name,
- satisfying_pkg->name);
+ pkg->name, satisfying_pkg->name);
continue;
}
/* failure to meet recommendations is not an error */
if (compound_depend->type != RECOMMEND
&& compound_depend->type != SUGGEST)
- the_lost =
- add_unresolved_dep(pkg, the_lost,
- i);
+ the_lost = add_unresolved_dep(pkg, the_lost, i);
else
opkg_msg(NOTICE,
- "%s: unsatisfied recommendation for %s\n",
- pkg->name,
- compound_depend->
- possibilities[0]->pkg->name);
+ "%s: unsatisfied recommendation for %s\n",
+ pkg->name,
+ compound_depend->possibilities[0]->pkg->name);
} else {
if (compound_depend->type == SUGGEST) {
/* just mention it politely */
opkg_msg(NOTICE,
- "package %s suggests installing %s\n",
- pkg->name,
- satisfier_entry_pkg->name);
+ "package %s suggests installing %s\n",
+ pkg->name, satisfier_entry_pkg->name);
} else {
char **newstuff = NULL;
if (satisfier_entry_pkg != pkg &&
- !is_pkg_in_pkg_vec(unsatisfied,
- satisfier_entry_pkg))
+ !is_pkg_in_pkg_vec(unsatisfied, satisfier_entry_pkg))
{
- pkg_vec_insert(unsatisfied,
- satisfier_entry_pkg);
- pkg_hash_fetch_unsatisfied_dependencies
- (satisfier_entry_pkg,
- unsatisfied, &newstuff);
- the_lost =
- merge_unresolved(the_lost,
- newstuff);
+ pkg_hash_fetch_unsatisfied_dependencies(
+ satisfier_entry_pkg, unsatisfied, &newstuff);
+ pkg_vec_insert(unsatisfied, satisfier_entry_pkg);
+ the_lost = merge_unresolved(the_lost, newstuff);
if (newstuff)
free(newstuff);
}
"Internal error: pkg_scout=NULL\n");
continue;
}
- if ((pkg_scout->state_status ==
- SS_INSTALLED
- || pkg_scout->state_want ==
- SW_INSTALL)
- &&
- version_constraints_satisfied
- (possible_satisfier, pkg_scout)
- && !is_pkg_a_replaces(pkg_scout,
- pkg)) {
- if (!is_pkg_in_pkg_vec
- (installed_conflicts,
- pkg_scout)) {
- pkg_vec_insert
- (installed_conflicts,
- pkg_scout);
+ if ((pkg_scout->state_status == SS_INSTALLED
+ || pkg_scout->state_want == SW_INSTALL)
+ && version_constraints_satisfied(possible_satisfier,
+ pkg_scout)
+ && !is_pkg_a_replaces(pkg_scout, pkg)) {
+ if (!is_pkg_in_pkg_vec(installed_conflicts,
+ pkg_scout)) {
+ pkg_vec_insert(installed_conflicts, pkg_scout);
}
}
}
return 0;
}
-int pkg_dependence_satisfied(depend_t * depend)
-{
- abstract_pkg_t *apkg = depend->pkg;
- abstract_pkg_vec_t *provider_apkgs = apkg->provided_by;
- int n_providers = provider_apkgs->len;
- abstract_pkg_t **apkgs = provider_apkgs->pkgs;
- int i;
- int n_pkgs;
- int j;
-
- for (i = 0; i < n_providers; i++) {
- abstract_pkg_t *papkg = apkgs[i];
- pkg_vec_t *pkg_vec = papkg->pkgs;
- if (pkg_vec) {
- n_pkgs = pkg_vec->len;
- for (j = 0; j < n_pkgs; j++) {
- pkg_t *pkg = pkg_vec->pkgs[j];
- if (version_constraints_satisfied(depend, pkg)) {
- if (pkg->state_status == SS_INSTALLED
- || pkg->state_status == SS_UNPACKED)
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg)
{
int i;
return resized;
}
+static void flag_related_packages(pkg_t *pkg, int state_flags)
+{
+ int i, j;
+ compound_depend_t *deps;
+
+ for (deps = pkg_get_ptr(pkg, PKG_DEPENDS), i = 0; deps && deps[i].type; i++)
+ for (j = 0; j < deps[i].possibility_count; j++) {
+ if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
+ opkg_msg(DEBUG, "propagating pkg flag to dependent abpkg %s\n",
+ deps[i].possibilities[j]->pkg->name);
+ deps[i].possibilities[j]->pkg->state_flag |= state_flags;
+ }
+ }
+
+ for (deps = pkg_get_ptr(pkg, PKG_CONFLICTS), i = 0; deps && deps[i].type; i++)
+ for (j = 0; j < deps[i].possibility_count; j++) {
+ if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
+ opkg_msg(DEBUG, "propagating pkg flag to conflicting abpkg %s\n",
+ deps[i].possibilities[j]->pkg->name);
+ deps[i].possibilities[j]->pkg->state_flag |= state_flags;
+ }
+ }
+}
+
abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
{
abstract_pkg_t *ab_pkg;
if (!ab_pkg->pkgs)
ab_pkg->pkgs = pkg_vec_alloc();
- abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
+ if (!abstract_pkg_vec_contains(ab_pkg->provided_by, ab_pkg))
+ abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
provides[0] = ab_pkg;
provides[1] = NULL;
pkg_set_ptr(pkg, PKG_PROVIDES, provides);
}
else if (count) {
- for (*count = 1; *provides; provides++)
+ for (*count = 1; *provides; provides++) {
+ if (pkg->state_flag & SF_NEED_DETAIL) {
+ if (!((*provides)->state_flag & SF_NEED_DETAIL)) {
+ opkg_msg(DEBUG, "propagating pkg flag to provided abpkg %s\n",
+ (*provides)->name);
+ (*provides)->state_flag |= SF_NEED_DETAIL;
+ }
+ }
(*count)++;
+ }
}
+ flag_related_packages(pkg, SF_NEED_DETAIL);
+
return provides;
}
provided_abpkg = ensure_abstract_pkg_by_name(item);
- abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
+ if (provided_abpkg->state_flag & SF_NEED_DETAIL) {
+ if (!(ab_pkg->state_flag & SF_NEED_DETAIL)) {
+ opkg_msg(DEBUG, "propagating provided abpkg flag to "
+ "provider abpkg %s\n", ab_pkg->name);
+ ab_pkg->state_flag |= SF_NEED_DETAIL;
+ }
+ }
+
+ if (!abstract_pkg_vec_contains(provided_abpkg->provided_by, ab_pkg))
+ abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
provides = tmp;
provides[count - 1] = provided_abpkg;
old_abpkg = ensure_abstract_pkg_by_name(item);
+ if (pkg->state_flag & SF_NEED_DETAIL) {
+ if (!(old_abpkg->state_flag & SF_NEED_DETAIL)) {
+ opkg_msg(DEBUG, "propagating pkg flag to replaced abpkg %s\n",
+ old_abpkg->name);
+ old_abpkg->state_flag |= SF_NEED_DETAIL;
+ }
+ }
+
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);
+ if (pkg_conflicts_abstract(pkg, old_abpkg)) {
+ if (!abstract_pkg_vec_contains(old_abpkg->replaced_by, ab_pkg))
+ abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg);
+ }
replaces = tmp;
replaces[count - 1] = old_abpkg;
deps = tmp;
memset(deps + count - 1, 0, sizeof(compound_depend_t));
- parseDepends(deps + count - 1, item);
-
- deps[count - 1].type = type;
+ parseDepends(deps + count - 1, item, type);
}
if (!deps)
return d;
}
-static int parseDepends(compound_depend_t * compound_depend, char *depend_str)
+static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type)
{
int i;
char *depend, *name, *vstr, *rest, *tok = NULL;
depend_t **possibilities = NULL, **tmp;
- compound_depend->type = DEPEND;
+ compound_depend->type = type;
for (i = 0, depend = strtok_r(depend_str, "|", &tok); depend; i++, depend = strtok_r(NULL, "|", &tok)) {
name = strtok(depend, " ");