[cvslog] (2007-01-13 12:23:52 UTC) Module eggdrop1.9: Change committed!

cvslog cvs at tsss.org
Sat Jan 13 06:24:05 CST 2007


CVSROOT    : /usr/local/cvsroot
Module     : eggdrop1.9
Commit time: 2007-01-13 12:23:51 UTC
Commited by: sven

Modified files:
     Doxyfile lib/eggdrop/binds.c lib/eggdrop/botnet.c
     lib/eggdrop/module.c lib/eggdrop/module.h
     lib/eggdrop/partymember.c lib/eggdrop/partymember.h
     lib/eggdrop/script.c lib/eggdrop/sockbuf.c
     modules/dccparty/dccparty.c modules/dccparty/events.c
     modules/ircparty/events.c modules/ircparty/ircparty.c
     modules/oldbotnet/oldbotnet.c modules/proxy/proxy.c
     modules/pythonscript/mystdio.c
     modules/pythonscript/pythonscript.c modules/server/server.c
     modules/telnetparty/events.c modules/telnetparty/telnetparty.c
     src/terminal.c

Added files:
     doc/developer/doxy.h

Log message:

 * Added doxy.h for the doxygen main and related pages.
 * Fixed a bug in bind_rem_list.
 * Added a function to send text to a partymember with printf like formatting
 * Added a owner struct to partymembers so they can be deleted if their module
   is unloaded.
 * Unlinked the config vars of the server amd all partyline modules on unload.
 * All partymembers are deleted on bot shutdown or resart.

 * Reworked the way modules are unloaded:
   The module API has now two closeing functions, close() and unload(). close()
   is called by the module_unload function as it was before and should end all
   normal operation for the module. unload() is called by the main loop and
   should take care of terminating and freeing memory.
   This allows module to unload themself, ie a dcc partyline user unloading the
   dccparty module or a python script unloading the pythonscript module.

---------------------- diff included ----------------------
Index: eggdrop1.9/Doxyfile
diff -u eggdrop1.9/Doxyfile:1.2 eggdrop1.9/Doxyfile:1.3
--- eggdrop1.9/Doxyfile:1.2	Mon Nov 20 19:38:40 2006
+++ eggdrop1.9/Doxyfile	Sat Jan 13 06:23:39 2007
@@ -379,7 +379,7 @@
 # directories like "/usr/src/myproject". Separate the files or directories 
 # with spaces.
 
-INPUT                  = src lib/eggdrop modules
+INPUT                  = src lib/eggdrop modules doc/developer/doxy.h
 
 # If the value of the INPUT tag contains directories, you can use the 
 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
Index: eggdrop1.9/doc/developer/doxy.h
diff -u /dev/null eggdrop1.9/doc/developer/doxy.h:1.1
--- /dev/null	Sat Jan 13 06:23:51 2007
+++ eggdrop1.9/doc/developer/doxy.h	Sat Jan 13 06:23:39 2007
@@ -0,0 +1,116 @@
+/*
+ * This file exists for the sole purpose of containing Doxygen code. Don't read
+ * this, run doxygen and read the pretty html pages instead.
+ */
+
+/*!
+
+\mainpage Eggdrop 1.9
+Welcome to the source code documentation of eggdrop version 1.9! This
+documentation is intended for developers, \b not users.
+
+Please read the related pages, more to be added ...
+
+\page events How to use asyncronous events.
+
+\section client_data The client_data
+
+Every asyncrounous event in the eggdrop API has a pointer to void called
+client_data. This can be supplied at the time the event is registered and will
+be passed back every time the event is triggered. It is never used in any other
+way so it's save to small integers instead of a pointer as long as <b>no
+assumptions about the max values are made</b>. This value is usually stored
+inside a member of the related struct called \e client_data. Although it can be
+changed it should not because that'd be an ugly hack.
+
+\section owner The event owner
+
+Modules and scripts can register events too, but they can also be unloaded at
+any time. Because it'd be a real mess if every script and module had to keep
+a list of all its registered events there is a way to indicate who owns what
+useing the ::event_owner_t struct. Just like the client_data, it's supplied at
+the time the event is registered, stored in a member (called \e owner) and
+should not be changed. Events registered by the eggdrop core code don't have
+to supply an owner but they can in case there'll be a feature that displays
+some kind of information about events and their owners in the future. Modules
+however \b must pass an owner to the registering function. Failing to do so
+will result in a crash sooner or later! Every time a script or module is
+unloaded, all events whose owners match the unloaded script or module are
+deleted without calling any kind of event dependent cancel callback. The
+::event_owner_t's \link event_owner_t::on_delete on_delete \endlink callback
+however will be called when the event is deleted no matter why. The automatic
+event deletion happens after the module's \link egg_module_t::close_func close
+\endlink function is called, so the on_delete code might be called even after
+that.
+
+\section on_delete The on_delete callback.
+
+The \link event_owner_t::on_delete on_delete \endlink callback function is a
+member of the ::event_owner_t struct and will be called after the object the
+owner belongs to has been deleted. <b>This means the object itself no longer
+exists at the time of this call.</b> The callback function should free the
+memory allocated for the client_data and the owner struct. This should not be
+done anywhere else and nothing else should be done here! If neither the
+client_data nor the owner have been malloc'd nothing needs to be done and the
+on_delete pointer may be a NULL pointer so nothing will be called.
+
+The callback function takes two parameters: A pointer to an ::event_owner_t
+struct called \e owner and a pointer to void called \e client_data. The owner
+parameter is the same pointer that was passed to the function registering the
+event that was just deleted. If it's malloc'd memory it should be free'd here
+otherwise it can be ignored. The client_data parameter is the same pointer
+that was passed to the function registering the event.
+
+An example might look like this:
+\code
+static void on_delete(event_owner_t *owner, void *client_data)
+{
+	somestruct_t *mydata = client_data;
+
+	free(mydata->member1);
+	free(mydata->member2);
+	free(mydata);
+
+	free(owner); // only if it was malloc'd.
+}
+\endcode
+
+\subsection multipleevents Handleing multiple callbacks with the same client_data.
+
+Sometimes multiple events use the same pointer for their client_data. For
+example the ::partymember_t event handler and the partymember's
+::sockbuf_t event handler use the same client_data. This means that only
+one of those two on_delete callbacks can actually free the malloc'd data.
+Usually both of these objects will be deleted at the same time but one will be
+created before the other. The freeing of the memory should happen in the
+on_delete callback of the object that was created first while the other's
+callback should just delete the first object. Because the two callbacks do
+different things they cannot have the same owner object.
+
+An example might look like this:
+\code
+static void first_on_delete(event_owner_t *owner, void *client_data)
+{   
+	somestruct_t *mydata = client_data;
+
+	mydata->object1 = NULL;
+	if (mydata->object2) object2_delete(mydata->object2); // should not happen.
+
+	free(mydata->member1);
+	free(mydata->member2);
+	free(mydata);
+
+	free(owner); // only if it was malloc'd.
+}
+
+static void second_on_delete(event_owner_t *owner, void *client_data)
+{   
+	somestruct_t *mydata = client_data;
+
+	mydata->object2 = NULL;
+	if (mydata->object1) object1_delete(mydata->object1); // the avarage case.
+}
+\endcode
+
+*/
+
Index: eggdrop1.9/lib/eggdrop/binds.c
diff -u eggdrop1.9/lib/eggdrop/binds.c:1.29 eggdrop1.9/lib/eggdrop/binds.c:1.30
--- eggdrop1.9/lib/eggdrop/binds.c:1.29	Mon Oct  2 23:02:12 2006
+++ eggdrop1.9/lib/eggdrop/binds.c	Sat Jan 13 06:23:39 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: binds.c,v 1.29 2006-10-03 04:02:12 sven Exp $";
+static const char rcsid[] = "$Id: binds.c,v 1.30 2007-01-13 12:23:39 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -491,8 +491,8 @@
 	table = bind_table_lookup(table_name);
 	if (!table) return;
 
