#include "opkg_remove.h"
#include "opkg_error.h"
-#include "opkg_state.h"
+#include "opkg_cmd.h"
#include "file_util.h"
#include "sprintf_alloc.h"
#include "str_util.h"
+#include "libbb/libbb.h"
/*
* Returns number of the number of packages depending on the packages provided by this package.
abstract_pkg_t **provides = pkg->provides;
int n_installed_dependents = 0;
int i;
- for (i = 0; i <= nprovides; i++) {
+ for (i = 0; i < nprovides; i++) {
abstract_pkg_t *providee = provides[i];
abstract_pkg_t **dependers = providee->depended_upon_by;
abstract_pkg_t *dep_ab_pkg;
/* if caller requested the set of installed dependents */
if (pdependents) {
int p = 0;
- abstract_pkg_t **dependents = (abstract_pkg_t **)malloc((n_installed_dependents+1)*sizeof(abstract_pkg_t *));
-
- if ( dependents == NULL ){
- fprintf(stderr,"%s Unable to allocate memory. REPORT THIS BUG IN BUGZILLA PLEASE\n", __FUNCTION__);
- return -1;
- }
+ abstract_pkg_t **dependents = xcalloc((n_installed_dependents+1), sizeof(abstract_pkg_t *));
*pdependents = dependents;
- for (i = 0; i <= nprovides; i++) {
+ for (i = 0; i < nprovides; i++) {
abstract_pkg_t *providee = provides[i];
abstract_pkg_t **dependers = providee->depended_upon_by;
abstract_pkg_t *dep_ab_pkg;
return 0;
}
-static int remove_autoinstalled (opkg_conf_t *conf, pkg_t *pkg)
+/*
+ * Find and remove packages that were autoinstalled and are orphaned
+ * by the removal of pkg.
+ */
+static int
+remove_autoinstalled(opkg_conf_t *conf, pkg_t *pkg)
{
- /*
- * find and remove packages that were autoinstalled and are orphaned by the removal of pkg
- */
-
- char *buffer, *d_str;
- int i;
-
- for (i = 0; i < pkg->depends_count; ++i)
- {
- int x = 0;
- pkg_t *p;
- d_str = pkg->depends_str[i];
- buffer = malloc (strlen (d_str) + 1);
- if (!buffer)
- {
- fprintf(stderr,"%s Unable to allocate memory.\n", __FUNCTION__);
- return -1;
- }
-
- while (d_str[x] != '\0' && d_str[x] != ' ')
- {
- buffer[x] = d_str[x];
- ++x;
- }
- buffer[x] = '\0';
- buffer = realloc (buffer, strlen (buffer) + 1);
- p = pkg_hash_fetch_installed_by_name (&conf->pkg_hash, buffer);
-
- /* if the package is not installed, this could have been a circular
- * depenancy and the package has already been removed */
- if (!p)
- return -1;
-
- if (p->auto_installed)
- {
- int deps;
- abstract_pkg_t **dependents;
-
- deps = pkg_has_installed_dependents(conf, NULL, p, &dependents);
- if (deps == 0)
- {
- opkg_message (conf, OPKG_INFO,
- "%s was autoinstalled but is now orphaned\n", buffer);
- opkg_remove_pkg(conf, p,0);
- }
- else
- opkg_message (conf, OPKG_INFO, "%s was autoinstalled and is still required by "
- "%d installed packages\n", buffer, deps);
- }
- free (buffer);
- }
+ int i, j;
+ 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];
+ if (cdep->type != DEPEND)
+ continue;
+ for (j=0; j<cdep->possibility_count; j++) {
+ p = pkg_hash_fetch_installed_by_name (&conf->pkg_hash,
+ cdep->possibilities[j]->pkg->name);
+
+ /* If the package is not installed, this could have
+ * been a circular dependency and the package has
+ * already been removed.
+ */
+ if (!p)
+ return -1;
+
+ if (!p->auto_installed)
+ continue;
+
+ n_deps = pkg_has_installed_dependents(conf, NULL, p,
+ &dependents);
+ if (n_deps == 0) {
+ opkg_message(conf, OPKG_NOTICE,
+ "%s was autoinstalled and is "
+ "now orphaned, removing\n",
+ p->name);
+ opkg_remove_pkg(conf, p, 0);
+ } else
+ opkg_message(conf, OPKG_INFO,
+ "%s was autoinstalled and is "
+ "still required by %d "
+ "installed packages.\n",
+ p->name, n_deps);
+
+ if (dependents)
+ free(dependents);
+ }
+ }
- return 0;
+ return 0;
}
int opkg_remove_pkg(opkg_conf_t *conf, pkg_t *pkg,int message)
if (!conf->force_removal_of_dependent_packages
&& !user_prefers_removing_dependents(conf, parent_pkg, pkg, dependents)) {
+ free(dependents);
return OPKG_PKG_HAS_DEPENDENTS;
}
return 0;
}
-int opkg_purge_pkg(opkg_conf_t *conf, pkg_t *pkg)
-{
- opkg_remove_pkg(conf, pkg,0);
- return 0;
-}
-
int remove_data_files_and_list(opkg_conf_t *conf, pkg_t *pkg)
{
str_list_t installed_dirs;
conffile_t *conffile;
int removed_a_dir;
pkg_t *owner;
+ int rootdirlen = 0;
str_list_init(&installed_dirs);
- installed_files = pkg_get_installed_files(pkg);
+ installed_files = pkg_get_installed_files(conf, pkg);
+
+ /* don't include trailing slash */
+ if (conf->offline_root)
+ rootdirlen = strlen(conf->offline_root);
- for (iter = installed_files->head; iter; iter = iter->next) {
- file_name = iter->data;
+ for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
+ file_name = (char *)iter->data;
if (file_is_dir(file_name)) {
- str_list_append(&installed_dirs, strdup(file_name));
+ str_list_append(&installed_dirs, file_name);
continue;
}
- conffile = pkg_get_conffile(pkg, file_name);
+ conffile = pkg_get_conffile(pkg, file_name+rootdirlen);
if (conffile) {
/* XXX: QUESTION: Is this right? I figure we only need to
save the conffile if it has been modified. Is that what
if (!conf->noaction) {
do {
removed_a_dir = 0;
- for (iter = installed_dirs.head; iter; iter = iter->next) {
- file_name = iter->data;
+ for (iter = str_list_first(&installed_dirs); iter; iter = str_list_next(&installed_dirs, iter)) {
+ file_name = (char *)iter->data;
if (rmdir(file_name) == 0) {
opkg_message(conf, OPKG_INFO, " deleting %s\n", file_name);
pkg_remove_installed_files_list(conf, pkg);
/* Don't print warning for dirs that are provided by other packages */
- for (iter = installed_dirs.head; iter; iter = iter->next) {
- file_name = iter->data;
+ for (iter = str_list_first(&installed_dirs); iter; iter = str_list_next(&installed_dirs, iter)) {
+ file_name = (char *)iter->data;
owner = file_hash_get_file_owner(conf, file_name);
if (owner) {
}
/* cleanup */
- for (iter = installed_dirs.head; iter; iter = iter->next) {
- free(iter->data);
- iter->data = NULL;
+ while (!void_list_empty(&installed_dirs)) {
+ iter = str_list_pop(&installed_dirs);
+ free(iter->data);
+ free(iter);
}
str_list_deinit(&installed_dirs);