aboutsummaryrefslogtreecommitdiff
path: root/zyklonb.c
diff options
context:
space:
mode:
Diffstat (limited to 'zyklonb.c')
-rw-r--r--zyklonb.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/zyklonb.c b/zyklonb.c
index 0d27758..c8fddeb 100644
--- a/zyklonb.c
+++ b/zyklonb.c
@@ -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;
}