aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-10-18 23:52:27 +0200
committerMarcel Holtmann <marcel@holtmann.org>2010-10-18 23:52:27 +0200
commit36ed9e7e4acd7b9695188d641d3e08eaac5f31a4 (patch)
treec12464b0ae1c624a204c57956ba55c2867751262
parent8c073fe5c47f70cdc77e4e86776688841ebade3e (diff)
downloadpacrunner-36ed9e7e4acd7b9695188d641d3e08eaac5f31a4.tar.gz
Add support for plugin infrastructure
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am36
-rw-r--r--configure.ac6
-rwxr-xr-xsrc/genbuiltin17
-rw-r--r--src/log.h47
-rw-r--r--src/pacrunner.h32
-rw-r--r--src/plugin.c144
-rw-r--r--src/plugin.h40
8 files changed, 289 insertions, 34 deletions
diff --git a/.gitignore b/.gitignore
index f2cbd3f..50692f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ missing
stamp-h1
autom4te.cache
+src/builtin.h
src/pacrunner
src/pacrunner.service
libproxy/libproxy-1.0.pc
diff --git a/Makefile.am b/Makefile.am
index 25ea449..775243c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,14 +14,30 @@ endif
gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \
gdbus/object.c gdbus/polkit.c
+builtin_modules =
+builtin_sources =
+builtin_cflags =
+builtin_libadd =
+
sbin_PROGRAMS = src/pacrunner
-src_pacrunner_SOURCES = $(gdbus_sources) src/pacrunner.h \
- src/main.c src/log.c src/client.c src/manager.c \
- src/proxy.c src/download.c src/mozjs.c src/javascript.h
+src_pacrunner_SOURCES = $(gdbus_sources) $(builtin_sources) \
+ src/main.c src/pacrunner.h \
+ src/log.h src/log.c src/plugin.h src/plugin.c \
+ src/client.c src/manager.c src/download.c \
+ src/proxy.c src/mozjs.c src/javascript.h
src_pacrunner_LDADD = @MOZJS_LIBS@ @CURL_LIBS@ \
- @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@
+ @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
+
+src_pacrunner_LDFLAGS = -Wl,--export-dynamic
+
+nodist_src_pacrunner_SOURCES = src/builtin.h
+
+src/plugin.$(OBJEXT): src/builtin.h
+
+src/builtin.h: src/genbuiltin $(builtin_sources)
+ $(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
if LIBPROXY
include_HEADERS = libproxy/proxy.h
@@ -54,10 +70,12 @@ unit_test_mozjs_SOURCES = unit/test-mozjs.c src/pacrunner.h \
unit_test_mozjs_LDADD = @MOZJS_LIBS@ @CURL_LIBS@ @GLIB_LIBS@
-AM_CFLAGS = @CAPNG_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
- @CURL_CFLAGS@ @MOZJS_CFLAGS@
+AM_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ @CAPNG_CFLAGS@ $(builtin_cflags) \
+ @MOZJS_CFLAGS@ @CURL_CFLAGS@ \
+ -DPACRUNNER_PLUGIN_BUILTIN \
+ -DPLUGINDIR=\""$(plugindir)"\"
-INCLUDES = -I$(srcdir)/src -I$(srcdir)/gdbus
+INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/gdbus
test_scripts = test/find-proxy-for-url test/create-proxy-config
@@ -66,7 +84,9 @@ testdir = $(pkglibdir)/test
test_SCRIPTS = $(test_scripts)
endif
-EXTRA_DIST = src/pacrunner.conf $(test_scripts) \
+CLEANFILES = src/builtin.h
+
+EXTRA_DIST = src/genbuiltin src/pacrunner.conf $(test_scripts) \
doc/architecture.txt doc/libproxy.txt \
doc/manager-api.txt doc/client-api.txt
diff --git a/configure.ac b/configure.ac
index ff513f5..cd65605 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,12 @@ AM_MAINTAINER_MODE
AC_PREFIX_DEFAULT(/usr/local)
+if (test "${libdir}" = '${exec_prefix}/lib'); then
+ libdir="${prefix}/lib"
+fi
+
+plugindir="${libdir}/pacrunner/plugins"
+
PKG_PROG_PKG_CONFIG
COMPILER_FLAGS
diff --git a/src/genbuiltin b/src/genbuiltin
new file mode 100755
index 0000000..562a7f0
--- /dev/null
+++ b/src/genbuiltin
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+for i in $*
+do
+ echo "extern struct pacrunner_plugin_desc __pacrunner_builtin_$i;"
+done
+
+echo
+echo "static struct pacrunner_plugin_desc *__pacrunner_builtin[] = {"
+
+for i in $*
+do
+ echo " &__pacrunner_builtin_$i,"
+done
+
+echo " NULL"
+echo "};"
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 0000000..da48f95
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * PACrunner - Proxy configuration daemon
+ *
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+void pacrunner_info(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+void pacrunner_warn(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+void pacrunner_error(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+void pacrunner_debug(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+
+struct pacrunner_debug_desc {
+ const char *name;
+ const char *file;
+#define PACRUNNER_DEBUG_FLAG_DEFAULT (0)
+#define PACRUNNER_DEBUG_FLAG_PRINT (1 << 0)
+ unsigned int flags;
+} __attribute__((aligned(8)));
+
+#define DBG(fmt, arg...) do { \
+ static struct pacrunner_debug_desc __pacrunner_debug_desc \
+ __attribute__((used, section("__debug"), aligned(8))) = { \
+ .file = __FILE__, .flags = PACRUNNER_DEBUG_FLAG_DEFAULT, \
+ }; \
+ if (__pacrunner_debug_desc.flags & PACRUNNER_DEBUG_FLAG_PRINT) \
+ pacrunner_debug("%s:%s() " fmt, \
+ __FILE__, __FUNCTION__ , ## arg); \
+} while (0)
diff --git a/src/pacrunner.h b/src/pacrunner.h
index 5ab65b8..db6182e 100644
--- a/src/pacrunner.h
+++ b/src/pacrunner.h
@@ -34,36 +34,16 @@
#define PACRUNNER_CLIENT_PATH PACRUNNER_PATH "/client"
-void pacrunner_info(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-void pacrunner_warn(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-void pacrunner_error(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-void pacrunner_debug(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-
-struct pacrunner_debug_desc {
- const char *name;
- const char *file;
-#define PACRUNNER_DEBUG_FLAG_DEFAULT (0)
-#define PACRUNNER_DEBUG_FLAG_PRINT (1 << 0)
- unsigned int flags;
-} __attribute__((aligned(8)));
-
-#define DBG(fmt, arg...) do { \
- static struct pacrunner_debug_desc __pacrunner_debug_desc \
- __attribute__((used, section("__debug"), aligned(8))) = { \
- .file = __FILE__, .flags = PACRUNNER_DEBUG_FLAG_DEFAULT, \
- }; \
- if (__pacrunner_debug_desc.flags & PACRUNNER_DEBUG_FLAG_PRINT) \
- pacrunner_debug("%s:%s() " fmt, \
- __FILE__, __FUNCTION__ , ## arg); \
-} while (0)
+#include "log.h"
int __pacrunner_log_init(const char *debug, gboolean detach);
void __pacrunner_log_cleanup(void);
+#include "plugin.h"
+
+int __pacrunner_plugin_init(void);
+void __pacrunner_plugin_cleanup(void);
+
enum pacrunner_proxy_method {
PACRUNNER_PROXY_METHOD_UNKNOWN = 0,
diff --git a/src/plugin.c b/src/plugin.c
new file mode 100644
index 0000000..3af4019
--- /dev/null
+++ b/src/plugin.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * PACrunner - Proxy configuration daemon
+ *
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+
+#include "pacrunner.h"
+
+static GSList *plugins = NULL;
+
+struct pacrunner_plugin {
+ void *handle;
+ struct pacrunner_plugin_desc *desc;
+};
+
+static gboolean add_plugin(void *handle, struct pacrunner_plugin_desc *desc)
+{
+ struct pacrunner_plugin *plugin;
+
+ if (desc->init == NULL)
+ return FALSE;
+
+ plugin = g_try_new0(struct pacrunner_plugin, 1);
+ if (plugin == NULL)
+ return FALSE;
+
+ plugin->handle = handle;
+ plugin->desc = desc;
+
+ if (desc->init() < 0) {
+ g_free(plugin);
+ return FALSE;
+ }
+
+ plugins = g_slist_append(plugins, plugin);
+ DBG("Plugin %s loaded", desc->name);
+
+ return TRUE;
+}
+
+#include "builtin.h"
+
+int __pacrunner_plugin_init(void)
+{
+ GDir *dir;
+ const char *file;
+ unsigned int i;
+
+ if (strlen(PLUGINDIR) == 0)
+ return -EINVAL;
+
+ DBG("");
+
+ for (i = 0; __pacrunner_builtin[i]; i++)
+ add_plugin(NULL, __pacrunner_builtin[i]);
+
+ dir = g_dir_open(PLUGINDIR, 0, NULL);
+ if (dir != NULL)
+ return -EIO;
+
+ while ((file = g_dir_read_name(dir)) != NULL) {
+ struct pacrunner_plugin_desc *desc;
+ void *handle;
+ char *filename;
+
+ if (g_str_has_prefix(file, "lib") == TRUE ||
+ g_str_has_suffix(file, ".so") == FALSE)
+ continue;
+
+ filename = g_build_filename(PLUGINDIR, file, NULL);
+
+ handle = dlopen(filename, RTLD_NOW);
+ if (handle == NULL) {
+ pacrunner_error("Can't load plugin %s: %s",
+ filename, dlerror());
+ g_free(filename);
+ continue;
+ }
+
+ g_free(filename);
+
+ desc = dlsym(handle, "pacrunner_plugin_desc");
+ if (desc == NULL) {
+ pacrunner_error("Can't load plugin description: %s",
+ dlerror());
+ dlclose(handle);
+ continue;
+ }
+
+ if (add_plugin(handle, desc) == FALSE)
+ dlclose(handle);
+ }
+
+ g_dir_close(dir);
+
+ return 0;
+}
+
+void __pacrunner_plugin_cleanup(void)
+{
+ GSList *list;
+
+ DBG("");
+
+ for (list = plugins; list; list = list->next) {
+ struct pacrunner_plugin *plugin = list->data;
+
+ if (plugin->desc->exit)
+ plugin->desc->exit();
+
+ if (plugin->handle != NULL)
+ dlclose(plugin->handle);
+
+ g_free(plugin);
+ }
+
+ g_slist_free(plugins);
+}
diff --git a/src/plugin.h b/src/plugin.h
new file mode 100644
index 0000000..5a5be37
--- /dev/null
+++ b/src/plugin.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * PACrunner - Proxy configuration daemon
+ *
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+struct pacrunner_plugin_desc {
+ const char *name;
+ int (*init) (void);
+ void (*exit) (void);
+};
+
+#ifdef PACRUNNER_PLUGIN_BUILTIN
+#define PACRUNNER_PLUGIN_DEFINE(name, init, exit) \
+ struct pacrunner_plugin_desc __pacrunner_builtin_ ## name = { \
+ #name, init, exit \
+ };
+#else
+#define PACRUNNER_PLUGIN_DEFINE(name, init, exit) \
+ extern struct pacrunner_plugin_desc pacrunner_plugin_desc \
+ __attribute__ ((visibility("default"))); \
+ struct pacrunner_plugin_desc pacrunner_plugin_desc = { \
+ #name, init, exit \
+ };
+#endif