summaryrefslogtreecommitdiff
path: root/src/common/HPM.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/HPM.c')
-rw-r--r--src/common/HPM.c350
1 files changed, 213 insertions, 137 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c
index f39954175..51a595310 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -30,6 +30,14 @@
struct malloc_interface iMalloc_HPM;
struct malloc_interface *HPMiMalloc;
+struct HPM_interface HPM_s;
+
+/**
+ * (char*) data name -> (unsigned int) HPMDataCheck[] index
+ **/
+DBMap *datacheck_db;
+int datacheck_version;
+const struct s_HPMDataCheck *datacheck_data;
void hplugin_trigger_event(enum hp_event_types type) {
unsigned int i;
@@ -48,22 +56,22 @@ void hplugin_export_symbol(void *var, char *name) {
void *hplugin_import_symbol(char *name, unsigned int pID) {
unsigned int i;
-
+
for( i = 0; i < HPM->symbol_count; i++ ) {
if( strcmp(HPM->symbols[i]->name,name) == 0 )
return HPM->symbols[i]->ptr;
}
-
+
ShowError("HPM:get_symbol:%s: '"CL_WHITE"%s"CL_RESET"' not found!\n",HPM->pid2name(pID),name);
return NULL;
}
bool hplugin_iscompatible(char* version) {
unsigned int req_major = 0, req_minor = 0;
-
+
if( version == NULL )
return false;
-
+
sscanf(version, "%u.%u", &req_major, &req_minor);
return ( req_major == HPM->version[0] && req_minor <= HPM->version[1] ) ? true : false;
@@ -102,7 +110,7 @@ bool hplugin_populate(struct hplugin *plugin, const char *filename) {
HPM_POP(ShowFatalError),
};
int i, length = ARRAYLENGTH(ToLink);
-
+
for(i = 0; i < length; i++) {
if( !( Link = plugin_import(plugin->dll, ToLink[i].name,void **) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve '%s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", ToLink[i].name, filename);
@@ -111,7 +119,7 @@ bool hplugin_populate(struct hplugin *plugin, const char *filename) {
}
*Link = ToLink[i].Ref;
}
-
+
return true;
}
#undef HPM_POP
@@ -122,56 +130,57 @@ struct hplugin *hplugin_load(const char* filename) {
bool anyEvent = false;
void **import_symbol_ref;
Sql **sql_handle;
+ int *HPMDataCheckVer;
unsigned int *HPMDataCheckLen;
struct s_HPMDataCheck *HPMDataCheck;
-
+
if( HPM->exists(filename) ) {
ShowWarning("HPM:plugin_load: attempting to load duplicate '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
return NULL;
}
-
+
plugin = HPM->create();
-
+
if( !( plugin->dll = plugin_open(filename) ) ){
ShowWarning("HPM:plugin_load: failed to load '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
if( !( info = plugin_import(plugin->dll, "pinfo",struct hplugin_info*) ) ) {
ShowDebug("HPM:plugin_load: failed to retrieve 'plugin_info' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
if( !(info->type & SERVER_TYPE) ) {
HPM->unload(plugin);
return NULL;
}
-
+
if( !HPM->iscompatible(info->req_version) ) {
ShowWarning("HPM:plugin_load: '"CL_WHITE"%s"CL_RESET"' incompatible version '%s' -> '%s', skipping...\n", filename, info->req_version, HPM_VERSION);
HPM->unload(plugin);
return NULL;
}
-
+
plugin->info = info;
plugin->filename = aStrdup(filename);
-
+
if( !( import_symbol_ref = plugin_import(plugin->dll, "import_symbol",void **) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'import_symbol' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
*import_symbol_ref = HPM->import_symbol;
-
+
if( !( sql_handle = plugin_import(plugin->dll, "mysql_handle",Sql **) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'mysql_handle' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
*sql_handle = HPM->import_symbol("sql_handle",plugin->idx);
if( !( HPMi = plugin_import(plugin->dll, "HPMi",struct HPMi_interface **) ) ) {
@@ -179,56 +188,63 @@ struct hplugin *hplugin_load(const char* filename) {
HPM->unload(plugin);
return NULL;
}
-
+
if( !( *HPMi = plugin_import(plugin->dll, "HPMi_s",struct HPMi_interface *) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'HPMi_s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
plugin->hpi = *HPMi;
-
+
if( ( plugin->hpi->event[HPET_INIT] = plugin_import(plugin->dll, "plugin_init",void (*)(void)) ) )
anyEvent = true;
-
+
if( ( plugin->hpi->event[HPET_FINAL] = plugin_import(plugin->dll, "plugin_final",void (*)(void)) ) )
anyEvent = true;
-
+
if( ( plugin->hpi->event[HPET_READY] = plugin_import(plugin->dll, "server_online",void (*)(void)) ) )
anyEvent = true;
-
+
if( ( plugin->hpi->event[HPET_POST_FINAL] = plugin_import(plugin->dll, "server_post_final",void (*)(void)) ) )
anyEvent = true;
-
+
if( ( plugin->hpi->event[HPET_PRE_INIT] = plugin_import(plugin->dll, "server_preinit",void (*)(void)) ) )
anyEvent = true;
-
+
if( !anyEvent ) {
ShowWarning("HPM:plugin_load: no events found for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
if( !HPM->populate(plugin,filename) )
return NULL;
-
+
if( !( HPMDataCheckLen = plugin_import(plugin->dll, "HPMDataCheckLen", unsigned int *) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheckLen' for '"CL_WHITE"%s"CL_RESET"', most likely not including HPMDataCheck.h, skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
+ if( !( HPMDataCheckVer = plugin_import(plugin->dll, "HPMDataCheckVer", int *) ) ) {
+ ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheckVer' for '"CL_WHITE"%s"CL_RESET"', most likely an outdated plugin, skipping...\n", filename);
+ HPM->unload(plugin);
+ return NULL;
+ }
+
if( !( HPMDataCheck = plugin_import(plugin->dll, "HPMDataCheck", struct s_HPMDataCheck *) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheck' for '"CL_WHITE"%s"CL_RESET"', most likely not including HPMDataCheck.h, skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
- if( HPM->DataCheck && !HPM->DataCheck(HPMDataCheck,*HPMDataCheckLen,plugin->info->name) ) {
+
+ // TODO: Remove the HPM->DataCheck != NULL check once login and char support is complete
+ if (HPM->DataCheck != NULL && !HPM->DataCheck(HPMDataCheck,*HPMDataCheckLen,*HPMDataCheckVer,plugin->info->name)) {
ShowWarning("HPM:plugin_load: '"CL_WHITE"%s"CL_RESET"' failed DataCheck, out of sync from the core (recompile plugin), skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
-
+
/* id */
plugin->hpi->pid = plugin->idx;
/* core */
@@ -245,19 +261,19 @@ struct hplugin *hplugin_load(const char* filename) {
/* server specific */
if( HPM->load_sub )
HPM->load_sub(plugin);
-
+
return plugin;
}
void hplugin_unload(struct hplugin* plugin) {
unsigned int i = plugin->idx, cursor = 0;
-
+
if( plugin->filename )
aFree(plugin->filename);
if( plugin->dll )
plugin_close(plugin->dll);
/* TODO: for manual packet unload */
- /* - Go thru known packets and unlink any belonging to the plugin being removed */
+ /* - Go through known packets and unlink any belonging to the plugin being removed */
aFree(plugin);
if( !HPM->off ) {
HPM->plugins[i] = NULL;
@@ -281,59 +297,66 @@ void hplugins_config_read(const char * const *extra_plugins, int extra_plugins_c
const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name
FILE *fp;
int i;
-
-// uncomment once login/char support is wrapped up
-// if( !HPM->DataCheck ) {
-// ShowError("HPM:config_read: HPM->DataCheck not set! Failure\n");
-// return;
-// }
-
+
/* yes its ugly, its temporary and will be gone as soon as the new inter-server.conf is set */
if( (fp = fopen("conf/import/plugins.conf","r")) ) {
config_filename = "conf/import/plugins.conf";
fclose(fp);
}
-
+
if (libconfig->read_file(&plugins_conf, config_filename))
return;
if( HPM->symbol_defaults_sub )
HPM->symbol_defaults_sub();
-
+
plist = libconfig->lookup(&plugins_conf, "plugins_list");
for (i = 0; i < extra_plugins_count; i++) {
config_setting_t *entry = libconfig->setting_add(plist, NULL, CONFIG_TYPE_STRING);
config_setting_set_string(entry, extra_plugins[i]);
}
-
+
if (plist != NULL) {
int length = libconfig->setting_length(plist);
char filename[60];
- for(i = 0; i < length; i++) {
- if( !strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first
+ char hooking_plugin_name[32];
+ const char *plugin_name_suffix = "";
+ if (SERVER_TYPE == SERVER_TYPE_LOGIN)
+ plugin_name_suffix = "_login";
+ else if (SERVER_TYPE == SERVER_TYPE_CHAR)
+ plugin_name_suffix = "_char";
+ else if (SERVER_TYPE == SERVER_TYPE_MAP)
+ plugin_name_suffix = "_map";
+ snprintf(hooking_plugin_name, sizeof(hooking_plugin_name), "HPMHooking%s", plugin_name_suffix);
+
+ for (i = 0; i < length; i++) {
+ const char *plugin_name = libconfig->setting_get_string_elem(plist,i);
+ if (strcmpi(plugin_name, "HPMHooking") == 0 || strcmpi(plugin_name, hooking_plugin_name) == 0) { //must load it first
struct hplugin *plugin;
- snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
- if( ( plugin = HPM->load(filename) ) ) {
+ snprintf(filename, 60, "plugins/%s%s", hooking_plugin_name, DLL_EXT);
+ if ((plugin = HPM->load(filename))) {
bool (*func)(bool *fr);
bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID);
- if( ( func = plugin_import(plugin->dll, "Hooked",bool (*)(bool *)) ) && ( addhook_sub = plugin_import(plugin->dll, "HPM_Plugin_AddHook",bool (*)(enum HPluginHookType, const char *, void *, unsigned int)) ) ) {
- if( func(&HPM->force_return) ) {
+ if ((func = plugin_import(plugin->dll, "Hooked",bool (*)(bool *)))
+ && (addhook_sub = plugin_import(plugin->dll, "HPM_Plugin_AddHook",bool (*)(enum HPluginHookType, const char *, void *, unsigned int)))) {
+ if (func(&HPM->force_return)) {
HPM->hooking = true;
HPM->addhook_sub = addhook_sub;
}
}
}
+ break;
}
}
- for(i = 0; i < length; i++) {
- if( strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//now all others
- snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
- HPM->load(filename);
- }
+ for (i = 0; i < length; i++) {
+ if (strncmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking", 10) == 0) // Already loaded, skip
+ continue;
+ snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
+ HPM->load(filename);
}
libconfig->destroy(&plugins_conf);
}
-
+
if( HPM->plugin_count )
ShowStatus("HPM: There are '"CL_WHITE"%d"CL_RESET"' plugins loaded, type '"CL_WHITE"plugins"CL_RESET"' to list them\n", HPM->plugin_count);
}
@@ -342,9 +365,9 @@ CPCMD(plugins) {
ShowInfo("HPC: there are no plugins loaded\n");
} else {
unsigned int i;
-
+
ShowInfo("HPC: There are '"CL_WHITE"%d"CL_RESET"' plugins loaded\n",HPM->plugin_count);
-
+
for(i = 0; i < HPM->plugin_count; i++) {
ShowInfo("HPC: - '"CL_WHITE"%s"CL_RESET"' (%s)\n",HPM->plugins[i]->info->name,HPM->plugins[i]->filename);
}
@@ -377,18 +400,18 @@ void hplugins_addToHPData(enum HPluginDataTypes type, unsigned int pluginID, voi
struct HPluginData *HPData, **HPDataSRC;
struct HPDataOperationStorage action;
unsigned int i, max;
-
+
HPM->grabHPData(&action,type,ptr);
if( action.hdatac == NULL ) { /* woo it failed! */
ShowError("HPM:addToHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index);
return;
}
-
+
/* flag */
HPDataSRC = *(action.HPDataSRCPtr);
max = *(action.hdatac);
-
+
/* duplicate check */
for(i = 0; i < max; i++) {
if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index ) {
@@ -396,20 +419,20 @@ void hplugins_addToHPData(enum HPluginDataTypes type, unsigned int pluginID, voi
return;
}
}
-
+
/* HPluginData is always same size, probably better to use the ERS (with reasonable chunk size e.g. 10/25/50) */
CREATE(HPData, struct HPluginData, 1);
-
+
/* input */
HPData->pluginID = pluginID;
HPData->type = index;
HPData->flag.free = autofree ? 1 : 0;
HPData->data = data;
-
+
/* resize */
*(action.hdatac) += 1;
RECREATE(*(action.HPDataSRCPtr),struct HPluginData *,*(action.hdatac));
-
+
/* RECREATE modified the address */
HPDataSRC = *(action.HPDataSRCPtr);
HPDataSRC[*(action.hdatac) - 1] = HPData;
@@ -419,23 +442,23 @@ void *hplugins_getFromHPData(enum HPluginDataTypes type, unsigned int pluginID,
struct HPDataOperationStorage action;
struct HPluginData **HPDataSRC;
unsigned int i, max;
-
+
HPM->grabHPData(&action,type,ptr);
-
+
if( action.hdatac == NULL ) { /* woo it failed! */
ShowError("HPM:getFromHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index);
return NULL;
}
-
+
/* flag */
HPDataSRC = *(action.HPDataSRCPtr);
max = *(action.hdatac);
-
+
for(i = 0; i < max; i++) {
if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index )
return HPDataSRC[i]->data;
}
-
+
return NULL;
}
@@ -443,30 +466,30 @@ void hplugins_removeFromHPData(enum HPluginDataTypes type, unsigned int pluginID
struct HPDataOperationStorage action;
struct HPluginData **HPDataSRC;
unsigned int i, max;
-
+
HPM->grabHPData(&action,type,ptr);
-
+
if( action.hdatac == NULL ) { /* woo it failed! */
ShowError("HPM:removeFromHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index);
return;
}
-
+
/* flag */
HPDataSRC = *(action.HPDataSRCPtr);
max = *(action.hdatac);
-
+
for(i = 0; i < max; i++) {
if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index )
break;
}
-
+
if( i != max ) {
unsigned int cursor;
-
+
aFree(HPDataSRC[i]->data);/* when its removed we delete it regardless of autofree */
aFree(HPDataSRC[i]);
HPDataSRC[i] = NULL;
-
+
for(i = 0, cursor = 0; i < max; i++) {
if( HPDataSRC[i] == NULL )
continue;
@@ -476,13 +499,12 @@ void hplugins_removeFromHPData(enum HPluginDataTypes type, unsigned int pluginID
}
*(action.hdatac) = cursor;
}
-
}
bool hplugins_addpacket(unsigned short cmd, short length,void (*receive) (int fd),unsigned int point,unsigned int pluginID) {
struct HPluginPacket *packet;
unsigned int i;
-
+
if( point >= hpPHP_MAX ) {
ShowError("HPM->addPacket:%s: unknown point '%u' specified for packet 0x%04x (len %d)\n",HPM->pid2name(pluginID),point,cmd,length);
return false;
@@ -494,15 +516,15 @@ bool hplugins_addpacket(unsigned short cmd, short length,void (*receive) (int fd
return false;
}
}
-
+
RECREATE(HPM->packets[point], struct HPluginPacket, ++HPM->packetsc[point]);
packet = &HPM->packets[point][HPM->packetsc[point] - 1];
-
+
packet->pluginID = pluginID;
packet->cmd = cmd;
packet->len = length;
packet->receive = receive;
-
+
return true;
}
/*
@@ -512,52 +534,52 @@ bool hplugins_addpacket(unsigned short cmd, short length,void (*receive) (int fd
*/
unsigned char hplugins_parse_packets(int fd, enum HPluginPacketHookingPoints point) {
unsigned int i;
-
+
for(i = 0; i < HPM->packetsc[point]; i++) {
if( HPM->packets[point][i].cmd == RFIFOW(fd,0) )
break;
}
-
+
if( i != HPM->packetsc[point] ) {
struct HPluginPacket *packet = &HPM->packets[point][i];
short length;
-
+
if( (length = packet->len) == -1 ) {
if( (length = RFIFOW(fd, 2)) > (int)RFIFOREST(fd) )
- return 2;
+ return 2;
}
-
+
packet->receive(fd);
RFIFOSKIP(fd, length);
return 1;
}
-
+
return 0;
}
char *hplugins_id2name (unsigned int pid) {
unsigned int i;
-
+
for( i = 0; i < HPM->plugin_count; i++ ) {
if( HPM->plugins[i]->idx == pid )
return HPM->plugins[i]->info->name;
}
-
+
return "UnknownPlugin";
}
char* HPM_file2ptr(const char *file) {
unsigned int i;
-
+
for(i = 0; i < HPM->fnamec; i++) {
if( HPM->fnames[i].addr == file )
return HPM->fnames[i].name;
}
-
+
i = HPM->fnamec;
-
+
/* we handle this memory outside of the server's memory manager because we need it to exist after the memory manager goes down */
HPM->fnames = realloc(HPM->fnames,(++HPM->fnamec)*sizeof(struct HPMFileNameCache));
-
+
HPM->fnames[i].addr = file;
HPM->fnames[i].name = strdup(file);
@@ -588,9 +610,9 @@ bool HPM_AddHook(enum HPluginHookType type, const char *target, void *hook, unsi
/* if not check if a sub-hooking list is available (from the server) and run it by */
if( HPM->addhook_sub && HPM->addhook_sub(type,target,hook,pID) )
return true;
-
+
ShowError("HPM:AddHook: unknown Hooking Point '%s'!\n",target);
-
+
return false;
}
void HPM_HookStop (const char *func, unsigned int pID) {
@@ -609,85 +631,135 @@ bool hpm_parse_arg(const char *arg, int *index, char *argv[], bool param) {
if( data->has_param && param ) *index += 1;
return true;
}
-
+
return false;
}
void hpm_arg_help(void) {
DBIterator *iter = db_iterator(HPM->arg_db);
struct HPMArgData *data = NULL;
-
+
for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) ) {
if( data->help != NULL )
data->help();
else
ShowInfo(" %s (%s)\t\t<no description provided>\n",data->name,HPM->pid2name(data->pluginID));
}
-
+
dbi_destroy(iter);
}
bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, void (*func) (char *param),void (*help) (void)) {
struct HPMArgData *data = NULL;
-
+
if( strdb_exists(HPM->arg_db, name) ) {
ShowError("HPM:add_arg:%s duplicate! (from %s)\n",name,HPM->pid2name(pluginID));
return false;
}
-
+
CREATE(data, struct HPMArgData, 1);
-
+
data->pluginID = pluginID;
data->name = aStrdup(name);
data->func = func;
data->help = help;
data->has_param = has_param;
-
+
strdb_put(HPM->arg_db, data->name, data);
-
+
return true;
}
bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)) {
struct HPConfListenStorage *conf;
unsigned int i;
-
+
if( type >= HPCT_MAX ) {
ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name);
return false;
}
-
+
for(i = 0; i < HPM->confsc[type]; i++) {
if( !strcmpi(name,HPM->confs[type][i].key) ) {
ShowError("HPM->addConf:%s: duplicate '%s', already in use by '%s'!",HPM->pid2name(pluginID),name,HPM->pid2name(HPM->confs[type][i].pluginID));
return false;
}
}
-
+
RECREATE(HPM->confs[type], struct HPConfListenStorage, ++HPM->confsc[type]);
conf = &HPM->confs[type][HPM->confsc[type] - 1];
-
+
conf->pluginID = pluginID;
safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH);
conf->func = func;
-
+
return true;
}
bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType point) {
unsigned int i;
-
+
/* exists? */
for(i = 0; i < HPM->confsc[point]; i++) {
if( !strcmpi(w1,HPM->confs[point][i].key) )
break;
}
-
+
/* trigger and we're set! */
if( i != HPM->confsc[point] ) {
HPM->confs[point][i].func(w2);
return true;
}
-
+
return false;
}
+/**
+ * Called by HPM->DataCheck on a plugins incoming data, ensures data structs in use are matching!
+ **/
+bool HPM_DataCheck(struct s_HPMDataCheck *src, unsigned int size, int version, char *name) {
+ unsigned int i, j;
+
+ if (version != datacheck_version) {
+ ShowError("HPMDataCheck:%s: DataCheck API version mismatch %d != %d\n", name, datacheck_version, version);
+ return false;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (!(src[i].type|SERVER_TYPE))
+ continue;
+
+ if (!strdb_exists(datacheck_db, src[i].name)) {
+ ShowError("HPMDataCheck:%s: '%s' was not found\n",name,src[i].name);
+ return false;
+ } else {
+ j = strdb_uiget(datacheck_db, src[i].name);/* not double lookup; exists sets cache to found data */
+ if (src[i].size != datacheck_data[j].size) {
+ ShowWarning("HPMDataCheck:%s: '%s' size mismatch %u != %u\n",name,src[i].name,src[i].size,datacheck_data[j].size);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void HPM_datacheck_init(const struct s_HPMDataCheck *src, unsigned int length, int version) {
+ unsigned int i;
+
+ datacheck_version = version;
+ datacheck_data = src;
+
+ /**
+ * Populates datacheck_db for easy lookup later on
+ **/
+ datacheck_db = strdb_alloc(DB_OPT_BASE,0);
+
+ for(i = 0; i < length; i++) {
+ strdb_uiput(datacheck_db, src[i].name, i);
+ }
+}
+
+void HPM_datacheck_final(void) {
+ db_destroy(datacheck_db);
+}
+
void hplugins_share_defaults(void) {
/* console */
#ifdef CONSOLE_INPUT
@@ -729,12 +801,15 @@ void hplugins_share_defaults(void) {
void hpm_init(void) {
unsigned int i;
-
+ datacheck_db = NULL;
+ datacheck_data = NULL;
+ datacheck_version = 0;
+
HPM->symbols = NULL;
HPM->plugins = NULL;
HPM->plugin_count = HPM->symbol_count = 0;
HPM->off = false;
-
+
memcpy(&iMalloc_HPM, iMalloc, sizeof(struct malloc_interface));
HPMiMalloc = &iMalloc_HPM;
HPMiMalloc->malloc = HPM_mmalloc;
@@ -744,21 +819,21 @@ void hpm_init(void) {
HPMiMalloc->astrdup = HPM_astrdup;
sscanf(HPM_VERSION, "%u.%u", &HPM->version[0], &HPM->version[1]);
-
+
if( HPM->version[0] == 0 && HPM->version[1] == 0 ) {
ShowError("HPM:init:failed to retrieve HPM version!!\n");
return;
}
-
+
for(i = 0; i < hpPHP_MAX; i++) {
HPM->packets[i] = NULL;
HPM->packetsc[i] = 0;
}
-
+
HPM->arg_db = strdb_alloc(DB_OPT_RELEASE_DATA, 0);
-
+
HPM->symbol_defaults();
-
+
#ifdef CONSOLE_INPUT
console->input->addCommand("plugins",CPCMD_A(plugins));
#endif
@@ -766,64 +841,63 @@ void hpm_init(void) {
}
void hpm_memdown(void) {
unsigned int i;
-
+
/* this memory is handled outside of the server's memory manager and thus cleared after memory manager goes down */
-
+
for( i = 0; i < HPM->fnamec; i++ ) {
free(HPM->fnames[i].name);
}
-
+
if( HPM->fnames )
free(HPM->fnames);
-
}
int hpm_arg_db_clear_sub(DBKey key, DBData *data, va_list args) {
struct HPMArgData *a = DB->data2ptr(data);
-
+
aFree(a->name);
-
+
return 0;
}
void hpm_final(void) {
unsigned int i;
-
+
HPM->off = true;
-
+
for( i = 0; i < HPM->plugin_count; i++ ) {
HPM->unload(HPM->plugins[i]);
}
-
+
if( HPM->plugins )
aFree(HPM->plugins);
-
+
for( i = 0; i < HPM->symbol_count; i++ ) {
aFree(HPM->symbols[i]);
}
-
+
if( HPM->symbols )
aFree(HPM->symbols);
-
+
for( i = 0; i < hpPHP_MAX; i++ ) {
if( HPM->packets[i] )
aFree(HPM->packets[i]);
}
-
+
for( i = 0; i < HPCT_MAX; i++ ) {
if( HPM->confsc[i] )
aFree(HPM->confs[i]);
}
-
+
HPM->arg_db->destroy(HPM->arg_db,HPM->arg_db_clear_sub);
-
+
/* HPM->fnames is cleared after the memory manager goes down */
iMalloc->post_shutdown = hpm_memdown;
-
+
return;
}
void hpm_defaults(void) {
unsigned int i;
HPM = &HPM_s;
-
+
HPM->fnames = NULL;
HPM->fnamec = 0;
HPM->force_return = false;
@@ -843,7 +917,7 @@ void hpm_defaults(void) {
/* */
HPM->init = hpm_init;
HPM->final = hpm_final;
-
+
HPM->create = hplugin_create;
HPM->load = hplugin_load;
HPM->unload = hplugin_unload;
@@ -866,5 +940,7 @@ void hpm_defaults(void) {
HPM->grabHPData = hplugins_grabHPData;
HPM->grabHPDataSub = NULL;
HPM->parseConf = hplugins_parse_conf;
- HPM->DataCheck = NULL;
+ HPM->DataCheck = HPM_DataCheck;
+ HPM->datacheck_init = HPM_datacheck_init;
+ HPM->datacheck_final = HPM_datacheck_final;
}