[NeoStats-Devel] [Commits] r2647 - trunk/src

[email protected]
Newsgroups gmane.comp.neostats.devel
Message-ID <[email protected]>
Author: Fish
Date: Thu Jul  7 20:57:08 2005
New Revision: 2647

Modified:
   trunk/src/conf.c
   trunk/src/dns.c
   trunk/src/ircprotocol.c
   trunk/src/main.c
   trunk/src/modules.c
   trunk/src/nsdba.c
   trunk/src/perl.c
   trunk/src/services.c
Log:
perl modules are now just like real modules internally

Modified: trunk/src/conf.c
==============================================================================
--- trunk/src/conf.c	(original)
+++ trunk/src/conf.c	Thu Jul  7 20:57:08 2005
@@ -30,7 +30,8 @@
 #include "log.h"
 #include "services.h"
 #include "modules.h"
-
+#include "dl.h"
+#include "perlmod.h"
 #define CONFIG_NAME		"neostats.conf"
 
 
@@ -296,7 +297,7 @@
 		nlog (LOG_NORMAL, "Loading configured modules");
 		for (i = 0; (i < NUM_MODULES) && (load_mods[i] != 0); i++) {
 			dlog (DEBUG1, "ConfLoadModules: Loading Module %s", (char *) load_mods[i]);
-			if (load_module (load_mods[i], NULL)) {
+			if (ns_load_module (load_mods[i], NULL)) {
 				nlog (LOG_NORMAL, "Loaded module %s", (char *) load_mods[i]);
 			} else {
 				nlog (LOG_WARNING, "Failed to load module %s. Please check above error messages", (char *) load_mods[i]);
@@ -370,10 +371,13 @@
 	char *file = opt->values[0]->string;
 	char buf2[MAXPATH];
 	struct stat buf;
-	ircsnprintf(buf2, MAXPATH, "%s/%s.so", MOD_PATH, file);
+	ircsnprintf(buf2, MAXPATH, "%s/%s%s", MOD_PATH, file, MOD_STDEXT);
 	if (stat(buf2, &buf) == -1) {
-		cfg_error(cfg, "File %s Specified in Option %s is Invalid: %s", buf2, opt->name, strerror(errno));
-		return CFG_PARSE_ERROR;
+		ircsnprintf(buf2, MAXPATH, "%s/%s%s", MOD_PATH, file, MOD_PERLEXT);
+		if (stat(buf2, &buf) == -1) {
+			cfg_error(cfg, "File %s Specified in Option %s is Invalid: %s", buf2, opt->name, strerror(errno));
+			return CFG_PARSE_ERROR;
+		}
 	}
 	if (!S_ISREG(buf.st_mode)) {
 		cfg_error(cfg, "File %s Specified in Option %s is Invalid: Not a Regular File", buf2, opt->name);

Modified: trunk/src/dns.c
==============================================================================
--- trunk/src/dns.c	(original)
+++ trunk/src/dns.c	Thu Jul  7 20:57:08 2005
@@ -237,6 +237,7 @@
 		adns_cancel(dnsdata->q);
 		ns_free (dnsdata->a);
 		ns_free (dnsdata);
+		dnsnode = list_next(dnslist, dnsnode);
 	}
 	list_destroy_nodes (dnslist);
 	list_destroy (dnslist);
@@ -244,6 +245,7 @@
 	while (dnsnode) {
 		dnsdata = lnode_get(dnsnode);
 		ns_free(dnsdata);
+		dnsnode = list_next(dnsqueue, dnsnode);
 	}
 	list_destroy_nodes (dnsqueue);
 	list_destroy (dnsqueue);
@@ -275,6 +277,7 @@
 			lnode_destroy(dnsnode);
 			dnsnode = lnode2;
 		}
+		dnsnode = list_next(dnslist, dnsnode);
 	}
 	dnsnode = list_first(dnsqueue);
 	while (dnsnode) {
@@ -286,6 +289,7 @@
 			lnode_destroy(dnsnode);
 			dnsnode = lnode2;
 		}
+		dnsnode = list_next(dnsqueue, dnsnode);
 	}
 	dns_check_queue();
 }

