libxbps: pkg remove: never remove base symlinks in the root directory.

The /bin, /sbin, /lib, /lib32, /lib64, /var/run symlinks should never be removed
in Void, so be safe and ignore the removal of them.

Added another test to the testsuite to verify its correctness.
This commit is contained in:
Juan RP 2013-11-28 10:27:36 +01:00
parent 5d63f6f442
commit dce26db1de
5 changed files with 75 additions and 6 deletions

3
NEWS
View File

@ -1,5 +1,8 @@
xbps-0.27 (???):
* libxbps: make sure that base symlinks in the root directory are never removed,
due to /usr switch in Void. This will also be harmless in other systems.
* The testsuite now contains more tests than ever and will be extended as new
issues appear.

View File

@ -33,6 +33,21 @@
#include "xbps_api_impl.h"
#ifndef __arraycount
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
/* These are symlinks in Void and must not be removed */
static const char *basesymlinks[] = {
"/bin",
"/sbin",
"/lib",
"/lib32",
"/lib64",
"/usr/lib64",
"/var/run",
};
int HIDDEN
xbps_remove_pkg_files(struct xbps_handle *xhp,
xbps_dictionary_t dict,
@ -44,9 +59,10 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
xbps_object_iterator_t iter;
xbps_object_t obj;
const char *file, *sha256, *curobj = NULL;
char *path = NULL, *pkgname = NULL;
char *path = NULL;
char buf[PATH_MAX];
int rv = 0;
bool found;
assert(xbps_object_type(dict) == XBPS_TYPE_DICTIONARY);
assert(key != NULL);
@ -68,9 +84,6 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
else if (strcmp(key, "dirs") == 0)
curobj = "directory";
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
while ((obj = xbps_object_iterator_next(iter))) {
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
@ -141,6 +154,22 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
continue;
}
}
/*
* Make sure to not remove any symlink of root directory.
*/
found = false;
for (uint8_t i = 0; i < __arraycount(basesymlinks); i++) {
if (strcmp(file, basesymlinks[i]) == 0) {
found = true;
xbps_dbg_printf(xhp, "[remove] %s ignoring "
"%s removal\n", pkgver, file);
break;
}
}
if (found) {
free(path);
continue;
}
/*
* Remove the object if possible.
*/
@ -158,7 +187,6 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
free(path);
}
xbps_object_iterator_release(iter);
free(pkgname);
return rv;
}

View File

@ -12,5 +12,6 @@ atf_test_program{name="issue6_test"}
atf_test_program{name="issue18_test"}
atf_test_program{name="issue20_test"}
atf_test_program{name="conf_files_test"}
atf_test_program{name="remove_test"}
include('find_pkg_orphans/Kyuafile')
include('pkgdb/Kyuafile')

View File

@ -1,7 +1,7 @@
TOPDIR = ../../../..
-include $(TOPDIR)/config.mk
TESTSHELL = conf_files_test issue6_test issue18_test issue20_test
TESTSHELL = conf_files_test issue6_test issue18_test issue20_test remove_test
include ../Makefile.inc
include $(TOPDIR)/mk/test.mk

View File

@ -0,0 +1,37 @@
#! /usr/bin/env atf-sh
# 1st test: make sure that base symlinks on rootdir are not removed.
atf_test_case keep_base_symlinks
keep_base_symlinks_head() {
atf_set "descr" "Tests for package removal: keep base symlinks test"
}
keep_base_symlinks_body() {
mkdir -p root/usr/bin
ln -sfr root/usr/bin root/bin
mkdir some_repo
mkdir -p pkg_A/usr/bin pkg_A/bin
touch -f pkg_A/usr/bin/foo
cd some_repo
xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
cd ..
xbps-install -r root --repository=some_repo -y foo
atf_check_equal $? 0
xbps-remove -r root -y foo
atf_check_equal $? 0
if [ -h root/bin ]; then
rv=0
else
rv=1
fi
atf_check_equal $rv 0
}
atf_init_test_cases() {
atf_add_test_case keep_base_symlinks
}