diff options
Diffstat (limited to 'lib/libalpm/remove.c')
-rw-r--r-- | lib/libalpm/remove.c | 119 |
1 files changed, 65 insertions, 54 deletions
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 44f3ee93..f5c3c078 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -22,8 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" - #include <stdlib.h> #include <errno.h> #include <string.h> @@ -216,7 +214,7 @@ static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file, { char filepath[PATH_MAX]; - if(alpm_list_find_str(skip_remove, file->name)) { + if(alpm_list_find(skip_remove, file->name, _alpm_fnmatch)) { /* return success because we will never actually remove this file */ return 1; } @@ -239,8 +237,9 @@ static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file, /* Helper function for iterating through a package's file and deleting them * Used by _alpm_remove_commit. */ -static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, - const alpm_file_t *fileobj, alpm_list_t *skip_remove, int nosave) +static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg, + alpm_pkg_t *newpkg, const alpm_file_t *fileobj, alpm_list_t *skip_remove, + int nosave) { struct stat buf; char file[PATH_MAX]; @@ -250,7 +249,7 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, /* check the remove skip list before removing the file. * see the big comment block in db_find_fileconflicts() for an * explanation. */ - if(alpm_list_find_str(skip_remove, fileobj->name)) { + if(alpm_list_find(skip_remove, fileobj->name, _alpm_fnmatch)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n", file); return 1; @@ -274,6 +273,10 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, } else if(files < 0) { _alpm_log(handle, ALPM_LOG_DEBUG, "keeping directory %s (could not count files)\n", file); + } else if(newpkg && _alpm_filelist_contains(alpm_pkg_get_files(newpkg), + fileobj->name)) { + _alpm_log(handle, ALPM_LOG_DEBUG, + "keeping directory %s (in new package)\n", file); } else { /* one last check- does any other package own this file? */ alpm_list_t *local, *local_pkgs; @@ -285,7 +288,8 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, /* we duplicated the package when we put it in the removal list, so we * so we can't use direct pointer comparison here. */ - if(_alpm_pkg_cmp(info, local_pkg) == 0) { + if(oldpkg->name_hash == local_pkg->name_hash + && strcmp(oldpkg->name, local_pkg->name) == 0) { continue; } filelist = alpm_pkg_get_files(local_pkg); @@ -308,7 +312,7 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, } } else { /* if the file needs backup and has been modified, back it up to .pacsave */ - alpm_backup_t *backup = _alpm_needbackup(fileobj->name, info); + alpm_backup_t *backup = _alpm_needbackup(fileobj->name, oldpkg); if(backup) { if(nosave) { _alpm_log(handle, ALPM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file); @@ -350,38 +354,15 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, return 0; } -int _alpm_remove_single_package(alpm_handle_t *handle, +static int remove_package_files(alpm_handle_t *handle, alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg, size_t targ_count, size_t pkg_count) { alpm_list_t *skip_remove; - size_t filenum = 0, position = 0; - const char *pkgname = oldpkg->name; - const char *pkgver = oldpkg->version; alpm_filelist_t *filelist; size_t i; - - if(newpkg) { - _alpm_log(handle, ALPM_LOG_DEBUG, "removing old package first (%s-%s)\n", - pkgname, pkgver); - } else { - EVENT(handle, ALPM_EVENT_REMOVE_START, oldpkg, NULL); - _alpm_log(handle, ALPM_LOG_DEBUG, "removing package %s-%s\n", - pkgname, pkgver); - - /* run the pre-remove scriptlet if it exists */ - if(alpm_pkg_has_scriptlet(oldpkg) && - !(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) { - char *scriptlet = _alpm_local_db_pkgpath(handle->db_local, - oldpkg, "install"); - _alpm_runscriptlet(handle, scriptlet, "pre_remove", pkgver, NULL, 0); - free(scriptlet); - } - } - - if(handle->trans->flags & ALPM_TRANS_FLAG_DBONLY) { - goto db; - } + int err = 0; + int nosave = handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE; if(newpkg) { alpm_filelist_t *newfiles; @@ -412,54 +393,89 @@ int _alpm_remove_single_package(alpm_handle_t *handle, alpm_file_t *file = filelist->files + i; if(!can_remove_file(handle, file, skip_remove)) { _alpm_log(handle, ALPM_LOG_DEBUG, - "not removing package '%s', can't remove all files\n", pkgname); + "not removing package '%s', can't remove all files\n", + oldpkg->name); + FREELIST(skip_remove); RET_ERR(handle, ALPM_ERR_PKG_CANT_REMOVE, -1); } - filenum++; } - _alpm_log(handle, ALPM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); + _alpm_log(handle, ALPM_LOG_DEBUG, "removing %zd files\n", filelist->count); if(!newpkg) { /* init progress bar, but only on true remove transactions */ - PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname, 0, + PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 0, pkg_count, targ_count); } /* iterate through the list backwards, unlinking files */ for(i = filelist->count; i > 0; i--) { alpm_file_t *file = filelist->files + i - 1; - int percent; - /* TODO: check return code and handle accordingly */ - unlink_file(handle, oldpkg, file, skip_remove, - handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE); + if(unlink_file(handle, oldpkg, newpkg, file, skip_remove, nosave) < 0) { + err++; + } if(!newpkg) { /* update progress bar after each file */ - percent = (position * 100) / filenum; - PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname, + int percent = ((filelist->count - i) * 100) / filelist->count; + PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, percent, pkg_count, targ_count); } - position++; } FREELIST(skip_remove); if(!newpkg) { /* set progress to 100% after we finish unlinking files */ - PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname, 100, + PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 100, pkg_count, targ_count); + } + + return err; +} - /* run the post-remove script if it exists */ +int _alpm_remove_single_package(alpm_handle_t *handle, + alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg, + size_t targ_count, size_t pkg_count) +{ + const char *pkgname = oldpkg->name; + const char *pkgver = oldpkg->version; + + if(newpkg) { + _alpm_log(handle, ALPM_LOG_DEBUG, "removing old package first (%s-%s)\n", + pkgname, pkgver); + } else { + EVENT(handle, ALPM_EVENT_REMOVE_START, oldpkg, NULL); + _alpm_log(handle, ALPM_LOG_DEBUG, "removing package %s-%s\n", + pkgname, pkgver); + + /* run the pre-remove scriptlet if it exists */ if(alpm_pkg_has_scriptlet(oldpkg) && !(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) { char *scriptlet = _alpm_local_db_pkgpath(handle->db_local, oldpkg, "install"); - _alpm_runscriptlet(handle, scriptlet, "post_remove", pkgver, NULL, 0); + _alpm_runscriptlet(handle, scriptlet, "pre_remove", pkgver, NULL, 0); free(scriptlet); } } -db: + if(!(handle->trans->flags & ALPM_TRANS_FLAG_DBONLY)) { + /* TODO check returned errors if any */ + remove_package_files(handle, oldpkg, newpkg, targ_count, pkg_count); + } + + /* run the post-remove script if it exists */ + if(!newpkg && alpm_pkg_has_scriptlet(oldpkg) && + !(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) { + char *scriptlet = _alpm_local_db_pkgpath(handle->db_local, + oldpkg, "install"); + _alpm_runscriptlet(handle, scriptlet, "post_remove", pkgver, NULL, 0); + free(scriptlet); + } + + if(!newpkg) { + EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL); + } + /* remove the package from the database */ _alpm_log(handle, ALPM_LOG_DEBUG, "updating database\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "removing database entry '%s'\n", pkgname); @@ -473,11 +489,6 @@ db: pkgname); } - if(!newpkg) { - /* TODO: awesome! we're passing invalid pointers. */ - EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL); - } - return 0; } |