Modified: trunk/src/ircprotocol.c
==============================================================================
--- trunk/src/ircprotocol.c	(original)
+++ trunk/src/ircprotocol.c	Thu Jul  7 20:57:08 2005
@@ -312,7 +312,7 @@
 	/* Clear IRCD info */
 	os_memset( &ircd_srv, 0, sizeof( ircd_srv ) );
 	/* Open protocol module */
-	ircsnprintf( protocol_path, 255, "%s/%s%s", MOD_PATH, me.protocol,MOD_EXT );
+	ircsnprintf( protocol_path, 255, "%s/%s%s", MOD_PATH, me.protocol,MOD_STDEXT );
 	nlog( LOG_NORMAL, "Using protocol module %s", protocol_path );
 	protocol_module_handle = ns_dlopen( protocol_path, RTLD_NOW || RTLD_GLOBAL );
 	if( !protocol_module_handle ) {

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Thu Jul  7 20:57:08 2005
@@ -263,7 +263,6 @@
 
 void FiniCore( void )
 {
-	FiniPerl();
 	FiniDCC();
 	FiniCurl();
 	FiniUsers();

Modified: trunk/src/modules.c
==============================================================================
--- trunk/src/modules.c	(original)
+++ trunk/src/modules.c	Thu Jul  7 20:57:08 2005
@@ -37,6 +37,8 @@
 #include "servers.h"
 #include "exclude.h"
 #ifdef USE_PERL
+#undef _
+#define PERLDEFINES
 #include "perlmod.h"
 #endif
 
@@ -49,6 +51,8 @@
 unsigned int fusermoddata = 0;
 unsigned int fservermoddata = 0;
 unsigned int fchannelmoddata = 0;
+Module *load_stdmodule (const char *modfilename, Client * u);
+
 
 /* @brief Module hash list */
 static hash_t *modulehash;
@@ -89,18 +93,25 @@
 	int err = NS_SUCCESS; /*FAILURE;*/
 	int (*ModSynch) (void);
 
-	module_ptr->insynch = 1;
-	ModSynch = ns_dlsym ((int *) module_ptr->handle, "ModSynch");
-	if (ModSynch) {
-		SET_RUN_LEVEL(module_ptr);
-		err = (*ModSynch) (); 
-		RESET_RUN_LEVEL();
+#ifdef USE_PERL	
+	/* only standard modules get a sync */
+	if (IS_STD_MOD(module_ptr)) {
+#endif
+		module_ptr->insynch = 1;
+		ModSynch = ns_dlsym ((int *) module_ptr->handle, "ModSynch");
+		if (ModSynch) {
+			SET_RUN_LEVEL(module_ptr);
+			err = (*ModSynch) (); 
+			RESET_RUN_LEVEL();
+		}
+		SET_SEGV_LOCATION();
+		module_ptr->synched = 1;
+#ifdef USE_PERL
 	}
-	SET_SEGV_LOCATION();
-	module_ptr->synched = 1;
+#endif
 	return err;
 }
-
+	
 /** @brief SynchModule 
  *
  * 
@@ -229,7 +240,7 @@
  * @return none
  */
 
-static void load_module_error(const Client *target, const char *fmt, ...)
+void load_module_error(const Client *target, const char *fmt, ...)
 {
 	static char buf[BUFSIZE];
 	va_list ap;
@@ -243,6 +254,31 @@
 	nlog (LOG_WARNING, buf);
 }
 
+/** @brief determine the type of module based on extension and then
+ * call the relevent procedure to load it
+ */
+Module *
+ns_load_module(const char *modfilename, Client * u)
+{ 
+	char path[255];
+	char loadmodname[255];
+	struct stat buf;
+
+	strlcpy (loadmodname, modfilename, 255);
+	strlwr (loadmodname);
+	ircsnprintf (path, 255, "%s/%s%s", MOD_PATH, loadmodname, MOD_STDEXT);
+	if (stat(path, &buf) != -1) {
+		return load_stdmodule(path, u);
+	}
+	ircsnprintf (path, 255, "%s/%s%s", MOD_PATH, loadmodname, MOD_PERLEXT);
+	if (stat(path, &buf) != -1) {
+		return load_perlmodule(path, u);
+	}
+	/* if we get here, ehhh, doesn't exist */
+	load_module_error (u, __("Unable to load module: %s", u), modfilename);
+	return NULL;
+
+}
 /** @brief 
  *
  * @param 
@@ -250,35 +286,30 @@
  * @return
  */
 Module *
-load_module (const char *modfilename, Client * u)
+load_stdmodule (const char *modfilename, Client * u)
 {
 	int err;
 	void *handle;
-	char path[255];
-	char loadmodname[255];
 	int moduleindex = 0;
 	ModuleInfo *infoptr = NULL;
 	ModuleEvent *eventlistptr = NULL;
 	Module *mod_ptr = NULL;
 	int (*ModInit) (void);
-	CmdParams *cmdparams;
+	CmdParams *cmd;
 
 	SET_SEGV_LOCATION();
 	if (hash_isfull (modulehash)) {
 		load_module_error (u, __("Unable to load module: module list is full", u));
 		return NULL;
 	} 
-	strlcpy (loadmodname, modfilename, 255);
-	strlwr (loadmodname);
-	ircsnprintf (path, 255, "%s/%s%s", MOD_PATH, loadmodname, MOD_EXT);
-	handle = ns_dlopen (path, RTLD_NOW || RTLD_GLOBAL);
+	handle = ns_dlopen (modfilename, RTLD_NOW || RTLD_GLOBAL);
 	if (!handle) {
-		load_module_error (u, __("Unable to load module: %s %s", u), ns_dlerrormsg, path);
+		load_module_error (u, __("Unable to load module: %s %s", u), ns_dlerrormsg, modfilename);
 		return NULL;
 	}
 	infoptr = ns_dlsym (handle, "module_info");
 	if(infoptr == NULL) {
-		load_module_error (u, __("Unable to load module: %s missing module_info", u), path);
+		load_module_error (u, __("Unable to load module: %s missing module_info", u), modfilename);
 		ns_dlclose (handle);
 		return NULL;
 	}
@@ -319,12 +350,14 @@
 	}
 	/* Allocate module */
 	mod_ptr = (Module *) ns_calloc (sizeof (Module));
-	hnode_create_insert (modulehash, mod_ptr, infoptr->name);
 	dlog(DEBUG1, "Module internal name: %s", infoptr->name);
 	dlog(DEBUG1, "Module description: %s", infoptr->description);
 	mod_ptr->info = infoptr;
 	mod_ptr->handle = handle;
+	insert_module(mod_ptr);
+#ifdef USE_PERL
 	mod_ptr->modtype = MOD_STANDARD;
+#endif
 	/* Extract pointer to event list */
 	eventlistptr = ns_dlsym (handle, "module_events");
 	if(eventlistptr) {
@@ -346,10 +379,7 @@
 		mod_ptr->authcb = ns_dlsym ((int *) handle, "ModAuthUser");
 	}
 	/* assign a module number to this module */
-	while (ModList[moduleindex] != NULL)
-		moduleindex++;
-	ModList[moduleindex] = mod_ptr;
-	mod_ptr->modnum = moduleindex;
+	assign_mod_number(mod_ptr);
 	dlog(DEBUG1, "Assigned %d to module %s for modulenum", moduleindex, mod_ptr->info->name);
 
 	SET_SEGV_LOCATION();
@@ -377,16 +407,46 @@
 			return NULL;
 		}
 	}
