Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm/remove.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/remove.c')
-rw-r--r--lib/libalpm/remove.c119
1 files changed, 65 insertions, 54 deletions
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 41cee514..bc196510 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, "removing database entry '%s'\n", pkgname);
if(_alpm_local_db_remove(handle->db_local, oldpkg) == -1) {
@@ -472,11 +488,6 @@ db:
pkgname);
}
- if(!newpkg) {
- /* TODO: awesome! we're passing invalid pointers. */
- EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL);
- }
-
return 0;
}