-	for (; cmds->mask; cmds++) {
-		snprintf(name, sizeof(name), "*%s:%s", table->name, cmds->mask);
+	for (; cmds->callback; cmds++) {
+		snprintf(name, sizeof(name), "*%s:%s", table->name, cmds->mask ? cmds->mask : "");
 		name[sizeof(name)-1] = 0;
 		bind_entry_del(table, cmds->mask, name, cmds->callback);
 	}
Index: eggdrop1.9/lib/eggdrop/botnet.c
diff -u eggdrop1.9/lib/eggdrop/botnet.c:1.4 eggdrop1.9/lib/eggdrop/botnet.c:1.5
--- eggdrop1.9/lib/eggdrop/botnet.c:1.4	Fri Dec 15 03:30:47 2006
+++ eggdrop1.9/lib/eggdrop/botnet.c	Sat Jan 13 06:23:39 2007
@@ -28,7 +28,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: botnet.c,v 1.4 2006-12-15 09:30:47 sven Exp $";
+static const char rcsid[] = "$Id: botnet.c,v 1.5 2007-01-13 12:23:39 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -352,7 +352,7 @@
 	snprintf(obuf, sizeof(obuf), "%s (%s)", reason, from->full_name);
 
 	if (bot->handler && bot->handler->on_lost_bot) bot->handler->on_lost_bot(bot->client_data, bot, obuf);
-	if (from->nick) partymember_msg(from, 0, _("Unlinked from %s."), bot->name);
+	if (from->nick) partymember_msgf(from, 0, _("Unlinked from %s."), bot->name);
 	botnet_delete(bot, reason);
 
 	return 0;
@@ -504,7 +504,7 @@
  * \param module The module whose bots should be deleted.
  * \param script The script whose bots should be deleted. NULL matches everything.
  *
- * \return The number of deleted bots. (Not counting recursive deletes.
+ * \return The number of deleted bots. (Not counting recursive deletes.)
  */
 
 int botnet_delete_by_owner(struct egg_module *module, void *script)
Index: eggdrop1.9/lib/eggdrop/module.c
diff -u eggdrop1.9/lib/eggdrop/module.c:1.12 eggdrop1.9/lib/eggdrop/module.c:1.13
--- eggdrop1.9/lib/eggdrop/module.c:1.12	Fri Dec  1 22:05:11 2006
+++ eggdrop1.9/lib/eggdrop/module.c	Sat Jan 13 06:23:39 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: module.c,v 1.12 2006-12-02 04:05:11 sven Exp $";
+static const char rcsid[] = "$Id: module.c,v 1.13 2007-01-13 12:23:39 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -26,20 +26,26 @@
 #include <unistd.h>
 
 typedef struct module_list {
+	struct module_list *prev;
 	struct module_list *next;
 	egg_module_t modinfo;
 	lt_dlhandle hand;
 	int refcount;
 } module_list_t;
 
-static module_list_t *module_list_head = NULL;
+static module_list_t *module_list_head = NULL, *deleted_head = NULL;
 static bind_table_t *BT_load, *BT_unload;
 
-static module_list_t *find_module(const char *name)
+static int module_cleanup(void *);
+
+#define find_active_module(name) find_module((name), module_list_head)
+#define find_deleted_module(name) find_module((name), deleted_head)
+
+static module_list_t *find_module(const char *name, module_list_t *head)
 {
 	module_list_t *entry;
 
-	for (entry = module_list_head; entry; entry = entry->next) {
+	for (entry = head; entry; entry = entry->next) {
 		if (!strcasecmp(name, entry->modinfo.name)) return(entry);
 	}
 	return(NULL);
@@ -52,13 +58,33 @@
 	return(0);
 }
 
+/*!
+ * \brief Shuts down the module interface.
+ *
+ * This function unloads all loaded modules and deletes the load and unload bind
+ * tables.
+ *
+ * The module_unload() function is called for every module that is currently
+ * loaded. If there is still a module loaded, for example because of
+ * dependencies, module_unload() is called again. This is done until either all
+ * modules have been unloaded or no more modules could be unloaded.
+ *
+ * \return Always 0.
+ */
+
 int module_shutdown(void)
 {
-	module_list_t **entry = &module_list_head;
+	int unloaded;
+	module_list_t *entry, *next;
+
+	do {
+		unloaded = 0;
+		for (entry = module_list_head; entry; entry = next) {
+			next = entry->next;
+			if (!module_unload(entry->modinfo.name, MODULE_RESTART)) unloaded = 1;
+		}
+	} while (unloaded);
 
-	while (*entry) {
-		if (module_unload((*entry)->modinfo.name, MODULE_RESTART)) entry = &(*entry)->next;
-	}
 	bind_table_del(BT_load);
 	bind_table_del(BT_unload);
 
@@ -98,6 +124,7 @@
  * \return -2 if the module could not be opened. (This will be logged.)
  * \return -3 if no start function is present. (Nothing will be logged.)
  * \return -4 if the start function returned an error. (Nothing will be logged.)
+ * \return -5 if the module can't be loaded because it's marked for unloading. (Nothing will be logged.)
  */
 
 int module_load(const char *name)
@@ -109,8 +136,10 @@
 
 
 	/* See if it's already loaded. */
-	entry = find_module(name);
+	entry = find_active_module(name);
 	if (entry) return(-1);
+	entry = find_deleted_module(name);
+	if (entry) return(-5);
 
 	hand = lt_dlopenext(name);
 	if (!hand) {
@@ -132,6 +161,7 @@
 
 	/* Create an entry for it. */
 	entry = calloc(1, sizeof(*entry));
+	entry->prev = NULL;
 	entry->next = module_list_head;
 	entry->refcount = 0;
 	entry->hand = hand;
@@ -153,8 +183,9 @@
  * \brief Unload a module.
  *
  * If a module's reference count is 0 its closing function will be executed.
- * If the closing function did not veto the unloading all of the modules
- * asyncronous events will be canceled. Finally the module itself is unloaded.
+ * If the closing function did not veto the unloading it will be removed from
+ * the list of active modules, the "unload" bind is triggered and a cleanup
+ * run is sceduled.
  *
  * \param name The name of the module to unload.
  * \param why The reason this function was called: ::MODULE_USER,
@@ -164,47 +195,97 @@
  * \return -1 if the module is not loaded. (Nothing will be logged.)
  * \return -2 if the module is in use by another module. (Nothing will be logged.)
  * \return -3 if the module's closing function vetoed. (Nothing will be logged.)
- * \return -4 on a ltdl error. (This will be logged.)
- *
- * \bug Not all events have owners right now: scripting functions and sockbufs will \b not be unloaded!
  */
 
 int module_unload(const char *name, int why)
 {
-	module_list_t *entry, *prev;
-	int retval, errors;
-	const char *error;
+	module_list_t *entry;
+	int retval;
 
-	for (entry = module_list_head, prev = NULL; entry; prev = entry, entry = entry->next) {
-		if (!strcasecmp(entry->modinfo.name, name)) break;
-	}
+	entry = find_active_module(name);
 	if (!entry) return(-1);
 	if (entry->refcount > 0) return(-2);
 	if (entry->modinfo.close_func) {
 		retval = entry->modinfo.close_func(why);
 		if (retval) return(-3);
 	}
+
+	if (entry->prev) entry->prev->next = entry->next;
+	else module_list_head = entry->next;
+	if (entry->next) entry->next->prev = entry->prev;
+
+	entry->next = NULL;
+	if (!deleted_head) {
+		deleted_head = entry;
+		entry->prev = NULL;
+	} else {
+		module_list_t *tail;
+
+		for (tail = deleted_head; tail->next; tail = tail->next);
+		tail->next = entry;
+		entry->prev = tail;
+	}
+
+	bind_check(BT_unload, NULL, name, name, why == MODULE_USER ? "request" : why == MODULE_SHUTDOWN ? "shutdown" : "restart");
+	putlog(LOG_MISC, "*", "Module unloaded: %s", name);
+	garbage_add(module_cleanup, NULL, GARBAGE_ONCE);
+	return 0;
+}
+
+/*!
+ * \brief Remove a module from the process's memory.
+ *
+ * Tis function will call the modules's unload function, remove all asyncronous
+ * events owned by this module and finally remove the module itself from
+ * memory.
+ *
+ * \param entry The module to remove. This \b must be in the list of deleted
+ *              modules.
+ */
+
+static void module_really_unload(module_list_t *entry)
+{
+	int errors;
+	const char *error;
+
+	if (entry->prev) entry->prev->next = entry->next;
+	else deleted_head = entry->next;
+	if (entry->next) entry->next->prev = entry->prev;
+
+	if (entry->modinfo.unload_func) entry->modinfo.unload_func();
+
 	script_remove_events_by_owner(&entry->modinfo, 0);
 
 	errors = lt_dlclose(entry->hand);
 	if (errors) {
-		putlog(LOG_MISC, "*", "Error unloading %s!", name);
+		putlog(LOG_MISC, "*", "Error unloading %s!", entry->modinfo.name);
 		while ((error = lt_dlerror())) putlog(LOG_MISC, "*", "ltdlerror: %s", error);
-		return -4;
 	}
-	if (prev) prev->next = entry->next;
-	else module_list_head = entry->next;
+
 	free(entry);
-	bind_check(BT_unload, NULL, name, name, why == MODULE_USER ? "request" : why == MODULE_SHUTDOWN ? "shutdown" : "restart");
-	putlog(LOG_MISC, "*", "Module unloaded: %s", name);
-	return(0);
+}
+
+/*!
+ * \brief Calls module_really_unload() for every module marked for unloading.
+ *
+ * This function is called automatically by garbage_run() if a module has
+ * has been closed.
+ *
+ * \return Always 0.
+ */
+
+static int module_cleanup(void *ignored)
+{
+	while (deleted_head) module_really_unload(deleted_head);
+
+	return 0;
 }
 
 egg_module_t *module_lookup(const char *name)
 {
 	module_list_t *entry;
 
-	entry = find_module(name);
+	entry = find_active_module(name);
 	if (entry) return(&entry->modinfo);
 	return(NULL);
 }
@@ -213,14 +294,14 @@
 {
 	if (name == NULL) return 0;
 
-	return (find_module(name) != NULL);
+	return (find_active_module(name) != NULL);
 }
 
 void *module_get_api(const char *name, int major, int minor)
 {
 	module_list_t *entry;
 
-	entry = find_module(name);
+	entry = find_active_module(name);
 	if (!entry) return(NULL);
 	entry->refcount++;
 	return entry->modinfo.module_api;
@@ -230,7 +311,7 @@
 {
 	module_list_t *entry;
 
-	entry = find_module(name);
+	entry = find_active_module(name);
 	if (!entry) return(-1);
 	entry->refcount++;
 	return(0);
@@ -240,7 +321,7 @@
 {
 	module_list_t *entry;
 
-	entry = find_module(name);
+	entry = find_active_module(name);
 	if (!entry) return(-1);
 	entry->refcount--;
 	return(0);
Index: eggdrop1.9/lib/eggdrop/module.h
diff -u eggdrop1.9/lib/eggdrop/module.h:1.47 eggdrop1.9/lib/eggdrop/module.h:1.48
--- eggdrop1.9/lib/eggdrop/module.h:1.47	Tue Jun 22 15:12:37 2004
+++ eggdrop1.9/lib/eggdrop/module.h	Sat Jan 13 06:23:39 2007
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Id: module.h,v 1.47 2004-06-22 20:12:37 wingman Exp $
+ * $Id: module.h,v 1.48 2007-01-13 12:23:39 sven Exp $
  */
 
 #ifndef _EGG_MODULE_H_
@@ -36,6 +36,7 @@
 
 typedef int (*egg_start_func_t)(egg_module_t *modinfo);
 typedef int (*egg_close_func_t)(int why);
+typedef void (*egg_unload_func_t)(void);
 
 struct egg_module {
 	const char *name;
@@ -44,6 +45,7 @@
 	const char *description;
 
 	egg_close_func_t close_func;
+	egg_unload_func_t unload_func;
 	void *module_data;
 
 	/* API and versioning info. */
Index: eggdrop1.9/lib/eggdrop/partymember.c
diff -u eggdrop1.9/lib/eggdrop/partymember.c:1.23 eggdrop1.9/lib/eggdrop/partymember.c:1.24
--- eggdrop1.9/lib/eggdrop/partymember.c:1.23	Fri Dec  1 22:05:11 2006
+++ eggdrop1.9/lib/eggdrop/partymember.c	Sat Jan 13 06:23:39 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: partymember.c,v 1.23 2006-12-02 04:05:11 sven Exp $";
+static const char rcsid[] = "$Id: partymember.c,v 1.24 2007-01-13 12:23:39 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -48,6 +48,7 @@
 
 int partymember_shutdown(void)
 {
+	while (party_head) partymember_delete(party_head, NULL, _("Bot shutdown"));
 	bind_rem_list(BTN_USER_DELETE, partymember_udelete_binds);
 	bind_table_del(BT_nick);
 	bind_table_del(BT_new);
@@ -112,7 +113,7 @@
 	return(id);
 }
 
-partymember_t *partymember_new(int id, user_t *user, botnet_bot_t *bot, const char *nick, const char *ident, const char *host, partyline_event_t *handler, void *client_data)
+partymember_t *partymember_new(int id, user_t *user, botnet_bot_t *bot, const char *nick, const char *ident, const char *host, partyline_event_t *handler, void *client_data, event_owner_t *owner)
 {
 	partymember_t *mem;
 
@@ -129,6 +130,7 @@
 	mem->common_name = bot ? mem->full_name : mem->nick;
 	mem->handler = handler;
 	mem->client_data = client_data;
+	mem->owner = owner;
 
 	mem->next = party_head;
 	if (party_head) party_head->prev = mem;
@@ -150,6 +152,33 @@
 	return(mem);
 }
 
+/*!
+ * \brief Deletes all partymembers with a given owner.
+ *
+ * Calls partymember_delete() for every partymember with a given owner.
+ *
+ * \param module The module whose partymembers should be deleted.
+ * \param script The script whose partymembers should be deleted. NULL matches everything.
+ *
+ * \return The number of deleted partymembers.
+ */
+
+int partymember_delete_by_owner(struct egg_module *module, void *script)
+{
+	int ret = 0;
+	partymember_t *p;
+
+	for (p = party_head; p; p = p->next) {
+		if (p->flags & PARTY_DELETED) continue;
+		if (p->owner && p->owner->module == module && (!script || p->owner->client_data == script)) {
+			partymember_delete(p, NULL, "Module unloaded");
+			++ret;
+		}
+	}
+
+	return ret;
+}
+
 int partymember_delete(partymember_t *p, const botnet_bot_t *lost_bot, const char *text)
 {
 	int i, len;
@@ -188,6 +217,7 @@
 	if (p->handler && p->handler->on_quit) {
 		(p->handler->on_quit)(p->client_data, p, lost_bot, text, strlen(text));
 	}
+	if (p->owner && p->owner->on_delete) p->owner->on_delete(p->owner, p->client_data);
 	return(0);
 }
 
@@ -344,6 +374,22 @@
 	return(0);
 }
 
+int partymember_msgf(partymember_t *p, partymember_t *src, const char *fmt, ...)
+{
+	va_list args;
+	char *ptr, buf[1024];
+	int len;
+
+	va_start(args, fmt);
+	ptr = egg_mvsprintf(buf, sizeof(buf), &len, fmt, args);
+	va_end(args);
+
+	partymember_msg(p, src, ptr, len);
+
+	if (ptr != buf) free(ptr);
+	return(0);
+}
+
 static int on_udelete(user_t *u)
 {
 	partymember_t *p;
Index: eggdrop1.9/lib/eggdrop/partymember.h
diff -u eggdrop1.9/lib/eggdrop/partymember.h:1.5 eggdrop1.9/lib/eggdrop/partymember.h:1.6
--- eggdrop1.9/lib/eggdrop/partymember.h:1.5	Tue Nov 14 08:51:23 2006
+++ eggdrop1.9/lib/eggdrop/partymember.h	Sat Jan 13 06:23:40 2007
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Id: partymember.h,v 1.5 2006-11-14 14:51:23 sven Exp $
+ * $Id: partymember.h,v 1.6 2007-01-13 12:23:40 sven Exp $
  */
 
 #ifndef _EGG_PARTYMEMBER_H
@@ -43,17 +43,20 @@
 
 	partyline_event_t *handler;
 	void *client_data;
+	event_owner_t *owner;
 };
 
 partymember_t *partymember_lookup(const char *name, struct botnet_bot *bot, int id);
-partymember_t *partymember_new(int id, user_t *user, struct botnet_bot *bot, const char *nick, const char *ident, const char *host, partyline_event_t *handler, void *client_data);
+partymember_t *partymember_new(int id, user_t *user, struct botnet_bot *bot, const char *nick, const char *ident, const char *host, partyline_event_t *handler, void *client_data, event_owner_t *owner);
 partymember_t *partymember_get_head(void);
 int partymember_delete(partymember_t *p, const struct botnet_bot *lost_bot, const char *text);
+int partymember_delete_by_owner(struct egg_module *module, void *script);
 int partymember_update_info(partymember_t *p, const char *ident, const char *host);
 int partymember_who(int **ids, int *len);
 int partymember_write_id(int id, const char *text, int len);
 int partymember_write(partymember_t *p, const char *text, int len);
 int partymember_msg(partymember_t *p, partymember_t *src, const char *text, int len);
+int partymember_msgf(partymember_t *p, partymember_t *src, const char *fmt, ...);
 int partymember_printf_id(int id, const char *fmt, ...);
 int partymember_printf(partymember_t *p, const char *fmt, ...);
 int partymember_set_nick(partymember_t *p, const char *nick);
Index: eggdrop1.9/lib/eggdrop/script.c
diff -u eggdrop1.9/lib/eggdrop/script.c:1.25 eggdrop1.9/lib/eggdrop/script.c:1.26
--- eggdrop1.9/lib/eggdrop/script.c:1.25	Fri Dec 15 03:30:47 2006
+++ eggdrop1.9/lib/eggdrop/script.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: script.c,v 1.25 2006-12-15 09:30:47 sven Exp $";
+static const char rcsid[] = "$Id: script.c,v 1.26 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -101,8 +101,7 @@
  * \return The number of deleted events.
  *
  * \bug Not all event types have a *_delete_by_owner() function yet.
- *      partymembers, sockets, socketfilters and scripting functions are
- *      missing.
+ *      sockets, socketfilters and scripting functions are missing.
  */
 
 int script_remove_events_by_owner(egg_module_t *module, void *script)
@@ -110,6 +109,7 @@
 	int removed = 0;
 
 	removed += botnet_delete_by_owner(module, script);
+	removed += partymember_delete_by_owner(module, script);
 	removed += kill_binds_by_owner(module, script);
 	removed += timer_destroy_by_owner(module, script);
 	removed += egg_dns_cancel_by_owner(module, script);
Index: eggdrop1.9/lib/eggdrop/sockbuf.c
diff -u eggdrop1.9/lib/eggdrop/sockbuf.c:1.21 eggdrop1.9/lib/eggdrop/sockbuf.c:1.22
--- eggdrop1.9/lib/eggdrop/sockbuf.c:1.21	Sun Aug 20 10:23:05 2006
+++ eggdrop1.9/lib/eggdrop/sockbuf.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: sockbuf.c,v 1.21 2006-08-20 15:23:05 sven Exp $";
+static const char rcsid[] = "$Id: sockbuf.c,v 1.22 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -279,7 +279,7 @@
 	}
 
 	sbuf->stats->bytes_in += len;
-	if (sbuf->handler->on_read ){
+	if (sbuf->handler->on_read) {
 		sbuf->handler->on_read(sbuf->client_data, idx, data, len);
 	}
 	return(0);
Index: eggdrop1.9/modules/dccparty/dccparty.c
diff -u eggdrop1.9/modules/dccparty/dccparty.c:1.14 eggdrop1.9/modules/dccparty/dccparty.c:1.15
--- eggdrop1.9/modules/dccparty/dccparty.c:1.14	Tue Nov 14 08:51:23 2006
+++ eggdrop1.9/modules/dccparty/dccparty.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: dccparty.c,v 1.14 2006-11-14 14:51:23 sven Exp $";
+static const char rcsid[] = "$Id: dccparty.c,v 1.15 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -36,12 +36,6 @@
 	{0}
 };
 
-static event_owner_t dcc_owner = {
-	"dccparty", 0,
-	0, 0,
-	0
-};
-
 EXPORT_SCOPE int dccparty_LTX_start(egg_module_t *modinfo);
 static int dccparty_close(int why);
 
@@ -54,11 +48,24 @@
 static int dcc_on_read(void *client_data, int idx, char *data, int len);
 static int dcc_on_eof(void *client_data, int idx, int err, const char *errmsg);
 static int dcc_on_delete(void *client_data, int idx);
+static int dcc_pm_delete(event_owner_t *owner, void *client_data);
 
 static int ident_result(void *client_data, const char *ip, int port, const char *reply);
 static int dns_result(void *client_data, const char *ip, char **hosts);
 static int process_results(dcc_session_t *session);
 
+static event_owner_t dcc_generic_owner = {
+	"dccparty", 0,
+	0, 0,
+	0
+};
+
+static event_owner_t dcc_pm_owner = {
+	"dccparty", 0,
+	0, 0,
+	dcc_pm_delete
+};
+
 static sockbuf_handler_t dcc_handler = {
 	"dcc",
 	dcc_on_connect, dcc_on_eof, NULL,
@@ -120,8 +127,8 @@
 	session->count = 0;
 
 	/* Start lookups. */
-	session->ident_id = egg_ident_lookup(peer_ip, peer_port, our_port, -1, ident_result, session, &dcc_owner);
-	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &dcc_owner);
+	session->ident_id = egg_ident_lookup(peer_ip, peer_port, our_port, -1, ident_result, session, &dcc_generic_owner);
+	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &dcc_generic_owner);
 
 	return(0);
 }
@@ -202,7 +209,7 @@
 				session->state = STATE_NICKNAME;
 			}
 			else {
-				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~dcc", session->host ? session->host : session->ip, &dcc_party_handler, session);
+				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~dcc", session->host ? session->host : session->ip, &dcc_party_handler, session, &dcc_pm_owner);
 				session->state = STATE_PARTYLINE;
 				egg_iprintf(idx, _("\r\nWelcome to the dcc partyline interface!\r\n"));
 				if (session->ident) egg_iprintf(idx, _("Your ident is: %s\r\n"), session->ident);
@@ -232,6 +239,15 @@
 	return(0);
 }
 
+static int dcc_pm_delete(event_owner_t *owner, void *client_data)
+{
+	dcc_session_t *session = client_data;
+
+	sockbuf_delete(session->idx);
+
+	return 0;
+}
+
 static int dcc_on_delete(void *client_data, int idx)
 {
 	dcc_session_t *session = client_data;
@@ -246,6 +262,11 @@
 
 static int dccparty_close(int why)
 {
+	void *config_root;
+
+	config_root = config_get_root("eggdrop");
+	config_unlink_table(dcc_config_vars, config_root, "dccparty", 0, NULL);
+
 	return(0);
 }
 
@@ -253,7 +274,7 @@
 {
 	void *config_root;
 
-	dcc_owner.module = modinfo;
+	dcc_generic_owner.module = dcc_pm_owner.module = modinfo;
 
 	modinfo->name = "dccparty";
 	modinfo->author = "eggdev";
Index: eggdrop1.9/modules/dccparty/events.c
diff -u eggdrop1.9/modules/dccparty/events.c:1.7 eggdrop1.9/modules/dccparty/events.c:1.8
--- eggdrop1.9/modules/dccparty/events.c:1.7	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/modules/dccparty/events.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: events.c,v 1.7 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: events.c,v 1.8 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <string.h>
@@ -74,7 +74,6 @@
 
 	if (lostbot) return 0;
 	egg_iprintf(session->idx, "%s (%s@%s) has quit: %s\n", src->common_name, src->ident, src->host, text);
-	if (src == session->party) sockbuf_delete(session->idx);
 
 	return(0);
 }
Index: eggdrop1.9/modules/ircparty/events.c
diff -u eggdrop1.9/modules/ircparty/events.c:1.9 eggdrop1.9/modules/ircparty/events.c:1.10
--- eggdrop1.9/modules/ircparty/events.c:1.9	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/modules/ircparty/events.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: events.c,v 1.9 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: events.c,v 1.10 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -56,9 +56,9 @@
 {
 	irc_session_t *session = client_data;
 
-	if (src != session->party && src->bot) egg_iprintf(session->idx, ":%s*%s:%d!%s@%s NICK %s*%s:%d\n", oldnick, src->bot->name, src->id, src->ident, src->host, newnick, src->bot->name, src->id);
-	else if (src != session->party) egg_iprintf(session->idx, ":%s:%d!%s@%s NICK %s:%d\n", oldnick, src->id, src->ident, src->host, newnick, src->bot->name, src->id); 
-	else egg_iprintf(session->idx, ":%s!%s@%s NICK %s\n", oldnick, src->ident, src->host, newnick);
+	if (src != session->party && src->bot) egg_iprintf(session->idx, ":%s*%s:%d!%s@%s NICK %s*%s:%d\r\n", oldnick, src->bot->name, src->id, src->ident, src->host, newnick, src->bot->name, src->id);
+	else if (src != session->party) egg_iprintf(session->idx, ":%s:%d!%s@%s NICK %s:%d\r\n", oldnick, src->id, src->ident, src->host, newnick, src->bot->name, src->id); 
+	else egg_iprintf(session->idx, ":%s!%s@%s NICK %s\r\n", oldnick, src->ident, src->host, newnick);
 	return(0);
 }
 
@@ -66,9 +66,9 @@
 {
 	irc_session_t *session = client_data;
 
-	if (src != session->party && src->bot) egg_iprintf(session->idx, ":%s*%s:%d!%s@%s QUIT :%s\n", src->nick, src->bot->name, src->id, src->ident, src->host, text);
-	else if (src != session->party) egg_iprintf(session->idx, ":%s:%d!%s@%s QUIT :%s\n", src->nick, src->id, src->ident, src->host, text);
-	else sockbuf_delete(session->idx);
+	if (src != session->party && src->bot) egg_iprintf(session->idx, ":%s*%s:%d!%s@%s QUIT :%s\r\n", src->nick, src->bot->name, src->id, src->ident, src->host, text);
+	else if (src != session->party) egg_iprintf(session->idx, ":%s:%d!%s@%s QUIT :%s\r\n", src->nick, src->id, src->ident, src->host, text);
+	else egg_iprintf(session->idx, "ERROR :%s\r\n", text);
 
 	return(0);
 }
Index: eggdrop1.9/modules/ircparty/ircparty.c
diff -u eggdrop1.9/modules/ircparty/ircparty.c:1.17 eggdrop1.9/modules/ircparty/ircparty.c:1.18
--- eggdrop1.9/modules/ircparty/ircparty.c:1.17	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/modules/ircparty/ircparty.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: ircparty.c,v 1.17 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: ircparty.c,v 1.18 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -34,12 +34,6 @@
 	{0}
 };
 
-static event_owner_t irc_owner = {
-	"ircparty", 0,
-	0, 0,
-	0
-};
-
 EXPORT_SCOPE int ircparty_LTX_start(egg_module_t *modinfo);
 static int ircparty_close(int why);
 
@@ -63,6 +57,7 @@
 static int irc_on_read(void *client_data, int idx, char *data, int len);
 static int irc_on_eof(void *client_data, int idx, int err, const char *errmsg);
 static int irc_on_delete(void *client_data, int idx);
+static int irc_pm_delete(event_owner_t *owner, void *client_data);
 
 static int ident_result(void *client_data, const char *ip, int port, const char *reply);
 static int dns_result(void *client_data, const char *ip, char **hosts);
@@ -78,6 +73,18 @@
 	{0}
 };
 
+static event_owner_t irc_generic_owner = {
+	"ircparty", 0,
+	0, 0,
+	0
+};
+
+static event_owner_t irc_pm_owner = {
+	"ircparty", 0,
+	0, 0,
+	irc_pm_delete
+};
+
 static sockbuf_handler_t server_handler = {
 	"ircparty server",
 	NULL, NULL, irc_on_newclient,
@@ -138,8 +145,8 @@
 	}
 
 	/* Start lookups. */
-	session->ident_id = egg_ident_lookup(peer_ip, peer_port, irc_port, -1, ident_result, session, &irc_owner);
-	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &irc_owner);
+	session->ident_id = egg_ident_lookup(peer_ip, peer_port, irc_port, -1, ident_result, session, &irc_generic_owner);
+	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &irc_generic_owner);
 
 	return(0);
 }