-	cmdparams = ns_calloc (sizeof(CmdParams));
-	cmdparams->param = (char*)infoptr->name;
-	SendAllModuleEvent(EVENT_MODULELOAD, cmdparams);
-	ns_free(cmdparams);
+	cmd = ns_calloc (sizeof(CmdParams));
+	cmd->param = (char*)infoptr->name;
+	SendAllModuleEvent(EVENT_MODULELOAD, cmd);
+	ns_free(cmd);
 	if (u) {
 		irc_prefmsg (ns_botptr, u, __("Module %s loaded, %s",u), infoptr->name, infoptr->description);
 		irc_globops (NULL, _("Module %s loaded"), infoptr->name);
 	}
 	return mod_ptr;
 }
+/** @brief generate module number and assign it
+ *
+ * @param mod_ptr module pointer 
+ *
+ * @return Nothing 
+ */
+
+void 
+assign_mod_number(Module *mod_ptr) {
+	int moduleindex = 0;
+
+	while (ModList[moduleindex] != NULL)
+		moduleindex++;
+	ModList[moduleindex] = mod_ptr;
+	mod_ptr->modnum = moduleindex;
+}
+
+/** @brief insert module pointer into module hash. 
+ *
+ * @param mod_ptr module pointer 
+ *
+ * @return Nothing 
+ */
+
+void 
+insert_module(Module *mod_ptr) {
+	hnode_create_insert (modulehash, mod_ptr, mod_ptr->info->name);
+}
+
+
 
 /** @brief 
  *
@@ -408,9 +468,6 @@
 		irc_prefmsg (ns_botptr, cmdparams->source, __("Module: %d %s (%s)", cmdparams->source), mod_ptr->modnum, mod_ptr->info->name, mod_ptr->info->version);
 		irc_prefmsg (ns_botptr, cmdparams->source, "      : %s", mod_ptr->info->description);
 	}
-#ifdef USE_PERL
-		ns_cmd_modperlist(cmdparams);
-#endif
 	irc_prefmsg (ns_botptr, cmdparams->source, __("End of Module List", cmdparams->source));
 	return 0;
 }
@@ -463,13 +520,19 @@
 	 */
 	dlog(DEBUG1, "Deleting Module %s from Hash", modname);
 	hash_delete (modulehash, modnode);		
