diff --git a/NEWS b/NEWS index 0752da59..ac10d540 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ xbps-0.44 (???): + * libxbps: properly detect when a file has been moved between packages: + if the mtime stored in the pkg metadata does not match the mtime + of the same file stored on disk, don't detect this as an obsolete file. + * xbps-pkgdb(8): this now exits with an error if any test has failed. * libxbps: while unpacking pkg files that were not modified (sha256 hash matched), diff --git a/lib/package_find_obsoletes.c b/lib/package_find_obsoletes.c index ba24935b..88cf713f 100644 --- a/lib/package_find_obsoletes.c +++ b/lib/package_find_obsoletes.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2014 Juan Romero Pardines. + * Copyright (c) 2009-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,8 +76,6 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, xbps_dictionary_t newd) { xbps_array_t instfiles, newfiles, obsoletes; - xbps_object_t obj, obj2; - xbps_string_t oldstr, newstr; /* These are symlinks in Void and must not be removed */ const char *basesymlinks[] = { "./bin", @@ -89,10 +87,7 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, "./usr/lib64", "./var/run", }; - const char *oldhash; - char file[PATH_MAX]; int rv = 0; - bool found; assert(xbps_object_type(instd) == XBPS_TYPE_DICTIONARY); assert(xbps_object_type(newd) == XBPS_TYPE_DICTIONARY); @@ -112,7 +107,14 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, * Iterate over files list from installed package. */ for (unsigned int i = 0; i < xbps_array_count(instfiles); i++) { - found = false; + xbps_object_t obj, obj2; + xbps_string_t oldstr, newstr; + struct stat st; + uint64_t mtime = 0; + const char *oldhash; + char file[PATH_MAX]; + bool found = false; + obj = xbps_array_get(instfiles, i); if (xbps_object_type(obj) != XBPS_TYPE_DICTIONARY) { /* ignore unexistent files */ @@ -124,13 +126,11 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, snprintf(file, sizeof(file), ".%s", xbps_string_cstring_nocopy(oldstr)); - oldhash = NULL; - xbps_dictionary_get_cstring_nocopy(obj, "sha256", &oldhash); - if (oldhash) { + if (xbps_dictionary_get_cstring_nocopy(obj, "sha256", &oldhash)) { rv = xbps_file_hash_check(file, oldhash); if (rv == ENOENT || rv == ERANGE) { /* - * Skip unexistent and files that do not + Skip unexistent and files that do not * match the hash. */ continue; @@ -157,7 +157,6 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, /* * Make sure to not remove any symlink of root directory. */ - found = false; for (uint8_t x = 0; x < __arraycount(basesymlinks); x++) { if (strcmp(file, basesymlinks[x]) == 0) { found = true; @@ -169,6 +168,22 @@ xbps_find_pkg_obsoletes(struct xbps_handle *xhp, if (found) { continue; } + /* + * Finally check if file mtime on disk matched what + * the installed pkg has stored. + */ + if (xbps_dictionary_get_uint64(obj, "mtime", &mtime)) { + if (lstat(file, &st) == -1) { + xbps_dbg_printf(xhp, "[obsoletes] lstat failed " + "for %s: %s\n", file, strerror(errno)); + continue; + } + if (mtime != (uint64_t)st.st_mtime) + continue; + + xbps_dbg_printf(xhp, + "[obsoletes] %s: matched mtime, adding obsolete.\n", file); + } /* * Obsolete found, add onto the array. */ diff --git a/tests/xbps/libxbps/shell/install_test.sh b/tests/xbps/libxbps/shell/install_test.sh index 8f3864d0..e3ad7966 100644 --- a/tests/xbps/libxbps/shell/install_test.sh +++ b/tests/xbps/libxbps/shell/install_test.sh @@ -315,7 +315,7 @@ update_file_timestamps_body() { atf_check_equal "$expected" "$result" - sleep 2 + sleep 1 cd repo touch -f pkg_A/usr/include/gsm/gsm.h xbps-create -A noarch -n foo-1.1_1 -s "foo pkg" ../pkg_A @@ -386,6 +386,7 @@ update_move_file_body() { xbps-rindex -d -a repo/*.xbps atf_check_equal $? 0 xbps-install -r root --repository=repo -yvd A B + sleep 1 cd repo rm ../pkg_B/usr/bin/sg rm ../pkg_A/usr/bin/newgrp diff --git a/tests/xbps/libxbps/shell/obsoletefiles_test.sh b/tests/xbps/libxbps/shell/obsoletefiles_test.sh index 799f9022..e374ddb9 100644 --- a/tests/xbps/libxbps/shell/obsoletefiles_test.sh +++ b/tests/xbps/libxbps/shell/obsoletefiles_test.sh @@ -212,7 +212,11 @@ files_move_to_dependency2_body() { xbps-install -r root --repository=$PWD -yvd libressl atf_check_equal $? 0 + sleep 1 rm -f ../pkg_libressl/usr/lib/libcrypto.* + touch -f ../pkg_libcrypto/usr/lib/libcrypto.so.30 + xbps-create -A noarch -n libcrypto-1.0_2 -s "libcrypto pkg" ../pkg_libcrypto + atf_check_equal $? 0 xbps-create -A noarch -n libressl-1.1_1 -s "libressl pkg" --dependencies "libcrypto>=1.0" ../pkg_libressl atf_check_equal $? 0 xbps-rindex -d -a $PWD/*.xbps