lib/package_remove: order directories before removal

The order of entries in files.plist is inconsistent
between different releases of xbps. Hence they must be
ordered before removal to, so sub directories are removed
before their parents.
This commit is contained in:
Johannes Brechtmann 2019-03-23 21:57:21 +01:00 committed by Johannes
parent a46be6867a
commit 2745e25740

View File

@ -93,13 +93,23 @@ check_remove_pkg_files(struct xbps_handle *xhp,
return fail;
}
struct order_length_t {
unsigned int pos;
size_t len;
};
static int cmp_order_length(const void *l1, const void *l2) {
return ((const struct order_length_t*)l1)->len <
((const struct order_length_t*)l2)->len;
}
static int
remove_pkg_files(struct xbps_handle *xhp,
xbps_dictionary_t dict,
const char *key,
const char *pkgver)
{
xbps_array_t array;
xbps_array_t array, dirs;
xbps_object_iterator_t iter;
xbps_object_t obj;
const char *curobj = NULL;
@ -139,6 +149,40 @@ remove_pkg_files(struct xbps_handle *xhp,
xbps_object_iterator_reset(iter);
/*
* directories must be ordered before removal
*/
if (strcmp(key, "dirs") == 0) {
unsigned int i = 0;
unsigned int n = xbps_array_count(array);
struct order_length_t *lengths =
(struct order_length_t*) malloc(sizeof(struct order_length_t) * n);
if (lengths == NULL)
return ENOMEM;
while ((obj = xbps_object_iterator_next(iter))) {
const char *file;
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
lengths[i].len = strlen(file);
lengths[i].pos = i;
i++;
}
qsort(lengths, n, sizeof(struct order_length_t), cmp_order_length);
dirs = xbps_array_create_with_capacity(n);
for (i = 0; i < n; i++) {
xbps_array_add(dirs, xbps_array_get(array, lengths[i].pos));
}
xbps_object_iterator_release(iter);
iter = xbps_array_iterator(dirs);
free(lengths);
}
xbps_object_iterator_reset(iter);
while ((obj = xbps_object_iterator_next(iter))) {
const char *file, *sha256;
char path[PATH_MAX];