-	/* call ModFini (replacement for library __fini() call */
-	ModFini = ns_dlsym ((int *) mod_ptr->handle, "ModFini");
-	if (ModFini) {
-		SET_RUN_LEVEL(mod_ptr);
-		(*ModFini) ();
-		RESET_RUN_LEVEL();
-		SET_SEGV_LOCATION();
+
+	/* now determine if its perl, or standard module */
+	if (IS_STD_MOD(mod_ptr)) {
+		/* call ModFini (replacement for library __fini() call */
+		ModFini = ns_dlsym ((int *) mod_ptr->handle, "ModFini");
+		if (ModFini) {
+			SET_RUN_LEVEL(mod_ptr);
+			(*ModFini) ();
+			RESET_RUN_LEVEL();
+			SET_SEGV_LOCATION();
+		}
+	} else {
+		PerlModFini(mod_ptr);
 	}
 	/* Delete any bots used by this module. Done after ModFini, so the bot 
 	 * can still send messages during ModFini 
@@ -491,7 +554,11 @@
 #ifndef VALGRIND
 	SET_RUN_LEVEL(mod_ptr);
 	DBACloseDatabase ();
-	ns_dlclose (mod_ptr->handle);
+	if (IS_STD_MOD(mod_ptr)) {
+		ns_dlclose (mod_ptr->handle);
+	} else {
+		unload_perlmod(mod_ptr);
+	}
 	RESET_RUN_LEVEL();
 #endif
 	ns_free (mod_ptr);

Modified: trunk/src/nsdba.c
==============================================================================
--- trunk/src/nsdba.c	(original)
+++ trunk/src/nsdba.c	Thu Jul  7 20:57:08 2005
@@ -81,7 +81,7 @@
 	void *dbm_module_handle;
 	dbm_sym *pdbm_sym;
 
-	ircsnprintf( dbm_path, 255, "%s/%s%s", MOD_PATH, me.dbm, MOD_EXT );
+	ircsnprintf( dbm_path, 255, "%s/%s%s", MOD_PATH, me.dbm, MOD_STDEXT );
 	nlog( LOG_NORMAL, "Using dbm module %s", dbm_path );
 	dbm_module_handle = ns_dlopen( dbm_path, RTLD_NOW || RTLD_GLOBAL );
 	if( !dbm_module_handle ) {
@@ -197,19 +197,21 @@
 
 	dlog( DEBUG1, "DBACloseDatabase %s", GET_CUR_MODNAME() );
 	node = hash_lookup( dbhash, GET_CUR_MODNAME() );
-	dbe = ( dbentry* )hnode_get( node );
-	hash_scan_begin( &ts, dbe->tablehash );
-	while(( tnode = hash_scan_next( &ts ) ) != NULL  ) {
-		tbe = (tableentry *) hnode_get( tnode );
-		DBACloseTable( tbe->table );
-		hash_delete( dbe->tablehash, tnode );
-		hnode_destroy( tnode );
-		ns_free( tbe );
+	if (node) {
+		dbe = ( dbentry* )hnode_get( node );
+		hash_scan_begin( &ts, dbe->tablehash );
+		while(( tnode = hash_scan_next( &ts ) ) != NULL  ) {
+			tbe = (tableentry *) hnode_get( tnode );
+			DBACloseTable( tbe->table );
+			hash_delete( dbe->tablehash, tnode );
+			hnode_destroy( tnode );
+			ns_free( tbe );
+		}
+		hash_destroy( dbe->tablehash );
+		hash_delete( dbhash, node );
+		hnode_destroy( node );
+		ns_free( dbe );
 	}
-	hash_destroy( dbe->tablehash );
-	hash_delete( dbhash, node );
-	hnode_destroy( node );
-	ns_free( dbe );
 	return NS_SUCCESS;
 }
 

Modified: trunk/src/perl.c
==============================================================================
--- trunk/src/perl.c	(original)
+++ trunk/src/perl.c	Thu Jul  7 20:57:08 2005
@@ -27,12 +27,14 @@
 
 #include "neostats.h"
 #include "services.h"
+#include "modules.h"
 #undef _
+#define PERLDEFINES
+#include "perlmod.h"
 #include <sys/types.h>
 #include <dirent.h>
 
-static int perl_load_file (char *script_name);
-static void free_perlmod(Module *mod);
+extern void boot_DynaLoader (pTHX_ CV * cv);
 
 
 
@@ -58,52 +60,14 @@
 
 #endif
 
-/* leave this before XSUB.h, to avoid readdir() being redefined */
-static void
-perl_auto_load (void)
-{
-	DIR *dir;
-	struct dirent *ent;
-
-	dir = opendir ("modules");
-	if (dir) {
-		while ((ent = readdir (dir))) {
-			int len = strlen (ent->d_name);
-			if (len > 3 && strcasecmp (".pl", ent->d_name + len - 3) == 0) {
-				char *file = malloc (len + strlen ("modules") + 2);
-				sprintf (file, "modules/%s", ent->d_name);
-				dlog(DEBUG2, "Loading Perl Module %s", file);
-				perl_load_file (file);
-				free (file);
-			}
-		}
-		closedir (dir);
-	}
-}
-
-#include <EXTERN.h>
-#define WIN32IOP_H
-#include <perl.h>
-#include <XSUB.h>
-
-
-
-list_t *perlmods;
 
-typedef struct {
-	char filename[MAXPATH];
-	Module *mod;
-	PerlInterpreter *my_perl;
-} PerlModInfo;
-
-extern void boot_DynaLoader (pTHX_ CV * cv);
 
 
 /*
   this is used for autoload and shutdown callbacks
 */
 static int
-execute_perl (PerlModInfo *pm, SV * function, char *args)
+execute_perl (Module *mod, SV * function, char *args)
 {
 
 	int count, ret_value = 1;
@@ -112,8 +76,9 @@
 	dSP;
 	ENTER;
 	SAVETMPS;
-	SET_RUN_LEVEL(pm->mod);
-	PERL_SET_CONTEXT(pm->my_perl);
+
+	SET_RUN_LEVEL(mod);
+	PERL_SET_CONTEXT((PMI *)mod->pm->my_perl);
 
 	PUSHMARK (SP);
 	XPUSHs (sv_2mortal (newSVpv (args, 0)));
@@ -775,24 +740,19 @@
 int
 Init_Perl (void)
 {
-	/* create the perl modules list */
-	perlmods = list_create(-1);
 
-	/* now load the modules */
-	perl_auto_load();
 	return NS_SUCCESS;
 }
 
 
-static int
-perl_load_file (char *filename)
+Module *load_perlmodule (const char *filename, Client *u)
 {
 	char *perl_args[] = { "", "-e", "0", "-w" };
+	CmdParams *cmd;
 	const char perl_definitions[] = {
 #include "neostats.pm.h"
 	};
-	PerlModInfo *pm;
-	lnode_t *node;
+	Module *mod;
 	
 	
 
@@ -807,85 +767,78 @@
 							 "run perl scripts.\n\n"
 							 "http://www.activestate.com/ActivePerl/\n\n"
 							 "Make sure perl's bin directory is in your PATH.");
-			return FALSE;
+			return NULL;
 		}
 		FreeLibrary (lib);
 	}
 #endif
 