@@ -306,7 +313,7 @@
 				}
 				free(session->pass);
 				session->pass = NULL;
-				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~ircparty", session->host ? session->host : session->ip, &irc_party_handler, session);
+				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~ircparty", session->host ? session->host : session->ip, &irc_party_handler, session, &irc_pm_owner);
 				session->state = STATE_PARTYLINE;
 				irc_greet(session);
 				partychan_join_name("*", session->party, 0);
@@ -334,6 +341,15 @@
 	return(0);
 }
 
+static int irc_pm_delete(event_owner_t *owner, void *client_data)
+{
+	irc_session_t *session = client_data;
+
+	sockbuf_delete(session->idx);
+
+	return 0;
+}
+
 static int irc_on_delete(void *client_data, int idx)
 {
 	irc_session_t *session = client_data;
@@ -348,6 +364,11 @@
 
 static int ircparty_close(int why)
 {
+	void *config_root;
+
+	config_root = config_get_root("eggdrop");
+	config_unlink_table(irc_config_vars, config_root, "ircparty", 0, NULL);
+
 	sockbuf_delete(irc_idx);
 	return(0);
 }
@@ -356,7 +377,7 @@
 {
 	void *config_root;
 
-	irc_owner.module = modinfo;
+	irc_generic_owner.module = irc_pm_owner.module = modinfo;
 
 	modinfo->name = "ircparty";
 	modinfo->author = "eggdev";
Index: eggdrop1.9/modules/oldbotnet/oldbotnet.c
diff -u eggdrop1.9/modules/oldbotnet/oldbotnet.c:1.14 eggdrop1.9/modules/oldbotnet/oldbotnet.c:1.15
--- eggdrop1.9/modules/oldbotnet/oldbotnet.c:1.14	Fri Dec  1 22:05:11 2006
+++ eggdrop1.9/modules/oldbotnet/oldbotnet.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: oldbotnet.c,v 1.14 2006-12-02 04:05:11 sven Exp $";
+static const char rcsid[] = "$Id: oldbotnet.c,v 1.15 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -67,6 +67,12 @@
 	bot_on_delete
 };
 
+static event_owner_t generic_owner = {
+	"oldbotnet", NULL,
+	NULL, NULL,
+	NULL
+};
+
 /*static event_owner_t sock_owner = {
 	"oldbotnet", NULL,
 	NULL, NULL,
@@ -526,7 +532,7 @@
 	}
 
 	if (word[2][0] == '!') linking = 0;
-	new = botnet_new(word[0], NULL, src, bot, NULL, NULL, NULL, linking);
+	new = botnet_new(word[0], NULL, src, bot, NULL, NULL, &generic_owner, linking);
 	if (!new) {
 		/* Invalid botname ... should probably do some really clever name mangleing here ... */
 		char obuf[512];
@@ -609,7 +615,7 @@
 		}
 		else host = word[0];
 
