From 0b7a99e65bb95cd86d8846a21fce1cfc2b0b7495 Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Sun, 14 Dec 2008 23:18:06 -0500 Subject: * Rename top level ipkg directory to opkg git-svn-id: http://opkg.googlecode.com/svn/trunk@8 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- (limited to 'ipkg_remove.c') diff --git a/ipkg_remove.c b/ipkg_remove.c deleted file mode 100644 index 5d9cec9..0000000 --- a/ipkg_remove.c +++ /dev/null @@ -1,383 +0,0 @@ -/* ipkg_remove.c - the itsy package management system - - Carl D. Worth - - Copyright (C) 2001 University of Southern California - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. -*/ - -#include "ipkg.h" -#include "ipkg_message.h" - -#include - -#include "ipkg_remove.h" - -#include "file_util.h" -#include "sprintf_alloc.h" -#include "str_util.h" - -#include "ipkg_cmd.h" - -/* - * Returns number of the number of packages depending on the packages provided by this package. - * Every package implicitly provides itself. - */ -int pkg_has_installed_dependents(ipkg_conf_t *conf, abstract_pkg_t *parent_apkg, pkg_t *pkg, abstract_pkg_t *** pdependents) -{ - int nprovides = pkg->provides_count; - abstract_pkg_t **provides = pkg->provides; - int n_installed_dependents = 0; - int 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 (dependers == NULL) - continue; - while ((dep_ab_pkg = *dependers++) != NULL) { - if (dep_ab_pkg->state_status == SS_INSTALLED){ - n_installed_dependents++; - } - } - - } - /* 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; - } - - *pdependents = dependents; - 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 (dependers == NULL) - continue; - while ((dep_ab_pkg = *dependers++) != NULL) { - if (dep_ab_pkg->state_status == SS_INSTALLED && !(dep_ab_pkg->state_flag & SF_MARKED)) { - dependents[p++] = dep_ab_pkg; - dep_ab_pkg->state_flag |= SF_MARKED; - } - } - } - dependents[p] = NULL; - /* now clear the marks */ - for (i = 0; i < p; i++) { - abstract_pkg_t *dep_ab_pkg = dependents[i]; - dep_ab_pkg->state_flag &= ~SF_MARKED; - } - } - return n_installed_dependents; -} - -int ipkg_remove_dependent_pkgs (ipkg_conf_t *conf, pkg_t *pkg, abstract_pkg_t **dependents) -{ - int i; - int a; - int count; - pkg_vec_t *dependent_pkgs = pkg_vec_alloc(); - abstract_pkg_t * ab_pkg; - - if((ab_pkg = pkg->parent) == NULL){ - fprintf(stderr, "%s: unable to get dependent pkgs. pkg %s isn't in hash table\n", - __FUNCTION__, pkg->name); - return 0; - } - - if (dependents == NULL) - return 0; - - // here i am using the dependencies_checked - if (ab_pkg->dependencies_checked == 2) // variable to make out whether this package - return 0; // has already been encountered in the process - // of marking packages for removal - Karthik - ab_pkg->dependencies_checked = 2; - - i = 0; - count = 1; - while (dependents [i] != NULL) { - abstract_pkg_t *dep_ab_pkg = dependents[i]; - - if (dep_ab_pkg->dependencies_checked == 2){ - i++; - continue; - } - if (dep_ab_pkg->state_status == SS_INSTALLED) { - for (a = 0; a < dep_ab_pkg->pkgs->len; a++) { - pkg_t *dep_pkg = dep_ab_pkg->pkgs->pkgs[a]; - if (dep_pkg->state_status == SS_INSTALLED) { - pkg_vec_insert(dependent_pkgs, dep_pkg); - count++; - } - } - } - i++; - /* 1 - to keep track of visited ab_pkgs when checking for possiblility of a broken removal of pkgs. - * 2 - to keep track of pkgs whose deps have been checked alrdy - Karthik */ - } - - if (count == 1) - return 0; - - - for (i = 0; i < dependent_pkgs->len; i++) { - int err = ipkg_remove_pkg(conf, dependent_pkgs->pkgs[i],0); - if (err) - return err; - } - return 0; -} - -static int user_prefers_removing_dependents(ipkg_conf_t *conf, abstract_pkg_t *abpkg, pkg_t *pkg, abstract_pkg_t **dependents) -{ - abstract_pkg_t *dep_ab_pkg; - ipkg_message(conf, IPKG_ERROR, "Package %s is depended upon by packages:\n", pkg->name); - while ((dep_ab_pkg = *dependents++) != NULL) { - if (dep_ab_pkg->state_status == SS_INSTALLED) - ipkg_message(conf, IPKG_ERROR, "\t%s\n", dep_ab_pkg->name); - } - ipkg_message(conf, IPKG_ERROR, "These might cease to work if package %s is removed.\n\n", pkg->name); - ipkg_message(conf, IPKG_ERROR, ""); - ipkg_message(conf, IPKG_ERROR, "You can force removal of this package with -force-depends.\n"); - ipkg_message(conf, IPKG_ERROR, "You can force removal of this package and its dependents\n"); - ipkg_message(conf, IPKG_ERROR, "with -force-removal-of-dependent-packages or -recursive\n"); - ipkg_message(conf, IPKG_ERROR, "or by setting option force_removal_of_dependent_packages\n"); - ipkg_message(conf, IPKG_ERROR, "in ipkg.conf.\n"); - return 0; -} - -int ipkg_remove_pkg(ipkg_conf_t *conf, pkg_t *pkg,int message) -{ -/* Actually, when "message == 1" I have been called from an upgrade, and not from a normal remove - thus I wan't check for essential, as I'm upgrading. - I hope it won't break anything :) -*/ - int err; - abstract_pkg_t *parent_pkg = NULL; - - if (pkg->essential && !message) { - if (conf->force_removal_of_essential_packages) { - fprintf(stderr, "WARNING: Removing essential package %s under your coercion.\n" - "\tIf your system breaks, you get to keep both pieces\n", - pkg->name); - } else { - fprintf(stderr, "ERROR: Refusing to remove essential package %s.\n" - "\tRemoving an essential package may lead to an unusable system, but if\n" - "\tyou enjoy that kind of pain, you can force ipkg to proceed against\n" - "\tits will with the option: -force-removal-of-essential-packages\n", - pkg->name); - return IPKG_PKG_IS_ESSENTIAL; - } - } - - if ((parent_pkg = pkg->parent) == NULL) - return 0; - - /* only attempt to remove dependent installed packages if - * force_depends is not specified or the package is being - * replaced. - */ - if (!conf->force_depends - && !(pkg->state_flag & SF_REPLACE)) { - abstract_pkg_t **dependents; - int has_installed_dependents = - pkg_has_installed_dependents(conf, parent_pkg, pkg, &dependents); - - if (has_installed_dependents) { - /* - * if this package is depended up by others, then either we should - * not remove it or we should remove it and all of its dependents - */ - - if (!conf->force_removal_of_dependent_packages - && !user_prefers_removing_dependents(conf, parent_pkg, pkg, dependents)) { - return IPKG_PKG_HAS_DEPENDENTS; - } - - /* remove packages depending on this package - Karthik */ - err = ipkg_remove_dependent_pkgs (conf, pkg, dependents); - free(dependents); - if (err) return err; - } - } - - if ( message==0 ){ - printf("Removing package %s from %s...\n", pkg->name, pkg->dest->name); - fflush(stdout); - } - pkg->state_flag |= SF_FILELIST_CHANGED; - - pkg->state_want = SW_DEINSTALL; - ipkg_state_changed++; - - pkg_run_script(conf, pkg, "prerm", "remove"); - - /* DPKG_INCOMPATIBILITY: dpkg is slightly different here. It - maintains an empty filelist rather than deleting it. That seems - like a big pain, and I don't see that that should make a big - difference, but for anyone who wants tighter compatibility, - feel free to fix this. */ - remove_data_files_and_list(conf, pkg); - - pkg_run_script(conf, pkg, "postrm", "remove"); - - remove_maintainer_scripts_except_postrm(conf, pkg); - - /* Aman Gupta - Since ipkg is made for handheld devices with limited - * space, it doesn't make sense to leave extra configurations, files, - * and maintainer scripts left around. So, we make remove like purge, - * and take out all the crap :) */ - - remove_postrm(conf, pkg); - pkg->state_status = SS_NOT_INSTALLED; - - if (parent_pkg) - parent_pkg->state_status = SS_NOT_INSTALLED; - - return 0; -} - -int ipkg_purge_pkg(ipkg_conf_t *conf, pkg_t *pkg) -{ - ipkg_remove_pkg(conf, pkg,0); - return 0; -} - -int remove_data_files_and_list(ipkg_conf_t *conf, pkg_t *pkg) -{ - str_list_t installed_dirs; - str_list_t *installed_files; - str_list_elt_t *iter; - char *file_name; - conffile_t *conffile; - int removed_a_dir; - pkg_t *owner; - - str_list_init(&installed_dirs); - installed_files = pkg_get_installed_files(pkg); - - for (iter = installed_files->head; iter; iter = iter->next) { - file_name = iter->data; - - if (file_is_dir(file_name)) { - str_list_append(&installed_dirs, strdup(file_name)); - continue; - } - - conffile = pkg_get_conffile(pkg, file_name); - if (conffile) { - /* XXX: QUESTION: Is this right? I figure we only need to - save the conffile if it has been modified. Is that what - dpkg does? Or does dpkg preserve all conffiles? If so, - this seems like a better thing to do to conserve - space. */ - if (conffile_has_been_modified(conf, conffile)) { - printf(" not deleting modified conffile %s\n", file_name); - fflush(stdout); - continue; - } - } - - ipkg_message(conf, IPKG_INFO, " deleting %s (noaction=%d)\n", file_name, conf->noaction); - if (!conf->noaction) - unlink(file_name); - } - - if (!conf->noaction) { - do { - removed_a_dir = 0; - for (iter = installed_dirs.head; iter; iter = iter->next) { - file_name = iter->data; - - if (rmdir(file_name) == 0) { - ipkg_message(conf, IPKG_INFO, " deleting %s\n", file_name); - removed_a_dir = 1; - str_list_remove(&installed_dirs, &iter); - } - } - } while (removed_a_dir); - } - - pkg_free_installed_files(pkg); - /* We have to remove the file list now, so that - find_pkg_owning_file does not always just report this package */ - 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; - - owner = file_hash_get_file_owner(conf, file_name); - if (owner) { - free(iter->data); - iter->data = NULL; - str_list_remove(&installed_dirs, &iter); - } - } - - /* cleanup */ - for (iter = installed_dirs.head; iter; iter = iter->next) { - free(iter->data); - iter->data = NULL; - } - str_list_deinit(&installed_dirs); - - return 0; -} - -int remove_maintainer_scripts_except_postrm(ipkg_conf_t *conf, pkg_t *pkg) -{ - int i, err; - char *globpattern; - glob_t globbuf; - - if (conf->noaction) return 0; - - sprintf_alloc(&globpattern, "%s/%s.*", - pkg->dest->info_dir, pkg->name); - err = glob(globpattern, 0, NULL, &globbuf); - free(globpattern); - if (err) { - return 0; - } - - for (i = 0; i < globbuf.gl_pathc; i++) { - if (str_ends_with(globbuf.gl_pathv[i], ".postrm")) { - continue; - } - ipkg_message(conf, IPKG_INFO, " deleting %s\n", globbuf.gl_pathv[i]); - unlink(globbuf.gl_pathv[i]); - } - globfree(&globbuf); - - return 0; -} - -int remove_postrm(ipkg_conf_t *conf, pkg_t *pkg) -{ - char *postrm_file_name; - - if (conf->noaction) return 0; - - sprintf_alloc(&postrm_file_name, "%s/%s.postrm", - pkg->dest->info_dir, pkg->name); - unlink(postrm_file_name); - free(postrm_file_name); - - return 0; -} -- cgit v0.9.1