308 lines
7.2 KiB
C
308 lines
7.2 KiB
C
/* GKrellM
|
|
| Copyright (C) 1999-2014 Bill Wilson
|
|
|
|
|
| Author: Bill Wilson billw@gkrellm.net
|
|
| Latest versions might be found at: http://gkrellm.net
|
|
|
|
|
|
|
|
| GKrellM is free software: you can redistribute it and/or modify it
|
|
| under the terms of the GNU General Public License as published by
|
|
| the Free Software Foundation, either version 3 of the License, or
|
|
| (at your option) any later version.
|
|
|
|
|
| GKrellM 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, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
| Additional permission under GNU GPL version 3 section 7
|
|
|
|
|
| If you modify this program, or any covered work, by linking or
|
|
| combining it with the OpenSSL project's OpenSSL library (or a
|
|
| modified version of that library), containing parts covered by
|
|
| the terms of the OpenSSL or SSLeay licenses, you are granted
|
|
| additional permission to convey the resulting work.
|
|
| Corresponding Source for a non-source form of such a combination
|
|
| shall include the source code for the parts of OpenSSL used as well
|
|
| as that of the covered work.
|
|
*/
|
|
|
|
#include "gkrellmd.h"
|
|
#include "gkrellmd-private.h"
|
|
#if defined(WIN32)
|
|
#include "win32-plugin.h"
|
|
#endif
|
|
|
|
#include <gmodule.h>
|
|
|
|
|
|
static GList *plugin_list;
|
|
GList *gkrellmd_plugin_enable_list;
|
|
gchar *plugin_install_log;
|
|
|
|
|
|
/* ======================================================================= */
|
|
/* Plugin interface to gkrellmd.
|
|
*/
|
|
|
|
|
|
static void
|
|
gkrellmd_plugin_log(gchar *string1, ...)
|
|
{
|
|
va_list args;
|
|
gchar *s, *old_log;
|
|
|
|
if (!string1)
|
|
return;
|
|
va_start(args, string1);
|
|
s = string1;
|
|
while (s)
|
|
{
|
|
old_log = plugin_install_log;
|
|
if (plugin_install_log)
|
|
plugin_install_log = g_strconcat(plugin_install_log, s, NULL);
|
|
else
|
|
plugin_install_log = g_strconcat(s, NULL);
|
|
g_free(old_log);
|
|
s = va_arg(args, gchar *);
|
|
}
|
|
va_end(args);
|
|
}
|
|
|
|
GkrellmdMonitor *
|
|
gkrellmd_plugin_install(gchar *plugin_name)
|
|
{
|
|
GModule *module;
|
|
GkrellmdMonitor *m;
|
|
GkrellmdMonitor *(*init_plugin)();
|
|
gchar buf[256];
|
|
|
|
if (!g_module_supported())
|
|
return NULL;
|
|
module = g_module_open(plugin_name, 0);
|
|
gkrellmd_plugin_log(plugin_name, "\n", NULL);
|
|
|
|
if (! module)
|
|
{
|
|
snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error());
|
|
gkrellmd_plugin_log(buf, NULL);
|
|
return NULL;
|
|
}
|
|
if (!g_module_symbol(module, "gkrellmd_init_plugin",
|
|
(gpointer) &init_plugin))
|
|
{
|
|
snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error());
|
|
gkrellmd_plugin_log(buf, NULL);
|
|
g_module_close(module);
|
|
return NULL;
|
|
}
|
|
|
|
// mon_tmp.name = g_strdup(plugin_name);
|
|
// gkrellm_record_state(INIT_MONITOR, &mon_tmp);
|
|
|
|
#if defined(WIN32)
|
|
{
|
|
win32_plugin_callbacks ** plugin_cb = NULL;
|
|
|
|
if (!g_module_symbol(module, "cb", (gpointer) &plugin_cb))
|
|
{
|
|
snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error());
|
|
gkrellmd_plugin_log(buf, NULL);
|
|
g_module_close(module);
|
|
return NULL;
|
|
}
|
|
*plugin_cb = &gkrellmd_callbacks;
|
|
}
|
|
#endif
|
|
|
|
m = (*init_plugin)();
|
|
|
|
// g_free(mon_tmp.name);
|
|
// mon_tmp.name = NULL;
|
|
// gkrellm_record_state(INTERNAL, NULL);
|
|
|
|
if (m == NULL)
|
|
{
|
|
gkrellmd_plugin_log(
|
|
_("\tOoops! plugin returned NULL, not installng\n"), NULL);
|
|
g_module_close(module);
|
|
return NULL;
|
|
}
|
|
|
|
gkrellmd_plugin_log(_("\tInstalled OK\n"), NULL);
|
|
|
|
if (!m->privat) /* may get set in gkrellm_config_getline() */
|
|
{
|
|
m->privat = g_new0(GkrellmdMonitorPrivate, 1);
|
|
m->privat->config_list = gkrellmd_plugin_config_list;
|
|
}
|
|
|
|
m->privat->handle = module;
|
|
m->privat->path = plugin_name;
|
|
if (!m->name)
|
|
m->name = g_path_get_basename(m->privat->path);
|
|
|
|
return m;
|
|
}
|
|
|
|
|
|
static gchar *
|
|
gkrellmd_string_suffix(gchar *string, gchar *suffix)
|
|
{
|
|
gchar *dot;
|
|
|
|
if (string == NULL || suffix == NULL)
|
|
return NULL;
|
|
dot = strrchr(string, '.');
|
|
if (dot && !strcmp(dot + 1, suffix))
|
|
return dot + 1;
|
|
return NULL;
|
|
}
|
|
|
|
static gboolean
|
|
gkrellmd_plugin_enabled(gchar *name)
|
|
{
|
|
GList *list;
|
|
gchar *check, *s;
|
|
gint len;
|
|
|
|
for (list = gkrellmd_plugin_enable_list; list; list = list->next)
|
|
{
|
|
check = (gchar *) list->data;
|
|
s = strstr(name, check);
|
|
len = strlen(check);
|
|
if ( s
|
|
&& s == name
|
|
&& (*(name + len) == '\0' || !strcmp(name + len, ".so"))
|
|
)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gkrellmd_plugin_scan(gchar *path)
|
|
{
|
|
GDir *dir;
|
|
gchar *name, *filename;
|
|
GList *list;
|
|
GkrellmdMonitor *m = NULL;
|
|
gchar *s;
|
|
gboolean exists;
|
|
|
|
/*if (path != NULL)
|
|
g_print("Searching for plugins in '%s'\n", path);*/
|
|
|
|
if (!path || !*path || (dir = g_dir_open(path, 0, NULL)) == NULL)
|
|
return;
|
|
while ((name = (gchar *) g_dir_read_name(dir)) != NULL)
|
|
{
|
|
if (!gkrellmd_string_suffix(name, G_MODULE_SUFFIX))
|
|
continue;
|
|
|
|
/* If there's a libtool .la archive, won't want to load this .so
|
|
*/
|
|
if ( !gkrellmd_string_suffix(name, "la")
|
|
&& (s = strrchr(name, '.')) != NULL
|
|
)
|
|
{
|
|
s = g_strndup(name, s - name);
|
|
filename = g_strconcat(path, G_DIR_SEPARATOR_S, s, ".la", NULL);
|
|
exists = g_file_test(filename, G_FILE_TEST_EXISTS);
|
|
g_free(s);
|
|
g_free(filename);
|
|
if (exists)
|
|
continue;
|
|
}
|
|
if (_GK.list_plugins)
|
|
{
|
|
// TODO: list plugins support on win32
|
|
g_message("%s (%s)\n", name, path);
|
|
continue;
|
|
}
|
|
for (list = plugin_list; list; list = list->next)
|
|
{
|
|
m = (GkrellmdMonitor *) list->data;
|
|
s = g_path_get_basename(m->privat->path);
|
|
exists = !strcmp(s, name);
|
|
g_free(s);
|
|
if (exists)
|
|
break;
|
|
m = NULL;
|
|
}
|
|
s = g_strconcat(path, G_DIR_SEPARATOR_S, name, NULL);
|
|
if (m)
|
|
{
|
|
gkrellmd_plugin_log(_("Ignoring duplicate plugin "), s, "\n", NULL);
|
|
g_free(s);
|
|
continue;
|
|
}
|
|
if (!gkrellmd_plugin_enabled(name))
|
|
{
|
|
gkrellmd_plugin_log(s, "\n",
|
|
"\tNot enabled in gkrellmd.conf - skipping\n", NULL);
|
|
continue;
|
|
}
|
|
m = gkrellmd_plugin_install(s);
|
|
if (m) /* s is saved for use */
|
|
plugin_list = g_list_append(plugin_list, m);
|
|
else
|
|
g_free(s);
|
|
}
|
|
g_dir_close(dir);
|
|
}
|
|
|
|
GList *
|
|
gkrellmd_plugins_load(void)
|
|
{
|
|
GkrellmdMonitor *m;
|
|
gchar *path;
|
|
|
|
if (_GK.command_line_plugin)
|
|
{
|
|
if ( *_GK.command_line_plugin != '.'
|
|
&& !strchr(_GK.command_line_plugin, G_DIR_SEPARATOR)
|
|
)
|
|
path = g_strconcat(".", G_DIR_SEPARATOR_S,
|
|
_GK.command_line_plugin, NULL);
|
|
else
|
|
path = g_strdup(_GK.command_line_plugin);
|
|
gkrellmd_plugin_log(_("*** Command line plugin:\n"), NULL);
|
|
if ((m = gkrellmd_plugin_install(path)) == NULL)
|
|
g_free(path);
|
|
else
|
|
plugin_list = g_list_append(plugin_list, m);
|
|
gkrellmd_plugin_log("\n", NULL);
|
|
}
|
|
|
|
path = g_build_filename(_GK.homedir, GKRELLMD_PLUGINS_DIR, NULL);
|
|
gkrellmd_plugin_scan(path);
|
|
g_free(path);
|
|
|
|
#if defined(WIN32)
|
|
gchar *install_path;
|
|
install_path = g_win32_get_package_installation_directory_of_module(NULL);
|
|
if (install_path != NULL)
|
|
{
|
|
path = g_build_filename(install_path, "lib", "gkrellm2", "plugins-gkrellmd", NULL);
|
|
gkrellmd_plugin_scan(path);
|
|
g_free(path);
|
|
g_free(install_path);
|
|
}
|
|
#endif
|
|
|
|
#if defined(GKRELLMD_LOCAL_PLUGINS_DIR)
|
|
gkrellmd_plugin_scan(GKRELLMD_LOCAL_PLUGINS_DIR);
|
|
#endif
|
|
|
|
#if defined(GKRELLMD_SYSTEM_PLUGINS_DIR)
|
|
gkrellmd_plugin_scan(GKRELLMD_SYSTEM_PLUGINS_DIR);
|
|
#endif
|
|
|
|
return plugin_list;
|
|
}
|