-		p = partymember_new(id, NULL, frombot, word[1], ident, host, &oldbotnet_party, NULL);
+		p = partymember_new(id, NULL, frombot, word[1], ident, host, &oldbotnet_party, NULL, &generic_owner);
 	}
 	partychan_join_name(assoc_get_name(btoi(word[2])), p, linking);
 	egg_free_word_array(word, 5);
@@ -759,7 +765,7 @@
 
 int oldbotnet_LTX_start(egg_module_t *modinfo)
 {
-	bot_owner.module = /*sock_owner.module = */modinfo;
+	bot_owner.module = generic_owner.module = modinfo;
 	modinfo->name = "oldbotnet";
 	modinfo->author = "eggdev";
 	modinfo->version = "1.0.0";
Index: eggdrop1.9/modules/proxy/proxy.c
diff -u eggdrop1.9/modules/proxy/proxy.c:1.7 eggdrop1.9/modules/proxy/proxy.c:1.8
--- eggdrop1.9/modules/proxy/proxy.c:1.7	Sun Oct 17 00:14:06 2004
+++ eggdrop1.9/modules/proxy/proxy.c	Sat Jan 13 06:23:40 2007
@@ -54,6 +54,11 @@
 
 static int proxy_close(int why)
 {
+	void *config_root;
+
+	config_root = config_get_root("eggdrop");
+	config_unlink_table(proxy_config_vars, config_root, "proxy", 0, NULL);
+
 	return(0);
 }
 
Index: eggdrop1.9/modules/pythonscript/mystdio.c
diff -u eggdrop1.9/modules/pythonscript/mystdio.c:1.1 eggdrop1.9/modules/pythonscript/mystdio.c:1.2
--- eggdrop1.9/modules/pythonscript/mystdio.c:1.1	Fri Dec 16 19:25:06 2005
+++ eggdrop1.9/modules/pythonscript/mystdio.c	Sat Jan 13 06:23:40 2007
@@ -18,10 +18,11 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: mystdio.c,v 1.1 2005-12-17 01:25:06 sven Exp $";
+static const char rcsid[] = "$Id: mystdio.c,v 1.2 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <Python.h>
+#include <structmember.h>
 #include <eggdrop/eggdrop.h>
 
 #include "pythonscript.h"
@@ -30,7 +31,8 @@
 
 typedef struct {
 	PyObject_HEAD
-	unsigned  Type;
+	int softspace;
+	unsigned Type;
 } StdioObject;
 
 typedef struct {
@@ -59,6 +61,7 @@
 		return 0;
 	}
 	if (!(Stdio = (StdioObject *) Type->tp_alloc(Type, 0))) return 0;
+	Stdio->softspace = 0;
 	Stdio->Type = IOtype;
 	return (PyObject *) Stdio;
 }
