ant-http/plugin_manager.c

150 lines
3.4 KiB
C
Raw Normal View History

2015-10-22 11:39:11 +02:00
#include "plugin_manager.h"
/**
* Plugin table to store the loaded plugin
*/
static struct plugin_entry *plugin_table[HASHSIZE];
/**
* Locate a plugin in the plugin table
* @param s plugin name
* @return a plugin entry in the plugin table
*/
struct plugin_entry *plugin_lookup(char *s)
{
struct plugin_entry *np;
2015-11-24 17:58:32 +01:00
for (np = plugin_table[hash(s, HASHSIZE)]; np != NULL; np = np->next)
2015-10-22 11:39:11 +02:00
if (strcmp(s, np->pname) == 0)
return np; /* found */
return NULL; /* not found */
}
/**
* Load a plugin to the plugin table
* Only load when not available in the plugin table
* @param name plugin name
* @return pointer to the loaded plugin
*/
struct plugin_entry *plugin_load(char *name)
{
struct plugin_entry *np;
unsigned hashval;
if ((np = plugin_lookup(name)) == NULL) { /* not found */
np = (struct plugin_entry *) malloc(sizeof(*np));
if (np == NULL || (np->pname = strdup(name)) == NULL)
{
if(np) free(np);
return NULL;
}
2015-10-22 11:39:11 +02:00
if ((np->handle = plugin_from_file(name)) == NULL)
{
if(np) free(np);
2015-10-22 11:39:11 +02:00
return NULL;
}
hashval = hash(name,HASHSIZE);
2015-10-22 11:39:11 +02:00
np->next = plugin_table[hashval];
plugin_table[hashval] = np;
} else /* already there */
{
2019-12-11 23:17:42 +01:00
LOG("The plugin %s id already loaded", name);
2015-10-22 11:39:11 +02:00
}
return np;
}
/**
* Find a plugin in a file, and load it in to the plugin table
* @param name Name of the plugin
* @return
*/
void * plugin_from_file(char* name)
{
void *lib_handle;
char* error;
char* path = __s("%s%s%s",config()->plugins_dir,name,config()->plugins_ext);
2018-02-10 11:22:41 +01:00
void (*fn)(const char*, config_t*);
2019-11-14 18:48:44 +01:00
lib_handle = dlopen(path, RTLD_NOW| RTLD_GLOBAL);
2015-10-22 11:39:11 +02:00
if (!lib_handle)
{
2019-12-11 23:17:42 +01:00
ERROR("Cannot load plugin '%s' : '%s'",name,dlerror());
2018-03-02 19:04:00 +01:00
if(path)
free(path);
2015-10-22 11:39:11 +02:00
return NULL;
}
// set database path
2018-02-10 11:22:41 +01:00
fn = (void (*)(const char *, config_t*))dlsym(lib_handle, "__init_plugin__");
2015-10-22 11:39:11 +02:00
if ((error = dlerror()) != NULL)
2019-12-11 23:17:42 +01:00
ERROR("Problem when finding plugin init function for %s : %s", name,error);
2015-10-22 11:39:11 +02:00
else
(*fn)(name,config());
2017-07-30 01:00:36 +02:00
if(path)
2015-10-22 11:39:11 +02:00
free(path);
return lib_handle;
}
2016-03-04 11:38:08 +01:00
void unload_plugin(struct plugin_entry* np)
{
char* error;
void (*fn)() = NULL;
// find and execute the exit function
fn = (void(*)()) dlsym(np->handle, "__release__");
2018-03-02 19:04:00 +01:00
if ((error = dlerror()) != NULL)
{
2019-12-11 23:17:42 +01:00
ERROR("Cant not release plugin %s : %s", np->pname,error);
2018-03-02 19:04:00 +01:00
}
if(fn)
{
(*fn)();
}
2016-03-04 11:38:08 +01:00
dlclose(np->handle);
//free((void *) np->handle);
free((void *) np->pname);
}
/*
Unload a plugin by its name
*/
void unload_plugin_by_name(const char* name)
{
struct plugin_entry *np;
int hasval = hash(name, HASHSIZE);
np = plugin_table[hasval];
if(strcmp(np->pname,name) == 0)
{
unload_plugin(np);
plugin_table[hasval] = np->next;
}
else
{
2019-12-20 16:49:41 +01:00
for (np = plugin_table[hasval] ; np != NULL; np = np->next)
2019-12-11 23:17:42 +01:00
{
2016-03-04 11:38:08 +01:00
if (np->next != NULL && strcmp(name, np->next->pname) == 0)
2019-12-11 23:17:42 +01:00
{
2016-03-04 11:38:08 +01:00
break;
2019-12-11 23:17:42 +01:00
}
}
2016-03-04 11:38:08 +01:00
if(np == NULL) return; // the plugin is is not loaded
unload_plugin(np->next);
np->next = np->next->next;
}
}
2015-10-22 11:39:11 +02:00
/**
* Unload all the plugin loaded on the plugin table
*/
void unload_all_plugin()
{
2019-12-11 23:17:42 +01:00
LOG("Unload all plugins");
2015-10-22 11:39:11 +02:00
for(int i=0;i<HASHSIZE;i++)
{
2018-03-02 19:04:00 +01:00
struct plugin_entry **np, *curr;
np = &plugin_table[i];
while((curr = *np) != NULL)
{
(*np) = (*np)->next;
unload_plugin(curr);
free(curr);
}
2015-10-22 11:39:11 +02:00
plugin_table[i] = NULL;
}
exit(0);
2015-10-22 11:39:11 +02:00
}