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.
This commit is contained in:
parent
b68e5ceedc
commit
03ed097353
@ -132,8 +132,6 @@ set (HAVE_EDITLINE "${WANT_LIBEDIT}")
|
|||||||
set (HAVE_LUA "${WITH_LUA}")
|
set (HAVE_LUA "${WITH_LUA}")
|
||||||
|
|
||||||
include (GNUInstallDirs)
|
include (GNUInstallDirs)
|
||||||
# ZyklonB is currently an odd duck but degesch follows normal XDG rules
|
|
||||||
set (zyklonb_plugin_dir ${CMAKE_INSTALL_LIBDIR}/zyklonb/plugins)
|
|
||||||
configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
||||||
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
||||||
|
|
||||||
@ -187,8 +185,9 @@ add_custom_target (clang-tidy
|
|||||||
# Installation
|
# Installation
|
||||||
install (TARGETS zyklonb degesch kike DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install (TARGETS zyklonb degesch kike DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||||
|
# XXX: our defaults for XDG_DATA_DIRS expect /usr/local/shore or /usr/share
|
||||||
install (DIRECTORY plugins/zyklonb/
|
install (DIRECTORY plugins/zyklonb/
|
||||||
DESTINATION ${zyklonb_plugin_dir} USE_SOURCE_PERMISSIONS)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/zyklonb/plugins USE_SOURCE_PERMISSIONS)
|
||||||
install (DIRECTORY plugins/degesch/
|
install (DIRECTORY plugins/degesch/
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/degesch/plugins)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/degesch/plugins)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
#define PROGRAM_VERSION "${project_version}"
|
#define PROGRAM_VERSION "${project_version}"
|
||||||
#define ZYKLONB_PLUGIN_DIR "${CMAKE_INSTALL_PREFIX}/${zyklonb_plugin_dir}"
|
#define LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}"
|
||||||
|
|
||||||
#cmakedefine HAVE_READLINE
|
#cmakedefine HAVE_READLINE
|
||||||
#cmakedefine HAVE_EDITLINE
|
#cmakedefine HAVE_EDITLINE
|
||||||
|
38
zyklonb.c
38
zyklonb.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* zyklonb.c: the experimental IRC bot
|
* 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
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted.
|
* purpose with or without fee is hereby granted.
|
||||||
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#define PROGRAM_NAME "ZyklonB"
|
#define PROGRAM_NAME "ZyklonB"
|
||||||
#define PLUGIN_DIR ZYKLONB_PLUGIN_DIR
|
|
||||||
|
|
||||||
#include "common.c"
|
#include "common.c"
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ static struct simple_config_item g_config_table[] =
|
|||||||
{ "prefix", ":", "The prefix for bot commands" },
|
{ "prefix", ":", "The prefix for bot commands" },
|
||||||
{ "admin", NULL, "Host mask for administrators" },
|
{ "admin", NULL, "Host mask for administrators" },
|
||||||
{ "plugins", NULL, "The plugins to load on startup" },
|
{ "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" },
|
{ "recover", "on", "Whether to re-launch on crash" },
|
||||||
|
|
||||||
{ NULL, NULL, NULL }
|
{ NULL, NULL, NULL }
|
||||||
@ -1015,21 +1014,41 @@ is_valid_plugin_name (const char *name)
|
|||||||
return true;
|
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 *
|
static struct plugin *
|
||||||
plugin_launch (struct bot_context *ctx, const char *name, struct error **e)
|
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");
|
const char *plugin_dir = str_map_find (&ctx->config, "plugin_dir");
|
||||||
if (!plugin_dir)
|
if (plugin_dir)
|
||||||
{
|
{
|
||||||
error_set (e, "plugin directory not set");
|
// resolve_relative_filename_generic() won't accept relative paths,
|
||||||
return NULL;
|
// 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 not found");
|
||||||
|
goto fail_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stdin_pipe[2];
|
int stdin_pipe[2];
|
||||||
if (pipe (stdin_pipe) == -1)
|
if (pipe (stdin_pipe) == -1)
|
||||||
{
|
{
|
||||||
error_set (e, "%s: %s", "pipe", strerror (errno));
|
error_set (e, "%s: %s", "pipe", strerror (errno));
|
||||||
return NULL;
|
goto fail_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stdout_pipe[2];
|
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
|
// Restore some of the signal handling
|
||||||
signal (SIGPIPE, SIG_DFL);
|
signal (SIGPIPE, SIG_DFL);
|
||||||
|
|
||||||
char *argv[] = { xstrdup_printf ("%s/%s", plugin_dir, name), NULL };
|
char *argv[] = { path, NULL };
|
||||||
execve (argv[0], argv, environ);
|
execve (argv[0], argv, environ);
|
||||||
|
|
||||||
// We will collect the failure later via SIGCHLD
|
// 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);
|
str_free (&work_dir);
|
||||||
|
free (path);
|
||||||
|
|
||||||
xclose (stdin_pipe[0]);
|
xclose (stdin_pipe[0]);
|
||||||
xclose (stdout_pipe[1]);
|
xclose (stdout_pipe[1]);
|
||||||
@ -1108,6 +1128,8 @@ fail_2:
|
|||||||
fail_1:
|
fail_1:
|
||||||
xclose (stdin_pipe[0]);
|
xclose (stdin_pipe[0]);
|
||||||
xclose (stdin_pipe[1]);
|
xclose (stdin_pipe[1]);
|
||||||
|
fail_0:
|
||||||
|
free (path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user