@@ -85,7 +88,7 @@
 	written = newline - Text + 1;
 	*newline = 0;
 	if (written > 1 && newline[-1] == '\r') newline[-1] = 0;
-	if (*Text) Log(Target, Text);
+	Log(Target, Text);
 	return written;
 }
 
@@ -113,7 +116,7 @@
 }
 
 void Flush(unsigned Target) {
-	Write(Target, "\n", 1);
+	if (LineBuf[Target].strlen) Write(Target, "\n", 1);
 }
 
 static PyObject *Stdio_Write(PyObject *self, PyObject *args) {
@@ -135,6 +138,11 @@
 	return Py_None;
 }
 
+static PyMemberDef Stdio_Members[] = {
+	{"softspace", T_INT, offsetof(StdioObject, softspace), 0, "Has a documented use for print and an undocumented use for the interactive interpreter."},
+	{0}
+};
+
 static PyMethodDef Stdio_Methods[] = {
  {"write", Stdio_Write, METH_VARARGS, "Write some text"},
  {"flush", Stdio_Flush, METH_NOARGS, "Display the buffered content *now*"},
@@ -172,7 +180,7 @@
 	0,                           /* tp_iter */
 	0,                           /* tp_iternext */
 	Stdio_Methods,               /* tp_methods */
-	0,                           /* tp_members */
+	Stdio_Members,               /* tp_members */
 	0,                           /* tp_getset */
 	0,                           /* tp_base */
 	0,                           /* tp_dict */
Index: eggdrop1.9/modules/pythonscript/pythonscript.c
diff -u eggdrop1.9/modules/pythonscript/pythonscript.c:1.4 eggdrop1.9/modules/pythonscript/pythonscript.c:1.5
--- eggdrop1.9/modules/pythonscript/pythonscript.c:1.4	Thu Jan  5 14:42:42 2006
+++ eggdrop1.9/modules/pythonscript/pythonscript.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: pythonscript.c,v 1.4 2006-01-05 20:42:42 sven Exp $";
+static const char rcsid[] = "$Id: pythonscript.c,v 1.5 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <Python.h>
@@ -551,14 +551,18 @@
 
 static int pythonscript_close(int why)
 {
-	Py_Finalize();
-
 	bind_rem_list("party", party_commands);
 
 	script_unregister_module(&my_script_interface);
+
 	return 0;
 }
 
+static void pythonscript_unload(void)
+{
+	Py_Finalize();
+}
+
 static PyMethodDef *methods = {
 	0
 };
@@ -575,6 +579,7 @@
 	modinfo->version = "0.0.1";
 	modinfo->description = "provides python scripting support";
 	modinfo->close_func = pythonscript_close;
+	modinfo->unload_func = pythonscript_unload;
 
 	/* Create the interpreter and let tcl load its init.tcl */
 	Py_Initialize();
Index: eggdrop1.9/modules/server/server.c
diff -u eggdrop1.9/modules/server/server.c:1.66 eggdrop1.9/modules/server/server.c:1.67
--- eggdrop1.9/modules/server/server.c:1.66	Wed Dec 28 11:27:31 2005
+++ eggdrop1.9/modules/server/server.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: server.c,v 1.66 2005-12-28 17:27:31 sven Exp $";
+static const char rcsid[] = "$Id: server.c,v 1.67 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include "server.h"
@@ -200,32 +200,6 @@
 	return(0);
 }
 
