aboutsummaryrefslogtreecommitdiff
path: root/src/rc-plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rc-plugin.c')
-rw-r--r--src/rc-plugin.c241
1 files changed, 0 insertions, 241 deletions
diff --git a/src/rc-plugin.c b/src/rc-plugin.c
deleted file mode 100644
index 613f049e..00000000
--- a/src/rc-plugin.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- librc-plugin.c
- Simple plugin handler
- */
-
-/*
- * Copyright 2007 Roy Marples
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "einfo.h"
-#include "rc.h"
-#include "rc-misc.h"
-#include "rc-plugin.h"
-#include "strlist.h"
-
-#define RC_PLUGIN_HOOK "rc_plugin_hook"
-
-bool rc_in_plugin = false;
-
-typedef struct plugin
-{
- char *name;
- void *handle;
- int (*hook) (rc_hook_t, const char *);
- struct plugin *next;
-} plugin_t;
-
-static plugin_t *plugins = NULL;
-
-#ifndef __FreeBSD__
-dlfunc_t dlfunc (void * __restrict handle, const char * __restrict symbol)
-{
- union {
- void *d;
- dlfunc_t f;
- } rv;
-
- rv.d = dlsym (handle, symbol);
- return (rv.f);
-}
-#endif
-
-void rc_plugin_load (void)
-{
- DIR *dp;
- struct dirent *d;
- plugin_t *plugin = plugins;
- char *p;
- void *h;
- int (*fptr) (rc_hook_t, const char *);
-
- /* Don't load plugins if we're in one */
- if (rc_in_plugin)
- return;
-
- /* Ensure some sanity here */
- rc_plugin_unload ();
-
- if (! (dp = opendir (RC_PLUGINDIR)))
- return;
-
- while ((d = readdir (dp))) {
- if (d->d_name[0] == '.')
- continue;
-
- p = rc_strcatpaths (RC_PLUGINDIR, d->d_name, NULL);
- h = dlopen (p, RTLD_LAZY);
- free (p);
- if (! h) {
- eerror ("dlopen: %s", dlerror ());
- continue;
- }
-
- fptr = (int (*)(rc_hook_t, const char*)) dlfunc (h, RC_PLUGIN_HOOK);
- if (! fptr) {
- eerror ("%s: cannot find symbol `%s'", d->d_name, RC_PLUGIN_HOOK);
- dlclose (h);
- } else {
- if (plugin) {
- plugin->next = xmalloc (sizeof (plugin_t));
- plugin = plugin->next;
- } else
- plugin = plugins = xmalloc (sizeof (plugin_t));
-
- memset (plugin, 0, sizeof (plugin_t));
- plugin->name = xstrdup (d->d_name);
- plugin->handle = h;
- plugin->hook = fptr;
- }
- }
- closedir (dp);
-}
-
-int rc_waitpid (pid_t pid)
-{
- int status = 0;
- pid_t savedpid = pid;
- int retval = -1;
-
- errno = 0;
- while ((pid = waitpid (savedpid, &status, 0)) > 0) {
- if (pid == savedpid)
- retval = WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_FAILURE;
- }
-
- return (retval);
-}
-
-void rc_plugin_run (rc_hook_t hook, const char *value)
-{
- plugin_t *plugin = plugins;
-
- /* Don't run plugins if we're in one */
- if (rc_in_plugin)
- return;
-
- while (plugin) {
- if (plugin->hook) {
- int i;
- int flags;
- int pfd[2];
- pid_t pid;
-
- /* We create a pipe so that plugins can affect our environment
- * vars, which in turn influence our scripts. */
- if (pipe (pfd) == -1) {
- eerror ("pipe: %s", strerror (errno));
- return;
- }
-
- /* Stop any scripts from inheriting us.
- * This is actually quite important as without this, the splash
- * plugin will probably hang when running in silent mode. */
- for (i = 0; i < 2; i++)
- if ((flags = fcntl (pfd[i], F_GETFD, 0)) < 0 ||
- fcntl (pfd[i], F_SETFD, flags | FD_CLOEXEC) < 0)
- eerror ("fcntl: %s", strerror (errno));
-
- /* We run the plugin in a new process so we never crash
- * or otherwise affected by it */
- if ((pid = fork ()) == -1) {
- eerror ("fork: %s", strerror (errno));
- return;
- }
-
- if (pid == 0) {
- int retval;
-
- rc_in_plugin = true;
- close (pfd[0]);
- rc_environ_fd = fdopen (pfd[1], "w");
- retval = plugin->hook (hook, value);
- fclose (rc_environ_fd);
- rc_environ_fd = NULL;
-
- /* Just in case the plugin sets this to false */
- rc_in_plugin = true;
- exit (retval);
- } else {
- char *buffer;
- char *token;
- char *p;
- ssize_t nr;
-
- close (pfd[1]);
- buffer = xmalloc (sizeof (char) * RC_LINEBUFFER);
- memset (buffer, 0, RC_LINEBUFFER);
-
- while ((nr = read (pfd[0], buffer, RC_LINEBUFFER)) > 0) {
- p = buffer;
- while (*p && p - buffer < nr) {
- token = strsep (&p, "=");
- if (token) {
- unsetenv (token);
- if (*p) {
- setenv (token, p, 1);
- p += strlen (p) + 1;
- } else
- p++;
- }
- }
- }
-
- free (buffer);
- close (pfd[0]);
-
- rc_waitpid (pid);
- }
- }
- plugin = plugin->next;
- }
-}
-
-void rc_plugin_unload (void)
-{
- plugin_t *plugin = plugins;
- plugin_t *next;
-
- while (plugin) {
- next = plugin->next;
- dlclose (plugin->handle);
- free (plugin->name);
- free (plugin);
- plugin = next;
- }
- plugins = NULL;
-}