Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Improve `pkgdb_access` API
Vsevolod Stakhov committed 1 year ago
commit 6037e67075476005ddf4c4900b499a43cbb035f1
parent ec12d11
10 files changed +65 -29
modified libpkg/pkg.h.in
@@ -847,17 +847,28 @@ void pkg_repo_create_set_expired_packages(struct pkg_repo_create *prc, const cha
int pkg_repo_create(struct pkg_repo_create *, char *path);

/**
-
 * Test if the EUID has sufficient privilege to carry out some
-
 * operation (mode is a bitmap indicating READ, WRITE, CREATE) on the
-
 * databases indicated in the database bitmap.
+
 * Flags for accessing pkg database
 */
#define PKGDB_MODE_READ		(0x1<<0)
#define PKGDB_MODE_WRITE	(0x1<<1)
#define PKGDB_MODE_CREATE	(0x1<<2)

+
/**
+
 * What repos should we open: local or remote
+
 */
#define PKGDB_DB_LOCAL		(0x1<<0)
#define PKGDB_DB_REPO		(0x1<<1)
-
int pkgdb_access(unsigned mode, unsigned database);
+
/**
+
 * Test if the EUID has sufficient privilege to carry out some
+
 * operation (mode is a bitmap indicating READ, WRITE, CREATE) on the
+
 * databases indicated in the database bitmap.
+
 *
+
 * It also accepts a number of arguments representing pkg repositories requested
+
 * to be opened. This list *MUST* be terminated with `NULL` repo.
+
 * If no repositories are specified (e.g. when NULL is the first argument,
+
 * then all repositories are tried to be accessed).
+
 */
+
int pkgdb_access(unsigned mode, unsigned database, ...);

/**
 * Open the local package database.
modified libpkg/pkgdb.c
@@ -711,7 +711,7 @@ out:
}

int
-
pkgdb_access(unsigned mode, unsigned database)
+
pkgdb_access(unsigned mode, unsigned database, ...)
{
	int			 retval = EPKG_OK;

@@ -735,6 +735,7 @@ pkgdb_access(unsigned mode, unsigned database)
	 * EPKG_OK: We can go ahead
	 */

+

	if ((mode & ~(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE))
	    != 0)
		return (EPKG_FATAL); /* EINVAL */
@@ -763,22 +764,45 @@ pkgdb_access(unsigned mode, unsigned database)
	}

	if ((database & PKGDB_DB_REPO) != 0) {
+
		va_list	ap;
		struct pkg_repo	*r = NULL;
+
		const char	*dbname;
+
		ucl_object_t *repos_seen = ucl_object_typed_new(UCL_OBJECT);
+

+
		va_start(ap, database);
+
		while((dbname = va_arg(ap, const char *)) != NULL) {
+
			ucl_object_insert_key(repos_seen, ucl_object_typed_new(UCL_BOOLEAN),
+
			    dbname, strlen(dbname), false);
+
		}
+
		va_end(ap);

		while (pkg_repos(&r) == EPKG_OK) {
			/* Ignore any repos marked as inactive */
			if (!pkg_repo_enabled(r))
				continue;

+
			if (repos_seen->len > 0 && r->name &&
+
			    !ucl_object_lookup(repos_seen, r->name)) {
+
				/* Skip what is not needed */
+
				continue;
+
			}
+

			retval = r->ops->access(r, mode);
			if (retval != EPKG_OK) {
				if (retval == EPKG_ENODB &&
-
				    mode == PKGDB_MODE_READ)
+
				    !(mode & PKGDB_MODE_READ)) {
					pkg_emit_error("Repository %s missing."
-
					    " 'pkg update' required", r->name);
+
						       " 'pkg update' required",
+
					    r->name);
+
				}
+

+
				ucl_object_unref(repos_seen);
+

				return (retval);
			}
		}
+

+
		ucl_object_unref(repos_seen);
	}
	return (retval);
}
modified src/add.c
@@ -2,7 +2,7 @@
 * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -12,7 +12,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -121,7 +121,7 @@ exec_add(int argc, char **argv)
	retcode = pkgdb_access(PKGDB_MODE_READ  |
			       PKGDB_MODE_WRITE |
			       PKGDB_MODE_CREATE,
-
			       PKGDB_DB_LOCAL);
+
			       PKGDB_DB_LOCAL, NULL);
	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to add packages");
		return (EXIT_FAILURE);