-static int server_close(int why)
-{
-	kill_server(_("server module unloading"));
-	cycle_delay = 100;
-
-	bind_rem_list("raw", server_raw_binds);
-	//bind_rem_list("party", server_party_commands);
-	bind_rem_simple("secondly", NULL, NULL, server_secondly);
-	bind_rem_simple("status", NULL, NULL, server_status);
-	bind_rem_simple("config_save", NULL, "eggdrop", server_config_save);
-
-	/* Clear the server and nick lists. */
-	server_clear();
-	nick_clear();
-
-	server_binds_destroy();
-
-	channel_destroy();
-	channel_events_destroy();
-	uhost_cache_destroy();
-
-	server_script_destroy();
-
-	return(0);
-}
-
 static config_var_t server_config_vars[] = {
 	{"chanfile", &server_config.chanfile, CONFIG_STRING},
 	/* Registration information. */
@@ -253,6 +227,37 @@
 	{0}
 };
 
+static int server_close(int why)
+{
+	void *config_root;
+
+	kill_server(_("server module unloading"));
+	cycle_delay = 100;
+
+	config_root = config_get_root("eggdrop");
+	config_unlink_table(server_config_vars, config_root, "server", 0, NULL);
+
+	bind_rem_list("raw", server_raw_binds);
+	//bind_rem_list("party", server_party_commands);
+	bind_rem_simple("secondly", NULL, NULL, server_secondly);
+	bind_rem_simple("status", NULL, NULL, server_status);
+	bind_rem_simple("config_save", NULL, "eggdrop", server_config_save);
+
+	/* Clear the server and nick lists. */
+	server_clear();
+	nick_clear();
+
+	server_binds_destroy();
+
+	channel_destroy();
+	channel_events_destroy();
+	uhost_cache_destroy();
+
+	server_script_destroy();
+
+	return(0);
+}
+
 static void server_config_init()
 {
 	int i;
Index: eggdrop1.9/modules/telnetparty/events.c
diff -u eggdrop1.9/modules/telnetparty/events.c:1.10 eggdrop1.9/modules/telnetparty/events.c:1.11
--- eggdrop1.9/modules/telnetparty/events.c:1.10	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/modules/telnetparty/events.c	Sat Jan 13 06:23:40 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: events.c,v 1.10 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: events.c,v 1.11 2007-01-13 12:23:40 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -57,10 +57,6 @@
 	if (lostbot) return 0;
 	partyline_idx_quit(session->idx, src, text, len);
 
-	/* if this quit are we delete our sockbuf. */
-	if (src == session->party)
-		sockbuf_delete(session->idx);
-
 	return(0);
 }
 
