From b6b446d32eb833d3eba4d775926ee1baad2acf9d Mon Sep 17 00:00:00 2001 From: Juan RP Date: Thu, 26 Feb 2015 19:37:46 +0100 Subject: [PATCH] libxbps: properly detect obsolete files with files being between pkgs. 120 test cases now successfully pass, and all known issues about pkg updates that move files between them should be gone (hopefully). --- NEWS | 4 ++ lib/package_find_obsoletes.c | 39 +++++++++++++------ tests/xbps/libxbps/shell/install_test.sh | 3 +- .../xbps/libxbps/shell/obsoletefiles_test.sh | 4 ++ 4 files changed, 37 insertions(+), 13 deletions(-) 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