lib/transaction_files.c: better handle preserve files
This commit is contained in:
committed by
Duncan Overbruck
parent
f2b119ef31
commit
8837e8c607
@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user