Index: eggdrop1.9/modules/telnetparty/telnetparty.c
diff -u eggdrop1.9/modules/telnetparty/telnetparty.c:1.23 eggdrop1.9/modules/telnetparty/telnetparty.c:1.24
--- eggdrop1.9/modules/telnetparty/telnetparty.c:1.23	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/modules/telnetparty/telnetparty.c	Sat Jan 13 06:23:41 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: telnetparty.c,v 1.23 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: telnetparty.c,v 1.24 2007-01-13 12:23:41 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>
@@ -35,12 +35,6 @@
 	{0}
 };
 
-static event_owner_t telnet_owner = {
-	"telnetparty", 0,
-	0, 0,
-	0
-};
-
 EXPORT_SCOPE int telnetparty_LTX_start(egg_module_t *modinfo);
 static int telnetparty_close(int why);
 
@@ -61,6 +55,19 @@
 static int ident_result(void *client_data, const char *ip, int port, const char *reply);
 static int dns_result(void *client_data, const char *ip, char **hosts);
 static int process_results(telnet_session_t *session);
+static int telnet_pm_delete(event_owner_t *owner, void *client_data);
+
+static event_owner_t telnet_generic_owner = {
+	"telnetparty", 0,
+	0, 0,
+	0
+};
+
+static event_owner_t telnet_partymember_owner = {
+	"telnetparty", 0,
+	0, 0,
+	telnet_pm_delete
+};
 
 static sockbuf_handler_t server_handler = {
 	"telnet server",
@@ -93,6 +100,15 @@
 	return(0);
 }
 
