1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2013-2014 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
31 #include <glib-unix.h>
34 #include <sys/prctl.h>
36 #include "gsignond/gsignond-log.h"
37 #include "daemon/dbus/gsignond-dbus.h"
38 #include "gsignond-plugin-daemon.h"
40 static GSignondPluginDaemon *_daemon = NULL;
41 static guint _sig_source_id[3];
44 _on_daemon_closed (gpointer data, GObject *server)
47 DBG ("Daemon closed");
48 if (data) g_main_loop_quit ((GMainLoop *)data);
52 _handle_quit_signal (gpointer user_data)
54 GMainLoop *ml = (GMainLoop *) user_data;
56 g_return_val_if_fail (ml != NULL, FALSE);
57 DBG ("Received quit signal");
58 if (ml) g_main_loop_quit (ml);
64 _install_sighandlers (GMainLoop *main_loop)
66 GSource *source = NULL;
67 GMainContext *ctx = g_main_loop_get_context (main_loop);
69 source = g_unix_signal_source_new (SIGTERM);
70 g_source_set_callback (source,
74 _sig_source_id[0] = g_source_attach (source, ctx);
76 source = g_unix_signal_source_new (SIGINT);
77 g_source_set_callback (source,
81 _sig_source_id[1] = g_source_attach (source, ctx);
83 source = g_unix_signal_source_new (SIGHUP);
84 g_source_set_callback (source,
88 _sig_source_id[2] = g_source_attach (source, ctx);
90 if (prctl(PR_SET_PDEATHSIG, SIGHUP))
91 WARN ("failed to set parent death signal");
94 static void _list_plugins()
96 const gchar *plugin_path = GSIGNOND_GPLUGINS_DIR;
99 const gchar *env_val = g_getenv("SSO_GPLUGINS_DIR");
101 plugin_path = env_val;
103 GDir* plugin_dir = g_dir_open(plugin_path, 0, NULL);
104 if (plugin_dir == NULL) {
109 const gchar* plugin_soname = g_dir_read_name(plugin_dir);
110 if (plugin_soname == NULL)
112 if (g_str_has_prefix(plugin_soname, "lib") &&
113 g_str_has_suffix(plugin_soname, ".so")) {
114 gchar* plugin_name = g_strndup(plugin_soname+3,
115 strlen(plugin_soname) - 6);
116 g_print("%s\n", plugin_name);
120 g_dir_close(plugin_dir);
123 int main (int argc, char **argv)
125 GError *error = NULL;
126 GMainLoop *main_loop = NULL;
127 GOptionContext *opt_context = NULL;
128 gint in_fd = 0, out_fd = 1;
130 gboolean list_plugins = FALSE;
131 gchar* plugin_name = NULL;
132 GOptionEntry main_entries[] =
134 { "list-plugins", 0, 0, G_OPTION_ARG_NONE, &list_plugins, "List available plugins", NULL},
135 { "load-plugin", 0, 0, G_OPTION_ARG_STRING, &plugin_name, "Load a plugin and start a d-bus connection with it on stdio channel", "name"},
139 opt_context = g_option_context_new ("gSSO glib plugin loader");
140 g_option_context_add_main_entries (opt_context, main_entries, NULL);
142 if (!g_option_context_parse (opt_context, &argc, &argv, &error)) {
143 WARN ("option parsing failed: %s\n", error->message);
145 g_option_context_free(opt_context);
148 g_option_context_free(opt_context);
156 g_print("Use --help to list command line options\n");
161 /* Duplicates stdin,stdout,stderr descriptors and point the descriptors
162 * to /dev/null to avoid anyone writing to descriptors before initial
163 * "plugind-is-ready" notification is sent to gsignond
167 WARN ("Failed to dup stdin : %s(%d)", strerror(errno), errno);
170 if (!freopen("/dev/null", "r+", stdin)) {
171 WARN ("Unable to redirect stdin to /dev/null");
176 WARN ("Failed to dup stdout : %s(%d)", strerror(errno), errno);
180 /* Reattach stderr to stdout */
183 #if !GLIB_CHECK_VERSION (2, 36, 0)
187 const gchar *plugin_path = GSIGNOND_GPLUGINS_DIR;
189 const gchar *env_val = g_getenv("SSO_GPLUGINS_DIR");
191 plugin_path = env_val;
193 gchar* filename = g_module_build_path (plugin_path, plugin_name);
195 _daemon = gsignond_plugin_daemon_new (filename, plugin_name, in_fd,
199 if (_daemon == NULL) {
203 main_loop = g_main_loop_new (NULL, FALSE);
204 g_object_weak_ref (G_OBJECT (_daemon), _on_daemon_closed, main_loop);
205 _install_sighandlers (main_loop);
207 DBG ("Entering main event loop");
209 g_main_loop_run (main_loop);
212 g_object_unref (_daemon);
216 g_main_loop_unref (main_loop);