Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
libpkg: Support system triggers
Lexi Winter committed 7 months ago
commit 7831a194f38554db1c6a0f527774ae81ea1c9121
parent bc1ad77
4 files changed +65 -21
modified docs/pkg.conf.5
@@ -27,7 +27,7 @@
.\"
.\"     @(#)pkg.1
.\"
-
.Dd March 17, 2025
+
.Dd September 17, 2025
.Dt PKG.CONF 5
.Os
.Sh NAME
@@ -300,8 +300,9 @@ Default:
Enable or disable execution of triggers at the end of the transactions.
Default: YES.
.It Cm PKG_TRIGGERS_DIR
-
Directory where the triggers are stored
+
List of directories where triggers are stored.
Default:
+
.Pa /usr/share/pkg/triggers ,
.Pa /usr/local/share/pkg/triggers .
.It Cm PKG_SSH_ARGS: string
Extra arguments to pass to
modified libpkg/pkg_config.c
@@ -385,9 +385,9 @@ static struct config_entry c[] = {
		PREFIX "/lib/compat/pkg",
	},
	{
-
		PKG_STRING,
+
		PKG_ARRAY,
		"PKG_TRIGGERS_DIR",
-
		PREFIX "/share/pkg/triggers",
+
		"/usr/share/pkg/triggers/,"PREFIX"/share/pkg/triggers",
	},
	{
		PKG_BOOL,
@@ -1565,7 +1565,6 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
	ctx.backup_libraries = pkg_object_bool(pkg_config_get("BACKUP_LIBRARIES"));
	ctx.backup_library_path = pkg_object_string(pkg_config_get("BACKUP_LIBRARY_PATH"));
	ctx.triggers = pkg_object_bool(pkg_config_get("PKG_TRIGGERS_ENABLE"));
-
	ctx.triggers_path = pkg_object_string(pkg_config_get("PKG_TRIGGERS_DIR"));
	ctx.compression_format = pkg_object_string(pkg_config_get("COMPRESSION_FORMAT"));
	ctx.compression_level = pkg_object_int(pkg_config_get("COMPRESSION_LEVEL"));
	ctx.compression_threads = pkg_object_int(pkg_config_get("COMPRESSION_THREADS"));
modified libpkg/private/pkg.h
@@ -145,7 +145,6 @@ struct pkg_ctx {
	bool backup_libraries;
	const char *backup_library_path;
	bool triggers;
-
	const char *triggers_path;
	pkghash *touched_dir_hash;
	bool defer_triggers;
	bool repo_accept_legacy_pkg;
modified libpkg/triggers.c
@@ -254,18 +254,36 @@ err:
void
trigger_is_it_a_cleanup(struct triggers *t, const char *path)
{
-
	const char *trigger_name;
+
	const char *trigger_name, *dir;
+
	const pkg_object *dirs, *cur;
	struct trigger *trig;
+
	pkg_iter it;

	if (t->schema == NULL)
		t->schema = trigger_open_schema();
-
	if (strncmp(path, ctx.triggers_path, strlen(ctx.triggers_path)) != 0)
-
		return;

-
	trigger_name = path + strlen(ctx.triggers_path);
+
	/* Check if the file was installed in a trigger directory. */
+
	it = NULL;
+
	trigger_name = NULL;
+
	dirs = pkg_config_get("PKG_TRIGGERS_DIR");
+
	while ((cur = pkg_object_iterate(dirs, &it))) {
+
		size_t len;
+

+
		dir = pkg_object_string(cur);
+
		len = strlen(dir);
+

+
		if (strncmp(path, dir, len) == 0) {
+
			trigger_name = path + strlen(dir);
+
			break;
+
		}
+
	}
+

+
	if (trigger_name == NULL)
+
		return;

	if (t->dfd == -1)
-
		t->dfd = openat(ctx.rootfd, RELATIVE_PATH(ctx.triggers_path), O_DIRECTORY);
+
		t->dfd = openat(ctx.rootfd, RELATIVE_PATH(dir), O_DIRECTORY);
+

	trig = trigger_load(t->dfd, RELATIVE_PATH(trigger_name), true, t->schema);
	if (trig != NULL) {
		if (t->cleanup == NULL)
@@ -275,28 +293,33 @@ trigger_is_it_a_cleanup(struct triggers *t, const char *path)
	}
}

-
trigger_t *
-
triggers_load(bool cleanup_only)
+
/*
+
 * Load triggers from a specific directory and add them to a vec.
+
 */
+
void
+
triggers_load_from(trigger_t *triggers, bool cleanup_only, const char *dir)
{
	int dfd;
	DIR *d;
	struct dirent *e;
	struct trigger *t;
-
	trigger_t *triggers = xcalloc(1, sizeof(*triggers));
	ucl_object_t *schema;
	struct stat st;

-
	dfd = openat(ctx.rootfd, RELATIVE_PATH(ctx.triggers_path), O_DIRECTORY);
+
	dfd = openat(ctx.rootfd, dir, O_DIRECTORY);
	if (dfd == -1) {
		if (errno != ENOENT)
-
			pkg_emit_error("Unable to open the trigger directory");
-
		return (triggers);
+
			pkg_emit_error("Unable to open the trigger directory %s: %s",
+
			    dir, strerror(errno));
+
		return;
	}
+

	d = fdopendir(dfd);
	if (d == NULL) {
-
		pkg_emit_error("Unable to open the trigger directory");
+
		pkg_emit_error("Unable to open the trigger directory %s: %s",
+
		    dir, strerror(errno));
		close(dfd);
-
		return (triggers);
+
		return;
	}

	schema = trigger_open_schema();
@@ -315,7 +338,7 @@ triggers_load(bool cleanup_only)
		/* only regular files are considered */
		if (fstatat(dfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
			pkg_emit_errno("fstatat", e->d_name);
-
			return (triggers);
+
			continue;
		}
		if (!S_ISREG(st.st_mode))
			continue;
@@ -326,7 +349,29 @@ triggers_load(bool cleanup_only)

	closedir(d);
	ucl_object_unref(schema);
-
	return (triggers);
+
}
+

+
/*
+
 * Load triggers from PKG_TRIGGERS_DIR.
+
 */
+
trigger_t *
+
triggers_load(bool cleanup_only)
+
{
+
	trigger_t *ret;
+
	const pkg_object *dirs, *cur;
+
	pkg_iter it = NULL;
+

+
	ret = xcalloc(1, sizeof(*ret));
+

+
	dirs = pkg_config_get("PKG_TRIGGERS_DIR");
+
	while ((cur = pkg_object_iterate(dirs, &it))) {
+
		const char *dir;
+

+
		dir = RELATIVE_PATH(pkg_object_string(cur));
+
		triggers_load_from(ret, cleanup_only, dir);
+
	}
+

+
	return (ret);
}

void