xbps-pkgdb: simplify the check code; make the reqby check work again.

This commit is contained in:
Juan RP 2012-11-17 17:43:54 +01:00
parent fcdb6b0930
commit e763f154a0
8 changed files with 70 additions and 146 deletions

View File

@ -38,7 +38,6 @@ struct checkpkg {
size_t totalpkgs;
size_t npkgs;
size_t nbrokenpkgs;
bool flush;
};
static int
@ -49,19 +48,18 @@ cb_pkg_integrity(struct xbps_handle *xhp,
{
struct checkpkg *cpkg = arg;
const char *pkgname, *version;
bool flush = false;
(void)done;
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
printf("[%zu/%zu] checking %s-%s ...\n",
cpkg->npkgs, cpkg->totalpkgs, pkgname, version);
if (check_pkg_integrity(xhp, obj, pkgname, false, &flush) != 0)
if (check_pkg_integrity(xhp, obj, pkgname) != 0)
cpkg->nbrokenpkgs++;
if (flush && !cpkg->flush)
cpkg->flush = flush;
cpkg->npkgs++;
return 0;
}
@ -78,12 +76,10 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
cpkg.totalpkgs = prop_array_count(xhp->pkgdb);
(void)xbps_pkgdb_foreach_cb(xhp, cb_pkg_integrity, &cpkg);
if (cpkg.flush) {
if ((rv = xbps_pkgdb_update(xhp, true)) != 0) {
xbps_error_printf("failed to write pkgdb: %s\n",
strerror(rv));
return rv;
}
if ((rv = xbps_pkgdb_update(xhp, true)) != 0) {
xbps_error_printf("failed to write pkgdb: %s\n",
strerror(rv));
return rv;
}
printf("%zu package%s processed: %zu broken.\n", cpkg.npkgs,
cpkg.npkgs == 1 ? "" : "s", cpkg.nbrokenpkgs);
@ -93,15 +89,12 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
int
check_pkg_integrity(struct xbps_handle *xhp,
prop_dictionary_t pkgd,
const char *pkgname,
bool flush,
bool *setflush)
const char *pkgname)
{
prop_dictionary_t opkgd, propsd;
const char *sha256;
char *buf;
int rv = 0;
bool pkgdb_update = false, broken = false;
propsd = opkgd = NULL;
@ -127,14 +120,13 @@ check_pkg_integrity(struct xbps_handle *xhp,
printf("%s: unexistent metafile, converting to 0.18 "
"format...\n", pkgname);
if ((rv = convert_pkgd_metadir(xhp, opkgd)) != 0)
goto out;
return rv;
return 0;
pkgdb_update = true;
goto out1;
} else if (prop_dictionary_count(propsd) == 0) {
xbps_error_printf("%s: incomplete metadata file.\n", pkgname);
broken = true;
goto out;
return 1;
}
prop_dictionary_get_cstring_nocopy(opkgd, "metafile-sha256", &sha256);
@ -144,47 +136,32 @@ check_pkg_integrity(struct xbps_handle *xhp,
rv = xbps_file_hash_check(buf, sha256);
free(buf);
if (rv == ERANGE) {
broken = true;
fprintf(stderr, "%s: metadata file has been "
"modified!\n", pkgname);
goto out;
return 1;
}
}
#define RUN_PKG_CHECK(x, name, arg, arg2) \
#define RUN_PKG_CHECK(x, name, arg) \
do { \
rv = check_pkg_##name(x, pkgname, arg, arg2); \
rv = check_pkg_##name(x, pkgname, arg); \
if (rv) \
broken = true; \
return rv; \
else if (rv == -1) { \
xbps_error_printf("%s: the %s test " \
"returned error!\n", pkgname, #name); \
goto out; \
return rv; \
} \
} while (0)
/* Execute pkg checks */
RUN_PKG_CHECK(xhp, files, propsd, &pkgdb_update);
RUN_PKG_CHECK(xhp, symlinks, propsd, &pkgdb_update);
RUN_PKG_CHECK(xhp, rundeps, propsd, &pkgdb_update);
RUN_PKG_CHECK(xhp, requiredby, opkgd, &pkgdb_update);
RUN_PKG_CHECK(xhp, unneeded, opkgd, &pkgdb_update);
out1:
if (flush && pkgdb_update) {
if (!xbps_pkgdb_replace_pkgd(xhp, opkgd, pkgname, false, true)) {
rv = EINVAL;
goto out;
}
}
if (setflush && pkgdb_update)
*setflush = true;
RUN_PKG_CHECK(xhp, files, propsd);
RUN_PKG_CHECK(xhp, symlinks, propsd);
RUN_PKG_CHECK(xhp, rundeps, propsd);
RUN_PKG_CHECK(xhp, requiredby, opkgd);
RUN_PKG_CHECK(xhp, unneeded, opkgd);
#undef RUN_PKG_CHECK
out:
if (broken)
return 1;
return rv;
return 0;
}

View File

@ -46,10 +46,7 @@
* Return 0 if test ran successfully, 1 otherwise and -1 on error.
*/
int
check_pkg_files(struct xbps_handle *xhp,
const char *pkgname,
void *arg,
bool *pkgdb_update)
check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
prop_array_t array;
prop_object_t obj;
@ -60,8 +57,6 @@ check_pkg_files(struct xbps_handle *xhp,
int rv = 0;
bool mutable, broken = false, test_broken = false;
(void)pkgdb_update;
array = prop_dictionary_get(pkg_filesd, "files");
if (array != NULL && prop_array_count(array) > 0) {
iter = xbps_array_iter_from_dict(pkg_filesd, "files");

View File

@ -34,31 +34,25 @@
#include <xbps_api.h>
#include "defs.h"
struct check_reqby_data {
prop_dictionary_t pkgd;
prop_array_t pkgd_reqby;
const char *pkgname;
const char *pkgver;
bool pkgd_reqby_alloc;
};
static int
check_reqby_pkg_cb(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *done)
{
struct check_reqby_data *crd = arg;
prop_array_t curpkg_rdeps, provides;
prop_dictionary_t pkgd = arg;
prop_array_t curpkg_rdeps, provides, pkgd_reqby;
prop_dictionary_t curpkg_propsd;
prop_string_t curpkgver;
const char *curpkgn;
const char *curpkgn, *pkgname, *pkgver;
(void)done;
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &curpkgn);
/* skip same pkg */
if (strcmp(curpkgn, crd->pkgname) == 0)
if (strcmp(curpkgn, pkgname) == 0)
return 0;
/*
@ -80,13 +74,13 @@ check_reqby_pkg_cb(struct xbps_handle *xhp,
/*
* Check for pkgpattern match with real packages...
*/
if (!xbps_match_pkgdep_in_array(curpkg_rdeps, crd->pkgver)) {
if (!xbps_match_pkgdep_in_array(curpkg_rdeps, pkgver)) {
/*
* ... otherwise check if package provides any virtual
* package and is matched against any object in
* run_depends.
*/
provides = prop_dictionary_get(obj, "provides");
provides = prop_dictionary_get(pkgd, "provides");
if (provides == NULL) {
/* doesn't provide any virtual pkg */
return 0;
@ -97,14 +91,14 @@ check_reqby_pkg_cb(struct xbps_handle *xhp,
return 0;
}
}
crd->pkgd_reqby = prop_dictionary_get(crd->pkgd, "requiredby");
pkgd_reqby = prop_dictionary_get(pkgd, "requiredby");
curpkgver = prop_dictionary_get(curpkg_propsd, "pkgver");
if (crd->pkgd_reqby != NULL) {
if (pkgd_reqby != NULL) {
/*
* Now check that current pkgver has been registered into
* its requiredby array.
*/
if (xbps_match_string_in_array(crd->pkgd_reqby,
if (xbps_match_string_in_array(pkgd_reqby,
prop_string_cstring_nocopy(curpkgver))) {
/*
* Current package already requires our package,
@ -116,55 +110,49 @@ check_reqby_pkg_cb(struct xbps_handle *xhp,
/*
* Missing requiredby array object, create it.
*/
crd->pkgd_reqby = prop_array_create();
assert(crd->pkgd_reqby);
crd->pkgd_reqby_alloc = true;
pkgd_reqby = prop_array_create();
assert(pkgd_reqby);
}
/*
* Added pkgdep into pkg's requiredby array.
*/
if (!prop_array_add(crd->pkgd_reqby, curpkgver))
if (!prop_array_add(pkgd_reqby, curpkgver))
return -1;
printf("%s: added missing requiredby entry for %s.\n\n",
crd->pkgver, prop_string_cstring_nocopy(curpkgver));
printf("%s: added requiredby entry for %s.\n\n",
pkgver, prop_string_cstring_nocopy(curpkgver));
return 1;
return 0;
}
/*
* Removes unused entries in pkg's requiredby array.
*/
static bool
remove_stale_entries_in_reqby(struct xbps_handle *xhp,
struct check_reqby_data *crd)
static void
remove_stale_entries_in_reqby(struct xbps_handle *xhp, prop_dictionary_t pkgd)
{
prop_array_t reqby;
prop_dictionary_t pkgd;
const char *str;
const char *str, *pkgver;
size_t i;
bool needs_update = false;
reqby = prop_dictionary_get(crd->pkgd, "requiredby");
reqby = prop_dictionary_get(pkgd, "requiredby");
if (reqby == NULL || prop_array_count(reqby) == 0)
return false;
return;
crd->pkgd_reqby = prop_dictionary_get(crd->pkgd, "requiredby");
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
for (i = 0; i < prop_array_count(reqby); i++) {
prop_array_get_cstring_nocopy(reqby, i, &str);
if ((pkgd = xbps_pkgdb_get_pkgd_by_pkgver(xhp, str)) != NULL)
continue;
printf("%s: found stale entry in requiredby `%s' (fixed)\n",
crd->pkgver, str);
if (xbps_remove_string_from_array(xhp, crd->pkgd_reqby, str))
needs_update = true;
if (!xbps_remove_string_from_array(xhp, reqby, str))
fprintf(stderr, "%s: failed to remove %s from "
"requiredby!\n", pkgver, str);
else
printf("%s: removed stale entry in requiredby `%s'\n",
pkgver, str);
}
if (needs_update) {
prop_dictionary_set(crd->pkgd, "requiredby", crd->pkgd_reqby);
return true;
}
return false;
}
/*
@ -177,36 +165,20 @@ remove_stale_entries_in_reqby(struct xbps_handle *xhp,
* Returns 0 if test ran successfully, 1 otherwise and -1 on error.
*/
int
check_pkg_requiredby(struct xbps_handle *xhp,
const char *pkgname,
void *arg,
bool *pkgdb_update)
check_pkg_requiredby(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
prop_dictionary_t pkgd = arg;
struct check_reqby_data crd;
int rv;
crd.pkgd = pkgd;
crd.pkgd_reqby = NULL;
crd.pkgd_reqby_alloc = false;
crd.pkgname = pkgname;
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &crd.pkgver);
(void)pkgname;
/* missing reqby entries in pkgs */
rv = xbps_pkgdb_foreach_cb(xhp, check_reqby_pkg_cb, &crd);
if (rv < 0) {
rv = xbps_pkgdb_foreach_cb(xhp, check_reqby_pkg_cb, pkgd);
if (rv != 0)
return rv;
} else if (rv == 1) {
*pkgdb_update = true;
prop_dictionary_set(pkgd, "requiredby", crd.pkgd_reqby);
if (crd.pkgd_reqby_alloc)
prop_object_release(crd.pkgd_reqby);
printf("%s: requiredby fix done!\n\n", crd.pkgver);
}
/* remove stale entries in pkg's reqby */
if (remove_stale_entries_in_reqby(xhp, &crd))
*pkgdb_update = true;
remove_stale_entries_in_reqby(xhp, pkgd);
return 0;
}

View File

@ -45,10 +45,7 @@
*/
int
check_pkg_rundeps(struct xbps_handle *xhp,
const char *pkgname,
void *arg,
bool *pkgdb_update)
check_pkg_rundeps(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
prop_dictionary_t pkg_propsd = arg;
prop_object_t obj;
@ -56,8 +53,6 @@ check_pkg_rundeps(struct xbps_handle *xhp,
const char *reqpkg;
bool test_broken = false;
(void)pkgdb_update;
if (!xbps_pkg_has_rundeps(pkg_propsd))
return 0;

View File

@ -46,10 +46,7 @@
* returns 0 if test ran successfully, 1 otherwise and -1 on error.
*/
int
check_pkg_symlinks(struct xbps_handle *xhp,
const char *pkgname,
void *arg,
bool *pkgdb_update)
check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
prop_array_t array;
prop_object_t obj;
@ -59,8 +56,6 @@ check_pkg_symlinks(struct xbps_handle *xhp,
char *path, *buf, *buf2, *buf3, *dname, *path_target;
bool broken = false, test_broken = false;
(void)pkgdb_update;
array = prop_dictionary_get(pkg_filesd, "links");
if ((prop_object_type(array) == PROP_TYPE_ARRAY) &&
prop_array_count(array) > 0) {

View File

@ -43,23 +43,18 @@
* and remove them if that was true.
*/
int
check_pkg_unneeded(struct xbps_handle *xhp,
const char *pkgname,
void *arg,
bool *pkgdb_update)
check_pkg_unneeded(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
prop_dictionary_t pkgd = arg;
(void)pkgname;
(void)xhp;
(void)pkgname;
if (prop_dictionary_get(pkgd, "remove-and-update")) {
*pkgdb_update = true;
if (prop_dictionary_get(pkgd, "remove-and-update"))
prop_dictionary_remove(pkgd, "remove-and-update");
}
if (prop_dictionary_get(pkgd, "transaction")) {
*pkgdb_update = true;
if (prop_dictionary_get(pkgd, "transaction"))
prop_dictionary_remove(pkgd, "transaction");
}
return 0;
}

View File

@ -30,15 +30,11 @@
#include <xbps_api.h>
/* from check.c */
int check_pkg_integrity(struct xbps_handle *,
prop_dictionary_t,
const char *,
bool,
bool *);
int check_pkg_integrity(struct xbps_handle *, prop_dictionary_t, const char *);
int check_pkg_integrity_all(struct xbps_handle *);
#define CHECK_PKG_DECL(type) \
int check_pkg_##type (struct xbps_handle *, const char *, void *, bool *)
int check_pkg_##type (struct xbps_handle *, const char *, void *)
CHECK_PKG_DECL(unneeded);
CHECK_PKG_DECL(files);

View File

@ -115,8 +115,7 @@ main(int argc, char **argv)
rv = check_pkg_integrity_all(&xh);
} else {
for (i = optind; i < argc; i++) {
rv = check_pkg_integrity(&xh, NULL, argv[i],
true, NULL);
rv = check_pkg_integrity(&xh, NULL, argv[i]);
if (rv != 0)
fprintf(stderr, "Failed to check "
"`%s': %s\n", argv[i], strerror(rv));