From c33b387b3ed16bce4058b9088260c4ece1ff6342 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Dec 2007 20:51:05 +0100 Subject: [PATCH] Add plugin infrastructure --- Makefile.am | 2 +- configure.in | 13 +++- include/Makefile.am | 12 ++++ include/plugin.h | 46 +++++++++++++++ plugins/Makefile.am | 2 + src/Makefile.am | 15 ++++- src/connman.h | 10 ++++ src/main.c | 4 ++ src/plugin.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 include/Makefile.am create mode 100644 include/plugin.h create mode 100644 plugins/Makefile.am create mode 100644 src/plugin.c diff --git a/Makefile.am b/Makefile.am index baa76129..0a0969fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS = src +SUBDIRS = include src plugins MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ diff --git a/configure.in b/configure.in index 7cddb933..ecf67c43 100644 --- a/configure.in +++ b/configure.in @@ -18,9 +18,20 @@ AC_PROG_CC AC_PROG_CC_PIE AC_PROG_INSTALL +m4_define([_LT_AC_TAGCONFIG], []) +m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL_TAGS([])]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + +PKG_CHECK_MODULES(GMODULE, gmodule-2.0, dummy=yes, + AC_MSG_ERROR(gmodule is required)) +AC_SUBST(GMODULE_CFLAGS) +AC_SUBST(GMODULE_LIBS) + PKG_CHECK_MODULES(GDBUS, gdbus, dummy=yes, AC_MSG_ERROR(libgdbus is required)) AC_SUBST(GDBUS_CFLAGS) AC_SUBST(GDBUS_LIBS) -AC_OUTPUT(Makefile src/Makefile) +AC_OUTPUT(Makefile include/Makefile src/Makefile plugins/Makefile) diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 00000000..55bf6b5a --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,12 @@ + +includedir = @includedir@/connman + +noinst_HEADERS = plugin.h + +MAINTAINERCLEANFILES = Makefile.in + +all-local: + @if [ ! -e connman ] ; then $(LN_S) $(top_srcdir)/include connman ; fi + +clean-local: + @rm -f connman diff --git a/include/plugin.h b/include/plugin.h new file mode 100644 index 00000000..b7f1eb3a --- /dev/null +++ b/include/plugin.h @@ -0,0 +1,46 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007 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 + * + */ + +#ifndef __CONNMAN_PLUGIN_H +#define __CONNMAN_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct connman_plugin_desc { + const char *name; + const char *description; + const char *version; + int (*init) (void); + void (*exit) (void); +}; + +#define CONNMAN_PLUGIN_DEFINE(name,description,version,init,exit) \ + struct connman_plugin_desc connman_plugin_desc = { \ + name, description, version, init, exit \ + }; + +#ifdef __cplusplus +} +#endif + +#endif /* __CONNMAN_PLUGIN_H */ diff --git a/plugins/Makefile.am b/plugins/Makefile.am new file mode 100644 index 00000000..02742923 --- /dev/null +++ b/plugins/Makefile.am @@ -0,0 +1,2 @@ + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/Makefile.am b/src/Makefile.am index 87a6e78a..9f15cf37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,11 +5,20 @@ dbus_DATA = connman.conf sbin_PROGRAMS = connmand -connmand_SOURCES = main.c connman.h +connmand_SOURCES = main.c connman.h plugin.c -connmand_LDADD = @GDBUS_LIBS@ +connmand_LDADD = @GDBUS_LIBS@ @GMODULE_LIBS@ + +if MAINTAINER_MODE +plugindir = $(abs_top_srcdir)/plugins +else +plugindir = $(libdir)/connman +endif -AM_CFLAGS = @GDBUS_CFLAGS@ +AM_CFLAGS = @GMODULE_CFLAGS@ @GDBUS_CFLAGS@ \ + -DPLUGINDIR=\""$(plugindir)"\" + +INCLUDES = -I$(top_builddir)/include EXTRA_DIST = $(dbus_DATA) diff --git a/src/connman.h b/src/connman.h index 5282d144..f81ecd08 100644 --- a/src/connman.h +++ b/src/connman.h @@ -19,7 +19,17 @@ * */ +#include + +#define DBG(fmt, arg...) printf("%s: " fmt "\n" , __FUNCTION__ , ## arg) +//#define DBG(fmt, arg...) + #define CONNMAN_SERVICE "org.freedesktop.connman" #define CONNMAN_MANAGER_PATH "/" #define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager" + +#include + +int __connman_plugin_init(void); +void __connman_plugin_cleanup(void); diff --git a/src/main.c b/src/main.c index 76af50a6..74378029 100644 --- a/src/main.c +++ b/src/main.c @@ -54,6 +54,8 @@ int main(int argc, char *argv[]) g_dbus_register_object(conn, CONNMAN_MANAGER_PATH, NULL, NULL); + __connman_plugin_init(); + memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_term; sigaction(SIGINT, &sa, NULL); @@ -61,6 +63,8 @@ int main(int argc, char *argv[]) g_main_loop_run(main_loop); + __connman_plugin_cleanup(); + g_dbus_unregister_object(conn, CONNMAN_MANAGER_PATH); g_dbus_cleanup_connection(conn); diff --git a/src/plugin.c b/src/plugin.c new file mode 100644 index 00000000..8e164e1e --- /dev/null +++ b/src/plugin.c @@ -0,0 +1,141 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007 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 +#endif + +#include + +#include +#include + +#include + +#include "connman.h" + +static GSList *plugins = NULL; + +struct connman_plugin { + GModule *module; + struct connman_plugin_desc *desc; +}; + +static gboolean add_plugin(GModule *module, struct connman_plugin_desc *desc) +{ + struct connman_plugin *plugin; + + plugin = g_try_new0(struct connman_plugin, 1); + if (plugin == NULL) + return FALSE; + + plugin->module = module; + plugin->desc = desc; + + plugins = g_slist_append(plugins, plugin); + + desc->init(); + + return TRUE; +} + +static void load_plugins(const gchar *path) +{ + GDir *dir; + const gchar *file; + gchar *filename; + + dir = g_dir_open(path, 0, NULL); + if (dir != NULL) { + while ((file = g_dir_read_name(dir)) != NULL) { + GModule *module; + struct connman_plugin_desc *desc; + + if (g_str_has_prefix(file, "libconnman") == FALSE) + continue; + + filename = g_build_filename(path, file, NULL); + + module = g_module_open(filename, 0); + if (module == NULL) { + g_warning("Can't load %s", filename); + continue; + } + + g_free(filename); + + DBG("%s", g_module_name(module)); + + if (g_module_symbol(module, "connman_plugin_desc", + (gpointer) &desc) == FALSE) { + g_warning("Can't load symbol"); + g_module_close(module); + continue; + } + + if (desc == NULL || desc->init == NULL) { + g_module_close(module); + continue; + } + + if (add_plugin(module, desc) == FALSE) + g_module_close(module); + } + + g_dir_close(dir); + } +} + +int __connman_plugin_init(void) +{ + DBG(""); + + if (g_module_supported() == FALSE) { + g_warning("Modules not supported: %s", g_module_error()); + return FALSE; + } + + load_plugins(PLUGINDIR); + + return 0; +} + +void __connman_plugin_cleanup(void) +{ + GSList *list; + + DBG(""); + + for (list = plugins; list; list = list->next) { + struct connman_plugin *plugin = list->data; + + DBG("%s", g_module_name(plugin->module)); + + if (plugin->desc->exit) + plugin->desc->exit(); + + g_module_close(plugin->module); + + g_free(plugin); + } + + g_slist_free(plugins); +} -- 2.34.1