Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support running only specific checks in xbps-pkgdb #352

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 79 additions & 15 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 @@ -118,22 +128,76 @@ check_pkg_integrity(struct xbps_handle *xhp,

#define RUN_PKG_CHECK(x, name, arg) \
do { \
if ((rv = check_pkg_##name(x, pkgname, arg)) != 0) { \
if (check_pkg_##name(x, pkgname, arg)) { \
errors++; \
} \
} 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);

#undef RUN_PKG_CHECK

return errors ? EXIT_FAILURE : EXIT_SUCCESS;
return !!errors;
}

int
get_checks_to_run(unsigned *ctr, char *checks)
{
char *const 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
20 changes: 16 additions & 4 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"
" --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,13 +191,13 @@ 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': %s\n", argv[i], strerror(rv));
"`%s'\n", argv[i]);
}
}

Expand Down
13 changes: 13 additions & 0 deletions bin/xbps-pkgdb/xbps-pkgdb.1
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ Updates the pkgdb format to the latest version.
.Bl -tag -width -x
.It Fl a, Fl -all
Process all registered packages, regardless of its state.
.It Fl c, Fl -checks Ar checks
Run only the checks specified in
.Ar checks ,
a comma separated list. The available checks are
.Sy files ,
.Sy dependencies ,
which has a
.Sy deps
alias,
.Sy alternatives
and
.Sy pkgdb ,
for internal checks.
.It Fl C, Fl -config Ar dir
Specifies a path to the XBPS configuration directory.
If the first character is not '/' then it's a relative path of
Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ for f in all extra error shadow "format=2" missing-prototypes \
missing-include-dirs old-style-definition \
init-self redundant-decls float-equal missing-noreturn \
cast-align cast-qual pointer-arith comment \
declaration-after-statement write-strings stack-protector; do
declaration-after-statement stack-protector; do
check_compiler_flag ${f} W
done

Expand Down