-	pm = os_malloc(sizeof(PerlModInfo));
-	pm->mod = os_malloc(sizeof(Module));
-	pm->mod->info = os_malloc(sizeof(ModuleInfo));
-	pm->mod->modtype = MOD_PERL;
- 	pm->mod->info->name = NULL;
-	strlcpy(pm->filename, filename, MAXPATH);
-	pm->my_perl = perl_alloc ();
+	mod = ns_calloc(sizeof(Module));
+	mod->pm = ns_calloc(sizeof(PerlModInfo));
+	mod->info = ns_calloc(sizeof(ModuleInfo));
+	mod->modtype = MOD_PERL;
+ 	mod->info->name = NULL;
+	strlcpy(mod->pm->filename, filename, MAXPATH);
+	mod->pm->my_perl = perl_alloc ();
 	PL_perl_destruct_level = 1;
-	perl_construct (pm->my_perl);
+	perl_construct (mod->pm->my_perl);
 
-	perl_parse (pm->my_perl, xs_init, 4, perl_args, NULL);
+	perl_parse (mod->pm->my_perl, xs_init, 4, perl_args, NULL);
 	/*
 	   Now initialising the perl interpreter by loading the
 	   perl_definition array.
 	 */
 	eval_pv (perl_definitions, TRUE);
