Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Clean up output of messages for locked packages during `pkg delete'
Brad Davis committed 8 years ago
commit 0adc3fb7c64453fdb4224280f8ceefe9aeef151f
parent 40f84d3
9 files changed +135 -10
modified libpkg/libpkg.ver
@@ -67,7 +67,9 @@ global:
	pkg_jobs_cudf_parse_output;
	pkg_jobs_destdir;
	pkg_jobs_free;
+
	pkg_jobs_has_lockedpkgs;
	pkg_jobs_iter;
+
	pkg_jobs_iter_lockedpkgs;
	pkg_jobs_new;
	pkg_jobs_set_destdir;
	pkg_jobs_set_flags;
modified libpkg/pkg.h.in
@@ -1069,6 +1069,19 @@ int pkg_jobs_cudf_emit_file(struct pkg_jobs *, pkg_jobs_t , FILE *);
int pkg_jobs_cudf_parse_output(struct pkg_jobs *j, FILE *f);

/**
+
 * Check if there are locked packages
+
 * @return true if locked packages exist, false if not
+
 */
+
bool pkg_jobs_has_lockedpkgs(struct pkg_jobs *j);
+

+
/**
+
 * Iterate through the locked packages, calling the passed in function pointer
+
 * on each.
+
 */
+
typedef int(*locked_pkgs_cb)(struct pkg *, void *);
+
void pkg_jobs_iter_lockedpkgs(struct pkg_jobs *j, locked_pkgs_cb, void *);
+

+
/**
 * Solve a SAT problem
 * @return true if a problem is solvable
 */
modified libpkg/pkg_jobs.c
@@ -45,6 +45,7 @@
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
+
#include <search.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@@ -69,6 +70,11 @@ static int pkg_jobs_find_upgrade(struct pkg_jobs *j, const char *pattern, match_
static int pkg_jobs_fetch(struct pkg_jobs *j);
static bool new_pkg_version(struct pkg_jobs *j);
static int pkg_jobs_check_conflicts(struct pkg_jobs *j);
+
struct pkg_jobs_locked {
+
	int (*locked_pkg_cb)(struct pkg *, void *);
+
	void *context;
+
};
+
static __thread struct pkg_jobs_locked *pkgs_job_lockedpkg;

#define IS_DELETE(j) ((j)->type == PKG_JOBS_DEINSTALL || (j)->type == PKG_JOBS_AUTOREMOVE)

@@ -1382,6 +1388,15 @@ pkg_jobs_set_deinstall_reasons(struct pkg_jobs *j)
}

static int
+
comp(const void *a, const void *b)
+
{
+
	const struct pkg *pa = a;
+
	const struct pkg *pb = b;
+

+
	return strcmp(pa->name, pb->name);
+
}
+

+
static int
jobs_solve_deinstall(struct pkg_jobs *j)
{
	struct job_pattern *jp;
@@ -1398,7 +1413,9 @@ jobs_solve_deinstall(struct pkg_jobs *j)
		while (pkgdb_it_next(it, &pkg,
				PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS) == EPKG_OK) {
			if(pkg->locked) {
-
				pkg_emit_locked(pkg);
+
				if (tsearch(pkg, &j->lockedpkgs, comp) == NULL) {
+
					return (EPKG_FATAL);
+
				}
			}
			else {
				pkg_jobs_add_req(j, pkg);
@@ -2277,3 +2294,32 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)

	return (ret);
}
+

+
bool
+
pkg_jobs_has_lockedpkgs(struct pkg_jobs *j)
+
{
+

+
	return j->lockedpkgs ? true : false;
+
}
+

+
static void
+
pkg_jobs_visit_lockedpkgs(const void * node, VISIT v, int __unused0)
+
{
+

+
	if (v == postorder || v == leaf) {
+
		pkgs_job_lockedpkg->locked_pkg_cb(*(struct pkg **)node,
+
		    pkgs_job_lockedpkg->context);
+
	}
+
}
+

+
void
+
pkg_jobs_iter_lockedpkgs(struct pkg_jobs *j, locked_pkgs_cb cb, void * ctx)
+
{
+
	struct pkg_jobs_locked foo;
+

+
	foo.locked_pkg_cb = cb;
+
	foo.context = ctx;
+
	pkgs_job_lockedpkg = &foo;
+

+
	twalk(j->lockedpkgs, pkg_jobs_visit_lockedpkgs);
+
}
modified libpkg/pkg_jobs_universe.c
@@ -198,7 +198,6 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg,
	}

	if (pkg_is_locked(pkg)) {
-
		pkg_emit_locked(pkg);
		return (EPKG_LOCKED);
	}

modified libpkg/private/pkg_jobs.h
@@ -118,6 +118,7 @@ struct pkg_jobs {
	struct job_pattern *patterns;
	bool conservative;
	bool pinning;
+
	void		*lockedpkgs;
};

#define PKG_PATTERN_FLAG_FILE (1 << 0)
modified src/delete.c
@@ -59,6 +59,7 @@ exec_delete(int argc, char **argv)
	int		 ch;
	int		 i;
	int		 lock_type = PKGDB_LOCK_ADVISORY;
+
	int		 locked_pkgs = 0;

	struct option longopts[] = {
		{ "all",			no_argument,	NULL,	'a' },
@@ -190,14 +191,30 @@ exec_delete(int argc, char **argv)
		goto cleanup;
	}

+
	if (pkg_jobs_has_lockedpkgs(jobs)) {
+
		printf("The following package(s) are locked and may not ");
+
		printf("be removed:\n\n");
+
		pkg_jobs_iter_lockedpkgs(jobs, print_pkg, &locked_pkgs);
+
		printf("\n");
+
	}
+

	/* check if we have something to deinstall */
	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		if (argc == 0) {
			if (!quiet)
				printf("Nothing to do.\n");
+

			retcode = EX_OK;
+
			goto cleanup;
+
		}
+
		if (!quiet) {
+
			printf("%d packages requested for removal: "
+
			    "%d locked, %d missing\n",
+
			    argc, locked_pkgs, argc - locked_pkgs);
+
		}
+
		if (locked_pkgs > 0) {
+
			retcode = EPKG_LOCKED;
		} else {
-
			fprintf(stderr, "Package(s) not found!\n");
			retcode = EX_DATAERR;
		}
		goto cleanup;
modified src/pkgcli.h
@@ -28,6 +28,7 @@
#ifndef _PKGCLI_H
#define _PKGCLI_H

+
#include <search.h>
#include <stdint.h>
#include <utstring.h>
#include <bsd_compat.h>
@@ -271,6 +272,7 @@ void job_status_begin(UT_string *);
void job_status_end(UT_string *);

int event_callback(void *data, struct pkg_event *ev);
+
int print_pkg(struct pkg *p, void *ctx);
void progressbar_start(const char *pmsg);
void progressbar_tick(int64_t current, int64_t total);
void progressbar_stop(void);
modified src/utils.c
@@ -1036,3 +1036,16 @@ drop_privileges(void)
			err(EXIT_FAILURE, "Unable to setuid");
	}
}
+

+
int
+
print_pkg(struct pkg *p, void *ctx)
+
{
+
	const char *name;
+
	int *counter = ctx;
+

+
	pkg_get(p, PKG_NAME, &name);
+
	printf("\t%s\n", name);
+
	(*counter)++;
+

+
	return 0;
+
}
modified tests/frontend/lock.sh
@@ -3,14 +3,10 @@
. $(atf_get_srcdir)/test_environment.sh

tests_init \
-
	lock
+
	lock \
+
	lock_delete

-
lock_head() {
-
	atf_set "require.files" \
-
	   "${RESOURCEDIR}/png.ucl ${RESOURCEDIR}/sqlite3.ucl"
-
}
-

-
lock_body() {
+
lock_setup() {
	for pkg in 'png' 'sqlite3' ; do
		atf_check \
		    -o match:".*Installing.*\.\.\.$" \
@@ -21,6 +17,15 @@ lock_body() {

	test -f "./local.sqlite" || \
	    atf_fail "Can't populate $PKG_DBDIR/local.sqlite"
+
}
+

+
lock_head() {
+
	atf_set "require.files" \
+
	   "${RESOURCEDIR}/png.ucl ${RESOURCEDIR}/sqlite3.ucl"
+
}
+

+
lock_body() {
+
	lock_setup

	atf_check \
	    -o match:"Locking sqlite3.*" \
@@ -83,3 +88,30 @@ lock_body() {
	    -s exit:0 \
	    pkg lock -l
}
+

+
lock_delete_head() {
+
	lock_head
+
}
+

+
lock_delete_body() {
+
	lock_setup
+

+
	atf_check \
+
	    -o match:"Locking sqlite3.*" \
+
	    -e empty \
+
	    -s exit:0 \
+
	    pkg lock -y sqlite3
+

+
	atf_check \
+
	    -o match:".*locked and may not be removed.*" \
+
	    -o match:"sqlite3.*" \
+
	    -e empty \
+
	    -s exit:7 \
+
	    pkg delete -y sqlite3
+

+
	atf_check \
+
	    -o match:"sqlite3-3.8.6" \
+
	    -e empty \
+
	    -s exit:0 \
+
	    pkg lock -l
+
}