diff --git a/NEWS b/NEWS index 1d0404f1..9856653b 100644 --- a/NEWS +++ b/NEWS @@ -47,7 +47,7 @@ xbps-0.4 (2010-02-01): If set, files will be removed even if its hash doesn't match for the 'remove' target, and configuration files for the 'purge' target. - * libxbps: always overwrite files while unpacking, and compare old and - new files to remove obsoletes if necessary. This makes the "essential" - object in package dictionary unnecessary, because all packages are - treated as they were essential. + * libxbps: if updating a package, always overwrite files while unpacking; + compare old and new files to remove obsoletes if necessary. This makes + the "essential" object in package dictionary unnecessary, because all + packages are treated as they were essential. diff --git a/lib/unpack.c b/lib/unpack.c index cf35fe9e..ce0b824c 100644 --- a/lib/unpack.c +++ b/lib/unpack.c @@ -65,13 +65,24 @@ */ static void -set_extract_flags(int *flags) +set_extract_flags(int *flags, bool update) { - *flags = 0; + int lflags = 0; + if (getuid() == 0) - *flags = FEXTRACT_FLAGS; + lflags = FEXTRACT_FLAGS; else - *flags = EXTRACT_FLAGS; + lflags = EXTRACT_FLAGS; + + if (!update) { + /* + * Only overwrite files while updating. + */ + lflags |= ARCHIVE_EXTRACT_NO_OVERWRITE; + lflags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; + } + + *flags = lflags; } /* @@ -152,7 +163,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg) */ while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) { entry_str = archive_entry_pathname(entry); - set_extract_flags(&lflags); + set_extract_flags(&lflags, update); /* * Run the pre INSTALL action if the file is there. */