-	if (!execute_perl (pm, sv_2mortal (newSVpv ("NeoStats::Embed::load", 0)),
-								filename)) {
+	mod->insynch = 1;
+	if (!execute_perl (mod, sv_2mortal (newSVpv ("NeoStats::Embed::load", 0)),
+								(char *)filename)) {
 		/* XXX if we are here, check that pm->mod->info has something, otherwise the script didnt register */
-		if (!pm->mod->info->name[0]) {
-			nlog(LOG_WARNING, "Perl Module %s didn't register. Unloading", filename);	
-			perl_destruct (pm->my_perl);
-			perl_free (pm->my_perl);
-			free_perlmod(pm->mod);
-			free(pm);
-			return NS_FAILURE;
+		if (!mod->info->name[0]) {
+			load_module_error(u, __("Perl Module %s didn't register. Unloading", u), filename);
+			unload_perlmod(mod);
+			free(mod);
+			return NULL;
 		}		
 		/* it loaded ok */
-		nlog(LOG_NORMAL, "Loaded Perl Module %s (%s)", pm->mod->info->name, pm->mod->info->version);
+		mod->synched = 1;
 	} else {
-		nlog(LOG_WARNING, "Errors in Perl Module %s", filename);
-		perl_destruct (pm->my_perl);
-		perl_free (pm->my_perl);
-		free_perlmod(pm->mod);
-		free(pm);
-		return NS_FAILURE;	
+		load_module_error(u, __("Errors in Perl Module %s", u), filename);
+		unload_perlmod(mod);
+		free(mod);
+		return NULL;	
 	}
-	node = lnode_create(pm);
-	list_append(perlmods, node);
-	return NS_SUCCESS;
-}
+	assign_mod_number(mod);
 
-void
-FiniPerl (void)
-{
-	lnode_t *node;
-	PerlModInfo *pm;
-	node = list_first(perlmods);
-	while (node != NULL) {
-		pm = lnode_get(node);
-		execute_perl (pm, sv_2mortal (newSVpv ("NeoStats::Embed::unload", 0)), pm->filename);
-		perl_destruct (pm->my_perl);
-		perl_free (pm->my_perl);
-		free_perlmod(pm->mod);
-		free(pm);
-		node = list_next(perlmods, node);
-	}
+	insert_module(mod);
+
+	cmd = ns_calloc (sizeof(CmdParams));
+	cmd->param = (char*)mod->info->name;
+	SendAllModuleEvent(EVENT_MODULELOAD, cmd);
+	ns_free(cmd);
+
+	nlog(LOG_NORMAL, "Loaded Perl Module %s (%s)", mod->info->name, mod->info->version);
+         if (u) {
+	         irc_prefmsg (ns_botptr, u, __("Perl Module %s loaded, %s",u), mod->info->name, mod->info->description);
+                  irc_globops (NULL, _("Perl Module %s loaded"), mod->info->name);
+         }
+	return mod;
 }
 
-void ns_cmd_modperlist(CmdParams *cmd) {
-	lnode_t *node;
-	PerlModInfo *pm;
-	node = list_first(perlmods);
-	while (node != NULL) {
-		pm = lnode_get(node);
-		irc_prefmsg(ns_botptr, cmd->source,__("Perl Module: %s (%s)", cmd->source), pm->mod->info->name, pm->mod->info->version);
-		irc_prefmsg(ns_botptr, cmd->source,"      : %s", pm->mod->info->description);
-		node = list_next(perlmods, node);
-	}
+void PerlModFini(Module *mod) {
+		SET_RUN_LEVEL(mod);
+		if (mod->synched == 1) {
+			/* only execute unload if synced */
+			execute_perl (mod, sv_2mortal (newSVpv ("NeoStats::Embed::unload", 0)), mod->pm->filename);
+		}
+		RESET_RUN_LEVEL();
 }
 
+void unload_perlmod(Module *mod) {
+
+		perl_destruct ((PMI *)mod->pm->my_perl);
+
+		perl_free ((PMI *)mod->pm->my_perl);
 
-static void free_perlmod(Module *mod) {
 		free((void *)mod->info->name);
 
 		free((void *)mod->info->description);
@@ -893,7 +846,8 @@
 		free((void *)mod->info->version);
 
 		free(mod->info);
+		
+		free(mod->pm);
 
-		free(mod);
 
 }

Modified: trunk/src/services.c
==============================================================================
--- trunk/src/services.c	(original)
+++ trunk/src/services.c	Thu Jul  7 20:57:08 2005
@@ -441,7 +441,7 @@
 static int ns_cmd_load( CmdParams *cmdparams )
 {
 	SET_SEGV_LOCATION();
-	if( load_module( cmdparams->av[0], cmdparams->source ) ) {
+	if( ns_load_module( cmdparams->av[0], cmdparams->source ) ) {
 		irc_chanalert( ns_botptr, _( "%s loaded module %s" ), cmdparams->source->name, cmdparams->av[0] );
 	} else {
 		irc_chanalert( ns_botptr, _( "%s tried to load module %s, but load failed" ), cmdparams->source->name, cmdparams->av[0] );
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.