Skip to content

Commit

Permalink
xbps-pkgdb: add check selection.
Browse files Browse the repository at this point in the history
Add the --checks option to xbps-pkgdb, which allows the user to select
which package checks should be run. It works for a single package as
well as with the --all option.
  • Loading branch information
ericonr committed Dec 5, 2020
1 parent 552d836 commit c8fe086
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 18 deletions.
90 changes: 77 additions & 13 deletions bin/xbps-pkgdb/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
#include <xbps.h>
#include "defs.h"

struct pkgdb_cb_args {
int errors;
unsigned ctr;
};

static int
pkgdb_cb(struct xbps_handle *xhp UNUSED,
xbps_object_t obj,
Expand All @@ -44,7 +49,8 @@ pkgdb_cb(struct xbps_handle *xhp UNUSED,
{
const char *pkgver = NULL;
char pkgname[XBPS_NAME_SIZE];
int rv, *errors = (int *)arg;
struct pkgdb_cb_args *p = arg;
int rv;

xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
if (xhp->flags & XBPS_FLAG_VERBOSE)
Expand All @@ -53,24 +59,28 @@ pkgdb_cb(struct xbps_handle *xhp UNUSED,
if (!xbps_pkg_name(pkgname, sizeof(pkgname), pkgver)) {
abort();
}
if ((rv = check_pkg_integrity(xhp, obj, pkgname)) != 0)
*errors += 1;
if ((rv = check_pkg_integrity(xhp, obj, pkgname, p->ctr)) != 0)
p->errors += 1;

return 0;
}

int
check_pkg_integrity_all(struct xbps_handle *xhp)
check_pkg_integrity_all(struct xbps_handle *xhp, unsigned checks_to_run)
{
int errors = 0;
xbps_pkgdb_foreach_cb_multi(xhp, pkgdb_cb, &errors);
return errors ? -1 : 0;
struct pkgdb_cb_args args = {
.errors = 0,
.ctr = checks_to_run,
};
xbps_pkgdb_foreach_cb_multi(xhp, pkgdb_cb, &args);
return args.errors ? -1 : 0;
}

int
check_pkg_integrity(struct xbps_handle *xhp,
xbps_dictionary_t pkgd,
const char *pkgname)
const char *pkgname,
unsigned checks_to_run)
{
xbps_dictionary_t opkgd, filesd;
const char *sha256;
Expand Down Expand Up @@ -124,11 +134,18 @@ do { \
} while (0)

/* Execute pkg checks */
RUN_PKG_CHECK(xhp, files, filesd);
RUN_PKG_CHECK(xhp, symlinks, filesd);
RUN_PKG_CHECK(xhp, rundeps, opkgd);
RUN_PKG_CHECK(xhp, unneeded, opkgd);
RUN_PKG_CHECK(xhp, alternatives, opkgd);
if (checks_to_run | CHECK_FILES) {
RUN_PKG_CHECK(xhp, files, filesd);
RUN_PKG_CHECK(xhp, symlinks, filesd);
}
if (checks_to_run | CHECK_DEPENDENCIES)
RUN_PKG_CHECK(xhp, rundeps, opkgd);
if (checks_to_run | CHECK_ALTERNATIVES)
RUN_PKG_CHECK(xhp, alternatives, opkgd);
/* pkgdb internal checks go here */
if (checks_to_run | CHECK_PKGDB) {
RUN_PKG_CHECK(xhp, unneeded, opkgd);
}

if (filesd)
xbps_object_release(filesd);
Expand All @@ -137,3 +154,50 @@ do { \

return !!errors;
}

int
get_checks_to_run(unsigned *ctr, char *checks)
{
static char *available[] = {
[0] = "files",
/* 'deps' is an alias for 'dependencies' */
[1] = "dependencies",
[2] = "deps",
[3] = "alternatives",
[4] = "pkgdb",
NULL
};

/* Reset ctr before adding options */
*ctr = 0;

while (*checks) {
char *value;
int opt = getsubopt(&checks, available, &value);

/* Checks don't support options like foo=bar */
if (value)
return 1;

switch(opt) {
case 0:
*ctr |= CHECK_FILES;
break;
case 1:
case 2:
*ctr |= CHECK_DEPENDENCIES;
break;
case 3:
*ctr |= CHECK_ALTERNATIVES;
break;
case 4:
*ctr |= CHECK_PKGDB;
break;
default:
return 1;
}
}

/* If getsubopt exited because of end of string, return success */
return 0;
}
13 changes: 11 additions & 2 deletions bin/xbps-pkgdb/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@
#include <sys/time.h>
#include <xbps.h>

enum checks_to_run {
CHECK_FILES = 1,
CHECK_DEPENDENCIES = 1 << 1,
CHECK_ALTERNATIVES = 1 << 2,
CHECK_PKGDB = 1 << 3,
};

/* from check.c */
int check_pkg_integrity(struct xbps_handle *, xbps_dictionary_t, const char *);
int check_pkg_integrity_all(struct xbps_handle *);
int check_pkg_integrity(struct xbps_handle *, xbps_dictionary_t, const char *, unsigned);
int check_pkg_integrity_all(struct xbps_handle *, unsigned);

#define CHECK_PKG_DECL(type) \
int check_pkg_##type (struct xbps_handle *, const char *, void *)
Expand All @@ -42,6 +49,8 @@ CHECK_PKG_DECL(rundeps);
CHECK_PKG_DECL(symlinks);
CHECK_PKG_DECL(alternatives);

int get_checks_to_run(unsigned *, char *);

/* from convert.c */
void convert_pkgdb_format(struct xbps_handle *);

Expand Down
18 changes: 15 additions & 3 deletions bin/xbps-pkgdb/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ usage(bool fail)
"Usage: xbps-pkgdb [OPTIONS] [PKGNAME...]\n\n"
"OPTIONS\n"
" -a, --all Process all packages\n"
" -c, --checks <files,dependencies,alternatives,pkgdb>\n"
" Choose checks to run\n"
" -C, --config <dir> Path to confdir (xbps.d)\n"
" -d, --debug Debug mode shown to stderr\n"
" -h, --help Show usage\n"
Expand Down Expand Up @@ -83,22 +85,27 @@ change_pkg_mode(struct xbps_handle *xhp, const char *pkgname, const char *mode)
int
main(int argc, char **argv)
{
const char *shortopts = "aC:dhm:r:uVv";
const char *shortopts = "aC:dhm:r:uVvc:";
const struct option longopts[] = {
{ "all", no_argument, NULL, 'a' },
{ "config", required_argument, NULL, 'C' },
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "mode", required_argument, NULL, 'm' },
{ "pkg-names", required_argument, NULL, 'n' },
{ "rootdir", required_argument, NULL, 'r' },
{ "update", no_argument, NULL, 'u' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
/* XXX: add shortopt */
{ "checks", required_argument, NULL, 0 },
{ NULL, 0, NULL, 0 }
};
struct xbps_handle xh;
const char *confdir = NULL, *rootdir = NULL, *instmode = NULL;
int c, i, rv, flags = 0;
/* we want all checks to run if no checks are specified */
unsigned checks_to_run = ~0U;
bool update_format = false, all = false;

while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
Expand Down Expand Up @@ -130,6 +137,11 @@ main(int argc, char **argv)
case 'V':
printf("%s\n", XBPS_RELVER);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case 0:
if (get_checks_to_run(&checks_to_run, optarg))
usage(true);
break;
case '?':
default:
usage(true);
Expand Down Expand Up @@ -179,10 +191,10 @@ main(int argc, char **argv)
}
}
} else if (all) {
rv = check_pkg_integrity_all(&xh);
rv = check_pkg_integrity_all(&xh, checks_to_run);
} else {
for (i = optind; i < argc; i++) {
rv = check_pkg_integrity(&xh, NULL, argv[i]);
rv = check_pkg_integrity(&xh, NULL, argv[i], checks_to_run);
if (rv != 0)
fprintf(stderr, "Failed to check "
"`%s'\n", argv[i]);
Expand Down

0 comments on commit c8fe086

Please sign in to comment.