Introduce xbps_regpkgdb_foreach_pkg_cb() and use it in xbps-bin check.
This commit is contained in:
		@@ -35,55 +35,68 @@
 | 
			
		||||
#include <xbps_api.h>
 | 
			
		||||
#include "defs.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
check_pkg_integrity_all(void)
 | 
			
		||||
struct checkpkg {
 | 
			
		||||
	size_t npkgs;
 | 
			
		||||
	size_t nbrokenpkgs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
cb_pkg_integrity(prop_object_t obj, void *arg, bool *done)
 | 
			
		||||
{
 | 
			
		||||
	const struct xbps_handle *xhp;
 | 
			
		||||
	prop_array_t regpkgs;
 | 
			
		||||
	prop_object_t obj;
 | 
			
		||||
	struct checkpkg *cpkg = arg;
 | 
			
		||||
	const char *pkgname, *version;
 | 
			
		||||
	size_t i, npkgs = 0, nbrokenpkgs = 0;
 | 
			
		||||
 | 
			
		||||
	xhp = xbps_handle_get();
 | 
			
		||||
	regpkgs = prop_dictionary_get(xhp->regpkgdb_dictionary, "packages");
 | 
			
		||||
	if (prop_object_type(regpkgs) != PROP_TYPE_ARRAY)
 | 
			
		||||
		return 0;
 | 
			
		||||
	(void)done;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < prop_array_count(regpkgs); i++) {
 | 
			
		||||
		obj = prop_array_get(regpkgs, i);
 | 
			
		||||
	prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
 | 
			
		||||
	prop_dictionary_get_cstring_nocopy(obj, "version", &version);
 | 
			
		||||
	printf("Checking %s-%s ...\n", pkgname, version);
 | 
			
		||||
		if (check_pkg_integrity(pkgname) != 0)
 | 
			
		||||
			nbrokenpkgs++;
 | 
			
		||||
	if (check_pkg_integrity(obj, pkgname) != 0)
 | 
			
		||||
		cpkg->nbrokenpkgs++;
 | 
			
		||||
 | 
			
		||||
		npkgs++;
 | 
			
		||||
	cpkg->npkgs++;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
	printf("%zu package%s processed: %zu broken.\n", npkgs,
 | 
			
		||||
	    npkgs == 1 ? "" : "s", nbrokenpkgs);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
check_pkg_integrity_all(void)
 | 
			
		||||
{
 | 
			
		||||
	struct checkpkg *cpkg;
 | 
			
		||||
 | 
			
		||||
	cpkg = calloc(1, sizeof(*cpkg));
 | 
			
		||||
	if (cpkg == NULL)
 | 
			
		||||
		return ENOMEM;
 | 
			
		||||
 | 
			
		||||
	(void)xbps_regpkgdb_foreach_pkg_cb(cb_pkg_integrity, cpkg);
 | 
			
		||||
	printf("%zu package%s processed: %zu broken.\n", cpkg->npkgs,
 | 
			
		||||
	    cpkg->npkgs == 1 ? "" : "s", cpkg->nbrokenpkgs);
 | 
			
		||||
	free(cpkg);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
check_pkg_integrity(const char *pkgname)
 | 
			
		||||
check_pkg_integrity(prop_dictionary_t pkgd, const char *pkgname)
 | 
			
		||||
{
 | 
			
		||||
	prop_dictionary_t pkgd, propsd, filesd;
 | 
			
		||||
	prop_dictionary_t opkgd, propsd, filesd;
 | 
			
		||||
	int rv = 0;
 | 
			
		||||
	bool broken = false;
 | 
			
		||||
 | 
			
		||||
	propsd = filesd = NULL;
 | 
			
		||||
	propsd = filesd = opkgd = NULL;
 | 
			
		||||
 | 
			
		||||
	/* find real pkg by name */
 | 
			
		||||
	pkgd = xbps_find_pkg_dict_installed(pkgname, false);
 | 
			
		||||
	if (pkgd == NULL) {
 | 
			
		||||
		opkgd = xbps_find_pkg_dict_installed(pkgname, false);
 | 
			
		||||
		if (opkgd == NULL) {
 | 
			
		||||
			/* find virtual pkg by name */
 | 
			
		||||
		pkgd = xbps_find_virtualpkg_dict_installed(pkgname, false);
 | 
			
		||||
			pkgd = xbps_find_virtualpkg_dict_installed(pkgname,
 | 
			
		||||
			    false);
 | 
			
		||||
		}
 | 
			
		||||
	if (pkgd == NULL) {
 | 
			
		||||
		if (opkgd == NULL) {
 | 
			
		||||
			printf("Package %s is not installed.\n", pkgname);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	 * Check for props.plist metadata file.
 | 
			
		||||
	 */
 | 
			
		||||
@@ -117,7 +130,7 @@ check_pkg_integrity(const char *pkgname)
 | 
			
		||||
 | 
			
		||||
#define RUN_PKG_CHECK(name)						\
 | 
			
		||||
do {									\
 | 
			
		||||
	rv = check_pkg_##name(pkgd, propsd, filesd);		\
 | 
			
		||||
	rv = check_pkg_##name(pkgd ? pkgd : opkgd, propsd, filesd);	\
 | 
			
		||||
	if (rv)								\
 | 
			
		||||
		broken = true;						\
 | 
			
		||||
	else if (rv == -1) {						\
 | 
			
		||||
@@ -141,8 +154,8 @@ out:
 | 
			
		||||
		prop_object_release(filesd);
 | 
			
		||||
	if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY)
 | 
			
		||||
		prop_object_release(propsd);
 | 
			
		||||
	if (prop_object_type(pkgd) == PROP_TYPE_DICTIONARY)
 | 
			
		||||
		prop_object_release(pkgd);
 | 
			
		||||
	if (prop_object_type(opkgd) == PROP_TYPE_DICTIONARY)
 | 
			
		||||
		prop_object_release(opkgd);
 | 
			
		||||
	if (broken)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ int	exec_transaction(bool, bool);
 | 
			
		||||
int	remove_installed_pkgs(int, char **, bool, bool, bool, bool);
 | 
			
		||||
 | 
			
		||||
/* from check.c */
 | 
			
		||||
int	check_pkg_integrity(const char *);
 | 
			
		||||
int	check_pkg_integrity(prop_dictionary_t, const char *);
 | 
			
		||||
int	check_pkg_integrity_all(void);
 | 
			
		||||
 | 
			
		||||
#define CHECK_PKG_DECL(type)					\
 | 
			
		||||
 
 | 
			
		||||
@@ -295,7 +295,7 @@ main(int argc, char **argv)
 | 
			
		||||
		if (strcasecmp(argv[1], "all") == 0)
 | 
			
		||||
			rv = check_pkg_integrity_all();
 | 
			
		||||
		else
 | 
			
		||||
			rv = check_pkg_integrity(argv[1]);
 | 
			
		||||
			rv = check_pkg_integrity(NULL, argv[1]);
 | 
			
		||||
 | 
			
		||||
	} else if (strcasecmp(argv[0], "autoupdate") == 0) {
 | 
			
		||||
		/*
 | 
			
		||||
 
 | 
			
		||||
@@ -56,8 +56,8 @@
 | 
			
		||||
 */
 | 
			
		||||
#define XBPS_PKGINDEX_VERSION	"1.3"
 | 
			
		||||
 | 
			
		||||
#define XBPS_API_VERSION	"20111219"
 | 
			
		||||
#define XBPS_VERSION		"0.11.0"
 | 
			
		||||
#define XBPS_API_VERSION	"20111222"
 | 
			
		||||
#define XBPS_VERSION		"0.12"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @def XBPS_RELVER
 | 
			
		||||
@@ -419,7 +419,7 @@ struct xbps_handle {
 | 
			
		||||
	 */
 | 
			
		||||
	cfg_t *cfg;
 | 
			
		||||
	/**
 | 
			
		||||
	 * @var regpkgdb_dictionary.
 | 
			
		||||
	 * @private regpkgdb_dictionary.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Internalized proplib dictionary with the registed package database
 | 
			
		||||
	 * stored in XBPS_META_PATH/XBPS_REGPKGDB.
 | 
			
		||||
@@ -545,13 +545,8 @@ struct xbps_handle {
 | 
			
		||||
 * Initialize the XBPS library with the following steps:
 | 
			
		||||
 *
 | 
			
		||||
 *   - Set function callbacks for fetching and unpacking.
 | 
			
		||||
 *   - Set root directory (if not set, defaults to /).
 | 
			
		||||
 *   - Set cache directory (if not set, defaults to XBPS_CACHE_PATH).
 | 
			
		||||
 *   - Set global flags.
 | 
			
		||||
 *   - Set default cache connections for libfetch.
 | 
			
		||||
 *   - Initialize the debug printfs.
 | 
			
		||||
 *   - Internalize the proplib dictionary in config file.
 | 
			
		||||
 *   - Internalize the regpkgdb dictionary (if available).
 | 
			
		||||
 *   - Parse configuration file.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] xhp Pointer to an xbps_handle structure, as returned by
 | 
			
		||||
 * \a xbps_handle_alloc().
 | 
			
		||||
@@ -769,6 +764,19 @@ int xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict,
 | 
			
		||||
			int (*fn)(prop_object_t, void *, bool *),
 | 
			
		||||
			void *arg);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Executes a function callback per a package dictionary registered
 | 
			
		||||
 * in "regpkgdb" plist.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] fn Function callback to run for any pkg dictionary.
 | 
			
		||||
 * @param[in] arg Argument to be passed to the function callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success (all objects were processed), otherwise an
 | 
			
		||||
 * errno value.
 | 
			
		||||
 */
 | 
			
		||||
int xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *),
 | 
			
		||||
				 void *arg);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds the proplib's dictionary associated with a package, by looking
 | 
			
		||||
 * it via its name in a proplib dictionary.
 | 
			
		||||
 
 | 
			
		||||
@@ -100,3 +100,31 @@ xbps_regpkgdb_dictionary_release(void)
 | 
			
		||||
	regpkgdb_initialized = false;
 | 
			
		||||
	xbps_dbg_printf("[regpkgdb] released ok.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *),
 | 
			
		||||
			     void *arg)
 | 
			
		||||
{
 | 
			
		||||
	prop_array_t array;
 | 
			
		||||
	prop_object_t obj;
 | 
			
		||||
	struct xbps_handle *xhp = xbps_handle_get();
 | 
			
		||||
	size_t i;
 | 
			
		||||
	int rv;
 | 
			
		||||
	bool done = false;
 | 
			
		||||
 | 
			
		||||
	/* initialize regpkgdb */
 | 
			
		||||
	if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0)
 | 
			
		||||
		return rv;
 | 
			
		||||
 | 
			
		||||
	array = prop_dictionary_get(xhp->regpkgdb_dictionary, "packages");
 | 
			
		||||
	if (prop_object_type(array) != PROP_TYPE_ARRAY)
 | 
			
		||||
		return EINVAL;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < prop_array_count(array); i++) {
 | 
			
		||||
		obj = prop_array_get(array, i);
 | 
			
		||||
		rv = (*fn)(obj, arg, &done);
 | 
			
		||||
		if (rv != 0 || done)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	return rv;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user