diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2020-10-28 14:02:03 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2020-10-28 17:17:34 +0100 |
commit | 03ed0973531708d855da1129f54ee6b3f933b0af (patch) | |
tree | 1212c0d9ca0a6f921d067e00dcfa01409d9b485f /zyklonb.c | |
parent | b68e5ceedc3bc126ac94617053efd184dc5658a5 (diff) | |
download | xK-03ed0973531708d855da1129f54ee6b3f933b0af.tar.gz xK-03ed0973531708d855da1129f54ee6b3f933b0af.tar.xz xK-03ed0973531708d855da1129f54ee6b3f933b0af.zip |
ZyklonB: use XDG paths by default
Install plugins to /usr/share rather than /usr/lib since they're
arch-independent. Many precedents can be found for scripted plugins
in /usr/share and fewer for /usr/lib.
Look for plugins in all XDG data directories and repurpose
the "plugin_dir" setting to override this behaviour.
This adds some complexity to the bot but unifies the project.
It might make sense to remove the "plugin_dir" setting.
Diffstat (limited to 'zyklonb.c')
-rw-r--r-- | zyklonb.c | 38 |
1 files changed, 30 insertions, 8 deletions
@@ -1,7 +1,7 @@ /* * zyklonb.c: the experimental IRC bot * - * Copyright (c) 2014 - 2016, Přemysl Eric Janouch <p@janouch.name> + * Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted. @@ -18,7 +18,6 @@ #include "config.h" #define PROGRAM_NAME "ZyklonB" -#define PLUGIN_DIR ZYKLONB_PLUGIN_DIR #include "common.c" @@ -49,7 +48,7 @@ static struct simple_config_item g_config_table[] = { "prefix", ":", "The prefix for bot commands" }, { "admin", NULL, "Host mask for administrators" }, { "plugins", NULL, "The plugins to load on startup" }, - { "plugin_dir", PLUGIN_DIR, "Where to search for plugins" }, + { "plugin_dir", NULL, "Plugin search path override" }, { "recover", "on", "Whether to re-launch on crash" }, { NULL, NULL, NULL } @@ -1015,21 +1014,41 @@ is_valid_plugin_name (const char *name) return true; } +static char * +plugin_resolve_relative_filename (const char *filename) +{ + struct strv paths = strv_make (); + get_xdg_data_dirs (&paths); + strv_append (&paths, LIBDIR); // Legacy, we do not compile any plugins + char *result = resolve_relative_filename_generic + (&paths, PROGRAM_NAME "/plugins/", filename); + strv_free (&paths); + return result; +} + static struct plugin * plugin_launch (struct bot_context *ctx, const char *name, struct error **e) { + char *path = NULL; const char *plugin_dir = str_map_find (&ctx->config, "plugin_dir"); - if (!plugin_dir) + if (plugin_dir) + { + // resolve_relative_filename_generic() won't accept relative paths, + // so just keep the old behaviour and expect the file to exist. + // We could use resolve_filename() on "plugin_dir" with paths=getcwd(). + path = xstrdup_printf ("%s/%s", plugin_dir, name); + } + else if (!(path = plugin_resolve_relative_filename (name))) { - error_set (e, "plugin directory not set"); - return NULL; + error_set (e, "plugin not found"); + goto fail_0; } int stdin_pipe[2]; if (pipe (stdin_pipe) == -1) { error_set (e, "%s: %s", "pipe", strerror (errno)); - return NULL; + goto fail_0; } int stdout_pipe[2]; @@ -1079,7 +1098,7 @@ plugin_launch (struct bot_context *ctx, const char *name, struct error **e) // Restore some of the signal handling signal (SIGPIPE, SIG_DFL); - char *argv[] = { xstrdup_printf ("%s/%s", plugin_dir, name), NULL }; + char *argv[] = { path, NULL }; execve (argv[0], argv, environ); // We will collect the failure later via SIGCHLD @@ -1089,6 +1108,7 @@ plugin_launch (struct bot_context *ctx, const char *name, struct error **e) } str_free (&work_dir); + free (path); xclose (stdin_pipe[0]); xclose (stdout_pipe[1]); @@ -1108,6 +1128,8 @@ fail_2: fail_1: xclose (stdin_pipe[0]); xclose (stdin_pipe[1]); +fail_0: + free (path); return NULL; } |