gplugin/gplugin

abandoning this branch
feature/java
2021-04-28, Gary Kramlich
01fbef6b01cb
abandoning this branch
/*
* Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
*
* This program 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.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <gplugin.h>
#include <gplugin-native.h>
#include <gmodule.h>
/******************************************************************************
* Globals
*****************************************************************************/
static GModule *jvm = NULL;
static GModule *jsig = NULL;
/******************************************************************************
* Helpers
*****************************************************************************/
static gchar *
gplugin_java_get_arch_name(void) {
#if defined(__x86_64__)
return "amd64";
#elif defined(__i386__)
return "i386";
#else
return NULL;
#endif
}
static gchar *
gplugin_java_env_find_java(const gchar *java_path, GError **error) {
gchar *path = g_strdup(java_path);
gchar *tmp = NULL;
while(g_file_test(path, G_FILE_TEST_IS_SYMLINK)) {
tmp = path;
path = g_file_read_link(tmp, error);
g_free(tmp);
if(*error) {
g_free(path);
path = NULL;
break;
}
}
/* remove java from the path */
tmp = g_path_get_dirname(path);
g_free(path);
/* remove bin from the path */
path = tmp;
tmp = g_path_get_dirname(path);
g_free(path);
/* now return the adjusted path */
return tmp;
}
static gchar *
gplugin_java_get_library_path(const gchar *jdk_path, const gchar *library) {
const gchar *arch = gplugin_java_get_arch_name();
gchar *path = NULL, *module_path = NULL;
path = g_build_filename(jdk_path, "lib", arch, "server", NULL);
module_path = g_module_build_path(path, library);
g_free(path);
return module_path;
}
static gboolean
gplugin_java_load_library(const gchar *jdk_path, const gchar *name,
GModule **module, GError **error)
{
gboolean ret = TRUE;
gchar *path = gplugin_java_get_library_path(jdk_path, name);
*module = g_module_open(path, 0);
if(*module == NULL) {
if(error) {
*error = g_error_new(GPLUGIN_DOMAIN, 0,
"Failed to open %s: %s", path,
g_module_error());
}
ret = FALSE;
}
g_free(path);
return ret;
}
static void
gplugin_java_export_symbol(const gchar *name) {
gpointer symbol;
gboolean r = FALSE;
r = g_module_symbol(jvm, name, &symbol);
g_message("r: %d; sym: %s(%p);", r, name, symbol);
}
static void
gplugin_java_export_symbols(void) {
gplugin_java_export_symbol("JNI_GetDefaultJavaVMInitArgs");
gplugin_java_export_symbol("JNI_CreateJavaVM");
}
/******************************************************************************
* Plugin Exports
*****************************************************************************/
G_MODULE_EXPORT GPluginPluginInfo *
gplugin_query(GPLUGIN_UNUSED GError **error) {
const gchar * const authors[] = {
"Gary Kramlich <grim@reaperworld.com>",
NULL
};
return gplugin_plugin_info_new(
"gplugin/java-loader-env",
GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
"internal", TRUE,
"load-on-query", TRUE,
"name", "Java Plugin Loader Environment",
"version", GPLUGIN_VERSION,
"license-id", "GPL3",
"summary", "Sets up the Java environment for the Java plugin loader",
"description", "This plugin sets up the Java environment for the Java "
"plugin loader.",
"authors", authors,
"website", GPLUGIN_WEBSITE,
"category", "loaders",
NULL
);
}
G_MODULE_EXPORT gboolean
gplugin_load(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
GError **error)
{
gchar *path = gplugin_java_env_find_java("/usr/bin/java", error);
if(path == NULL) {
*error = g_error_new(GPLUGIN_DOMAIN, 0,
"Failed to find a Java virtual machine");
return FALSE;
}
if(!gplugin_java_load_library(path, "jsig", &jsig, error)) {
return FALSE;
}
if(!gplugin_java_load_library(path, "jvm", &jvm, error)) {
return FALSE;
}
gplugin_java_export_symbols();
return TRUE;
}
G_MODULE_EXPORT gboolean
gplugin_unload(GPLUGIN_UNUSED GPluginNativePlugin *plugin,
GError **error)
{
if(!g_module_close(jvm)) {
if(error) {
*error = g_error_new(GPLUGIN_DOMAIN, 0,
"Failed to unload the jvm");
}
return FALSE;
}
if(!g_module_close(jsig)) {
if(error) {
*error = g_error_new(GPLUGIN_DOMAIN, 0,
"Failed to unload jsig");
}
return FALSE;
}
return TRUE;
}