|
@@ -1,6 +1,11 @@
|
|
|
/*
|
|
|
* plugin.c
|
|
|
*/
|
|
|
+
|
|
|
+#ifdef HAVE_CONFIG_H
|
|
|
+#include "config.h"
|
|
|
+#endif /* HAVE_CONFIG_H */
|
|
|
+
|
|
|
#include "private.h"
|
|
|
#include "lub/string.h"
|
|
|
#include "lub/list.h"
|
|
@@ -9,7 +14,9 @@
|
|
|
#include <string.h>
|
|
|
#include <stdio.h>
|
|
|
#include <assert.h>
|
|
|
+#ifdef HAVE_DLFCN_H
|
|
|
#include <dlfcn.h>
|
|
|
+#endif
|
|
|
|
|
|
/**********************************************************
|
|
|
* SYM functions *
|
|
@@ -127,16 +134,16 @@ int clish_sym_clone(clish_sym_t *dst, clish_sym_t *src)
|
|
|
**********************************************************/
|
|
|
|
|
|
/*--------------------------------------------------------- */
|
|
|
-clish_plugin_t *clish_plugin_new(const char *file, const char *alias)
|
|
|
+clish_plugin_t *clish_plugin_new(const char *name)
|
|
|
{
|
|
|
clish_plugin_t *this;
|
|
|
|
|
|
this = malloc(sizeof(*this));
|
|
|
|
|
|
- this->file = lub_string_dup(file);
|
|
|
- this->name = NULL;
|
|
|
+ this->name = lub_string_dup(name);
|
|
|
this->conf = NULL;
|
|
|
- this->alias = lub_string_dup(alias);
|
|
|
+ this->alias = NULL;
|
|
|
+ this->file = NULL;
|
|
|
this->dlhan = NULL;
|
|
|
/* Initialise the list of symbols */
|
|
|
this->syms = lub_list_new(clish_sym_compare);
|
|
@@ -159,9 +166,9 @@ void clish_plugin_free(clish_plugin_t *this, void *userdata)
|
|
|
if (this->fini)
|
|
|
this->fini(userdata, this);
|
|
|
|
|
|
- lub_string_free(this->file);
|
|
|
lub_string_free(this->name);
|
|
|
lub_string_free(this->alias);
|
|
|
+ lub_string_free(this->file);
|
|
|
lub_string_free(this->conf);
|
|
|
|
|
|
/* Free symbol list */
|
|
@@ -173,9 +180,10 @@ void clish_plugin_free(clish_plugin_t *this, void *userdata)
|
|
|
lub_list_node_free(iter);
|
|
|
}
|
|
|
lub_list_free(this->syms);
|
|
|
+#ifdef HAVE_DLFCN_H
|
|
|
if (this->dlhan)
|
|
|
dlclose(this->dlhan);
|
|
|
-
|
|
|
+#endif
|
|
|
free(this);
|
|
|
}
|
|
|
|
|
@@ -230,6 +238,13 @@ clish_sym_t *clish_plugin_add_phook(clish_plugin_t *this,
|
|
|
name, type, BOOL_TRUE);
|
|
|
}
|
|
|
|
|
|
+/*--------------------------------------------------------- */
|
|
|
+void clish_plugin_add_fini(clish_plugin_t *this,
|
|
|
+ clish_plugin_fini_t *fini)
|
|
|
+{
|
|
|
+ this->fini = fini;
|
|
|
+}
|
|
|
+
|
|
|
/*--------------------------------------------------------- */
|
|
|
clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name, int type)
|
|
|
{
|
|
@@ -255,43 +270,57 @@ clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name, int ty
|
|
|
int clish_plugin_load(clish_plugin_t *this, void *userdata)
|
|
|
{
|
|
|
int res;
|
|
|
+ char *file = NULL; /* Plugin so file name */
|
|
|
+ char *init_name = NULL; /* Init function name */
|
|
|
|
|
|
if (!this)
|
|
|
return -1;
|
|
|
+ assert(this->name);
|
|
|
+
|
|
|
+#ifdef HAVE_DLFCN_H
|
|
|
+ if (this->file) {
|
|
|
+ file = lub_string_dup(this->file);
|
|
|
+ } else {
|
|
|
+ lub_string_cat(&file, "clish_plugin_");
|
|
|
+ lub_string_cat(&file, this->name);
|
|
|
+ lub_string_cat(&file, ".so");
|
|
|
+ }
|
|
|
|
|
|
/* Open dynamic library */
|
|
|
- if (!(this->dlhan = dlopen(this->file, RTLD_NOW | RTLD_LOCAL))) {
|
|
|
+ this->dlhan = dlopen(file, RTLD_NOW | RTLD_LOCAL);
|
|
|
+ lub_string_free(file);
|
|
|
+ if (!this->dlhan) {
|
|
|
fprintf(stderr, "Error: Can't open plugin %s: %s\n",
|
|
|
- this->file, dlerror());
|
|
|
+ this->name, dlerror());
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Get plugin init function */
|
|
|
- this->init = (clish_plugin_init_t *)dlsym(this->dlhan, CLISH_PLUGIN_INIT_NAME);
|
|
|
+ lub_string_cat(&init_name, CLISH_PLUGIN_INIT_NAME_PREFIX);
|
|
|
+ lub_string_cat(&init_name, this->name);
|
|
|
+ lub_string_cat(&init_name, CLISH_PLUGIN_INIT_NAME_SUFFIX);
|
|
|
+ this->init = (clish_plugin_init_t *)dlsym(this->dlhan, init_name);
|
|
|
+ lub_string_free(init_name);
|
|
|
if (!this->init) {
|
|
|
fprintf(stderr, "Error: Can't get plugin %s init function: %s\n",
|
|
|
- this->file, dlerror());
|
|
|
+ this->name, dlerror());
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- /* Get plugin fini function */
|
|
|
- this->fini = (clish_plugin_fini_t *)dlsym(this->dlhan, CLISH_PLUGIN_FINI_NAME);
|
|
|
+#else /* HAVE_DLFCN_H */
|
|
|
+ /* We have no any dl functions. */
|
|
|
+
|
|
|
+
|
|
|
+#endif /* HAVE_DLFCN_H */
|
|
|
|
|
|
/* Execute init function */
|
|
|
if ((res = this->init(userdata, this)))
|
|
|
fprintf(stderr, "Error: Plugin %s init retcode: %d\n",
|
|
|
- this->file, res);
|
|
|
+ this->name, res);
|
|
|
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-/*--------------------------------------------------------- */
|
|
|
-void clish_plugin__set_name(clish_plugin_t *this, const char *name)
|
|
|
-{
|
|
|
- lub_string_free(this->name);
|
|
|
- this->name = lub_string_dup(name);
|
|
|
-}
|
|
|
-
|
|
|
/*--------------------------------------------------------- */
|
|
|
char *clish_plugin__get_name(const clish_plugin_t *this)
|
|
|
{
|
|
@@ -317,6 +346,13 @@ char *clish_plugin__get_pubname(const clish_plugin_t *this)
|
|
|
return (this->alias ? this->alias : this->name);
|
|
|
}
|
|
|
|
|
|
+/*--------------------------------------------------------- */
|
|
|
+void clish_plugin__set_file(clish_plugin_t *this, const char *file)
|
|
|
+{
|
|
|
+ lub_string_free(this->file);
|
|
|
+ this->file = lub_string_dup(file);
|
|
|
+}
|
|
|
+
|
|
|
/*--------------------------------------------------------- */
|
|
|
char *clish_plugin__get_file(const clish_plugin_t *this)
|
|
|
{
|