@@ -188,7 +188,7 @@ exec_add(int argc, char **argv)
	}
	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);
-
	
+

	if(failedpkgcount > 0) {
		fflush(failedpkgs->fp);
		printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, failedpkgs->buf);
modified src/annotate.c
@@ -1,7 +1,7 @@
/*-
 * Copyright (c) 2013-2014 Matthew Seaman <matthew@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -11,7 +11,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -110,7 +110,7 @@ do_modify(struct pkgdb *db, struct pkg *pkg, const char *tag, const char *value)
		}
	}
	return (ret);
-
} 
+
}

static int
do_delete(struct pkgdb *db, struct pkg *pkg, const char *tag)
@@ -136,7 +136,7 @@ do_delete(struct pkgdb *db, struct pkg *pkg, const char *tag)
		}
	}
	return (ret);
-
} 
+
}

static int
do_show(struct pkg *pkg, const char *tag)
modified src/clean.c
@@ -329,7 +329,7 @@ exec_clean(int argc, char **argv)
		return (errno == ENOENT ? EXIT_SUCCESS : EXIT_FAILURE);
	}

-
	retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
+
	retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO, NULL);

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to clean old packages");
modified src/fetch.c
@@ -145,7 +145,7 @@ exec_fetch(int argc, char **argv)
	else
		mode = PKGDB_MODE_READ;

-
	retcode = pkgdb_access(mode, PKGDB_DB_REPO);
+
	retcode = pkgdb_access(mode, PKGDB_DB_REPO, reponame, NULL);

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to access repo catalogue");
modified src/install.c
@@ -176,12 +176,13 @@ exec_install(int argc, char **argv)
	else
		repo_type = PKGDB_DB_LOCAL|PKGDB_DB_REPO;

-
	retcode = pkgdb_access(mode, repo_type);
+
	/* It is safe to use both `reponame` and `NULL` here */
+
	retcode = pkgdb_access(mode, repo_type, reponame, NULL);

	if (retcode == EPKG_ENOACCESS && dry_run) {
		auto_update = false;
		retcode = pkgdb_access(PKGDB_MODE_READ,
-
				       repo_type);
+
				       repo_type, reponame, NULL);
	}

	if (retcode == EPKG_ENOACCESS) {
modified src/rquery.c
@@ -205,7 +205,7 @@ exec_rquery(int argc, char **argv)
		}
	}

-
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO, reponame, NULL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to query the package database");
		xstring_free(sqlcond);
modified src/search.c
@@ -5,7 +5,7 @@
 * Copyright (c) 2012-2013 Bryan Drewery <bdrewery@FreeBSD.org>
 * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -15,7 +15,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -44,7 +44,7 @@ typedef struct _cliopt {
	char key;
} cliopt;

-
/* an option string should not be a prefix of any other option string */ 
+
/* an option string should not be a prefix of any other option string */
static const cliopt search_label[] = {
	{ "comment",     'c'  },
	{ "description", 'd'  },
@@ -77,7 +77,7 @@ static const cliopt modifiers[] = {
	{ "version",              'v'  },
	{ "www",                  'w'  },
	{ NULL,                   '\0' },
-
};	
+
};

static char
match_optarg(const cliopt *optlist, const char *opt)
@@ -415,7 +415,7 @@ exec_search(int argc, char **argv)
		quiet = false;
	}

-
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO, reponame, NULL);
	switch(ret) {
	case EPKG_ENOACCESS:
		warnx("Insufficient privileges to query the package database");
modified src/update.c
@@ -4,7 +4,7 @@
 * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
 * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -14,7 +14,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -52,7 +52,7 @@ pkgcli_update(bool force, bool strict, const char *reponame)

	/* Only auto update if the user has write access. */
	if (pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
-
	    PKGDB_DB_REPO) == EPKG_ENOACCESS)
+
	    PKGDB_DB_REPO, reponame, NULL) == EPKG_ENOACCESS)
		return (EPKG_OK);

	if (pkg_repos_total_count() == 0) {
@@ -166,7 +166,7 @@ exec_update(int argc, char **argv)
	}

	ret = pkgdb_access(PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
-
			   PKGDB_DB_REPO);
+
			   PKGDB_DB_REPO, reponame, NULL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to update the repository "
		      "catalogue.");