lib/transaction_files.c: better handle preserve files

This commit is contained in:
Duncaen
2019-06-18 13:49:24 +02:00
committed by Duncan Overbruck
parent f2b119ef31
commit 8837e8c607

View File

@ -50,6 +50,8 @@ struct item {
uint64_t size; uint64_t size;
enum type type; enum type type;
unsigned int index; unsigned int index;
bool preserve;
bool update;
} old, new; } old, new;
bool deleted; bool deleted;
}; };
@ -230,12 +232,18 @@ collect_obsoletes(struct xbps_handle *xhp)
item = items[i]; item = items[i];
if (item->new.type == 0 && item->old.type != TYPE_DIR) {
if (item->new.type == 0) {
/* /*
* File was removed and is not provided by any * File was removed and is not provided by any
* new package. * new package.
* Probably obsolete. * Probably obsolete.
*/ */
if (item->old.preserve && item->old.update) {
xbps_dbg_printf(xhp, "[files] %s: skipping `preserve` %s: %s\n",
item->old.pkgver, typestr(item->old.type), item->file);
continue;
}
} else if (item->new.type == TYPE_CONFFILE) { } else if (item->new.type == TYPE_CONFFILE) {
/* /*
* Ignore conf files. * Ignore conf files.
@ -363,7 +371,8 @@ collect_obsoletes(struct xbps_handle *xhp)
static int static int
collect_file(struct xbps_handle *xhp, const char *file, size_t size, collect_file(struct xbps_handle *xhp, const char *file, size_t size,
const char *pkgname, const char *pkgver, unsigned int idx, const char *pkgname, const char *pkgver, unsigned int idx,
const char *sha256, enum type type, bool remove) const char *sha256, enum type type, bool update, bool preserve,
bool remove)
{ {
struct item *item; struct item *item;
@ -395,6 +404,22 @@ collect_file(struct xbps_handle *xhp, const char *file, size_t size,
xbps_dbg_printf(xhp, "[files] %s: file already removed" xbps_dbg_printf(xhp, "[files] %s: file already removed"
" by package `%s': %s\n", pkgver, item->old.pkgver, file); " by package `%s': %s\n", pkgver, item->old.pkgver, file);
/*
* Check if `preserve` is violated.
*/
if (item->old.preserve && !preserve) {
xbps_set_cb_state(xhp, XBPS_STATE_FILES_FAIL,
EPERM, item->old.pkgver,
"%s: preserved file `%s' removed by %s.",
item->old.pkgver, file, pkgver);
return EPERM;
} else if (preserve && !item->old.preserve) {
xbps_set_cb_state(xhp, XBPS_STATE_FILES_FAIL,
EPERM, pkgver,
"%s: preserved file `%s' removed by %s.",
pkgver, file, item->old.pkgver);
return EPERM;
}
return 0; return 0;
} }
goto add; goto add;
@ -433,6 +458,8 @@ add:
item->old.type = type; item->old.type = type;
item->old.size = size; item->old.size = size;
item->old.index = idx; item->old.index = idx;
item->old.preserve = preserve;
item->old.update = update;
if (sha256) if (sha256)
item->old.sha256 = strdup(sha256); item->old.sha256 = strdup(sha256);
} else { } else {
@ -441,6 +468,8 @@ add:
item->new.type = type; item->new.type = type;
item->new.size = size; item->new.size = size;
item->new.index = idx; item->new.index = idx;
item->new.preserve = preserve;
item->new.update = update;
} }
if (item->old.type && item->new.type) { if (item->old.type && item->new.type) {
/* /*
@ -466,7 +495,7 @@ add:
static int static int
collect_files(struct xbps_handle *xhp, xbps_dictionary_t d, collect_files(struct xbps_handle *xhp, xbps_dictionary_t d,
const char *pkgname, const char *pkgver, unsigned int idx, const char *pkgname, const char *pkgver, unsigned int idx,
bool remove) bool update, bool preserve, bool remove)
{ {
xbps_array_t a; xbps_array_t a;
xbps_dictionary_t filed; xbps_dictionary_t filed;
@ -484,7 +513,7 @@ collect_files(struct xbps_handle *xhp, xbps_dictionary_t d,
size = 0; size = 0;
xbps_dictionary_get_uint64(filed, "size", &size); xbps_dictionary_get_uint64(filed, "size", &size);
rv = collect_file(xhp, file, size, pkgname, pkgver, idx, sha256, rv = collect_file(xhp, file, size, pkgname, pkgver, idx, sha256,
TYPE_FILE, remove); TYPE_FILE, update, preserve, remove);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }
@ -503,7 +532,7 @@ collect_files(struct xbps_handle *xhp, xbps_dictionary_t d,
size = 0; size = 0;
#endif #endif
rv = collect_file(xhp, file, size, pkgname, pkgver, idx, sha256, rv = collect_file(xhp, file, size, pkgname, pkgver, idx, sha256,
TYPE_FILE, remove); TYPE_FILE, update, preserve, remove);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }
@ -513,7 +542,7 @@ collect_files(struct xbps_handle *xhp, xbps_dictionary_t d,
filed = xbps_array_get(a, i); filed = xbps_array_get(a, i);
xbps_dictionary_get_cstring_nocopy(filed, "file", &file); xbps_dictionary_get_cstring_nocopy(filed, "file", &file);
rv = collect_file(xhp, file, 0, pkgname, pkgver, idx, NULL, rv = collect_file(xhp, file, 0, pkgname, pkgver, idx, NULL,
TYPE_LINK, remove); TYPE_LINK, update, preserve, remove);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }
@ -523,7 +552,7 @@ collect_files(struct xbps_handle *xhp, xbps_dictionary_t d,
filed = xbps_array_get(a, i); filed = xbps_array_get(a, i);
xbps_dictionary_get_cstring_nocopy(filed, "file", &file); xbps_dictionary_get_cstring_nocopy(filed, "file", &file);
rv = collect_file(xhp, file, 0, pkgname, pkgver, idx, NULL, rv = collect_file(xhp, file, 0, pkgname, pkgver, idx, NULL,
TYPE_DIR, remove); TYPE_DIR, update, preserve, remove);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }
@ -535,7 +564,7 @@ out:
static int static int
collect_binpkg_files(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod, collect_binpkg_files(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod,
unsigned int idx) unsigned int idx, bool update)
{ {
xbps_dictionary_t filesd; xbps_dictionary_t filesd;
struct archive *ar = NULL; struct archive *ar = NULL;
@ -614,7 +643,8 @@ collect_binpkg_files(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod,
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
rv = collect_files(xhp, filesd, pkgname, pkgver, idx, false); rv = collect_files(xhp, filesd, pkgname, pkgver, idx,
update, false, false);
goto out; goto out;
} }
archive_read_data_skip(ar); archive_read_data_skip(ar);
@ -653,7 +683,7 @@ xbps_transaction_files(struct xbps_handle *xhp, xbps_object_iterator_t iter)
return EINVAL; return EINVAL;
while ((obj = xbps_object_iterator_next(iter)) != NULL) { while ((obj = xbps_object_iterator_next(iter)) != NULL) {
bool update = false;
/* /*
* `idx` is used as package install index, to chose which * `idx` is used as package install index, to chose which
* choose the first package which owns or used to own the * choose the first package which owns or used to own the
@ -674,12 +704,12 @@ xbps_transaction_files(struct xbps_handle *xhp, xbps_object_iterator_t iter)
pkgname = xbps_pkg_name(pkgver); pkgname = xbps_pkg_name(pkgver);
assert(pkgname); assert(pkgname);
update = strcmp(trans, "update") == 0;
if ((strcmp(trans, "install") == 0) || if (update || (strcmp(trans, "install") == 0)) {
(strcmp(trans, "update") == 0)) {
xbps_set_cb_state(xhp, XBPS_STATE_FILES, 0, pkgver, xbps_set_cb_state(xhp, XBPS_STATE_FILES, 0, pkgver,
"%s: collecting files...", pkgver); "%s: collecting files...", pkgver);
rv = collect_binpkg_files(xhp, obj, idx); rv = collect_binpkg_files(xhp, obj, idx, update);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }
@ -711,7 +741,8 @@ xbps_transaction_files(struct xbps_handle *xhp, xbps_object_iterator_t iter)
assert(oldpkgver); assert(oldpkgver);
xbps_set_cb_state(xhp, XBPS_STATE_FILES, 0, oldpkgver, xbps_set_cb_state(xhp, XBPS_STATE_FILES, 0, oldpkgver,
"%s: collecting files...", oldpkgver); "%s: collecting files...", oldpkgver);
rv = collect_files(xhp, filesd, pkgname, pkgver, idx, preserve, true); rv = collect_files(xhp, filesd, pkgname, pkgver, idx,
update, preserve, true);
if (rv != 0) if (rv != 0)
goto out; goto out;
} }