From cc6f9901f126864a9f4bedc3de2b68975c481ce2 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 30 Jul 2014 16:18:57 +0200 Subject: [PATCH] Fix #50 (Existent files on disk might be overwritten by packages with conf_files). --- NEWS | 4 +++ lib/package_config_files.c | 18 ++++++++--- lib/package_unpack.c | 16 +-------- tests/xbps/libxbps/shell/conf_files_test.sh | 36 +++++++++++++++++++++ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 393b1103..10978c32 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ xbps-0.38 (???): + * Always preserve files that exist on disk, but are managed by a package. + When such condition ocurrs install the pkg configuration file as `file.new-`. + This fixes GH issue #50 https://github.com/voidlinux/xbps/issues/50. + * Implemented support for post-install and pre-remove messages, as explained in issue #44 https://github.com/voidlinux/xbps/issues/44. diff --git a/lib/package_config_files.c b/lib/package_config_files.c index f6343a74..0978fa3f 100644 --- a/lib/package_config_files.c +++ b/lib/package_config_files.c @@ -68,7 +68,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, xbps_dictionary_t forigd; xbps_object_t obj, obj2; xbps_object_iterator_t iter, iter2; - const char *cffile, *sha256_new = NULL; + const char *version = NULL, *cffile, *sha256_new = NULL; char buf[PATH_MAX], *sha256_cur = NULL, *sha256_orig = NULL; int rv = 0; @@ -90,8 +90,18 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); if (forigd == NULL) { + /* + * File exists on disk but it's not managed by the same package. + * Install it as file.new-. + */ + version = xbps_pkg_version(pkgver); + assert(version); xbps_dbg_printf(xhp, "%s: conf_file %s not currently " - "installed\n", pkgver, entry_pname); + "installed, renaming to %s.new-%s\n", pkgver, entry_pname, version); + snprintf(buf, sizeof(buf), "%s.new-%s", entry_pname, version); + xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, + 0, pkgver, "File `%s' exists, installing configuration file to `%s'.", entry_pname, buf); + archive_entry_copy_pathname(entry, buf); rv = 1; goto out; } @@ -207,13 +217,11 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, } else if ((strcmp(sha256_orig, sha256_cur)) && (strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_orig, sha256_new))) { - const char *version; - version = xbps_pkg_version(pkgver); assert(version); snprintf(buf, sizeof(buf), ".%s.new-%s", cffile, version); xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, - 0, pkgver, "Installing new configuration file to `%s'.", buf); + 0, pkgver, "File `%s' exists, installing configuration file to `%s'.", cffile, buf); archive_entry_copy_pathname(entry, buf); rv = 1; break; diff --git a/lib/package_unpack.c b/lib/package_unpack.c index 20b1c820..df9d95b8 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -410,8 +410,8 @@ unpack_archive(struct xbps_handle *xhp, "matches existing SHA256, " "skipping...\n", pkgver, entry_pname); - skip_extract = true; } + skip_extract = true; rv = 0; } } @@ -497,20 +497,6 @@ unpack_archive(struct xbps_handle *xhp, "mode to %s.\n", pkgver, entry_pname, archive_entry_strmode(entry)); } - if (!update && conf_file && file_exists && !skip_extract) { - /* - * If installing new package preserve old configuration - * file but renaming it to .old. - */ - buf = xbps_xasprintf("%s.old", entry_pname); - (void)rename(entry_pname, buf); - free(buf); - buf = NULL; - xbps_set_cb_state(xhp, - XBPS_STATE_CONFIG_FILE, 0, pkgver, - "Renamed old configuration file " - "`%s' to `%s.old'.", entry_pname, entry_pname); - } if (!force && skip_extract) { archive_read_data_skip(ar); continue; diff --git a/tests/xbps/libxbps/shell/conf_files_test.sh b/tests/xbps/libxbps/shell/conf_files_test.sh index 2f0e6c26..738df44f 100644 --- a/tests/xbps/libxbps/shell/conf_files_test.sh +++ b/tests/xbps/libxbps/shell/conf_files_test.sh @@ -128,8 +128,44 @@ tc3_body() { atf_check_equal $rval 0 } +# 4th test: existent file on disk; new package defines configuration file. +# result: keep on-disk file as is, install new conf file as file.new-. +atf_test_case tc4 + +tc4_head() { + atf_set "descr" "Tests for configuration file handling: existent on-disk, new install" +} + +tc4_body() { + mkdir repo + cd repo + mkdir -p pkg_a/etc + echo "fooblah" > pkg_a/etc/cf1.conf + chmod 755 pkg_a/etc/cf1.conf + xbps-create -A noarch -n a-0.1_1 -s "pkg a" --config-files "/etc/cf1.conf" pkg_a + atf_check_equal $? 0 + rm -rf pkg_a + xbps-rindex -a *.xbps + atf_check_equal $? 0 + + mkdir -p rootdir/etc + echo "blahblah" > rootdir/etc/cf1.conf + + xbps-install -C null.conf -r rootdir --repository=$PWD -yvd a + atf_check_equal $? 0 + + result="$(cat rootdir/etc/cf1.conf)" + resultpkg="$(cat rootdir/etc/cf1.conf.new-0.1_1)" + rval=1 + if [ "${result}" = "blahblah" -a "${resultpkg}" = "fooblah" ]; then + rval=0 + fi + atf_check_equal $rval 0 +} + atf_init_test_cases() { atf_add_test_case tc1 atf_add_test_case tc2 atf_add_test_case tc3 + atf_add_test_case tc4 }