summaryrefslogtreecommitdiff
path: root/lib/libalpm/conflict.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/conflict.c')
-rw-r--r--lib/libalpm/conflict.c83
1 files changed, 43 insertions, 40 deletions
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 66e0b08d..a5f9590f 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -313,8 +313,7 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts,
return(conflicts);
}
-alpm_list_t *_alpm_db_find_conflicts(pmdb_t *db, pmtrans_t *trans, char *root,
- alpm_list_t **skip_list)
+alpm_list_t *_alpm_db_find_conflicts(pmdb_t *db, pmtrans_t *trans, char *root)
{
alpm_list_t *i, *j, *k;
alpm_list_t *conflicts = NULL;
@@ -366,50 +365,54 @@ alpm_list_t *_alpm_db_find_conflicts(pmdb_t *db, pmtrans_t *trans, char *root,
if(dbpkg) {
/* older ver of package currently installed */
tmpfiles = chk_filedifference(p1->files, alpm_pkg_get_files(dbpkg));
- for(j = tmpfiles; j; j = j->next) {
- filestr = j->data;
- _alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s", filestr);
-
- snprintf(path, PATH_MAX, "%s%s", root, filestr);
-
- /* stat the file - if it exists and is not a dir, do some checks */
- if(lstat(path, &buf) == 0 && !S_ISDIR(buf.st_mode)) {
- /* Look at all the targets to see if file has changed hands */
- for(k = targets; k; k = k->next) {
- p2 = (pmpkg_t *)k->data;
- /* Ensure we aren't looking at current package */
- if(strcmp(p2->name, p1->name)) {
- pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name);
- /* Check if it used to exist in a package, but doesn't anymore */
- if(localp2 && !alpm_list_find_str(alpm_pkg_get_files(p2), filestr)
- && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) {
- *skip_list = alpm_list_add(*skip_list, strdup(filestr));
- _alpm_log(PM_LOG_DEBUG, "adding to skiplist: %s", filestr);
- } else {
- conflicts = add_fileconflict(conflicts, PM_CONFLICT_TYPE_FILE,
- filestr, p1->name, NULL);
- break;
- }
- }
- }
- }
- }
- alpm_list_free_inner(tmpfiles, &free);
- alpm_list_free(tmpfiles);
} else {
/* no version of package currently installed */
- for(j = p1->files; j; j = j->next) {
- filestr = j->data;
-
- snprintf(path, PATH_MAX, "%s%s", root, filestr);
+ tmpfiles = alpm_list_strdup(p1->files);
+ }
- /* stat the file - if it exists and is not a dir, report a conflict */
- if(lstat(path, &buf) == 0 && !S_ISDIR(buf.st_mode)) {
- conflicts = add_fileconflict(conflicts, PM_CONFLICT_TYPE_FILE,
- filestr, p1->name, NULL);
+ /* loop over each file to be installed */
+ for(j = tmpfiles; j; j = j->next) {
+ filestr = j->data;
+ _alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s", filestr);
+
+ snprintf(path, PATH_MAX, "%s%s", root, filestr);
+
+ /* stat the file - if it exists and is not a dir, do some checks */
+ if(lstat(path, &buf) == 0 && !S_ISDIR(buf.st_mode)) {
+ /* Look at all the targets to see if file has changed hands */
+ for(k = targets; k; k = k->next) {
+ p2 = (pmpkg_t *)k->data;
+ /* Ensure we aren't looking at current package */
+ if(p2 == p1) {
+ continue;
+ }
+ pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name);
+ /* Check if it used to exist in a package, but doesn't anymore */
+ if(localp2 && !alpm_list_find_str(alpm_pkg_get_files(p2), filestr)
+ && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) {
+ /* check if the file is now in the backup array */
+ if(alpm_list_find_str(alpm_pkg_get_backup(p1), filestr)) {
+ /* keep file intact if it is in backup array */
+ trans->skip_add = alpm_list_add(trans->skip_add, strdup(path));
+ trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(path));
+ _alpm_log(PM_LOG_DEBUG, "file in backup array, adding to add and remove skiplist: %s", filestr);
+ } else {
+ /* skip removal of file, but not add. this will prevent a second
+ * package from removing the file when it was already installed
+ * by its new owner */
+ trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(path));
+ _alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s", filestr);
+ }
+ } else {
+ conflicts = add_fileconflict(conflicts, PM_CONFLICT_TYPE_FILE,
+ filestr, p1->name, NULL);
+ break;
+ }
}
}
}
+ alpm_list_free_inner(tmpfiles, &free);
+ alpm_list_free(tmpfiles);
}
return(conflicts);