+static int telnet_pm_delete(event_owner_t *owner, void *client_data)
+{
+	telnet_session_t *session = client_data;
+
+	sockbuf_delete(session->idx);
+
+	return 0;
+}
+
 void telnet_code(int idx, int cmd, int what)
 {
 	char temp[3];
@@ -319,8 +335,8 @@
 	}
 
 	/* Start lookups. */
-	session->ident_id = egg_ident_lookup(peer_ip, peer_port, telnet_port, -1, ident_result, session, &telnet_owner);
-	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &telnet_owner);
+	session->ident_id = egg_ident_lookup(peer_ip, peer_port, telnet_port, -1, ident_result, session, &telnet_generic_owner);
+	session->dns_id = egg_dns_reverse(peer_ip, -1, dns_result, session, &telnet_generic_owner);
 
 	return(0);
 }
@@ -410,7 +426,7 @@
 				session->state = STATE_NICKNAME;
 			}
 			else {
-				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~telnet", session->host ? session->host : session->ip, &telnet_party_handler, session);
+				session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~telnet", session->host ? session->host : session->ip, &telnet_party_handler, session, &telnet_partymember_owner);
 				session->state = STATE_PARTYLINE;
 				egg_iprintf(idx, "\r\nWelcome to the telnet partyline interface!\r\n");
 				if (session->ident) egg_iprintf(idx, "Your ident is: %s\r\n", session->ident);
@@ -614,6 +630,11 @@
 
 static int telnetparty_close(int why)
 {	
+	void *config_root;
+
+	config_root = config_get_root("eggdrop");
+	config_unlink_table(telnet_config_vars, config_root, "telnetparty", 0, NULL);
+
 	sockbuf_delete(telnet_idx);
 	return(0);
 }
@@ -622,7 +643,7 @@
 {
 	void *config_root;
 
-	telnet_owner.module = modinfo;
+	telnet_generic_owner.module = telnet_partymember_owner.module = modinfo;
 	modinfo->name = "telnetparty";
 	modinfo->author = "eggdev";
 	modinfo->version = "1.0.0";
Index: eggdrop1.9/src/terminal.c
diff -u eggdrop1.9/src/terminal.c:1.7 eggdrop1.9/src/terminal.c:1.8
--- eggdrop1.9/src/terminal.c:1.7	Tue Nov 14 08:51:24 2006
+++ eggdrop1.9/src/terminal.c	Sat Jan 13 06:23:41 2007
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: terminal.c,v 1.7 2006-11-14 14:51:24 sven Exp $";
+static const char rcsid[] = "$Id: terminal.c,v 1.8 2007-01-13 12:23:41 sven Exp $";
 #endif
 
 #include <eggdrop/eggdrop.h>			/* partyline_*		*/
@@ -84,7 +84,7 @@
 
 	terminal_session.party = partymember_new(-1,
 		terminal_user, NULL, TERMINAL_NICK, TERMINAL_USER,
-			TERMINAL_HOST, &terminal_party_handler, NULL);
+			TERMINAL_HOST, &terminal_party_handler, NULL, NULL);
 
 	/* Put them on the main channel. */
 	partychan_join_name("*", terminal_session.party, 0);
----------------------- End of diff -----------------------



More information about the Changes mailing list