Check if we overwrote an exiting pacnew file before unlinking it.
Otherwise, updating to a version with an unchanged file would delete
existing pacnew files.

FS#47993

Signed-off-by: Andrew Gregory <[email protected]>
---
 lib/libalpm/add.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 18a8175..b8ac082 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -178,7 +178,7 @@ static int extract_single_file(alpm_handle_t *handle, 
struct archive *archive,
        char filename[PATH_MAX]; /* the actual file we're extracting */
        int needbackup = 0, notouch = 0;
        const char *hash_orig = NULL;
-       int errors = 0;
+       int isnewfile = 0, errors = 0;
        struct stat lsbuf;
        size_t filename_len;
 
@@ -226,7 +226,8 @@ static int extract_single_file(alpm_handle_t *handle, 
struct archive *archive,
         *  6- skip extraction, dir already exists.
         */
 
-       if(llstat(filename, &lsbuf) != 0) {
+       isnewfile = (llstat(filename, &lsbuf) != 0 && errno == ENOENT);
+       if(isnewfile) {
                /* cases 1,2: file doesn't exist, skip all backup checks */
        } else if(S_ISDIR(lsbuf.st_mode) && S_ISDIR(entrymode)) {
 #if 0
@@ -301,6 +302,7 @@ static int extract_single_file(alpm_handle_t *handle, 
struct archive *archive,
                        return 1;
                }
                strcpy(filename + filename_len, ".pacnew");
+               isnewfile = (llstat(filename, &lsbuf) != 0 && errno == ENOENT);
        }
 
        _alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
@@ -354,7 +356,9 @@ static int extract_single_file(alpm_handle_t *handle, 
struct archive *archive,
                         * including any user changes */
                        _alpm_log(handle, ALPM_LOG_DEBUG,
                                        "action: leaving existing file in 
place\n");
-                       unlink(filename);
+                       if(isnewfile) {
+                               unlink(filename);
+                       }
                } else if(hash_orig && hash_local && strcmp(hash_orig, 
hash_local) == 0) {
                        /* installed file has NOT been changed by user,
                         * update to the new version */
-- 
2.7.0

Reply via email to