[cvslog] (2004-09-26 09:42:19 UTC) Module eggdrop1.9: Change committed!

cvslog cvs at tsss.org
Sun Sep 26 03:42:20 CST 2004


CVSROOT    : /usr/local/cvsroot
Module     : eggdrop1.9
Commit time: 2004-09-26 09:42:19 UTC
Commited by: stdarg <stdarg at techmonkeys.org>

Modified files:
     lib/eggdrop/Makefile.am lib/eggdrop/binds.c lib/eggdrop/config.c
     lib/eggdrop/eggdrop.c lib/eggdrop/eggdrop.h lib/eggdrop/garbage.c
     lib/eggdrop/hash_table.c lib/eggdrop/memory.h
     lib/eggdrop/memutil.c lib/eggdrop/module.c lib/eggdrop/users.c
     lib/eggdrop/users.h lib/eggdrop/xml.c lib/eggdrop/xml.h
     lib/eggdrop/xmlread.c lib/eggdrop/xmlwrite.c
     modules/server/Makefile.am modules/server/channels.c
     modules/server/channels.h modules/server/egg_server_api.c
     modules/server/egg_server_internal.h modules/server/input.c
     modules/server/party_commands.c modules/server/server.c
     modules/server/servsock.c src/bg.c src/core_config.c
     src/core_party.c src/logfile.c src/logfile.h src/main.c

Log message:

* module_load checks modname_LTX_start in addition to start.
* add linked list info to xml nodes
* there were some memory errors somewhere... no idea where... so for now I've changed it back to the old config api and commented out the help system

---------------------- diff included ----------------------
Index: eggdrop1.9/lib/eggdrop/Makefile.am
diff -u eggdrop1.9/lib/eggdrop/Makefile.am:1.36 eggdrop1.9/lib/eggdrop/Makefile.am:1.37
--- eggdrop1.9/lib/eggdrop/Makefile.am:1.36	Thu Aug 26 13:32:07 2004
+++ eggdrop1.9/lib/eggdrop/Makefile.am	Sun Sep 26 04:42:08 2004
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.36 2004/08/26 18:32:07 darko Exp $
+# $Id: Makefile.am,v 1.37 2004/09/26 09:42:08 stdarg Exp $
 
 MAINTAINERCLEANFILES	= Makefile.in
 
@@ -26,13 +26,11 @@
 			net.c net.h \
 			owner.c owner.h \
 			string.c string.h \
-			memory.h memory.c \
 			timer.c timer.h \
 			fileutil.c fileutil.h \
 			flags.c flags.h \
 			garbage.c garbage.h \
 			hash_table.c hash_table.h \
-			help.c help.h \
 			irccmp.c irccmp.h \
 			ircmasks.c ircmasks.h \
 			ircparse.c ircparse.h \
@@ -52,7 +50,6 @@
 			users.c users.h \
 			xml.c xml.h \
 			xmlread.c xmlwrite.c \
-			variant.c variant.h \
 			timeutil.c timeutil.h
 
 libeggdrop_la_LIBADD	= @LIBLTDL@ \
Index: eggdrop1.9/lib/eggdrop/binds.c
diff -u eggdrop1.9/lib/eggdrop/binds.c:1.19 eggdrop1.9/lib/eggdrop/binds.c:1.20
--- eggdrop1.9/lib/eggdrop/binds.c:1.19	Fri Jun 25 12:44:03 2004
+++ eggdrop1.9/lib/eggdrop/binds.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: binds.c,v 1.19 2004/06/25 17:44:03 darko Exp $";
+static const char rcsid[] = "$Id: binds.c,v 1.20 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <string.h>
@@ -29,7 +29,7 @@
 static bind_table_t *bind_table_list_head = NULL;
 
 /* main routine for bind checks */
-static int bind_vcheck_hits (bind_table_t *table, flags_t *user_flags, const char *match, int *hits, va_list args);
+static int bind_vcheck_hits(bind_table_t *table, flags_t *user_flags, const char *match, int *hits, va_list args);
 
 /* Garbage collection stuff. */
 static void bind_table_really_del(bind_table_t *table);
@@ -337,9 +337,9 @@
 	va_list args;
 	int ret;
 
-	va_start (args, match);
-	ret = bind_vcheck_hits (table, user_flags, match, NULL, args);	
-	va_end (args);
+	va_start(args, match);
+	ret = bind_vcheck_hits(table, user_flags, match, NULL, args);	
+	va_end(args);
 
 	return ret;
 }
@@ -349,14 +349,14 @@
 	va_list args;
 	int ret;
 
-	va_start (args, hits);
-	ret = bind_vcheck_hits (table, user_flags, match, hits, args);
-	va_end (args);
+	va_start(args, hits);
+	ret = bind_vcheck_hits(table, user_flags, match, hits, args);
+	va_end(args);
 
 	return ret;
 }
 
-static int bind_vcheck_hits (bind_table_t *table, flags_t *user_flags, const char *match, int *hits, va_list ap)
+static int bind_vcheck_hits(bind_table_t *table, flags_t *user_flags, const char *match, int *hits, va_list ap)
 {
 	void *args[11];
 	bind_entry_t *entry, *next, *winner = NULL;
Index: eggdrop1.9/lib/eggdrop/config.c
diff -u eggdrop1.9/lib/eggdrop/config.c:1.8 eggdrop1.9/lib/eggdrop/config.c:1.9
--- eggdrop1.9/lib/eggdrop/config.c:1.8	Wed Jun 30 12:10:46 2004
+++ eggdrop1.9/lib/eggdrop/config.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: config.c,v 1.8 2004/06/30 17:10:46 wingman Exp $";
+static const char rcsid[] = "$Id: config.c,v 1.9 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -42,7 +42,7 @@
 } config_handle_t;
 
 static config_handle_t *roots = NULL;
-int nroots = 0;
+static int nroots = 0;
 
 static void config_delete_var(void *client_data);
 
@@ -111,19 +111,19 @@
 	return(-1);
 }
 
-/* XXX: remove this */
-xml_node_t *doc;
-
 void *config_load(const char *fname)
 {
-	if (xml_load_file(fname, &doc, XML_TRIM_TEXT) != 0) {
+	xml_node_t *root;
+
+	root = xml_parse_file(fname);
+	if (!root) {
 		/* XXX: do not use putlog here since it might not be initialized yet */
 		fprintf(stderr, "ERROR\n");
 		fprintf(stderr, "\tFailed to load config '%s': %s\n\n", fname, xml_last_error());
 		return NULL;
 	}
 
-	return xml_root_element(doc);
+	return(root);
 }
 
 int config_save(const char *handle, const char *fname)
@@ -134,7 +134,7 @@
 	if (root) bind_check(BT_config_save, NULL, handle, handle);
 	if (!fname) fname = "config.xml";
 
-	if (xml_save_file(fname, doc, XML_INDENT) == 0)
+	if (xml_save_file(fname, root, XML_INDENT) == 0)
 		return (0);
 	
 	putlog(LOG_MISC, "*", _("Failed to save config '%s': %s"), fname, xml_last_error());
@@ -192,17 +192,16 @@
 {
 	va_list args;
 	xml_node_t *root = config_root;
-	int intval;
 
 	va_start(args, config_root);
 	root = xml_node_vlookup(root, args, 0);
 	va_end(args);
 
-	if (!xml_node_get_int(&intval, root, NULL)) {
-		*intptr = intval;
-		return(0);
+	if (!root) {
+		*intptr = 0;
+		return(-1);
 	}
-	return(-1);
+	return xml_node_get_int(intptr, root, NULL);
 }
 
 int config_get_str(char **strptr, void *config_root, ...)
@@ -214,6 +213,10 @@
 	root = xml_node_vlookup(root, args, 0);
 	va_end(args);
 
+	if (!root) {
+		*strptr = NULL;
+		return(-1);
+	}
 	return xml_node_get_str(strptr, root, NULL);
 }
 
@@ -366,326 +369,3 @@
 	}
 	return(0);
 }
-
-/****************************************************************************/
-
-
-config_type_t CONFIG_TYPE_STRING    = { "#string#", sizeof(char *), NULL };
-config_type_t CONFIG_TYPE_INT       = { "#int#", sizeof(int), NULL };
-config_type_t CONFIG_TYPE_BOOL      = { "#bool#", sizeof(int), NULL };
-config_type_t CONFIG_TYPE_TIMESTAMP = { "#timestamp#", sizeof(time_t), NULL };
-
-static int link_node(xml_node_t *node, config_type_t *type, void *addr);
-static int link_addr(xml_node_t *node, variant_t *data, config_variable_t *var, void **addr);
-
-static int sync_node(xml_node_t *node, config_type_t *type, void *addr);
-static int sync_addr(xml_node_t *node, variant_t *data, config_variable_t *var, void *addr);
-
-int config2_link(int config, config_type_t *type, void *addr)
-{
-	int ret;
-	ret = link_node(xml_node_path_lookup(xml_root_element(doc),type->name, 0, 1), type, addr);
-	return ret;
-}
-
-int config2_sync(int config, config_type_t *type, void *addr)
-{
-	int ret;
-	ret = sync_node(xml_node_path_lookup(xml_root_element(doc),type->name, 0, 1), type, addr);
-	return ret;
-}
-
-static int sync_node(xml_node_t *node, config_type_t *type, void *addr)
-{
-	config_variable_t *var, *e;
-	unsigned char *bytes;
-	xml_node_t *child, *c;
-	variant_t *data;
-	
-	bytes = (unsigned char *)addr;
-	if (bytes == NULL)
-		return (-1);	
-	
-	for (var = type->vars; var->type; var++) {
-		if (var->path == NULL)
-			child = node;			
-		else
-			child = xml_node_path_lookup(node, var->path, 0, 1);		
-		data = &child->data;												
-		switch (var->modifier) {
-		
-			case (CONFIG_NONE):
-			{
-				if (sync_addr(child, data, var, bytes) != 0)
-					continue;					
-				bytes += var->type->size;
-				break;
-			}
-				
-			case (CONFIG_ENUM):
-			{
-				int val, i;
-				
-				/* remove all nodes */
-				for (i = child->nchildren - 1; i >= 0; i--) {
-					if (0 == strcmp(child->children[i]->name, var->type->name)) {
-						xml_node_remove(child, child->children[i]);
-					}
-				}
-
-				val = *(int *)bytes; bytes += sizeof(int);
-
-				for (e = var->type->vars; e->path; e++) {
-					if (val & e->modifier) {
-						c = xml_create_element(var->type->name);
-						xml_set_text_str(c, e->path);
-						xml_node_append(child, c);
-					}
-				}
-
-				break;
-			}
-
-			case (CONFIG_LIST):
-			case (CONFIG_LIST_DL):
-			{
-				void *head_ptr, *item, *next;
-				unsigned char *cur;
-			
-				head_ptr = *((void **)bytes); bytes += sizeof(void *);
-	
-				/* remove all nodes */
-				xml_node_remove_by_name(child, var->type->name);
-		
-				for (item = head_ptr; item; ) {
-					cur = (unsigned char *)item;
-	
-					/* skip prev ptr */
-					if (var->modifier == CONFIG_LIST_DL)
-						cur += sizeof(void *);
-
-					/* save next and skip next ptr */
-					next = *((void **)cur); cur += sizeof(void *);
-
-					c = xml_create_element(var->type->name);
-					sync_node(c, var->type, cur);
-					xml_node_append(child, c);
-
-					item = next;
-				}				
-				break;
-			}
-
-			case (CONFIG_ARRAY):
-			{
-				void **items; 
-				int length, i; 
-							
-				/* items */	
-				items = *((void ***)bytes); bytes += sizeof(void **);
-				
-				/* length */
-				length = *((int *)bytes); bytes += sizeof(int);
-				
-				/* remove all nodes */
-				xml_node_remove_by_name(child, var->type->name);
-				
-				for (i = 0; i < length; i++) {
-					c = xml_create_element(var->type->name);
-					xml_node_append(child, c);
-					sync_node(c, var->type, &items[i]);
-				}
-								
-				break;
-			}			
-							
-		}
-	}
-			
-	return (0);
-}
-
-static int sync_addr(xml_node_t *node, variant_t *data, config_variable_t *var, void *addr)
-{
-	if (var->type == &CONFIG_TYPE_STRING)
-		variant_set_str(data, *((char **)addr));
-	else if (var->type == &CONFIG_TYPE_INT)
-		variant_set_int(data, *((int *)addr));
-	else if (var->type == &CONFIG_TYPE_BOOL)
-		variant_set_bool(data, *((int *)addr));
-	else if (var->type == &CONFIG_TYPE_TIMESTAMP)
-		variant_set_ts(data, *((time_t *)addr));
-	else {
-		if (sync_node(node, var->type, addr) != 0)
-			return (-1);
-	}
-	
-	return (0);
-}
-
-static int link_addr(xml_node_t *node, variant_t *data, config_variable_t *var, void **addr)
-{	
-	if (var->type == &CONFIG_TYPE_STRING)
-		*((char **)addr) = (char *)variant_get_str(data, NULL);
-	else if (var->type == &CONFIG_TYPE_INT)
-		*((int *)addr) = variant_get_int(data, MIN_INT);
-	else if (var->type == &CONFIG_TYPE_BOOL)
-		*((int *)addr) = variant_get_bool(data, 0);
-	else if (var->type == &CONFIG_TYPE_TIMESTAMP)
-		*((time_t *)addr) = variant_get_ts(data, (time_t)0);
-	else {
-		if (link_node(node, var->type, addr) != 0)
-			return (-1);
-	}
-
-	return (0);
-}
-
-static int link_node(xml_node_t *node, config_type_t *type, void *addr)
-{
-	config_variable_t *var, *e;
-	xml_node_t *child;
-	variant_t *data;
-	unsigned char *bytes;
-	
-	bytes = (unsigned char *)addr;
-	if (bytes == NULL)
-		return (-1);
-	memset(bytes, 0, type->size);
-	
-	for (var = type->vars; var->type; var++) {				
-		if (var->path == NULL)
-			child = node;
-		else
-			child = xml_node_path_lookup(node, var->path, 0, 1);			
-		data = &child->data;
-		
-		switch (var->modifier) {
-		
-			case (CONFIG_NONE):
-			{
-				if (link_addr(child, data, var, (void *)bytes) != 0)
-					;					
-				bytes += var->type->size;
-				break;
-			}
-				
-			case (CONFIG_ENUM):
-			{
-				int i;
-				int *en;
-
-				en = (int *)bytes; bytes += sizeof(int);
-
-				for (i = 0; i < child->nchildren; i++) {
-					xml_node_t *c = child->children[i];
-					if (0 != strcmp(c->name, var->type->name))
-						continue;
-
-					for (e = var->type->vars; e->path; e++) {
-						if (0 == strcmp(xml_get_text_str(c, ""), e->path)) {
-							(*en) |= e->modifier;
-						}	
-					}	
-				}
-				break;
-			}
-
-			case (CONFIG_LIST):
-			case (CONFIG_LIST_DL):
-			{
-				int i;
-				void **head_ptr;
-				unsigned char *cur, *prev;
-
-				prev = NULL;
-				head_ptr = (void **)bytes; bytes += sizeof(void *);
-
-				for (i = 0; i < child->nchildren; i++) {
-					xml_node_t *c = child->children[i];
-					if (0 != strcmp(c->name, var->type->name)) {
-						continue;
-					}
-
-					/* allocate memory for current item */
-					cur = (unsigned char *)malloc(var->type->size);
-					if (cur == NULL)
-						return (-1);
-					memset(cur, 0, var->type->size);		
-					
-					cur += sizeof(void *); /* skip either next or prev ptr */
-					if (var->modifier == CONFIG_LIST_DL)
-						cur += sizeof(void *); /* skip next ptr */
-
-					/* link it */
-					if (link_addr(c, &c->data, var, (void *)cur) != 0) {
-						/* failed to link, free this item and continue
- 						 * with next one */
-						free(cur);
-						continue;
-					}
-
-					cur -= sizeof(void *);
-					if (var->modifier == CONFIG_LIST_DL)
-						cur -= sizeof(void *); 
-
-					/* set head if not yet set */
-					if (*head_ptr == NULL) {
-						*head_ptr = cur;
-					}
-
-					/* set current item's prev */
-					if (prev) {
-						if (var->modifier == CONFIG_LIST_DL) {
-							*((void **)bytes) = prev;
-						}	
-					}
-		
-					/* set previous item's next */
-					if (prev) {
-						if (var->modifier == CONFIG_LIST_DL) {
-							prev += sizeof(void *); /* skip prev item */
-							*((void **)prev) = cur;
-						} else
-							*((void **)prev) = cur;
-					}
-
-					/* remember prev */
-					prev = cur;
-				}
-				break;
-			}
-
-			case (CONFIG_ARRAY):
-			{
-				void ***items; 
-				int *length, i; 
-							
-				/* items */	
-				items = (void ***)bytes; bytes += sizeof(void *);
-				
-				/* length */
-				length = (int *)bytes; bytes += sizeof(int);
-					
-				/* allocate enough memory (though not all memory by used here
-				 * since not all children must be items of this array */
-				*items = malloc(child->nchildren * var->type->size);
-				memset(*items, 0, child->nchildren * var->type->size);
-				
-				for (i = 0; i < child->nchildren; i++) {
-					if (0 != strcmp(child->children[i]->name, var->type->name))
-						continue;
-						
-					/* now link array item with the correspondending xml node */
-					if (link_addr(child->children[i], &child->children[i]->data, var, &(*items)[*length]) == 0) {
-						(*length)++;
-					}
-				}
-			}				
-		}				
-	}
-
-	return (0);
-}
-
-
Index: eggdrop1.9/lib/eggdrop/eggdrop.c
diff -u eggdrop1.9/lib/eggdrop/eggdrop.c:1.21 eggdrop1.9/lib/eggdrop/eggdrop.c:1.22
--- eggdrop1.9/lib/eggdrop/eggdrop.c:1.21	Wed Jun 23 16:12:57 2004
+++ eggdrop1.9/lib/eggdrop/eggdrop.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: eggdrop.c,v 1.21 2004/06/23 21:12:57 stdarg Exp $";
+static const char rcsid[] = "$Id: eggdrop.c,v 1.22 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdlib.h>
@@ -39,7 +39,6 @@
 	egg_net_init();
 	logging_init();
 	user_init();
-	help_init();
 	script_init();
 	partyline_init();
 	module_init();
@@ -54,7 +53,6 @@
 	module_shutdown();
 	partyline_shutdown();
 	script_shutdown();
-	help_shutdown();
 	user_shutdown();
 	logging_shutdown();
 	egg_net_shutdown();
@@ -69,6 +67,7 @@
 	return bind_check(BT_event, NULL, event, event);
 }
 
+/* Set command line parameters. */
 int eggdrop_set_params(const char **params, int nparams)
 {
 	eggparams = params;
@@ -76,6 +75,7 @@
 	return(0);
 }
 
+/* Look up a command line parameter. */
 const char *eggdrop_get_param(const char *key)
 {
 	int i, nparams;
Index: eggdrop1.9/lib/eggdrop/eggdrop.h
diff -u eggdrop1.9/lib/eggdrop/eggdrop.h:1.43 eggdrop1.9/lib/eggdrop/eggdrop.h:1.44
--- eggdrop1.9/lib/eggdrop/eggdrop.h:1.43	Thu Aug 19 13:39:36 2004
+++ eggdrop1.9/lib/eggdrop/eggdrop.h	Sun Sep 26 04:42:09 2004
@@ -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: eggdrop.h,v 1.43 2004/08/19 18:39:36 darko Exp $
+ * $Id: eggdrop.h,v 1.44 2004/09/26 09:42:09 stdarg Exp $
  */
 
 #ifndef _EGG_EGGDROP_H_
@@ -57,7 +57,6 @@
 #include <eggdrop/script.h>
 #include <eggdrop/throttle.h>
 #include <eggdrop/xml.h>
-#include <eggdrop/memory.h>
 #include <eggdrop/timeutil.h>
 
 /* Gettext macros */
Index: eggdrop1.9/lib/eggdrop/garbage.c
diff -u eggdrop1.9/lib/eggdrop/garbage.c:1.3 eggdrop1.9/lib/eggdrop/garbage.c:1.4
--- eggdrop1.9/lib/eggdrop/garbage.c:1.3	Tue Jun 22 05:54:42 2004
+++ eggdrop1.9/lib/eggdrop/garbage.c	Sun Sep 26 04:42:09 2004
@@ -18,13 +18,12 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: garbage.c,v 1.3 2004/06/22 10:54:42 wingman Exp $";
+static const char rcsid[] = "$Id: garbage.c,v 1.4 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdlib.h>
 
-#include <eggdrop/memory.h>
-#include <eggdrop/garbage.h>
+#include <eggdrop/eggdrop.h>
 
 typedef struct garbage_list {
 	struct garbage_list *next;
Index: eggdrop1.9/lib/eggdrop/hash_table.c
diff -u eggdrop1.9/lib/eggdrop/hash_table.c:1.12 eggdrop1.9/lib/eggdrop/hash_table.c:1.13
--- eggdrop1.9/lib/eggdrop/hash_table.c:1.12	Fri Jun 25 12:44:03 2004
+++ eggdrop1.9/lib/eggdrop/hash_table.c	Sun Sep 26 04:42:09 2004
@@ -18,15 +18,14 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: hash_table.c,v 1.12 2004/06/25 17:44:03 darko Exp $";
+static const char rcsid[] = "$Id: hash_table.c,v 1.13 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#include <eggdrop/memory.h>
-#include <eggdrop/hash_table.h>
+#include <eggdrop/eggdrop.h>
 
 static unsigned int my_string_hash(const void *key);
 static unsigned int my_int_hash(const void *key);
Index: eggdrop1.9/lib/eggdrop/memory.h
diff -u eggdrop1.9/lib/eggdrop/memory.h:1.2 eggdrop1.9/lib/eggdrop/memory.h:1.3
--- eggdrop1.9/lib/eggdrop/memory.h:1.2	Tue Jun 22 16:55:32 2004
+++ eggdrop1.9/lib/eggdrop/memory.h	Sun Sep 26 04:42:09 2004
@@ -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: memory.h,v 1.2 2004/06/22 21:55:32 wingman Exp $
+ * $Id: memory.h,v 1.3 2004/09/26 09:42:09 stdarg Exp $
  */
 #ifndef _EGG_MEMORY_H
 #define _EGG_MEMORY_H
@@ -27,7 +27,7 @@
 #define MEM_DEBUG_PRINT_EACH_CALL	(1 << 1)
 #define MEM_DEBUG_PRINT_ERRORS		(1 << 2)
 
-#ifdef DEBUG
+#if 0
 
 /* calloc */
 #	ifdef calloc
Index: eggdrop1.9/lib/eggdrop/memutil.c
diff -u eggdrop1.9/lib/eggdrop/memutil.c:1.18 eggdrop1.9/lib/eggdrop/memutil.c:1.19
--- eggdrop1.9/lib/eggdrop/memutil.c:1.18	Fri Jun 25 12:44:03 2004
+++ eggdrop1.9/lib/eggdrop/memutil.c	Sun Sep 26 04:42:09 2004
@@ -19,7 +19,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: memutil.c,v 1.18 2004/06/25 17:44:03 darko Exp $";
+static const char rcsid[] = "$Id: memutil.c,v 1.19 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -28,8 +28,7 @@
 #include <string.h>
 #include <stdarg.h>
 
-#include <eggdrop/memory.h>
-#include <eggdrop/memutil.h>
+#include <eggdrop/eggdrop.h>
 
 void str_redup(char **str, const char *newstr)
 {
Index: eggdrop1.9/lib/eggdrop/module.c
diff -u eggdrop1.9/lib/eggdrop/module.c:1.4 eggdrop1.9/lib/eggdrop/module.c:1.5
--- eggdrop1.9/lib/eggdrop/module.c:1.4	Wed Jun 23 16:12:57 2004
+++ eggdrop1.9/lib/eggdrop/module.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: module.c,v 1.4 2004/06/23 21:12:57 stdarg Exp $";
+static const char rcsid[] = "$Id: module.c,v 1.5 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <ltdl.h>
@@ -101,8 +101,15 @@
 
 	startfunc = (egg_start_func_t)lt_dlsym(hand, "start");
 	if (!startfunc) {
-		lt_dlclose(hand);
-		return(-3);
+		char *startname;
+
+		startname = egg_mprintf("%s_LTX_start", name);
+		startfunc = (egg_start_func_t)lt_dlsym(hand, startname);
+		free(startname);
+		if (!startfunc) {
+			lt_dlclose(hand);
+			return(-3);
+		}
 	}
 
 	/* Create an entry for it. */
@@ -160,7 +167,7 @@
 {
 	if (name == NULL) return 0;
 
-	return (find_module (name) != NULL);
+	return (find_module(name) != NULL);
 }
 
 void *module_get_api(const char *name, int major, int minor)
Index: eggdrop1.9/lib/eggdrop/users.c
diff -u eggdrop1.9/lib/eggdrop/users.c:1.40 eggdrop1.9/lib/eggdrop/users.c:1.41
--- eggdrop1.9/lib/eggdrop/users.c:1.40	Sat Jul 17 15:59:38 2004
+++ eggdrop1.9/lib/eggdrop/users.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: users.c,v 1.40 2004/07/17 20:59:38 darko Exp $";
+static const char rcsid[] = "$Id: users.c,v 1.41 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -112,13 +112,13 @@
 
 int user_load(const char *fname)
 {
-	int i, j, k, uid;
+	int j, k, uid;
 	xml_node_t *doc, *root, *user_node, *setting_node;
 	user_setting_t *setting;
 	char *handle, *ircmask, *chan, *name, *value, *flag_str;
 	user_t *u;
 
-	if (xml_load_file(fname, &doc, XML_TRIM_TEXT) != 0) {
+	if (!(doc = xml_parse_file(fname))) {
 		putlog(LOG_MISC, "*", _("Failed to load userfile '%s': %s"), fname, xml_last_error());
 		return -1;
 	}
@@ -133,10 +133,8 @@
 
 	g_uid = uid;
 	xml_node_get_int(&uid_wraparound, root, "uid_wraparound", 0, 0);
-	for (i = 0; i < root->nchildren; i++) {
-		user_node = root->children[i];
-		if (strcasecmp(user_node->name, "user")) continue;
-
+	user_node = xml_node_lookup(root, 0, "user", 0, 0);
+	for (; user_node; user_node = user_node->next_sibling) {
 		/* The only required user fields are 'handle' and 'uid'. */
 		xml_node_get_str(&handle, user_node, "handle", 0, 0);
 		xml_node_get_int(&uid, user_node, "uid", 0, 0);
@@ -672,16 +670,12 @@
 {
 	char hash[16], hashhex[33], *salt, new_salt[33];
 	MD5_CTX ctx;
-	int i;
 
 	user_get_setting(u, NULL, "salt", &salt);
 	if (!salt) {
 		salt = new_salt;
-		for (i = 0; i < 32; i++) {
-			new_salt[i] = random() % 26 + 'A';
-		}
-		new_salt[i] = 0;
-		user_set_setting(u, NULL, "salt", new_salt);
+		user_rand_pass(salt, sizeof(new_salt));
+		user_set_setting(u, NULL, "salt", salt);
 	}
 
 	if (!pass || !*pass) {
@@ -708,7 +702,7 @@
 	int i, c;
 
 	bufsize--;
-	if (!buf || bufsize < 0) return(-1);
+	if (!buf || bufsize <= 0) return(-1);
 	for (i = 0; i < bufsize; i++) {
 		c = (random() + (random() >> 16) + (random() >> 24)) % 62;
 		if (c < 10) c += 48;	/* Digits. */
@@ -740,20 +734,19 @@
 	return user_check_flags (u, chan, &f);
 }
 
-int
-user_change_handle(user_t *u, const char *old, const char *new)
+int user_change_handle(user_t *u, const char *newhandle)
 {
-	partymember_t *p;
+	partymember_t *p = NULL;
 
-	hash_table_remove(handle_ht, old, NULL);
+	p = partymember_lookup_nick(u->handle);
+	hash_table_remove(handle_ht, u->handle, NULL);
 	free(u->handle);
-	u->handle = strdup(new);
-	hash_table_insert(handle_ht, new, u);
-	if ((p = partymember_lookup_nick(old))) { /* Is person online? */
-		partymember_set_nick(p, new);
-		return 0;
+	u->handle = strdup(newhandle);
+	hash_table_insert(handle_ht, u->handle, u);
+	if (p) { /* Is person online? */
+		partymember_set_nick(p, u->handle);
 	}
-	return 1;
+	return(0);
 }
 
 static int
Index: eggdrop1.9/lib/eggdrop/users.h
diff -u eggdrop1.9/lib/eggdrop/users.h:1.13 eggdrop1.9/lib/eggdrop/users.h:1.14
--- eggdrop1.9/lib/eggdrop/users.h:1.13	Sat Jul 17 15:59:38 2004
+++ eggdrop1.9/lib/eggdrop/users.h	Sun Sep 26 04:42:09 2004
@@ -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: users.h,v 1.13 2004/07/17 20:59:38 darko Exp $
+ * $Id: users.h,v 1.14 2004/09/26 09:42:09 stdarg Exp $
  */
 
 #ifndef _EGG_USERS_H_
@@ -95,7 +95,7 @@
 int user_set_pass(user_t *u, const char *pass);
 int user_count();
 int user_rand_pass(char *buf, int bufsize);
-int user_change_handle(user_t *u, const char *old, const char *new);
+int user_change_handle(user_t *u, const char *newhandle);
 int partyline_cmd_match_ircmask(void *p, const char *mask, long start, long limit);
 int partyline_cmd_match_attr(void *p, const char *attr, const char *chan, long start, long limit);
 
Index: eggdrop1.9/lib/eggdrop/xml.c
diff -u eggdrop1.9/lib/eggdrop/xml.c:1.19 eggdrop1.9/lib/eggdrop/xml.c:1.20
--- eggdrop1.9/lib/eggdrop/xml.c:1.19	Wed Jun 30 16:07:02 2004
+++ eggdrop1.9/lib/eggdrop/xml.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: xml.c,v 1.19 2004/06/30 21:07:02 stdarg Exp $";
+static const char rcsid[] = "$Id: xml.c,v 1.20 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -27,71 +27,48 @@
 #include <stdarg.h>
 #include <ctype.h>			/* isdigit		*/
 
+#include <eggdrop/eggdrop.h>
+
 #include "xml.h"			/* prototypes		*/
 
 #define XML_PATH_SEPARATOR '/'
 
-xml_amp_conversion_t builtin_conversions[] =
-{
-	{"quot",	'"'  },
-	{"lt",		'<'  },
-	{"gt",		'>'  },
-	{"amp",		'&'  },
-	{"apos",	'\'' },
-	{"nbsp",	' '  },
-	{0}
-};
 
-char *last_error = NULL;
+static char *last_error = NULL;
 
 const char *xml_last_error(void)
 {
 	return last_error;
 }
 
-/* Get a new, blank node. */
-xml_node_t *xml_node_new(void)
+void xml_set_error(const char *err)
 {
-	xml_node_t *node;
-
-	node = (xml_node_t *)malloc(sizeof(xml_node_t));
-	if (node == NULL)
-		return NULL;
-	memset(node, 0, sizeof(xml_node_t));
-
-	/* default value is STRING NULL */
-	node->data.value.s_val = NULL;
-	node->data.type = VARIANT_STRING;
-
-	/* default type is element */	
-	node->type = XML_ELEMENT;
-	
-	return node;
+	str_redup(&last_error, err);
 }
 
-xml_node_t *xml_create_element(const char *name)
+/* Get a new, blank node. */
+xml_node_t *xml_node_new(void)
 {
 	xml_node_t *node;
-	
-	node = xml_node_new();
-	node->name = (name) ? strdup(name) : NULL;
+
+	node = calloc(sizeof(*node), 1);
 	
 	return node;
 }
 
-xml_node_t *xml_create_attribute(const char *name)
+/* Free all memory associated with a node. */
+void xml_node_free(xml_node_t *node)
 {
 	xml_attr_t *attr;
-	
-	attr = malloc(sizeof(xml_attr_t));
-	if (attr == NULL)
-		return NULL;
-	memset(attr, 0, sizeof(xml_attr_t));
-	
-	attr->type = XML_ATTRIBUTE;
-	attr->name = (name) ? strdup(name) : NULL;
-	
-	return (xml_node_t *)attr;
+	int i;
+
+	if (node->name) free(node->name);
+	if (node->text) free(node->text);
+	for (i = 0; i < node->nattributes; i++) {
+		attr = node->attributes[i];
+		xml_attr_free(attr);
+	}
+	if (node->attributes) free(node->attributes);
 }
 
 void xml_node_delete(xml_node_t *node)
@@ -101,61 +78,36 @@
 
 void xml_node_delete_callbacked(xml_node_t *node, void (*callback)(void *))
 {
-	int i;
+	xml_node_t *child;
 
-	if (node->client_data && callback)
-		callback(node->client_data);
+	if (node->client_data && callback) callback(node->client_data);
 
 	if (node->parent) {
 		xml_node_t *parent = node->parent;
-		for (i = 0; i < parent->nchildren; i++) {
-			if (parent->children[i] == node) break;
-		}
-		if (parent->nchildren == 1) {
-			free(parent->children);	parent->children = NULL;
-		} else {
-			memmove(parent->children+i, parent->children+i+1, sizeof(node) * (parent->nchildren-i-1));
-		}
-		parent->nchildren--;
-	}
 
-	/* free attributes */
-	for (i = 0; i < node->nattributes; i++) {
-		if (node->attributes[i].name) free(node->attributes[i].name);
-		if (node->attributes[i].data.type == VARIANT_STRING) {
-			if (node->attributes[i].data.value.s_val)
-				free(node->attributes[i].data.value.s_val);
-		}
-	}
-	if (node->attributes) free(node->attributes);
+		parent->nchildren--;
+		if (parent->children == node) parent->children = node->next;
+		if (parent->last_child == node) parent->last_child = node->prev;
 
-	/* free children */
-	for (i = 0; i < node->nchildren; i++) {
-		node->children[i]->parent = NULL;
-		xml_node_delete_callbacked(node->children[i], callback);
+		node->parent = NULL;
 	}
-	if (node->children) free(node->children);
 
-	/* only string needs to be free'd */
-	if (node->data.type == VARIANT_STRING)
-		free(node->data.value.s_val);
+	/* Unlink from node list. */
+	if (node->prev) node->prev->next = node->next;
+	if (node->next) node->next->prev = node->prev;
 
-	free(node->name);
-	free(node);
-}
+	/* Unlink from sibling list. */
+	if (node->prev_sibling) node->prev_sibling->next_sibling = node->next_sibling;
+	if (node->next_sibling) node->next_sibling->prev_sibling = node->prev_sibling;
 
-const char *xml_node_type(xml_node_t *node)
-{
-	switch (node->type) {
-		case (XML_DOCUMENT): return "XML_DOCUMENT";
-		case (XML_ELEMENT): return "XML_ELEMENT";
-		case (XML_CDATA_SECTION): return "XML_CDATA_SECTION";
-		case (XML_PROCESSING_INSTRUCTION): return "XML_PROCESSING_INSTRUCTION";
-		case (XML_COMMENT): return "XML_COMMENT";
-		case (XML_ATTRIBUTE): return "XML_ATTRIBUTE";
+	/* Delete children. */
+	for (child = node->children; child; child = child->next) {
+		child->parent = NULL;
+		xml_node_delete_callbacked(child, callback);
 	}
 
-	return "unknown";
+	/* Free memory taken by node. */
+	xml_node_free(node);
 }
 
 xml_node_t *xml_node_vlookup(xml_node_t *root, va_list args, int create)
@@ -185,8 +137,8 @@
 
 xml_node_t *xml_node_path_lookup(xml_node_t *root, const char *path, int index, int create)
 {
-	int i, thisindex, len;
-	xml_node_t *child, *newchild;
+	int thisindex, len;
+	xml_node_t *child;
 	const char *next;
 	char *name, *sep, buf[512];
 
@@ -228,52 +180,26 @@
 		/* If it's the last path element, add the index param. */
 		if (!next) thisindex += index;
 
-		child = NULL;
-		if (name[0] == '@') {
-			for (i = 0; i < root->nattributes; i++) {
-				if (strcasecmp(root->attributes[i].name, name + 1) == 0) {
-					child = (xml_node_t *)&root->attributes[i];
-					break;
-				}
-			}
+		for (child = root->children; child; child = child->next) {
+			if (child->name && !strcasecmp(child->name, name)) break;
 		}
-		else {
-			for (i = 0; i < root->nchildren; i++) {			
-				if (root->children[i]->name && !strcasecmp(root->children[i]->name, name)) {
-					if (thisindex-- > 0) continue;
-					child = root->children[i];
-					break;
-				}
-			}
+
+		while (child && thisindex > 0) {
+			thisindex--;
+			child = child->next_sibling;
 		}
 
 		if (!child && create) {
-			if (0 == strcmp(name, "."))
-				return NULL;
-				
 			do {		
-				if (name[0] == '@') {
-					root->attributes = realloc(root->attributes,
-						(root->nattributes + 1) * sizeof(xml_attr_t));
-					newchild = (xml_node_t *)&root->attributes[root->nattributes++];
-					memset(newchild, 0, sizeof(xml_attr_t));
-					newchild->name = strdup(name + 1);
-					newchild->type = XML_ATTRIBUTE;
-				} else {		
-					newchild = xml_create_element(name);
-					xml_node_append(root, newchild);
-				}									
-				
-				child = newchild;
+				child = xml_node_new();
+				child->type = XML_ELEMENT;
+				child->name = strdup(name);
+				xml_node_append(root, child);
 			} while (thisindex-- > 0);
 		}
-		
+		if (name != buf) free(name);
+
 		root = child;
-		if (root && root->type == XML_ATTRIBUTE)
-			break;
-			
-		if (name != buf)
-			free(name);
 	}
 	return(root);
 }
@@ -312,14 +238,25 @@
 	va_start(args, node);
 	node = xml_node_vlookup(node, args, 0);
 	va_end(args);
-	if (node) {
-		*value = variant_get_int(&node->data, 0);
+	if (node && node->text) {
+		*value = strtol(node->text, NULL, 0);
 		return(0);
 	}
 	*value = 0;
 	return(-1);
 }
 
+int xml_node_int(xml_node_t *node, int def)
+{
+	int value;
+	char *ptr;
+
+	if (!node || !node->text) return(def);
+	value = strtol(node->text, &ptr, 0);
+	if (!ptr || *ptr) return(def);
+	else return(value);
+}
+
 int xml_node_get_str(char **str, xml_node_t *node, ...)
 {
 	va_list args;
@@ -328,15 +265,22 @@
 	node = xml_node_vlookup(node, args, 0);
 	va_end(args);
 	if (node) {
-		*str = (char *)variant_get_str(&node->data, NULL);
+		*str = node->text;
 		return(0);
 	}
 	*str = NULL;
 	return(-1);
 }
 
+char *xml_node_str(xml_node_t *node, char *def)
+{
+	if (!node || !node->text) return(def);
+	else return(node->text);
+}
+
 int xml_node_set_int(int value, xml_node_t *node, ...)
 {
+	char buf[32];
 	va_list args;
 
 	va_start(args, node);
@@ -344,7 +288,8 @@
 	va_end(args);
 	if (!node) return(-1);
 
-	variant_set_int(&node->data, value);
+	snprintf(buf, sizeof(buf), "%d", value);
+	str_redup(&node->text, buf);
 
 	return(0);
 }
@@ -358,213 +303,95 @@
 	va_end(args);
 	if (!node) return(-1);
 
-	variant_set_str(&node->data, str);
+	str_redup(&node->text, str);
 
 	return(0);
 }
 
 xml_node_t *xml_root_element(xml_node_t *node)
 {
-	 int i;
-
-	 if (node == NULL)
-		  return NULL;
+	 if (node == NULL) return NULL;
 
-	 while (node && node->parent)
-		  node = node->parent;
+	 /* Zoom up to the document. */
+	 while (node && node->parent) node = node->parent;
 
-	 for (i = 0; i < node->nchildren; i++)
-		if (node->children[i]->type == XML_ELEMENT)
-			return node->children[i];
-	 return NULL;
-}
-
-xml_attr_t *xml_node_lookup_attr(xml_node_t *node, const char *name)
-{
-	int i;
-
-	for (i = 0; i < node->nattributes; i++) {
-		if (strcasecmp(node->attributes[i].name, name) == 0)
-			return &node->attributes[i];
-	}
-
-	return NULL;
-}
-
-void xml_node_remove(xml_node_t *parent, xml_node_t *child)
-{
-	int i;
-
-	for (i = 0; i < parent->nchildren; i++) {
-		if (parent->children[i] != child)
-			continue;
-
-		if (parent->nchildren == 1) {
-			free(parent->children); parent->children = NULL;
-		} else {
-			memmove(parent->children + i,
-				parent->children + i + 1,
-					parent->nchildren -i - 1);
-			parent->children = realloc(parent->children, (parent->nchildren - 1) * sizeof(xml_node_t *));
-		}
-		parent->nchildren--;
-
-		child->prev = NULL;
-		child->parent = NULL;
-		child->next = NULL;
-		return;
-	}
+	 /* Find first element. */
+	 node = node->children;
+	 while (node && node->type != XML_ELEMENT) node = node->next;
+	 return node;
 }
 
 void xml_node_append(xml_node_t *parent, xml_node_t *child)
 {	
-	if (child->type == XML_ATTRIBUTE) {
-		xml_node_append_attr(parent, (xml_attr_t *)child);
-		return;		
-	}
-	
-	/* remove from previous parent */
-	if (child->parent)
-		xml_node_remove(child->parent, child);
-
-	parent->children = realloc(parent->children, sizeof(xml_node_t *) * (parent->nchildren + 1));
-	parent->children[parent->nchildren] = child;
-
-	if (parent->nchildren > 0)
-		parent->children[parent->nchildren - 1]->next = child;
+	xml_node_t *node;
 
-	/* set new parent */
 	child->parent = parent;
-
 	parent->nchildren++;
-}
 
-void xml_node_append_attr (xml_node_t *node, xml_attr_t *attr)
-{
-	xml_attr_t *a;
-		
-	a = xml_node_lookup_attr (node, attr->name);
-	if (a == NULL) {
-		node->attributes = (xml_attr_t *)realloc(
-			node->attributes, sizeof(xml_attr_t) * (node->nattributes+1));
-		a = &node->attributes[node->nattributes++];
+	if (!parent->children) {
+		parent->children = child;
+	}
+	else {
+		parent->last_child->next = child;
+		child->prev = parent->last_child;
 	}
-	
-	a->type = XML_ATTRIBUTE;
-	a->name = attr->name;
-	
-	memcpy(&a->data, &attr->data, sizeof(attr->data));
-}
 
-void xml_node_remove_attr (xml_node_t *node, xml_attr_t *attr)
-{
-	int i;
+	parent->last_child = child;
 
-	for (i = 0; i < node->nattributes; i++) {
-		if (strcasecmp(node->attributes[i].name, attr->name) == 0) {
-			if (node->nattributes == 1) {
-				free (node->attributes); node->attributes = NULL;
-			} else {
-				memmove (node->attributes + i,
-					node->attributes + i + 1,
-						sizeof (xml_attr_t) * 
-							node->nattributes - i - 1);
-			}
-			node->nattributes--;
-			return;
+	for (node = child->prev; node; node = node->prev) {
+		if (!strcasecmp(node->name, child->name)) {
+			node->next_sibling = child;
+			child->prev_sibling = node;
+			break;
 		}
 	}
 }
 
-static xml_attr_t *xml_node_create_attr(xml_node_t *node, const char *name)
+xml_attr_t *xml_attr_new(char *name, char *value)
 {
 	xml_attr_t *attr;
-	
-	node->attributes = (xml_attr_t *)realloc(
-		node->attributes, sizeof(xml_attr_t) * (node->nattributes+1));
-	attr = &node->attributes[node->nattributes++];
-	memset(attr, 0, sizeof(xml_attr_t));
-		
-	attr->name = strdup(name);
-	
-	return attr;
-}
-
 
-#define XML_DEFINE_GET_AND_SET(name, type) \
-	void xml_set_text_## name(xml_node_t *node, type value) \
-	{ \
-		if (node == NULL) return; \
-		variant_set_## name(&node->data, value); \
-	} \
-	\
-	type xml_get_text_## name(xml_node_t *node, type nil) \
-	{ \
-		if (node == NULL) return nil; \
-		return variant_get_## name(&node->data, nil); \
-	} \
-	type xml_get_attr_## name(xml_node_t *node, const char *n, type nil) \
-	{ \
-		xml_attr_t *attr; \
-		attr = xml_node_lookup_attr(node, n); \
-		if (attr == NULL) return nil; \
-		return variant_get_## name(&attr->data, nil); \
-	} \
-	void xml_set_attr_## name(xml_node_t *node, const char *n, type value) \
-	{ \
-		xml_attr_t *attr; \
-		attr = xml_node_lookup_attr(node, n); \
-		if (attr == NULL) attr = xml_node_create_attr(node, n); \
-		variant_set_## name(&attr->data, value); \
-	}
-
-XML_DEFINE_GET_AND_SET(str, const char *)
-XML_DEFINE_GET_AND_SET(int, int)
-XML_DEFINE_GET_AND_SET(bool, int)
-XML_DEFINE_GET_AND_SET(ts, time_t)
+	attr = malloc(sizeof(*attr));
+	attr->name = name;
+	attr->value = value;
+	attr->len = strlen(value);
+	return(attr);
+}
 
-void xml_dump_data(variant_t *data)
+void xml_attr_free(xml_attr_t *attr)
 {
-	switch (data->type) {
-
-		case (VARIANT_STRING):
-			printf("%s (STRING)\n", data->value.s_val);
-			break;
-
-		case (VARIANT_INT):
-			printf("%i (INT)\n", data->value.i_val);
-			break;
-
-		case (VARIANT_BOOL):
-			printf("%s (BOOL)\n", (data->value.b_val) ? "yes" : "no");
-			break;
+	if (attr->name) free(attr->name);
+	if (attr->value) free(attr->value);
+	free(attr);
+}
 
-		case (VARIANT_TIMESTAMP):
-			printf("%li (TIMESTAMP)\n", data->value.ts_val);
-			break;
-	}
+int xml_node_append_attr(xml_node_t *node, xml_attr_t *attr)
+{
+	node->attributes = realloc(node->attributes, sizeof(*node->attributes) * (node->nattributes+1));
+	node->attributes[node->nattributes++] = attr;
+	return(0);
 }
 
-void xml_dump(xml_node_t *node)
+xml_attr_t *xml_attr_lookup(xml_node_t *node, const char *name)
 {
 	int i;
 
-	printf("%s %s\n", node->name, xml_node_type(node));
 	for (i = 0; i < node->nattributes; i++) {
-		printf("\t%s: ", node->attributes[i].name);
-		xml_dump_data(&node->attributes[i].data);	
-	}
-	for (i = 0; i < node->nchildren; i++) {
-		xml_dump(node->children[i]);
+		if (!strcasecmp(node->attributes[i]->name, name)) return(node->attributes[i]);
 	}
+	return(NULL);
 }
 
-void xml_node_remove_by_name(xml_node_t *parent, const char *name)
+int xml_attr_int(xml_node_t *node, const char *name, int def)
 {
-	int i;
+	xml_attr_t *attr = xml_attr_lookup(node, name);
+	if (attr && attr->value) return atoi(attr->value);
+	else return(def);
+}
 
-	for (i = parent->nchildren - 1; i >= 0; i--) {
-		if (0 == strcmp(parent->children[i]->name, name))
-			xml_node_remove(parent, parent->children[i]);
-	}
+char *xml_attr_str(xml_node_t *node, const char *name, char *def)
+{
+	xml_attr_t *attr = xml_attr_lookup(node, name);
+	if (attr && attr->value) return(attr->value);
+	else return(def);
 }
Index: eggdrop1.9/lib/eggdrop/xml.h
diff -u eggdrop1.9/lib/eggdrop/xml.h:1.18 eggdrop1.9/lib/eggdrop/xml.h:1.19
--- eggdrop1.9/lib/eggdrop/xml.h:1.18	Wed Jun 30 12:07:20 2004
+++ eggdrop1.9/lib/eggdrop/xml.h	Sun Sep 26 04:42:09 2004
@@ -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: xml.h,v 1.18 2004/06/30 17:07:20 wingman Exp $
+ * $Id: xml.h,v 1.19 2004/09/26 09:42:09 stdarg Exp $
  */
 
 #ifndef _EGG_XML_H_
@@ -24,9 +24,6 @@
 
 #include <stdio.h>			/* FILE			*/
 #include <stdarg.h>			/* va_list		*/
-#include <eggdrop/variant.h>		/* variant_t		*/
-
-typedef struct xml_node xml_node_t;
 
 #define XML_NONE	(1 << 0)
 #define XML_INDENT	(1 << 1)
@@ -44,35 +41,38 @@
 } xml_node_type_t;
 
 typedef struct {
-	xml_node_type_t type;
 	char *name;
-	variant_t data;	
-	void *client_data;	
+	char *value;
+	int len;
 } xml_attr_t;
 
 typedef struct {
-	char *key;
-	char value;
-} xml_amp_conversion_t;
+	char *name;
+	char *value;
+} xml_entity_t;
 
-struct xml_node
-{
+typedef struct xml_node {
 	xml_node_type_t type;
 	char *name;
-	variant_t data;
+
+	char *text;
+	int len;
+
 	void *client_data;
 	
-	xml_node_t *next;
-	xml_node_t *prev;
-	xml_node_t *parent;
-	xml_node_t **children;
+	struct xml_node *next, *prev;
+	struct xml_node *next_sibling, *prev_sibling;
+	struct xml_node *parent, *children, *last_child;
 	int nchildren;
 
-	int whitespace;
-
-	xml_attr_t *attributes;
+	xml_attr_t **attributes;
 	int nattributes;	
-};
+} xml_node_t;
+
+typedef struct {
+	char *filename;
+	xml_node_t *root;
+} xml_document_t;
 
 xml_node_t *xml_node_vlookup(xml_node_t *root, va_list args, int create);
 xml_node_t *xml_node_lookup(xml_node_t *root, int create, ...);
@@ -81,65 +81,28 @@
 char *xml_node_fullname(xml_node_t *node);
 
 int xml_node_get_str(char **str, xml_node_t *node, ...);
+char *xml_node_str(xml_node_t *node, char *def);
 int xml_node_set_str(const char *str, xml_node_t *node, ...);
 
 int xml_node_get_int(int *value, xml_node_t *node, ...);
+int xml_node_int(xml_node_t *node, int def);
 int xml_node_set_int(int value, xml_node_t *node, ...);
 
-void xml_dump(xml_node_t *node);
-
 xml_node_t *xml_node_new(void);
+void xml_node_free(xml_node_t *node);
 void xml_node_delete(xml_node_t *node);
 void xml_node_delete_callbacked(xml_node_t *node, void (*callback)(void *));
-
-xml_node_t *xml_create_element(const char *name);
-xml_node_t *xml_create_attribute(const char *name);
-
-const char *xml_last_error(void);
-const char *xml_node_type(xml_node_t *node);
-
-xml_node_t *xml_root_element(xml_node_t *node);
-
 void xml_node_append(xml_node_t *parent, xml_node_t *child);
-void xml_node_remove(xml_node_t *parent, xml_node_t *child);
-void xml_node_remove_by_name(xml_node_t *parent, const char *name);
-
-void xml_set_text_int(xml_node_t *node, int value);
-int xml_get_text_int(xml_node_t *node, int nil);
-
-void xml_set_text_str(xml_node_t *node, const char *value);
-const char *xml_get_text_str(xml_node_t *node, const char *nil);
-
-time_t xml_get_text_ts(xml_node_t *node, time_t nil);
-void xml_set_text_ts(xml_node_t *node, time_t value);
-
-int xml_get_text_bool(xml_node_t *node, int nil);
-void xml_set_text_bool(xml_node_t *node, int value);
 
-xml_attr_t *xml_node_lookup_attr(xml_node_t *node, const char *name);
-void xml_node_append_attr(xml_node_t *parent, xml_attr_t *attr);
-void xml_node_remove_attr(xml_node_t *parent, xml_attr_t *attr);
-
-void xml_set_attr_int(xml_node_t *node, const char *name, int value);
-int xml_get_attr_int(xml_node_t *node, const char *name, int nil);
-
-void xml_set_attr_str(xml_node_t *node, const char *name, const char *value);
-const char *xml_get_attr_str(xml_node_t *node, const char *name, const char *nil);
-
-time_t xml_get_attr_ts(xml_node_t *node, const char *name, time_t nil);
-void xml_set_attr_ts(xml_node_t *node, const char *name, time_t value); 
-
-int xml_get_attr_bool(xml_node_t *node, const char *name, int nil);
-void xml_set_attr_bool(xml_node_t *node, const char *name, int value);
+xml_node_t *xml_root_element(xml_node_t *node);
 
-/* load */
-int xml_load(FILE *fd, xml_node_t **node, int options);
-int xml_load_file(const char *file, xml_node_t **node, int options);
-int xml_load_str(char *str, xml_node_t **node, int options);
+xml_attr_t *xml_attr_new(char *name, char *value);
+void xml_attr_free(xml_attr_t *attr);
+int xml_node_append_attr(xml_node_t *node, xml_attr_t *attr);
 
-/* save */
-int xml_save(FILE *fd, xml_node_t *node, int options);
+xml_node_t *xml_parse_file(const char *fname);
 int xml_save_file(const char *file, xml_node_t *node, int options);
-int xml_save_str(char **str, xml_node_t *node, int options);
+void xml_set_error(const char *err);
+const char *xml_last_error(void);
 
 #endif /* !_EGG_XML_H_ */
Index: eggdrop1.9/lib/eggdrop/xmlread.c
diff -u eggdrop1.9/lib/eggdrop/xmlread.c:1.17 eggdrop1.9/lib/eggdrop/xmlread.c:1.18
--- eggdrop1.9/lib/eggdrop/xmlread.c:1.17	Mon Jun 28 12:36:34 2004
+++ eggdrop1.9/lib/eggdrop/xmlread.c	Sun Sep 26 04:42:09 2004
@@ -1,468 +1,336 @@
-/* xmlread.c: xml parser
- *
- * Copyright (C) 2002, 2003, 2004 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id: xmlread.c,v 1.17 2004/06/28 17:36:34 wingman Exp $";
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <eggdrop/eggdrop.h>
+
+static const char *name_terminators = "= \t\n\r?/>";
 
-#include <eggdrop/memutil.h>
-#include <eggdrop/memory.h>
-#include <eggdrop/xml.h>
-
-extern xml_amp_conversion_t builtin_conversions[];	/* from xml.c		*/
-extern char *last_error;				/* from xml.c		*/
-
-static int read_options = XML_NONE;
-
-/* These are pretty much in 'most common' order. */
-static const char *spaces = " \t\n\r\v";
-static const char *name_terminators = "= \t\n\r\v?/>";
-
-/*
- * Skip over whitespace.
- * Return number of bytes we used up.
- */
-int skip_whitespace(char **data)
+int xml_parse_children(xml_node_t *parent, char **bufptr);
+
+static xml_entity_t entities[] = {
+	{"lt", "<"},
+	{"gt", ">"},
+	{"amp", "&"},
+	{"apos", "'"},
+	{"quot", "\""}
+};
+static int nentities = 5;
+
+static int skip_space(char **bufptr)
 {
-	int n;
+	char *start, *ptr;
 
-	n = strspn(*data, spaces);
-	*data += n;
-	return(n);
+	start = ptr = *bufptr;
+	while (isspace(*ptr)) ptr++;
+	*bufptr = ptr;
+	return(ptr - start);
 }
 
-/*
- * Read in data up to a space, =, >, or ?
- */
-static void read_name(char **data, char **name)
+static void copy_text(char **ptr, int *ptrlen, int *ptrmax, char *str, int len)
 {
-	int n;
-
-	n = strcspn(*data, name_terminators);
-	if (!n) {
-		*name = NULL;
-		return;
+	if (*ptrlen + len + 1 > *ptrmax) {
+		*ptrmax = *ptrlen + len + 64;
+		*ptr = realloc(*ptr, *ptrmax);
 	}
-	*name = (char *)malloc(n+1);
-	memcpy(*name, *data, n);
-	(*name)[n] = 0;
-
-	*data += n;
+	memcpy(*ptr + *ptrlen, str, len);
+	*ptrlen += len;
 }
 
-/*
- * Read in an attribute value.
- */
-static void read_value(char **data, char **value)
+char *xml_entity_lookup(const char *name)
 {
-	const char *terminator;
-	int n;
-
-	/* It's supposed to startwith ' or ", but we'll take no ' or " to mean
-		it's a one word value. */
+	int i, num;
+	static char numcode[2] = {0, 0};
 
-	if (**data == '\'') terminator = "'";
-	else if (**data == '"') terminator = "\"";
-	else {
-		terminator = name_terminators;
-		(*data)--;
+	/* See if it's a hex code. */
+	if (*name == '#') {
+		name++;
+		if (*name == 'x') num = strtol(name+1, NULL, 16);
+		else num = strtol(name, NULL, 10);
+		numcode[0] = num;
+		return(numcode);
 	}
 
-	/* Skip past first ' or " so we can find the ending one. */
-	(*data)++;
+	for (i = 0; i < nentities; i++) {
+		if (!strcasecmp(entities[i].name, name)) return(entities[i].value);
+	}
+	return(NULL);
+}
 
-	n = strcspn(*data, terminator);
-	*value = (char *)malloc(n+1);
-	memcpy(*value, *data, n);
-	(*value)[n] = 0;
+int xml_decode_text(char *text, int len, char **outtext, int *outlen)
+{
+	char *amp, *colon, *entity;
+	int outmax, amplen;
 
-	/* Skip past closing ' or ". */
-	if (terminator != name_terminators) n++;
-	*data += n;
+	*outlen = 0;
+	outmax = len+1;
+	*outtext = malloc(outmax);
+
+	len -= skip_space(&text);
+
+	while ((amp = memchr(text, '&', len))) {
+		amplen = amp - text;
+		colon = memchr(amp, ';', len - amplen);
+		if (!colon) break;
+		copy_text(outtext, outlen, &outmax, text, amplen);
+		len -= (colon+1 - text);
+		text = colon+1;
+		*colon = 0;
+		entity = xml_entity_lookup(amp+1);
+		if (entity) copy_text(outtext, outlen, &outmax, entity, strlen(entity));
+	}
+	while (len > 0 && isspace(text[len-1])) len--;
+	copy_text(outtext, outlen, &outmax, text, len);
+	return(0);
 }
 
-static void read_text(xml_node_t *node, char **data)
+static void append_text(xml_node_t *node, char *text, int len, int decode)
 {
-	char *end;
-	char *text;
-	int len, node_len;
-
-	/* Find end-point. */
-	end = strchr(*data, '<');
-	if (!end) end = *data + strlen(*data);
+	char *finaltext;
+	int finallen;
 
-	/* Get length of text. */
-	len = end - *data;
-	node_len = (node->data.value.s_val) ? strlen(node->data.value.s_val) : 0;
+	if (decode) xml_decode_text(text, len, &finaltext, &finallen);
+	else {
+		finaltext = text;
+		finallen = len;
+	}
 
-	/* Add it to the node's current text value. */
-	text = (char *)realloc(node->data.value.s_val, len + node_len + 1);
-	memcpy(text + node_len, *data, len);
-	node->data.value.s_val = text;
-	node_len += len;
-	text[node_len] = 0;
+	node->text = realloc(node->text, node->len + finallen + 1);
+	memcpy(node->text + node->len, finaltext, finallen);
+	node->len += finallen;
+	node->text[node->len] = 0;
 
-	/* Update data to point to < (or \0). */
-	*data = end;
+	if (finaltext != text) free(finaltext);
 }
 
-/* Decoded result is guaranteed <= original. */
-int xml_decode_text(char *text)
+static char *read_name(char **bufptr)
 {
-	char *end, *result, *orig;
 	int n;
-	/* Some variables for &char; conversion. */
-	char *amp, *colon, *next;
-	int i, inlen;
-
-	inlen = (text) ? strlen(text) : 0;
-	if (!(read_options & XML_TRIM_TEXT))
-		return inlen;
-		
-	/* text = input, result = output */
-	orig = result = text;
-	end = text + inlen;
-
-	/* Can't start with a space. */
-	skip_whitespace(&text);
-
-	while (text < end) {
-		/* Get count of non-spaces. */
-		n = strcspn(text, spaces);
-
-		/* If we're supporting &char; notation, here's where it
-			happens. If we can't find the &char; in the conversions
-			table, then we leave the '&' for it by default. The
-			conversion table is defined in xml.c. */
-
-		next = text+n;
-		while (n > 0 && (amp = memchr(text, '&', n))) {
-			memmove(result, text, (amp-text));
-			result += (amp-text);
-			n -= (amp-text);
-			colon = memchr(amp, ';', n);
-			if (!colon) break;
-			*colon = 0;
-			text = colon+1;
-			n -= (colon-amp);
-			amp++; /* Skip past &. */
-			for (i = 0; builtin_conversions[i].key; i++) {
-				if (!strcasecmp(amp, builtin_conversions[i].key)) {
-					*result++ = builtin_conversions[i].value;
-					break;
-				}
-			}
-		}
-		memmove(result, text, n);
-		result += n;
-		text = next;
-
-		/* Skip over whitespace. */
-		n = skip_whitespace(&text);
-
-		/* If there was any, and it's not the end, replace it all with
-			a single space. */
-		if (n && text < end) {
-			*result++ = ' ';
-		}
-	}
-
-	*result = 0;
+	char *name;
 
-	return(result - orig);
+	n = strcspn(*bufptr, name_terminators);
+	if (!n) return NULL;
+	name = malloc(n+1);
+	memcpy(name, *bufptr, n);
+	name[n] = 0;
+	*bufptr += n;
+	return(name);
 }
 
-/* Parse a string of attributes. */
-static void read_attributes(xml_node_t *node, char **data)
+static char *read_value(char **bufptr)
 {
-	xml_attr_t attr;
-
-	for (;;) {
-		memset(&attr, 0, sizeof(xml_attr_t));
+	const char *term;
+	char *value;
+	int n;
 
-		/* Skip over any leading whitespace. */
-		skip_whitespace(data);
+	if (**bufptr == '\'') term = "'";
+	else if (**bufptr == '"') term = "\"";
+	else {
+		term = name_terminators;
+		(*bufptr)--;
+	}
 
-		/* Read in the attribute name. */
-		read_name(data, &attr.name);
-		if (!attr.name) return;
+	/* Skip past first quote. */
+	(*bufptr)++;
+	n = strcspn(*bufptr, term);
+	value = malloc(n+1);
+	memcpy(value, *bufptr, n);
+	value[n] = 0;
+
+	if (term != name_terminators) n++;
+	*bufptr += n;
+	return(value);
+}
 
-		skip_whitespace(data);
+static void read_attributes(xml_node_t *node, char **bufptr)
+{
+	xml_attr_t *attr;
+	char *name, *value;
 
-		/* Check for '=' sign. */
-		if (**data != '=') {
-			free(attr.name);
+	while (1) {
+		skip_space(bufptr);
+		name = read_name(bufptr);
+		if (!name || **bufptr != '=') {
+			if (name) free(name);
 			return;
 		}
-		(*data)++;
-
-		skip_whitespace(data);
-
-		read_value(data, &attr.data.value.s_val);
-
-		xml_node_append_attr (node, &attr);
+		(*bufptr)++;
+		value = read_value(bufptr);
+		attr = xml_attr_new(name, value);
+		xml_node_append_attr(node, attr);
 	}
 }
 
-/*
- * Read an entire node and all its children.
- * 0 - read the node successfully
- * 1 - reached end of input
- * 2 - reached end of node
- */
-static int xml_read_node(xml_node_t *parent, char **data)
+/* Parse a node. */
+int xml_parse_node(xml_node_t *parent, char **bufptr)
 {
 	xml_node_t *node;
-	int n;
-	char *end;
-	
-	/* Read in any excess data and save it with the parent. */
-	read_text(parent, data);
-
-	/* If read_text() doesn't make us point to an <, we're at the end. */
-	if (**data != '<') return(1);
-
-	/* Skip over the < and any whitespace. */
-	(*data)++;
-	skip_whitespace(data);
-
-	/* If this is a closing tag like </blah> then we're done. */
-	if (**data == '/') return(2);
-
-	/* If this is the start of the xml declaration, <?xml version=...?> then
-		we read it like a normal tag, but set the 'decl' member. */
-	if (**data == '?') {
-		(*data)++;
-	
-		node = xml_node_new();
-		node->type = XML_PROCESSING_INSTRUCTION;
-	}
-	else if (**data == '!') {
-		(*data)++;
-		if (**data == '-') {
-			/* Comment <!-- ... --> */
-			int len;
-
-			*data += 2; /* Skip past '--' part. */
-			end = strstr(*data, "-->");
-			len = end - *data;
-
-			node = xml_node_new();
-			node->data.value.s_val = (char *)malloc(len+1);
-			memcpy(node->data.value.s_val, *data, len);
-			node->data.value.s_val[len] = 0;
-
-			node->type = XML_COMMENT;
-	
-			xml_node_append(parent, node);
-			*data = end+3;
-			return(0); /* Skip past '-->' part. */
-		} else {
-			/* set error */
-			str_redup(&last_error, "Invalid comment declaration, expected character '-' not found.");
+	char *ptr, *buf = *bufptr;
+
+	if (*buf++ != '<') return(-1);
+	skip_space(&buf);
 
-			/* invalid tag start */
-			return (-1);
+	/* Is it a closing tag? (returns 0) */
+	if (*buf == '/') {
+		char *name;
+
+		if (!parent->name) return(-1);
+
+		buf++;
+		name = read_name(&buf);
+		if (strcasecmp(name, parent->name)) {
+			free(name);
+			xml_set_error("closing tag doesn't match opening tag");
+			return(-1);
 		}
-	}
-	else if (**data == '[') {
-		char *ptr;
-		size_t len;
-
-		/* we're likely to be a CDATA section, check it */
-		if (strncmp (*data, "[DATA[", 6) != 0)
-			return -1;
-		*data += 6;
-
-		/* search for ending ]]> */
-		ptr = strstr(*data, "]]>");
-		if (ptr == NULL)
-			return -1;
-		len = (size_t)(ptr - *data);
+		free(name);
 
-		/* copy text */
-		node = xml_node_new();
-		node->data.value.s_val = malloc(len + 1);
-		memcpy(node->data.value.s_val, *data, len - 1);
-		node->data.value.s_val[len] = 0;
+		ptr = strchr(buf, '>');
+		if (!ptr) return(-1);
+		*bufptr = ptr+1;
+		return(0);
+	}
 
-		/* set type */
-		node->type = XML_CDATA_SECTION;
+	/* Figure out what type of node this is. */
+	if (!strncmp(buf, "!--", 3)) {
+		/* A comment. */
+		buf += 3;
+		ptr = strstr(buf, "-->");
+		if (!ptr) {
+			xml_set_error("comment has no end");
+			return(-1);
+		}
 
-		/* add to parent */
+		node = xml_node_new();
+		node->type = XML_COMMENT;
+		append_text(node, buf, ptr-buf, 1);
 		xml_node_append(parent, node);
+		*bufptr = ptr+3;
+		return(1);
+	}
+	else if (!strncasecmp(buf, "![CDATA[", 8)) {
+		/* CDATA section. */
+		buf += 7;
+		ptr = strstr(buf, "]]>");
+		if (!ptr) {
+			xml_set_error("CDATA has no end");
+			return(-1);
+		}
 
-		/* skip text + ]]> */
-		*data += len + 3;
-
-		return 0;
-
-	} else {
+		append_text(parent, buf, ptr-buf, 0);
+		*bufptr = ptr+3;
+		return(1);
+	}
+	else if (!strncasecmp(buf, "!DOCTYPE", 8)) {
+		/* XXX Incorrect doctype parsing, fix later. */
+		buf += 8;
+		ptr = strchr(buf, '>');
+		if (!ptr) return(-1);
+		*bufptr = ptr+1;
+		return(1);
+	}
+	else if (*buf == '?') {
+		/* Processing instruction. */
+		buf++;
+		skip_space(&buf);
+		node = xml_node_new();
+		node->type = XML_PROCESSING_INSTRUCTION;
+	}
+	else {
+		/* Otherwise, try it as a normal node. */
 		node = xml_node_new();
 		node->type = XML_ELEMENT;
 	}
 
-	/* Read in the tag name. */
-	read_name(data, &node->name);
-	
-	/* sanity check for more than one document element */
-	if (parent->type == XML_DOCUMENT) {
-		int i, count = 0;
-
-		/* sanity check */
-		for (i = 0; i < parent->nchildren; i++) {
-			if (parent->children[i]->type == XML_ELEMENT)
-				count++;
-		}		
-
-		if (count > 0) {
-			str_redup(&last_error, "Only one root element allowed.");
-			return (-1);
+	node->name = read_name(&buf);
+	read_attributes(node, &buf);
+	if (node->type == XML_PROCESSING_INSTRUCTION) {
+		if (strncmp(buf, "?>", 2)) {
+			xml_node_free(node);
+			xml_set_error("invalid processing instruction");
+			return(-1);
 		}
+		xml_node_append(parent, node);
+		*bufptr = buf+2;
+		return(1);
 	}
 
-	/* Now that we have a name, go ahead and add the node to the tree. */
-	xml_node_append(parent, node);
-
-	/* Read in the attributes. */
-	read_attributes(node, data);
-
-	/* Now we should be pointing at ?, /, or >. */
-
-	/* '?' and '/' are empty tags with no children or text value. */
-	if (**data == '/' || **data == '?') {
-		end = strchr(*data, '>');
-		if (!end) return(1); /* End of input. */
-		*data = end + 1;
-		return(0);
+	/* Is it an empty tag? */
+	if (!strncmp(buf, "/>", 2)) {
+		xml_node_append(parent, node);
+		*bufptr = buf+2;
+		return(1);
 	}
-
-	/* Skip over closing '>' after attributes. */
-	(*data)++;
-
-	/* Parse children and text value. */
-	do {
-		if ((n = xml_read_node(node, data)) == -1)
-			return -1;
-	} while (n == 0);
-
-	/* Ok, the recursive xml_read_node() has read in all the text value for
-		this node, so decode it now. */
-	xml_decode_text(node->data.value.s_val);
-
-	/* Ok, now 1 means we reached end-of-input. */
-	/* 2 means we reached end-of-node. */
-	if (n == 2) {
-		/* We don't validate to make sure the start tag and end tag
-			matches. */
-		end = strchr(*data, '>');
-		if (!end) return(1);
-
-		*data = end+1;
-		return(0);
-		/* End of our node. */
+	else if (*buf != '>') {
+		xml_set_error("invalid tag");
+		return(-1);
 	}
 
-	/* Otherwise, end-of-input. */
-	return(1);
-}
-
-int xml_load(FILE *fd, xml_node_t **node, int options)
-{
-	size_t size, read;
-	char *data;
-	int ret;
-
-	/* seek to begin */
-	fseek(fd, 0l, SEEK_SET);
-
-	/* seek to end */
-	fseek(fd, 0l, SEEK_END);
-	size = ftell(fd) * sizeof(char);
-	fseek(fd, 0l, SEEK_SET);
-
-	data = malloc(size + (1 * sizeof(char)));
-	read = fread(data, sizeof(char), size, fd);
-	data[read] = 0;
-
-	ret = xml_load_str(data, node, options);
-
-	free(data);
+	/* Move past the '>'. */
+	buf++;
+	if (xml_parse_children(node, &buf) != -1) {
+		*bufptr = buf;
+		xml_node_append(parent, node);
+		return(1);
+	}
 
-	return ret;
+	/* Error reading children. */
+	xml_node_free(node);
+	return(-1);
 }
 
-int xml_load_file(const char *file, xml_node_t **node, int options)
+/* Parse all child nodes and attach them to the parent. */
+int xml_parse_children(xml_node_t *parent, char **bufptr)
 {
-	FILE *fd;
+	char *ptr, *buf = *bufptr;
 	int ret;
 
-	fd = fopen (file, "r");
-	if (fd == NULL) {
-		str_redup(&last_error, "unable to open file.");
-		return -1;
-	}
-	ret = xml_load(fd, node, options);
-	fclose (fd);
+	do {
+		ptr = strchr(buf, '<');
+		if (!ptr) {
+			append_text(parent, buf, strlen(buf), 1);
+			return(0);
+		}
 
-	return ret;
+		/* Append the intervening text to the parent. */
+		append_text(parent, buf, ptr - buf, 1);
+		buf = ptr;
+
+		ret = xml_parse_node(parent, &buf);
+		*bufptr = buf;
+	} while (ret == 1);
+	return(ret);
 }
 
-int xml_load_str(char *str, xml_node_t **node, int options)
+xml_node_t *xml_parse_file(const char *fname)
 {
-	int ret;
+	FILE *fp;
 	xml_node_t *root;
+	char *buf, *ptr;
+	int len;
 
-	(*node) = NULL;
-
+	fp = fopen(fname, "r");
+	if (!fp) {
+		xml_set_error(strerror(errno));
+		return(NULL);
+	}
+	fseek(fp, 0l, SEEK_END);
+	len = ftell(fp);
+	fseek(fp, 0l, SEEK_SET);
+	buf = malloc(len+1);
+	if (!buf) {
+		fclose(fp);
+		xml_set_error("out of memory");
+		return(NULL);
+	}
+	fread(buf, 1, len, fp);
+	fclose(fp);
 	root = xml_node_new();
 	root->type = XML_DOCUMENT;
-
-	/* clear last error */
-	last_error = NULL;
-
-	read_options = options;
-	do { 
-		if ((ret = xml_read_node(root, &str)) == -1)
-			break;
-	} while (ret == 0);
-	read_options = XML_NONE;
-
-	/* empty file will produce no errors so we check here for any
-	 * root element */
-	if (ret == -1 || xml_root_element(root) == NULL) {
-
-		/* emtpy file? heh... */
-		if (last_error == NULL)
-			str_redup(&last_error, "No elements found.");
-		xml_node_delete(root);
-
-		return (-1);
-	}
-
-	xml_decode_text(root->data.value.s_val);
-
-	(*node) = root;
-
-	return 0;
+	ptr = buf;
+	xml_parse_children(root, &ptr);
+	free(buf);
+	return xml_root_element(root);
 }
Index: eggdrop1.9/lib/eggdrop/xmlwrite.c
diff -u eggdrop1.9/lib/eggdrop/xmlwrite.c:1.10 eggdrop1.9/lib/eggdrop/xmlwrite.c:1.11
--- eggdrop1.9/lib/eggdrop/xmlwrite.c:1.10	Wed Jun 30 12:07:20 2004
+++ eggdrop1.9/lib/eggdrop/xmlwrite.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: xmlwrite.c,v 1.10 2004/06/30 17:07:20 wingman Exp $";
+static const char rcsid[] = "$Id: xmlwrite.c,v 1.11 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -26,99 +26,20 @@
 #include <string.h>
 #include <stdarg.h>
 
-#include <eggdrop/memutil.h>				/* str_redup		*/
-#include <eggdrop/xml.h>				/* prototypes		*/
-
-#define STREAM_STRING 	0
-#define STREAM_FILE	1
+#include <eggdrop/eggdrop.h>
 
 #define XML_INDENT_CHAR	'\t'
 
-extern char *last_error;                                /* from xml.c           */
 static int write_options = XML_NONE;
 
-typedef struct 
-{
-	union
-	{
-		FILE *file;
-		struct
-		{
-			char *buf;
-			size_t length;
-			size_t size;
-		} string;
-	} data;
-	int type;
-} stream_t;
-
-static int xml_write_node(stream_t *stream, xml_node_t *node);
-
-static int stream_printf(stream_t *stream, const char *format, ...)
-{
-	va_list args;
-	int ret = 0;
-
-	va_start(args, format);
-	switch (stream->type) {
-
-		case (STREAM_STRING):
-			while (1) {
-				/* (try to) write into our buffer */
-				if (stream->data.string.buf != NULL) {
-					ret = vsnprintf(stream->data.string.buf + stream->data.string.length,
-						stream->data.string.size - stream->data.string.length, format, args);
-				}
-
-				/* check if we succeeded */
-				if (stream->data.string.buf == NULL
-					|| ret >= stream->data.string.size - stream->data.string.length)
-				{	
-					/* we need to resize our buffer */
-					stream->data.string.buf = realloc(stream->data.string.buf,
-						stream->data.string.size + 256);
-
-					/* realloc failed, damn */
-					if (stream->data.string.buf == NULL) {
-						/* hehe, that'll fail... */
-						str_redup(&last_error, "out of memory");
-						return (-1);
-					}
-
-					memset(stream->data.string.buf + stream->data.string.length, 0,
-						stream->data.string.size - stream->data.string.length);
-
-					/* update size */
-					stream->data.string.size += 256;
-
-				} else {	
-					stream->data.string.length += ret;
-					break;
-				}
-			}
-
-			break;
-
-		case (STREAM_FILE):
-			ret = vfprintf(stream->data.file, format, args);
-			break;
-	
-		default:
-			str_redup(&last_error, "invalid stream type");
-			ret = -1;
-			break;
-	}
-	va_end(args);
-
-	return (ret > 0) ? 0 : ret;
-}
+static int xml_write_node(FILE *fp, xml_node_t *node);
 
 static int level = 0;
 static char indent[32] = {0};
 
-static int xml_write_children(stream_t *stream, xml_node_t *node)
+static int xml_write_children(FILE *fp, xml_node_t *node)
 {
-	int i, ret = 0;
+	int ret = 0;
 	const char *text;
 
 	/* init indent */
@@ -127,14 +48,12 @@
 	indent[++level] = 0;
 
 	/* XXX: encode text */
-	text = xml_get_text_str(node, NULL);
-	if (text && *text)
-		stream_printf(stream, "%s%s\n", indent, text);
-
-        for (i = 0; i < node->nchildren; i++) {
-		stream_printf(stream, "%s", indent);
-                if ((ret = xml_write_node(stream, node->children[i])) == -1)
-			break;
+	text = node->text;
+	if (text && *text) fprintf(fp, "%s%s\n", indent, text);
+
+        for (node = node->children; node; node = node->next) {
+		fprintf(fp, "%s", indent);
+                if ((ret = xml_write_node(fp, node)) == -1) break;
 	}
 
 	indent[--level] = 0;
@@ -142,187 +61,127 @@
         return ret;
 }
 
-static int xml_write_attributes(stream_t *stream, xml_node_t *node)
+static int xml_write_attributes(FILE *fp, xml_node_t *node)
 {
 	int i;
+	xml_attr_t *attr;
 
 	for (i = 0; i < node->nattributes; i++) {
-		xml_attr_t *attr = &node->attributes[i];
-		const char *text = variant_get_str(&attr->data, NULL);
-		if (text == NULL)
-			continue;
-		if (stream_printf(stream, " %s=\"%s\"", attr->name, text) == -1)
-			return (-1);
+		attr = node->attributes[i];
+		if (attr->value) fprintf(fp, " %s=\"%s\"", attr->name, attr->value);
 	}
 
 	return (0);
 }
 
-static int xml_write_element(stream_t *stream, xml_node_t *node)
+static int xml_write_element(FILE *fp, xml_node_t *node)
 {
-	if (stream_printf(stream, "<%s", node->name) == -1)
-		return (-1);
+	fprintf(fp, "<%s", node->name);
 	
-	if (xml_write_attributes(stream, node) == -1)
-		return (-1);
+	if (xml_write_attributes(fp, node) == -1) return(-1);
 
 	if (node->nchildren == 0) {
-		const char *text = xml_get_text_str(node, NULL);
-		if (text) {
-			stream_printf(stream, ">%s</%s>\n", text, node->name);
+		if (node->text) {
+			fprintf(fp, ">%s</%s>\n", node->text, node->name);
 		} else {
-			stream_printf(stream, "/>\n");
+			fprintf(fp, "/>\n");
 		}
 
 		return (0);
 	}
 
-	stream_printf(stream, ">\n");
-	if (xml_write_children(stream, node) != 0)
-		return (-1);
+	fprintf(fp, ">\n");
+	if (xml_write_children(fp, node) != 0) return(-1);
 
-	return stream_printf(stream, "%s</%s>\n", indent, node->name);
+	fprintf(fp, "%s</%s>\n", indent, node->name);
+	return(0);
 }
 
-static int xml_write_document(stream_t *stream, xml_node_t *node)
+static int xml_write_document(FILE *fp, xml_node_t *node)
 {
-	int i, ret;
+	int ret;
 
 	ret = 0;
-        for (i = 0; i < node->nchildren; i++) {
-                if ((ret = xml_write_node(stream, node->children[i])) != 0)
+        for (node = node->children; node; node = node->next) {
+                if ((ret = xml_write_node(fp, node)) != 0)
                         break;
         }
 	return ret;
 }
 
-static int xml_write_comment(stream_t *stream, xml_node_t *node)
+static int xml_write_comment(FILE *fp, xml_node_t *node)
 {
 	/* XXX: that's wrong, text needs to encoded */
-	return stream_printf(stream, "<!--%s-->\n", xml_get_text_str(node, NULL));
+	fprintf(fp, "<!--%s-->\n", node->text);
+	return(0);
 }
 
-static int xml_write_cdata_section(stream_t *stream, xml_node_t *node)
+static int xml_write_cdata_section(FILE *fp, xml_node_t *node)
 {
-	return stream_printf(stream, "<[CDATA[%s]]>\n", xml_get_text_str(node, NULL));
+	fprintf(fp, "<![CDATA[%s]]>\n", node->text);
+	return(0);
 }
 
-static int xml_write_processing_instruction(stream_t *stream, xml_node_t *node)
+static int xml_write_processing_instruction(FILE *fp, xml_node_t *node)
 {
-	if (stream_printf(stream, "<?%s", node->name) != 0)
-		return (-1);
-	
-	if (xml_write_attributes(stream, node) != 0)
-		return (-1);
+	fprintf(fp, "<?%s", node->name);
+
+	if (xml_write_attributes(fp, node) != 0) return(-1);
 
-	if (stream_printf(stream, "?>\n") != 0)
-		return (-1);
+	fprintf(fp, "?>\n");
 
 	return (0);
 }
 
-static int xml_write_node(stream_t *stream, xml_node_t *node)
+static int xml_write_node(FILE *fp, xml_node_t *node)
 {
 	switch (node->type) {
 	
 		case (XML_DOCUMENT):
-			return xml_write_document(stream, node);
+			return xml_write_document(fp, node);
 
 		case (XML_ELEMENT):
-			return xml_write_element(stream, node);
+			return xml_write_element(fp, node);
 
 		case (XML_COMMENT):
-			return xml_write_comment(stream, node);
+			return xml_write_comment(fp, node);
 	
 		case (XML_CDATA_SECTION):
-			return xml_write_cdata_section(stream, node);
+			return xml_write_cdata_section(fp, node);
 
 		case (XML_PROCESSING_INSTRUCTION):
-			return xml_write_processing_instruction(stream, node);
+			return xml_write_processing_instruction(fp, node);
 			
 		case (XML_ATTRIBUTE):
 			/* just ignore this */
 			return (0);
 	}
 
-	str_redup(&last_error, "Unknown node type.");
+	xml_set_error("unknown node type");
 
 	return (-1);
 }
 
-int xml_save(FILE *fd, xml_node_t *node, int options)
-{
-        stream_t stream;
-        int ret;
-
-	/* clear any last error */
-	str_redup(&last_error, NULL);
-
-        stream.data.file = fd;
-        stream.type = STREAM_FILE;
-
-        if (stream.data.file == NULL) {
-		str_redup(&last_error, "No file given.");
-                return -1;
-	}
-
-	write_options = options;
-        ret = xml_write_node(&stream, node);
-	write_options = XML_NONE;
-
-        return ret;
-}
-
 int xml_save_file(const char *file, xml_node_t *node, int options)
 {
-	stream_t stream;
+	FILE *fp;
 	int ret;
 
 	/* clear any last error */
-	str_redup(&last_error, NULL);
+	xml_set_error(NULL);
 
-	stream.data.file = fopen(file, "w");
-	stream.type = STREAM_FILE;
+	fp = fopen(file, "w");
 
-	if (stream.data.file == NULL) {
-		str_redup(&last_error, "failed to open file.");
+	if (!fp) {
+		xml_set_error("failed to open file");
 		return -1;
 	}
 
 	write_options = options;
-	ret = xml_write_node(&stream, node);
+	ret = xml_write_node(fp, node);
 	write_options = XML_NONE;
 
-	fclose(stream.data.file);
-
-	return ret;
-}
-
-int xml_save_str(char **str, xml_node_t *node, int options)
-{
-	stream_t stream;
-	int ret;
-
-	stream.data.string.buf = NULL;
-	stream.data.string.length = 0;
-	stream.data.string.size = 0;
-
-	stream.type = STREAM_STRING;
-
-	/* clear any last error */
-	str_redup(&last_error, NULL);
-
-	write_options = options;
-	ret = xml_write_node(&stream, node);
-	write_options = XML_NONE;
-	
-	*str = NULL;
-	if (ret == -1) {
-		if (stream.data.string.length > 0)
-			free(stream.data.string.buf);
-	} else {
-		(*str) = stream.data.string.buf;
-	}
+	fclose(fp);
 
 	return ret;
 }
Index: eggdrop1.9/modules/server/Makefile.am
diff -u eggdrop1.9/modules/server/Makefile.am:1.15 eggdrop1.9/modules/server/Makefile.am:1.16
--- eggdrop1.9/modules/server/Makefile.am:1.15	Thu Jun 17 08:32:44 2004
+++ eggdrop1.9/modules/server/Makefile.am	Sun Sep 26 04:42:09 2004
@@ -1,9 +1,9 @@
-# $Id: Makefile.am,v 1.15 2004/06/17 13:32:44 wingman Exp $
+# $Id: Makefile.am,v 1.16 2004/09/26 09:42:09 stdarg Exp $
 
 include $(top_srcdir)/$(ac_aux_dir)/module.mk
 
 pkglib_LTLIBRARIES	= server.la
-server_la_SOURCES	= server.c server.h binds.c binds.h input.c input.h output.c output.h serverlist.c serverlist.h channels.c channels.h nicklist.c nicklist.h scriptcmds.c servsock.c servsock.h party_commands.c dcc.c dcc.h egg_server_api.c egg_server_api.h
+server_la_SOURCES	= server.c server.h binds.c binds.h channels.c channels.h input.c input.h output.c output.h serverlist.c serverlist.h nicklist.c nicklist.h scriptcmds.c servsock.c servsock.h party_commands.c dcc.c dcc.h egg_server_api.c egg_server_api.h
 server_la_LDFLAGS	= -module -avoid-version -no-undefined
 server_la_LIBADD	= @LIBS@ $(top_builddir)/lib/eggdrop/libeggdrop.la
 
Index: eggdrop1.9/modules/server/channels.c
diff -u eggdrop1.9/modules/server/channels.c:1.31 eggdrop1.9/modules/server/channels.c:1.32
--- eggdrop1.9/modules/server/channels.c:1.31	Fri Aug 27 14:16:43 2004
+++ eggdrop1.9/modules/server/channels.c	Sun Sep 26 04:42:09 2004
@@ -18,16 +18,13 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: channels.c,v 1.31 2004/08/27 19:16:43 darko Exp $";
+static const char rcsid[] = "$Id: channels.c,v 1.32 2004/09/26 09:42:09 stdarg Exp $";
  #endif
 
 #include "server.h"
 
 #define UHOST_CACHE_SIZE 47
 
-#define CHAN_INACTIVE		0x1
-#define CHAN_CYCLE		0x2
-
 channel_t *channel_head = NULL;
 hash_table_t *uhost_cache_ht = NULL;
 
@@ -35,25 +32,15 @@
 
 static bind_list_t channel_raw_binds[];
 
-static const char *channel_builtin_bools[32];
-static const char *channel_builtin_ints[];
-static const char *channel_builtin_coupplets[];
-static const char *channel_builtin_strings[];
-
-static channel_t global_chan;
-
 /* Prototypes. */
 static int uhost_cache_delete(const void *key, void *data, void *param);
 static void clear_masklist(channel_mask_list_t *l);
-static void clear_masklists_online_only(channel_t *chanptr);
 static int got_list_item(void *client_data, char *from_nick, char *from_uhost, user_t *u, char *cmd, int nargs, char *args[]);
 static int got_list_end(void *client_data, char *from_nick, char *from_uhost, user_t *u, char *cmd, int nargs, char *args[]);
 void uhost_cache_decref(const char *nick);
 void server_channel_destroy();
-static int chanfile_load(const char *filename);
-int channame_member_has_flag(const char *nick, const char *channame, unsigned char c);
-static int chanptr_member_has_flag(const char *nick, channel_t *chan, unsigned char c);
-static int channels_minutely();
+
+static void clear_masklists(channel_t *chan);
 
 void server_channel_init()
 {
@@ -74,23 +61,17 @@
 	bind_entry_add(table, NULL, "368", "banlistend", BIND_WANTS_CD, got_list_end, (void *)'b');
 	bind_entry_add(table, NULL, "347", "invitelistend", BIND_WANTS_CD, got_list_end, (void *)'I');
 	bind_entry_add(table, NULL, "349", "exceptlistend", BIND_WANTS_CD, got_list_end, (void *)'e');
-
-	memset(&global_chan, 0, sizeof global_chan);
-	global_chan.builtin_bools = 1;
-	chanfile_load(server_config.chanfile);
-
-	bind_add_simple(BTN_EVENT, NULL, "minutely", channels_minutely);
 }
 
 static inline void free_member(channel_member_t *m)
 {
-	free(m->nick);
-	free(m->uhost);
+	if (m->nick) free(m->nick);
+	if (m->uhost) free(m->uhost);
 	free(m);
 }
 
-/* Free nicklist, banmasks, etc.. */
-static void free_channel_online_stuff(channel_t *chan)
+/* Free online data like nicklist, banmasks, etc.. */
+static void free_channel_online(channel_t *chan)
 {
 	channel_member_t *m, *next_mem;
 
@@ -99,40 +80,32 @@
 		uhost_cache_decref(m->nick);
 		free_member(m);
 	}
-	chan->member_head = NULL;
-	chan->nmembers = 0;
-	chan->bot = NULL;
-
-	free(chan->topic);
-	chan->topic = NULL;
-
-	free(chan->topic_nick);
-	chan->topic_nick = NULL;
-
-	chan->topic_time = 0;
-
-	memset(&chan->mode, 0, sizeof(chan->mode));
 
-	chan->limit = 0;
-
-	free(chan->key);
-	chan->key = NULL;
+	if (chan->topic) free(chan->topic);
+	if (chan->topic_nick) free(chan->topic_nick);
+	if (chan->key) free(chan->key);
 
-	clear_masklists_online_only(chan);
+	clear_masklists(chan);
 
 	free(chan->args);
 	chan->args = NULL;
 	chan->nargs = 0;
 }
 
+/* Free offline data like settings, etc. */
+static void free_channel_offline(channel_t *chan)
+{
+}
+
 /* Free online related settings for all cahnnels */
 static void free_all_online_stuff()
 {
 	channel_t *chan;
 
 	/* Clear out channel list. */
-	for (chan = channel_head; chan; chan = chan->next)
-		free_channel_online_stuff(chan);
+	for (chan = channel_head; chan; chan = chan->next) {
+		free_channel_online(chan);
+	}
 
 	/* And the uhost cache. */
 	hash_table_walk(uhost_cache_ht, uhost_cache_delete, NULL);
@@ -140,81 +113,8 @@
 	uhost_cache_ht = hash_table_create(NULL, NULL, UHOST_CACHE_SIZE, HASH_TABLE_STRINGS);
 }
 
-/* Completely destroy everything about the channel */
-int destroy_channel_record(const char *chan_name)
-{
-	channel_t *chan, *prev;
-	coupplet_t *cplt, *tmpcplt;
-	chanstring_t *cstr, *tmpcstr;
-	int i;
-
-	if (chan_name) {
-		channel_lookup(chan_name, 0, &chan, &prev);
-		if (!chan)
-			return -1;
-
-		if (chan->status & CHANNEL_JOINED)
-			printserv(SERVER_NORMAL, "PART %s\r\n", chan_name);
-
-		if (prev)
-			prev->next = chan->next;
-		else
-			channel_head = chan->next;
-		nchannels--;
-
-		free(chan->name);
-		free_channel_online_stuff(chan);
-	}
-	else
-		chan = &global_chan;
-
-	for (i = 0; i < chan->nlists; i++) {
-		clear_masklist(chan->lists[i]);
-		free(chan->lists[i]);
-	}
-	free(chan->lists);
-
-	for (cplt = chan->builtin_ints; cplt; cplt = tmpcplt) {
-		tmpcplt = cplt->next;
-		free(cplt->name);
-		free(cplt);
-	}
-
-	for (cplt = chan->builtin_coupplets; cplt; cplt = tmpcplt) {
-		tmpcplt = cplt->next;
-		free(cplt->name);
-		free(cplt);
-	}
-
-	for (cstr = chan->builtin_strings; cstr; cstr = tmpcstr) {
-		tmpcstr = cstr->next;
-		free(cstr->name);
-		free(cstr->data);
-		free(cstr);
-	}
-
-	if (chan != &global_chan)
-		free(chan);
-	else /* Just in case.. */
-		memset(chan, 0, sizeof *chan);
-	return 0;
-}
-
-/* Completely destroy all channel records */
-static void destroy_all_channel_records()
-{
-	free_all_online_stuff();
-	hash_table_delete(uhost_cache_ht);
-	while (channel_head)
-		destroy_channel_record(channel_head->name);
-}
-
 void server_channel_destroy()
 {
-	chanfile_save(server_config.chanfile);
-	destroy_all_channel_records();
-	destroy_channel_record(NULL); /* free any global channel stuff */
-	bind_rem_simple(BTN_EVENT, NULL, "minutely", channels_minutely);
 }
 
 /* Find or create channel when passed 0 or 1 */
@@ -261,8 +161,6 @@
 		}
 	}
 
-	chan->builtin_bools = global_chan.builtin_bools;
-/* FIXME - set other members to their respective default values (if any) */
 	chan->next = channel_head;
 	channel_head = chan;
 	*chanptr = chan;
@@ -344,15 +242,10 @@
 	}
 }
 
-/* Pass NULL as chan_name if you already have pointer to channel */
-static channel_member_t *channel_add_member(const char *chan_name, channel_t *chan, const char *nick, const char *uhost)
+static channel_member_t *channel_add_member(channel_t *chan, const char *nick, const char *uhost)
 {
 	channel_member_t *m;
 
-	if (chan_name)
-		channel_lookup(chan_name, 0, &chan, NULL);
-	if (!chan) return(NULL);
-
 	/* See if this member is already added. */
 	for (m = chan->member_head; m; m = m->next) {
 		if (!(current_server.strcmp)(m->nick, nick)) break;
@@ -381,30 +274,26 @@
 void channel_on_join(const char *chan_name, const char *nick, const char *uhost)
 {
 	channel_t *chan;
+	channel_member_t *m;
 
-	channel_lookup(chan_name, 0, &chan, NULL);
+	/* Lookup channel or create. */
+	channel_lookup(chan_name, 1, &chan, NULL);
+	if (!chan) return;
 
-	if (chan && !(chan->builtin_bools & CHAN_INACTIVE)) {
-		channel_member_t *m = channel_add_member(NULL, chan, nick, uhost);
-		if (match_my_nick(nick)) {
-			int i;
-			chan->bot = m;
-			chan->status |= (CHANNEL_WHOLIST | CHANNEL_JOINED);
-			printserv(SERVER_NORMAL, "WHO %s\r\n", chan_name);
-			printserv(SERVER_NORMAL, "MODE %s\r\n", chan_name);
-			for (i = 0; i < chan->nlists; i++)
-				chan->lists[i]->loading = 1;
-			printserv(SERVER_NORMAL, "MODE %s %s\r\n", chan_name, current_server.type1modes);
-		}
-		else {
-/* FIXME - Traverse ban list in search for closest ban */
-		}
-		return;
-	}
+	/* Add a new member. */
+	m = channel_add_member(chan, nick, uhost);
 
+	/* Is it me? If so, request channel lists. */
 	if (match_my_nick(nick)) {
-		putlog(LOG_MISC, "*", _("Ooops, joined %s but didn't want to!"), chan_name);
-		printserv(SERVER_NORMAL, "PART %s\r\n", chan_name);
+		int i;
+		chan->bot = m;
+		chan->status |= (CHANNEL_WHOLIST | CHANNEL_JOINED);
+		printserv(SERVER_NORMAL, "WHO %s\r\n", chan_name);
+		printserv(SERVER_NORMAL, "MODE %s\r\n", chan_name);
+		for (i = 0; i < chan->nlists; i++) {
+			chan->lists[i]->loading = 1;
+		}
+		printserv(SERVER_NORMAL, "MODE %s %s\r\n", chan_name, current_server.type1modes);
 	}
 }
 
@@ -414,8 +303,7 @@
 	channel_member_t *prev = NULL, *m;
 
 	channel_lookup(chan_name, 0, &chan, NULL);
-	if (!chan)
-		return;
+	if (!chan) return;
 
 	uhost_cache_decref(nick);
 	for (m = chan->member_head; m; m = m->next) {
@@ -431,19 +319,19 @@
 
 	bind_check(BT_leave, u ? &u->settings[0].flags : NULL, chan_name, nick, uhost, u, chan_name);
 
-	if (match_my_nick(nick))
-		free_channel_online_stuff(chan);
+	if (match_my_nick(nick)) free_channel_online(chan);
 }
 
 void channel_on_quit(const char *nick, const char *uhost, user_t *u)
 {
 	channel_t *chan;
 
-	if (match_my_nick(nick))
-		free_all_online_stuff();
-	else
-		for (chan = channel_head; chan; chan = chan->next)
+	if (match_my_nick(nick)) free_all_online_stuff();
+	else {
+		for (chan = channel_head; chan; chan = chan->next) {
 			channel_on_leave(chan->name, nick, uhost, u);
+		}
+	}
 }
 
 void channel_on_nick(const char *old_nick, const char *new_nick)
@@ -523,7 +411,7 @@
 	nick = args[5];
 	flags = args[6];
 	uhost = egg_mprintf("%s@%s", args[2], args[3]);
-	m = channel_add_member(NULL, chan, nick, uhost);
+	m = channel_add_member(chan, nick, uhost);
 	changestr[0] = '+';
 	changestr[2] = 0;
 	flags++;
@@ -575,7 +463,7 @@
 		while (*ptr && !isspace(*ptr)) ptr++;
 		if (*ptr) *ptr = 0;
 		else ptr = NULL;
-		m = channel_add_member(NULL, chan, nick, NULL);
+		m = channel_add_member(chan, nick, NULL);
 		*nick = 0;
 		while (*flags) {
 			prefixptr = strchr(current_server.whoprefix, *flags);
@@ -684,199 +572,32 @@
 /* Creates or updates an entry in the mask list, as a result of channel mode change.
    It is *NOT* allowed to create new list type because, when connected to server,
    we already know all valid types or use defaults. */
-void channel_irc_add_mask(channel_t *chan, char type, const char *mask, const char *set_by, int time)
+void channel_add_mask(channel_t *chan, char type, const char *mask, const char *set_by, int time)
 {
 	channel_mask_list_t *l;
 	channel_mask_t *m;
 
 	l = channel_get_mask_list(chan, type);
 
-	if (!l)
-		return;
-
-	for (m = l->head; m; m = m->next)
-		if (!(current_server.strcmp)(m->mask, mask))
-			break;
+	if (!l) return;
 
-	if (!m) {
-		m = calloc(1, sizeof(*m));
-		m->mask = strdup(mask);
-		m->next = l->head;
-		l->head = m;
-		l->len++;
-	}
+	m = calloc(1, sizeof(*m));
+	m->mask = strdup(mask);
+	m->next = l->head;
 	if (set_by) m->set_by = strdup(set_by);
 	m->time = time;
-	m->last_used = time;
-}
-
-/* FIXME - int expire should be long expire (EGGTIMEVALT) */
-/* Creates or updates an entry in the mask list, as a result of console command, script, other.. */
-/* It *WILL* create a new list type if need be */
-int channel_notirc_add_mask(channel_t *chan, char type, const char *mask, const char *creator,
-				const char *comment, int expire, int lastused, int sticky, int console)
-{
-	channel_mask_list_t *l;
-	channel_mask_t *m;
-
-	if (!chan) /* Global mask */
-		chan = &global_chan;
-
-	l = channel_get_mask_list(chan, type);
-	if (!l) {
-		void *tmpp = realloc(chan->lists, (chan->nlists+1) * sizeof(*chan->lists));
-		if (!tmpp)
-			return 1;
-		chan->lists = tmpp;
-		l = calloc(1, sizeof *l);
-		chan->lists[chan->nlists++] = l;
-		l->type = type;
-	}
-
-	for (m = l->head; m; m = m->next)
-		/* Here we do not use wild matching, so to allow for masks to be created
-		   even if wider covering mask already exists. Idea is to be able to set
-		   only the narrowest mask, once the need arises. */
-		if (current_server.strcmp) {
-			if (!(current_server.strcmp)(m->mask, mask))
-				break;
-		}
-		else {
-			if (!strcasecmp(m->mask, mask))
-				break;
-		}
-
-	if (m) {
-		if (m->creator)
-			return 2;
-	}
-	else {
-		m = calloc(1, sizeof(*m));
-		m->mask = strdup(mask);
-	}
+	m->last_used = 0;
 
-	m->creator = strdup(creator);
-	m->comment = strdup(comment?comment:"");
-	m->expire = expire;
-	m->last_used = lastused;
-	m->sticky = sticky;
-	m->next = l->head;
 	l->head = m;
 	l->len++;
-/* FIXME - check for enforcebans and kick if needed. Or maybe we should kick anyway?
-		Or maybe only kick if it was console .+ban?
-		Perhaps best, yet, is to create a separate function to traverse member list
-		and deal with this in appropriate way. We'll need it for other things too.
-		For now, let it just dump mode to channel */
-	if (chan == &global_chan)
-		for (chan = channel_head; chan; chan = chan->next) {
-			if (BOT_CAN_SET_MODES(chan)) {
-				printserv(SERVER_QUICK, "MODE %s +%c %s\r\n", chan->name, type, mask);
-			if (type == 'b' && console)
-				; /* Er, nothing for now */
-		}
-	}
-	else {
-		if (BOT_CAN_SET_MODES(chan)) {
-			printserv(SERVER_QUICK, "MODE %s +%c %s\r\n", chan->name, type, mask);
-			if (type == 'b' && console)
-				;
-		}
-	}
-
-	return 0;
-}
-
-/* This is not code i feel proud of. It should be written in the cleaner manner but let it be for now */
-int channel_del_mask(channel_t *chan, char type, const char *mask, int remove)
-{
-	channel_mask_list_t *l;
-	channel_mask_t *m, *prev;
-
-	if (!chan)
-		chan = &global_chan;
-
-	l = channel_get_mask_list(chan, type);
-	if (!l) return -1;
-
-	prev = NULL;
-	for (m = l->head; m; m = m->next) {
-		if (!(current_server.strcmp)(m->mask, mask)) break;
-		prev = m;
-	}
-	if (!m) return -2;
-
-	if (chan == &global_chan) {
-		if (prev) prev->next = m->next;
-		else l->head = m->next;
-		l->len--;
-		free(m->mask);
-		free(m->creator);
-		free(m->comment);
-		free(m);
-		for (chan = channel_head; chan; chan = chan->next) {
-			if (BOT_CAN_SET_MODES(chan))
-				printserv(SERVER_QUICK, "MODE %s -%c %s\r\n", chan->name, type, mask);
-		}
-	}
-	else if (remove) { /* We were called from p-line or script/module */
-		if (BOT_CAN_SET_MODES(chan) && m->set_by)
-			printserv(SERVER_QUICK, "MODE %s -%c %s\r\n", chan->name, type, mask);
-		free(m->creator);
-		free(m->comment);
-		if (!m->set_by) {
-			if (prev) prev->next = m->next;
-			else l->head = m->next;
-			l->len--;
-			free(m->mask);
-			free(m);
-		}
-		else { /* We're not deleting the node so clean up */
-			m->creator = NULL;
-			m->comment = NULL;
-		}
-	}
-	else { /* Function was called as a result of recived IRC message MODE */
-		free(m->set_by);
-		if (!m->creator) {
-			if (prev) prev->next = m->next;
-			else l->head = m->next;
-			l->len--;
-			free(m->mask);
-			free(m); /* Rest should've been freed already */
-		}
-		else {
-			m->set_by = NULL;
-			m->time = 0;
-		}
-	}
-
-	return 0;
 }
 
-static void clear_masklists_online_only(channel_t *chanptr)
+static void clear_masklists(channel_t *chan)
 {
-	channel_mask_t *m, *prev;
 	int i;
 
-	if (!chanptr)
-		return;
-
-	for (i = 0; i < chanptr->nlists; i++) {
-		prev = NULL;
-		for (m = chanptr->lists[i]->head; m; prev = m) {
-			if (!m->creator) {
-				if (m == chanptr->lists[i]->head)
-					chanptr->lists[i]->head = m->next;
-				else
-					prev = m->next;
-				free(m->set_by);
-				free(m);
-				chanptr->lists[i]->len--;
-			}
-			else
-				m = m->next;
-		}
+	for (i = 0; i < chan->nlists; i++) {
+		clear_masklist(chan->lists[i]);
 	}
 }
 
@@ -886,48 +607,11 @@
 
 	for (m = l->head; m; m = next) {
 		next = m->next;
-		free(m->mask);
-		free(m->creator);
-		free(m->set_by);
-		free(m->comment);
+		if (m->mask) free(m->mask);
+		if (m->set_by) free(m->set_by);
 		free(m);
 	}
-	l->head = NULL;
-}
-
-void channel_clear_masks(channel_t *chan, char type)
-{
-	channel_mask_list_t *l;
-
-	l = channel_get_mask_list(chan, type);
-	if (l) clear_masklist(l);
-}
-
-/* Returns a number of channel_mask_t nodes stored in *cm */
-int channel_list_masks(channel_mask_t ***cm, char type, channel_t *chanptr, const char *mask)
-{
-	channel_mask_list_t *l;
-	channel_mask_t *m;
-	int nmasks = 0;
-
-	if (chanptr == NULL)
-		chanptr = &global_chan;
-
-	l = channel_get_mask_list(chanptr, type);
-	if (!l)
-		return 0;
-
-	for (m = l->head; m; m = m->next)
-		if (wild_match(mask, m->mask)) {
-			void *tmpp = realloc(*cm, (nmasks+1)*(sizeof cm));
-			if (!tmpp)
-				return nmasks;
-			*cm = tmpp;
-
-			(*cm)[nmasks++] = m;
-		}
-
-	return nmasks;
+	memset(l, 0, sizeof(l));
 }
 
 /* :server 367 <ournick> <chan> <ban> [<nick> <time>]
@@ -945,7 +629,7 @@
 	if (!chan) return(0);
 	l = channel_get_mask_list(chan, type);
 	if (!l || !(l->loading)) return(0);
-	channel_irc_add_mask(chan, type, ban, (nargs > 3) ? args[3] : NULL, (nargs > 4) ? atoi(args[4]) : -1);
+	channel_add_mask(chan, type, ban, (nargs > 3) ? args[3] : NULL, (nargs > 4) ? atoi(args[4]) : -1);
 	return(0);
 }
 
@@ -1155,7 +839,7 @@
 		}
 		else if (modify_list) {
 			/* Add/remove an address from a list. */
-			if (changestr[0] == '+') channel_irc_add_mask(chan, *change, arg, from_nick, timer_get_now_sec(NULL));
+			if (changestr[0] == '+') channel_add_mask(chan, *change, arg, from_nick, timer_get_now_sec(NULL));
 			else channel_del_mask(chan, *change, arg, 0);
 		}
 		else if (changestr[0] == '+') {
@@ -1238,515 +922,34 @@
 	return(0);
 }
 
-static int channel_set_bool(channel_t *chanptr, const char *setting)
-{
-	int i;
-	int fakenchannels;
-	channel_t *fakechanptr;
-
-	for (i = 0; i < 32; i++)
-		if (!strcasecmp(&setting[1], channel_builtin_bools[i]))
-		   break;
-	if (i == 32)
-		return 0;
-
-	if (!chanptr) { /* Set this for all channels? */
-		fakenchannels = nchannels;
-		fakechanptr = channel_head;
-	}
-	else {
-		fakenchannels = 1;
-		fakechanptr = chanptr;
-	}
-
-	while (fakenchannels--) {
-		if (*setting == '+')
-			fakechanptr->builtin_bools |= (1 << i);
-		else
-			fakechanptr->builtin_bools &= ~(1 << i);
-
-		if (i == 0) /* +/-inactive */
-			printserv(SERVER_NORMAL, "%s %s %s\r\n", *setting=='+'?"PART":"JOIN",
-				fakechanptr->name, fakechanptr->key?fakechanptr->key:"");
-
-		fakechanptr = fakechanptr->next;
-	}
-
-	return 1;
-}
-
-static int channel_set_coupplet(coupplet_t *cplt, const char *value)
-{
-	unsigned long left, right;
-	char *endptr = NULL;
-	char *r, *l;
-
-	l = strdup(value);
-	if ((r = strchr(l, ':')) == NULL) {
-		free(l);
-		return 0;
-	}
-	*r++ = '\0';
-
-	left = strtoul(l, &endptr, 10);
-
-	if (!*l || *endptr) {
-		free(l);
-		return 0;
-	}
-
-	right = strtoul (r, &endptr, 10);
-
-	if (!*r || *endptr) {
-		free(l);
-		return 0;
-	}
-
-	cplt->left = left;
-	cplt->right = right;
-	free(l);
-	return 1;
-}
-
-static int channel_set_int(coupplet_t *cplt, const char *value)
-{
-	char *endptr = NULL;
-	unsigned long left;
-
-	left = strtoul(value, &endptr, 10);
-
-	if (*value && !*endptr) {
-		cplt->left = left;
-		return 1;
-	}
-
-	return 0;
-}
-
 int channel_set(channel_t *chanptr, const char *setting, const char *value)
 {
-	coupplet_t *cplt;
-	chanstring_t *cstr = NULL;
-	int i;
-
-	/* Is it one of the flags? (boolean, on|off) */
-	if (*setting == '+' || *setting == '-')
-		return channel_set_bool(chanptr, setting);
-
-	/* It isn't, so let's check if it's a numeric setting of some sort. An int? */
-	for (cplt = chanptr->builtin_ints; cplt; cplt = cplt->next)
-		if (strcasecmp(cplt->name, setting) == 0)
-			return channel_set_int(cplt, value);
-
-	/* Or an int that is being set for the first time? */
-	for (i = 0; channel_builtin_ints[i]; i++)
-		if (strcasecmp(channel_builtin_ints[i], setting) == 0) {
-			/* Ok, it is - add record for it */
-			cplt = malloc(sizeof *cplt);
-			if (!channel_set_int(cplt, value)) {
-				free(cplt);
-				return 0;
-			}
-			cplt->name = strdup(channel_builtin_ints[i]);
-			if (chanptr->builtin_ints)
-				cplt->next = chanptr->builtin_ints;
-			else
-				cplt->next = NULL;
-			chanptr->builtin_ints = cplt;
-			return 1;
-		}
-
-	/* Maybe it's a coupplet: <setting> X:Y */
-	for (cplt = chanptr->builtin_coupplets; cplt; cplt = cplt->next)
-		if (strcasecmp(cplt->name, setting) == 0)
-			return channel_set_coupplet(cplt, value);
-
-	/* No luck for now. Is it a valid coupplet at all? */
-	for (i = 0; channel_builtin_coupplets[i]; i++)
-		if (strcasecmp(channel_builtin_coupplets[i], setting) == 0) {
-			/* Ah, it is - add record for it */
-			cplt = malloc(sizeof *cplt);
-			if (!channel_set_coupplet(cplt, value)) {
-				free(cplt);
-				return 0;
-			}
-			cplt->name = strdup(channel_builtin_coupplets[i]);
-			if (chanptr->builtin_coupplets)
-				cplt->next = chanptr->builtin_coupplets;
-			else
-				cplt->next = NULL;
-			chanptr->builtin_coupplets = cplt;
-			return 1;
-		}
-
-	/* Well, maybe it's one of the 'string' settings? */
-	for (cstr = chanptr->builtin_strings; cstr; cstr = cstr->next)
-		if (strcasecmp(cstr->name, setting) == 0) {
-			free(cstr->data);
-			cstr->data = strdup(value);
-			return 1;
-		}
-
-	/* Or one of the 'string' settings that just wasn't used till now? */
-	for (i = 0; channel_builtin_strings[i]; i++)
-		if (strcasecmp(channel_builtin_strings[i], setting) == 0) {
-			/* It was - add record for it */
-			cstr = malloc(sizeof *cstr);
-			cstr->data = strdup(value);
-			cstr->name = strdup(channel_builtin_strings[i]);
-			if (chanptr->builtin_strings)
-				cstr->next = chanptr->builtin_strings;
-			else
-				cstr->next = NULL;
-			chanptr->builtin_strings = cstr;
-			return 1;
-		}
-
-	/* Lastly, it can be one of user defined settings */
-/* FIXME - will be done in near future, once more important things are ready */
-
 	return 0;
 }
 
 int channel_info(partymember_t *p, const char *channame)
 {
-	static char hack_gettext[64]; /* Seems like gettext() messes %lu foramt */
-	channel_t *chan;
-	int i;
-	const int hgl = sizeof(hack_gettext) - 1;
-
-	if (channel_lookup(channame, 0, &chan, NULL) == -1) {
-		partymember_printf(p, _("Error: Invalid channel '%s'"), channame);
-		return BIND_RET_BREAK;
-	}
-
-	partymember_printf(p, _("Information for channel '%s'"), channame);
-
-	if (chan->builtin_bools) {
-		partymember_printf(p, _("  Flags:"));
-		for (i = 0; i < 32; i++)
-			if (chan->builtin_bools & (1 << i))
-				partymember_printf(p, _("    +%s"), channel_builtin_bools[i]);
-	}
-
-	if (chan->builtin_ints) {
-		coupplet_t *cplt;
-		partymember_printf(p, _("  Settings:"));
-		for (cplt = chan->builtin_ints; cplt; cplt = cplt->next) {
-			snprintf(hack_gettext, hgl, "%lu", cplt->left);
-			hack_gettext[hgl] = '\0';
-			partymember_printf(p, _("    %s:\t%s"), cplt->name, hack_gettext);
-		}
-	}
-	if (chan->builtin_coupplets) {
-		coupplet_t *cplt;
-		if (!chan->builtin_ints)
-			partymember_printf(p, _("  Settings:"));
-		for (cplt = chan->builtin_coupplets; cplt; cplt = cplt->next) {
-			snprintf(hack_gettext, hgl, "%lu:%lu", cplt->left, cplt->right);
-			hack_gettext[hgl] = '\0';
-			partymember_printf(p, _("    %s:\t%s"), cplt->name, hack_gettext);
-		}
-	}
-
-	if (chan->builtin_strings) {
-		chanstring_t *cstr;
-		if (!chan->builtin_coupplets && !chan->builtin_ints)
-			partymember_printf(p, _("  Settings:"));
-		for (cstr = chan->builtin_strings; cstr; cstr = cstr->next)
-			partymember_printf(p, _("    %s:\t%s"), cstr->name, cstr->data);
-	}
-
-	return BIND_RET_LOG;
-}
-
-static int chanfile_save_channel(xml_node_t *root, channel_t *chan)
-{
-	xml_node_t *chan_node;
-	coupplet_t *cplt;
-	chanstring_t *cstr;
-	static char gettext_hack[64];
-	const int hgl = sizeof(gettext_hack) - 1;
-
-	int i, j;
-
-	chan_node = xml_node_new();
-
-	if (chan->name) {
-		chan_node->name = strdup("channel");
-		xml_node_set_str(chan->name, chan_node, "name", 0, 0);
-	}
-	else
-		chan_node->name = strdup("global");
-
-	for (i = j = 0; i < 32; i++) {
-		if (*channel_builtin_bools == '\0')
-			continue;
-		if (chan->builtin_bools & (1 << i))
-			xml_node_set_str(channel_builtin_bools[i], chan_node, "flag", j++, 0);
-	}
-
-	i = 0;
-	for (cplt = chan->builtin_ints; cplt ; cplt = cplt->next) {
-		xml_node_set_str(cplt->name, chan_node, "setting", i, "name", 0, 0);
-		snprintf(gettext_hack, sizeof gettext_hack, "%lu", cplt->left);
-		gettext_hack[hgl] = '\0';
-		xml_node_set_str(gettext_hack, chan_node, "setting", i++, "data", 0, 0);
-	}
-
-	for (cplt = chan->builtin_coupplets; cplt ; cplt = cplt->next) {
-		xml_node_set_str(cplt->name, chan_node, "setting", i, "name", 0, 0);
-		snprintf(gettext_hack, sizeof gettext_hack, "%lu:%lu", cplt->left, cplt->right);
-		gettext_hack[hgl] = '\0';
-		xml_node_set_str(gettext_hack, chan_node, "setting", i++, "data", 0, 0);
-	}
-
-	for (cstr = chan->builtin_strings; cstr ; cstr = cstr->next) {
-		xml_node_set_str(cstr->name, chan_node, "setting", i, "name", 0, 0);
-		xml_node_set_str(cstr->data, chan_node, "setting", i++, "data", 0, 0);
-	}
-
-	j = 0;
-	for (i = 0; i < chan->nlists; i++) {
-		channel_mask_t *m;
-		char type[2] = " ";
-		type[0] = chan->lists[i]->type;
-		for (m = chan->lists[i]->head; m; m = m->next) {
-			xml_node_set_str(type, chan_node, "chanmask", j, "type", 0, 0);
-			xml_node_set_str(m->mask, chan_node, "chanmask", j, "mask", 0, 0);
-			xml_node_set_str(m->creator, chan_node, "chanmask", j, "creator", 0, 0);
-			xml_node_set_str(m->comment, chan_node, "chanmask", j, "comment", 0, 0);
-			/* FIXME - This should be long integer */
-			xml_node_set_int(m->expire, chan_node, "chanmask", j, "expire", 0, 0);
-			xml_node_set_int(m->last_used, chan_node, "chanmask", j, "lastused", 0, 0);
-			xml_node_set_int(m->sticky, chan_node, "chanmask", j++, "sticky", 0, 0);
-		}
-	}
-
-	xml_node_append(root, chan_node);
-/* FIXME - Do we need to free() here? Appears not.
-	free(chan_node); */
 	return 0;
 }
 
-int chanfile_save(const char *fname)
-{
-	xml_node_t *root;
-	channel_t *chan;
-	int i;
-
-	root = xml_node_new();
-	root->name = strdup("channels");
-
-	chanfile_save_channel(root, &global_chan);
-
-	for (chan = channel_head; chan; chan = chan->next)
-		chanfile_save_channel(root, chan);
-
-	if (!fname)
-		fname = server_config.chanfile;
-
-	i = xml_save_file(fname, root, XML_INDENT);
-	xml_node_delete(root);
-
-	if (i == 0)
-		putlog(LOG_MISC, "*", _("Saving channels file '%s'"), fname);
-	return i;
-}
-
-static int chanfile_load(const char *fname)
+static int chanfile_save_channel(xml_node_t *root, channel_t *chan)
 {
-	int i;
-	xml_node_t *doc, *root, *chan_node, *setting_node;
-	channel_t *chan = NULL;
-	char *tmpptr, *tmp2ptr;
-	/* FIXME - storage size of cursecs is wrong */
-	int cursecs;
-
-	if (xml_load_file(fname?fname:"channels.xml", &doc, XML_TRIM_TEXT) != 0) {
-		putlog(LOG_MISC, "*", _("Failed to load channel file '%s': %s"), fname, xml_last_error());
-		return -1;
-	}
-
-	putlog(LOG_MISC, "*", _("Loading channels file '%s'"), fname?fname:"channels.xml");
-
-	root = xml_root_element(doc);
-
-	for (i = 0; i < root->nchildren; i++) {
-		int j;
-		chan_node = root->children[i];
-		if (!strcasecmp(chan_node->name, "channel")) {
-			xml_node_get_str(&tmpptr, chan_node, "name", 0, 0);
-/* FIXME - Maybe we should allow for already existing channels,
-		in which case we should just update the existing data */
-			if (!tmpptr || channel_lookup(tmpptr, 1, &chan, NULL) == -1)
-				continue;
-			chan->name = strdup(tmpptr);
-		}
-		else if (!strcasecmp(chan_node->name, "global")) {
-			chan = &global_chan;
-			chan->name = NULL;
-		}
-		else
-			continue;
-
-		j = 0;
-		while (xml_node_get_str(&tmpptr, chan_node, "flag", j++, 0) != -1) {
-			int k;
-			if (j > 31)
-				continue;
-			for (k = 0; k < 32; k++)
-				if (!strcasecmp(tmpptr, channel_builtin_bools[k])) {
-					chan->builtin_bools |= (1 << k);
-					break;
-				}
-		}
-
-		j = 0;
-		while ((setting_node = xml_node_lookup(chan_node, 0, "setting", j++, 0))) {
-			if (xml_node_get_str(&tmpptr, setting_node, "name", 0, 0) == -1)
-				continue;
-			if (xml_node_get_str(&tmp2ptr, setting_node, "data", 0, 0) == -1)
-				continue;
-			channel_set(chan, tmpptr, tmp2ptr);
-		}
-
-		j = 0;
-		timer_get_now_sec(&cursecs);
-		while ((setting_node = xml_node_lookup(chan_node, 0, "chanmask", j++, 0))) {
-			char *type, *mask, *creator, *comment;
-			/* FIXME - 'expire' should be long */
-			int expire, lastused, sticky;
-			if ((xml_node_get_int(&expire, setting_node, "expire", 0, 0) == -1) ||
-			    (cursecs > expire))
-				continue;
-			if (xml_node_get_str(&type, setting_node, "type", 0, 0) == -1)
-				continue;
-			if (xml_node_get_str(&mask, setting_node, "mask", 0, 0) == -1)
-				continue;
-			if (xml_node_get_str(&creator, setting_node, "creator", 0, 0) == -1)
-				continue;
-			if (xml_node_get_str(&comment, setting_node, "comment", 0, 0) == -1)
-				continue;
-			if (xml_node_get_int(&lastused, setting_node, "lastused", 0, 0) == -1)
-				continue;
-			if (xml_node_get_int(&sticky, setting_node, "sticky", 0, 0) == -1)
-				continue;
-			channel_notirc_add_mask(chan, *type, mask, creator, comment, expire, lastused, sticky, 0);
-		}
-	}
-
-	xml_node_delete(doc);
 	return 0;
 }
 
-/* Updates info about various channel aspects, once we recive such info */
-void update_channel_structures()
+int channel_save(const char *fname)
 {
-	channel_t *chan;
-	int i;
-
-	for (chan = channel_head; chan; chan = chan->next) {
-
-		if (current_server.type1modes && chan->nlists == 0) {
-			chan->nlists = strlen(current_server.type1modes);
-			chan->lists = calloc(chan->nlists, sizeof(*chan->lists));
-			for (i = 0; i < chan->nlists; i++) {
-				chan->lists[i] = calloc(1, sizeof *chan->lists[i]);
-				chan->lists[i]->type = current_server.type1modes[i];
-			}
-		}
-
-		if (current_server.type2modes && chan->nargs == 0) {
-			chan->nargs = strlen(current_server.type2modes);
-			chan->args = calloc(chan->nargs, sizeof(*chan->args));
-			for (i = 0; i < chan->nargs; i++) {
-				chan->args[i].type = current_server.type2modes[i];
-			}
-		}
-	}
-}
-
-/* Do the stuff like need-* or cycle.. */
-static int channels_minutely()
-{
-	channel_mask_t *m;
-	channel_t *chan;
-	/* FIXME - storage size of cursecs is wrong */
-	int cursecs = 0;
-	int i;
-
-	timer_get_now_sec(&cursecs);
-
-	/* Expire global masks */
-	for (i = 0; i < global_chan.nlists; i++)
-		for (m = (&global_chan)->lists[i]->head; m; m = m->next)
-			if (m->expire && cursecs > m->expire) {
-				char *tmpmask = strdup(m->mask);
-				putlog(LOG_MISC, "*", _("Expiring global +%c list item '%s'"),
-							(&global_chan)->lists[i]->type, tmpmask);
-				channel_del_mask(NULL, (&global_chan)->lists[i]->type, tmpmask, 1);
-				for (chan = channel_head; chan; chan = chan->next)
-					channel_del_mask(chan, (&global_chan)->lists[i]->type, tmpmask, 1);
-				free(tmpmask);
-			}
-
-	if (!current_server.registered)
-		return 0;
-
-	/* Stuff to do only if we're connected */
-	for (chan = channel_head; chan; chan = chan->next) {
-		if (chan->status & CHANNEL_JOINED && /* If we actaully are on channel */
-		   !(chan->builtin_bools & CHAN_INACTIVE)) { /* and channel is not inactive */
-			/* +cycle */
-			if (chan->builtin_bools & CHAN_CYCLE &&/* Channel is +cycle */
-			   chan->nmembers == 1 && /* and we are alone */
-			   !BOT_CAN_SET_MODES(chan) /* and we are not op/halfop */
-			   ) {
-				putlog(LOG_MISC, "*", _("Cycling channel '%s' for ops."), chan->name);
-				printserv(SERVER_NORMAL, "PART %s\r\n", chan->name);
-				printserv(SERVER_NORMAL, "JOIN %s %s\r\n", chan->name,
-						chan->key?chan->key:"");
-			}
-			/* expire channel masks */
-			for (i = 0; i < chan->nlists; i++)
-				for (m = chan->lists[i]->head; m; m = m->next)
-					if (m->expire && cursecs > m->expire) {
-						putlog(LOG_MISC, "*", _("Expiring %s +%c list item '%s'"),
-								chan->name, chan->lists[i]->type, m->mask);
-						channel_del_mask(chan, chan->lists[i]->type, m->mask, 1);
-					}
-		}
-	}
 	return 0;
 }
 
-/* Check if user has a given flag on channel pointed to by channel_t pointer */
-static int chanptr_member_has_flag(const char *nick, channel_t *chan, unsigned char c)
+int channel_load(const char *fname)
 {
-	channel_member_t *m;
-
-	if (!chan || !(chan->status & CHANNEL_JOINED))
-		return 0;
-
-	for (m = chan->member_head; m; m = m->next)
-		if (!(current_server.strcmp)(m->nick, nick))
-			return flag_match_single_char(&m->mode, c);
+	xml_node_t *root;
 
+	root = xml_node_new();
 	return 0;
 }
 
-/* Check if user has a given flag on channel with given name */
-int channame_member_has_flag(const char *nick, const char *channame, unsigned char c)
-{
-	channel_t *chan = NULL;
-
-	if (channel_lookup(channame, 0, &chan, NULL) == -1)
-		return 0;
-	else
-		return chanptr_member_has_flag(nick, chan, c);
-}
-
 static bind_list_t channel_raw_binds[] = {
 	/* WHO replies */
 	{NULL, "352", got352}, /* WHO reply */
@@ -1775,41 +978,3 @@
 
 	{NULL, NULL, NULL}
 };
-
-/* Do not change the order of these.
-   Do not remove setting, simply change it to empty string ""
-   Do not add, there can only be 32 such settings */
-
-static const char *channel_builtin_bools[32] = { /* DDD */
-	"inactive", "cycle", "", "",
-	"", "", "", "",
-	"", "", "", "",
-	"", "", "", "",
-	"", "", "", "",
-	"", "", "", "",
-	"", "", "", "",
-	"", "", "", ""
-	};
-
-/* TBIL = To Be Implemented Later */
-
-static const char *channel_builtin_ints[] = {
-	"idle-kick", /* TBIL */
-	"ban-time", /* TBIL */
-	"invite-time", /* TBIL */
-	"exempt-time", /* TBIL */
-	NULL
-};
-
-static const char *channel_builtin_coupplets[] = {
-	"automode-delay", /* TBIL */
-	NULL
-};
-
-static const char *channel_builtin_strings[] = {
-	"need-op", /* TBIL */
-	"need-unban", /* TBIL */
-	"need-key", /* TBIL */
-	"need-invite", /* TBIL */
-	NULL
-};
Index: eggdrop1.9/modules/server/channels.h
diff -u eggdrop1.9/modules/server/channels.h:1.19 eggdrop1.9/modules/server/channels.h:1.20
--- eggdrop1.9/modules/server/channels.h:1.19	Fri Aug 27 14:16:43 2004
+++ eggdrop1.9/modules/server/channels.h	Sun Sep 26 04:42:09 2004
@@ -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: channels.h,v 1.19 2004/08/27 19:16:43 darko Exp $
+ * $Id: channels.h,v 1.20 2004/09/26 09:42:09 stdarg Exp $
  */
 
 #ifndef _EGG_MOD_SERVER_CHANNELS_H_
@@ -33,18 +33,6 @@
 #define BOT_CAN_SET_MODES(chanptr) (((chanptr)->status & CHANNEL_JOINED) && (flag_match_single_char(&((chanptr)->bot->mode), 'o') \
 									|| flag_match_single_char(&((chanptr)->bot->mode), 'h')))
 
-typedef struct coupplet {
-	struct coupplet *next;
-	char *name;
-	unsigned long left, right;
-} coupplet_t;
-
-typedef struct chanstring {
-	struct chanstring *next;
-	char *name;
-	char *data;
-} chanstring_t;
-
 typedef struct {
 	char *nick;
 	char *uhost;
@@ -64,13 +52,9 @@
 	struct channel_mask *next;
 	char *mask;
 	char *set_by;
-	char *creator;
-	char *comment;
 /* FIXME - these should be long, not int. (EGGTIMEVALT) */
 	int time;
 	int last_used;
-	int expire;
-	int sticky;
 } channel_mask_t;
 
 typedef struct channel_mask_list {
@@ -107,12 +91,8 @@
 
 	channel_member_t *member_head;	/* Member list. */
 	int nmembers;
-	channel_member_t *bot;		/* All you need to know about me :-) */
 
-	unsigned long builtin_bools;	/* Channel flags (inactive, autovoice, etc..) */
-	coupplet_t *builtin_ints;	/* Channel settings of the form: <setting> X */
-	coupplet_t *builtin_coupplets;	/* Channel settings of the form: <setting> X:Y */
-	chanstring_t *builtin_strings;	/* Channel settings of the form: <setting> <anything> */
+	channel_member_t *bot;		/* All you need to know about me :-) */
 } channel_t;
 
 extern channel_t *channel_head;
@@ -122,12 +102,6 @@
 
 extern void server_channel_init();
 extern void server_channel_destroy();
-extern void update_channel_structures();
-extern int destroy_channel_record(const char *chan_name);
-extern int channel_set(channel_t *chanptr, const char *setting, const char *value);
-extern int chanfile_save(const char *fname);
-extern int channel_info(partymember_t *p, const char *channame);
-extern int channame_member_has_flag(const char *nick, const char *channame, unsigned char c);
 extern int channel_lookup(const char *chan_name, int create, channel_t **chanptr, channel_t **prevptr);
 extern char *uhost_cache_lookup(const char *nick);
 extern void uhost_cache_fillin(const char *nick, const char *uhost, int addref);
@@ -146,8 +120,6 @@
 extern int channel_list_members(const char *chan, const char ***members);
 extern channel_mask_list_t *channel_get_mask_list(channel_t *chan, char type);
 extern void channel_add_mask(channel_t *chan, char type, const char *mask, const char *set_by, int time);
-extern int channel_notirc_add_mask(channel_t *chan, char type, const char *mask, const char *creator,
-					const char *comment, int expire, int lastused, int sticky, int console);
 extern int channel_del_mask(channel_t *chan, char type, const char *mask, int remove);
 extern void channel_clear_masks(channel_t *chan, char type);
 extern int channel_list_masks(channel_mask_t ***cm, char type, channel_t *chanptr, const char *mask);
Index: eggdrop1.9/modules/server/egg_server_api.c
diff -u eggdrop1.9/modules/server/egg_server_api.c:1.1 eggdrop1.9/modules/server/egg_server_api.c:1.2
--- eggdrop1.9/modules/server/egg_server_api.c:1.1	Mon Jun  7 18:19:53 2004
+++ eggdrop1.9/modules/server/egg_server_api.c	Sun Sep 26 04:42:09 2004
@@ -3,6 +3,7 @@
 void *server_get_api()
 {
 	static egg_server_api_t api;
+#if 0
 
 	api.major = EGG_SERVER_API_MAJOR;
 	api.minor = EGG_SERVER_API_MINOR;
@@ -16,7 +17,7 @@
 	api.queue_entry_cleanup = queue_entry_cleanup;
 	api.queue_get_by_priority = queue_get_by_priority;
 	api.dequeue_messages = dequeue_messages;
-#if 0
+
 	/* Channel functions. */
 	int (*channel_list)(const char ***chans);
 	int (*channel_list_members)(const char *chan, const char ***members);
Index: eggdrop1.9/modules/server/egg_server_internal.h
diff -u eggdrop1.9/modules/server/egg_server_internal.h:1.4 eggdrop1.9/modules/server/egg_server_internal.h:1.5
--- eggdrop1.9/modules/server/egg_server_internal.h:1.4	Fri Aug 13 15:49:57 2004
+++ eggdrop1.9/modules/server/egg_server_internal.h	Sun Sep 26 04:42:09 2004
@@ -30,7 +30,6 @@
 #define server_channel_init server_LTX_server_channel_init
 #define server_channel_destroy server_LTX_server_channel_destroy
 #define free_all_online_stuff server_LTX_free_all_online_stuff
-#define server_channel_init server_LTX_server_channel_init
 #define channel_lookup server_LTX_channel_lookup
 #define uhost_cache_lookup server_LTX_uhost_cache_lookup
 #define uhost_cache_addref server_LTX_uhost_cache_addref
Index: eggdrop1.9/modules/server/input.c
diff -u eggdrop1.9/modules/server/input.c:1.34 eggdrop1.9/modules/server/input.c:1.35
--- eggdrop1.9/modules/server/input.c:1.34	Fri Jul 23 16:58:55 2004
+++ eggdrop1.9/modules/server/input.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: input.c,v 1.34 2004/07/23 21:58:55 darko Exp $";
+static const char rcsid[] = "$Id: input.c,v 1.35 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include "server.h"
@@ -199,8 +199,6 @@
 		str_redup(&current_server.whoprefix, "@+");
 	}
 
-	update_channel_structures();
-
 	return(0);
 }
 
Index: eggdrop1.9/modules/server/party_commands.c
diff -u eggdrop1.9/modules/server/party_commands.c:1.16 eggdrop1.9/modules/server/party_commands.c:1.17
--- eggdrop1.9/modules/server/party_commands.c:1.16	Fri Aug 27 14:16:43 2004
+++ eggdrop1.9/modules/server/party_commands.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: party_commands.c,v 1.16 2004/08/27 19:16:43 darko Exp $";
+static const char rcsid[] = "$Id: party_commands.c,v 1.17 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include "server.h"
@@ -168,128 +168,30 @@
 /* +chan <name> [settings] */
 static int party_pls_chan(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	const char *settings = NULL, *tmp;
-	char *channame = NULL;
-	channel_t *chanptr = NULL;
-
-	egg_get_arg(text, &settings, &channame);
-
-	if (!channame) {
-		partymember_printf(p, _("Syntax: +chan <name> [settings]"));
-		return 0;
-	}
-
-	if (server_support("CHANTYPES", &tmp) == -1)
-		tmp = "#&";
-
-	if (!strchr(tmp, *channame)) {
-		partymember_printf(p, _("Error: '%c' is not a valid channel prefix."), *channame);
-		partymember_printf(p, _("       This server supports '%s'"), tmp);
-		free(channame);
-		return 0;
-	}
-
-	if (channel_lookup(channame, 1, &chanptr, NULL) == -1) {
-		partymember_printf(p, _("Error: Channel '%s' already exists!"), channame);
-		free(channame);
-		return 0;
-	}
-
-/* FIXME - At this early stage just create channel with given name, with no settings considered. */
-
-	partymember_printf(p, _("Channel '%s' has been created but marked +inactive to give you a chance"), channame);
-	partymember_printf(p, _("  to finish configuring channel settings. When you are ready, type:"));
-	partymember_printf(p, _("    .chanset %s -inactive"), channame);
-	partymember_printf(p, _("  to let the bot join %s"), channame);
-	channel_set(chanptr, "+inactive", NULL);
-
-	free(channame);
 	return BIND_RET_LOG;
 }
 
 /* -chan <name> */
 static int party_mns_chan(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	if (text)
-		while (isspace(*text))
-			text++;
-
-	if (!text || !*text) {
-		partymember_printf(p, _("Syntax: -chan <name>"));
-		return 0;
-	}
-
-	if (destroy_channel_record(text) == 0)
-		partymember_printf(p, _("Removed channel '%s'"), text);
-	else
-		partymember_printf(p, _("Error: Invalid channel '%s'"), text);
-
 	return BIND_RET_LOG;
 }
 
 /* chanset <channel / *> <setting> [data] */
 static int party_chanset(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	const char *args = NULL;
-	char *channame = NULL, *setting = NULL;
-	channel_t *chanptr = NULL;
-	int allchans;
-
-	egg_get_args(text, &args, &channame, &setting, NULL);
-
-	if (!channame || !setting) {
-		partymember_printf(p, _("Syntax: chanset <channel/*> <setting> [value]"));
-		free(channame);
-		return 0;
-	}
-
-	allchans = !strcasecmp("*", channame);
-	if (!allchans && channel_lookup(channame, 0, &chanptr, NULL) == -1) {
-		partymember_printf(p, _("Error: Invalid channel '%s'"), channame);
-		free(channame);
-		free(setting);
-		return 0;
-	}
-
-	if (!args && *setting != '+' && *setting != '-') {
-		partymember_printf(p, _("Error: Setting '%s' requires another argument"), setting);
-		free(channame);
-		free(setting);
-		return 0;
-	}
-
-	if (channel_set(allchans?NULL:chanptr, setting, args))
-		partymember_printf(p, _("Ok, set"));
-	else
-		partymember_printf(p, _("Error: Invalid setting or value"));
-
-	free(channame);
-	free(setting);
 	return BIND_RET_LOG;
 }
 
 /* chaninfo <channel> */
 static int party_chaninfo(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	if (text)
-		while (isspace(*text))
-			text++;
-	if (!text || !*text) {
-		partymember_printf(p, _("Syntax: chaninfo <channel>"));
-		return 0;
-	}
-
-	return channel_info(p, text);
+	return BIND_RET_LOG;
 }
 
 /* chansave [filename] */
 static int party_chansave(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	if (text)
-		while (isspace(*text))
-			text++;
-	chanfile_save(text && *text ? text : NULL);
-
 	return BIND_RET_LOG;
 }
 
@@ -297,99 +199,6 @@
 /* +chanmask <type> <mask> [channel] [%XdYhZm] [comment] */
 static int party_plus_mask(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	const char *rest;
-	char typechar, *mask = NULL, *channame = NULL, *duration = NULL, *comment = NULL;
-	channel_t *chanptr = NULL;
-	int tmpint;
-	/* FIXME - this should be long/time_t */
-	int unixduration = 0;
-
-	if (!strcasecmp("+ban", cmd))
-		typechar = 'b';
-	else if (!strcasecmp("+exempt", cmd))
-		typechar = 'e';
-	else if (!strcasecmp("+invite", cmd))
-		typechar = 'I';
-	else {
-		char *type;
-		egg_get_arg(text, &rest, &type);
-		if (!type || strlen(type) != 1) {
-			partymember_printf(p, _("Syntax: +chanmask <type> <mask> [channel] [%%XdYhZm] [\"comment\"]"));
-			free(type);
-			return BIND_RET_LOG;
-		}
-		text = rest;
-		typechar = *type;
-		free(type);
-	}
-
-	egg_get_args(text, &rest, &mask, &channame, &duration, NULL);
-
-	if (!mask || !*mask) {
-		partymember_printf(p, _("Syntax: %s %s<mask> [channel] [%%XdYhZm] [\"comment\"]"),
-					cmd, !strcasecmp("+chanmask", cmd)?"<type> ":"");
-		goto ppb_out;
-	}
-
-	if (rest && *rest) {
-		comment = strdup(rest);
-		if (channel_lookup(channame, 0, &chanptr, NULL) == -1) {
-			partymember_printf(p, _("Error: Invalid channel '%s'"), channame);
-			goto ppb_out;
-		}
-		if (*duration != '%') {
-			partymember_printf(p, _("Error: Invalid duration. Must be of the form %%XdYhZm"));
-			goto ppb_out;
-		}
-	}
-	else if (duration) {
-		if (channel_lookup(channame, 0, &chanptr, NULL) == -1) {
-			if (*channame != '%') {
-				partymember_printf(p, _("Error: Invalid channel %s"), channame);
-				goto ppb_out;
-			}
-			comment = duration;
-			duration = channame;
-			channame = NULL;
-		} else if (*duration != '%') {
-			comment = duration;
-			duration = NULL;
-		}
-	}
-	else if (channame) {
-		if (channel_lookup(channame, 0, &chanptr, NULL) == -1) {
-			if (*channame == '%')
-				duration = channame;
-			else
-				comment = channame;
-			channame = NULL;
-		}
-	}
-
-	if (duration)
-		unixduration = parse_expire_string(duration);
-	if (unixduration) {
-		/* FIXME - int2long thing again */
-		int tmptime;
-		timer_get_now_sec(&tmptime);
-		unixduration+=tmptime;
-	}
-
-	if (comment && *comment == '@')
-		tmpint = channel_notirc_add_mask(chanptr, typechar, mask, u->handle, &comment[1], unixduration, 0, 1, 1);
-	else
-		tmpint = channel_notirc_add_mask(chanptr, typechar, mask, u->handle, comment, unixduration, 0, 0, 1);
-
-	if (tmpint == 2)
-		partymember_printf(p, _("Error: Entry already exists!"));
-	else if (tmpint == 0)
-		partymember_printf(p, _("Ok, added"));
-
-ppb_out:
-	free(mask);
-	free(channame);
-	free(duration);
-	free(comment);
 	return BIND_RET_LOG;
 }
 
@@ -397,87 +206,6 @@
 /* chanmask <type> [channel/all [mask]] */
 static int party_list_masks(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	char typechar, *mask = NULL, *channame = NULL;
-	channel_t *chanptr = NULL;
-	channel_mask_t **cm = NULL;
-	int allchans = 0, i;
-
-	if (!strcasecmp("bans", cmd))
-		typechar = 'b';
-	else if (!strcasecmp("exempts", cmd))
-		typechar = 'e';
-	else if (!strcasecmp("invites", cmd))
-		typechar = 'I';
-	else {
-		char *type = NULL;
-		const char *rest = NULL;
-		egg_get_arg(text, &rest, &type);
-		if (!type || strlen(type) != 1) {
-			partymember_printf(p, _("Syntax: chanmasks <type> [channel/all] [mask]"));
-			free(type);
-			return BIND_RET_LOG;
-		}
-		text = rest;
-		typechar = *type;
-		free(type);
-	}
-
-	egg_get_args(text, NULL, &channame, &mask, NULL);
-
-	if (channame) {
-		if (!strcasecmp("all", channame))
-			allchans = 1;
-		else if (channel_lookup(channame, 0, &chanptr, NULL) == -1) {
-			if (mask) {
-				partymember_printf(p, _("Error: Invalid channel '%s'"), channame),
-				free(mask);
-				free(channame);
-				return BIND_RET_LOG;
-			}
-			else {
-				mask = channame;
-				channame = NULL;
-				allchans = 1;
-			}
-		}
-	}
-	else
-		allchans = 1;
-
-	i = channel_list_masks(&cm, typechar, allchans?NULL:chanptr, mask?mask:"*");
-	if (i) {
-		int j;
-		if (allchans)
-			partymember_printf(p, _("  Global +%c list:"), typechar);
-		else
-			partymember_printf(p, _("  +%c list for channel '%s':"), typechar, channame);
-		for (j = 0; j < i; j++) {
-/* FIXME - sort out the aesthetics later, for now just print data */
-			partymember_printf(p, _(""));
-			partymember_printf(p, _("  %s%s"), cm[j]->mask,
-						cm[j]->sticky?" (sticky)":"");
-			if (cm[j]->creator)
-				partymember_printf(p, _("    Created by:\t%s"), cm[j]->creator);
-			if (cm[j]->set_by)
-				partymember_printf(p, _("    Set by:\t%s on %s"),
-						cm[j]->set_by, ctime((time_t *)&cm[j]->time));
-			if (cm[j]->creator)
-				partymember_printf(p, _("    Expires:\t%s"),
-				cm[j]->expire?ctime((time_t *)&cm[j]->expire):"never");
-			if (cm[j]->last_used) {
-				int daysago; /* FIXME - grr, another forced-to-declare int */
-				timer_get_now_sec(&daysago);
-				daysago -= cm[j]->last_used;
-				partymember_printf(p, _("    Last used:\t%s ago"), duration_to_string(daysago));
-			}
-			if (cm[j]->comment)
-				partymember_printf(p, _("    Comment:\t%s"), cm[j]->comment);
-		}
-		free(cm);
-	}
-	else
-		partymember_printf(p, _("  No results."));
-
 	return BIND_RET_LOG;
 }
 
@@ -485,53 +213,6 @@
 /* -chanmask <type> <mask/number> */
 static int party_minus_mask(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	char typechar, *mask = NULL, *channame = NULL;
-	channel_t *chanptr = NULL;
-	int tmpint;
-
-	if (!strcasecmp("-ban", cmd))
-		typechar = 'b';
-	else if (!strcasecmp("-exempt", cmd))
-		typechar = 'e';
-	else if (!strcasecmp("-invite", cmd))
-		typechar = 'I';
-	else {
-		const char *rest;
-		char *type;
-		egg_get_arg(text, &rest, &type);
-		if (!type || strlen(type) != 1) {
-			partymember_printf(p, _("Syntax: -chanmask <type> <mask/number> [channel]"));
-			free(type);
-			return BIND_RET_LOG;
-		}
-		text = rest;
-		typechar = *type;
-		free(type);
-	}
-
-	egg_get_args(text, NULL, &mask, &channame, NULL);
-
-	if (!mask) {
-		partymember_printf(p, _("Syntax: %s %s<mask/number> [channel]"),
-					cmd, !strcasecmp("-chanmask", cmd)?"<type> ":"");
-		return BIND_RET_LOG;
-	}
-
-	if (channame)
-		channel_lookup(channame, 0, &chanptr, NULL);
-
-	tmpint = channel_del_mask(chanptr, typechar, mask, 1);
-
-	if (tmpint == -2)
-		partymember_printf(p, _("Error: No matches for %s"), mask);
-	else if (tmpint == -1)
-		partymember_printf(p, _("Error: No '+%c' list"), typechar);
-	else
-		partymember_printf(p, _("Ok, removed %s from %s"), mask,
-					chanptr?channame:"global list");
-
-	free(mask);
-	free(channame);
 	return BIND_RET_LOG;
 }
 
@@ -562,5 +243,5 @@
 	{"n", "chanset", party_chanset},		/* DDC	*/	/* n|n */
 	{"m", "chaninfo", party_chaninfo},		/* DDC	*/	/* m|m */
 	{"n", "chansave", party_chansave},		/* DDC	*/	/* n|n */
-	{0}
+	{0, 0, 0}
 };
Index: eggdrop1.9/modules/server/server.c
diff -u eggdrop1.9/modules/server/server.c:1.59 eggdrop1.9/modules/server/server.c:1.60
--- eggdrop1.9/modules/server/server.c:1.59	Fri Jul 23 16:58:55 2004
+++ eggdrop1.9/modules/server/server.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: server.c,v 1.59 2004/07/23 21:58:55 darko Exp $";
+static const char rcsid[] = "$Id: server.c,v 1.60 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include "server.h"
@@ -160,7 +160,7 @@
 	cycle_delay = 100;
 
 	bind_rem_list("raw", server_raw_binds);
-	bind_rem_list("party", server_party_commands);
+	//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);
@@ -281,6 +281,7 @@
 
 	/* Initialize script interface. */
 	server_script_init();
+	printf("hello there\n");
 
 	return(0);
 }
Index: eggdrop1.9/modules/server/servsock.c
diff -u eggdrop1.9/modules/server/servsock.c:1.22 eggdrop1.9/modules/server/servsock.c:1.23
--- eggdrop1.9/modules/server/servsock.c:1.22	Mon Jun  7 18:14:48 2004
+++ eggdrop1.9/modules/server/servsock.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: servsock.c,v 1.22 2004/06/07 23:14:48 stdarg Exp $";
+static const char rcsid[] = "$Id: servsock.c,v 1.23 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include "server.h"
@@ -84,7 +84,7 @@
 
 	cycle_delay = server_config.cycle_delay;
 
-	channel_reset();
+	//channel_reset();
 	if (current_server.server_host) free(current_server.server_host);
 	if (current_server.server_self) free(current_server.server_self);
 	if (current_server.nick) free(current_server.nick);
Index: eggdrop1.9/src/bg.c
diff -u eggdrop1.9/src/bg.c:1.20 eggdrop1.9/src/bg.c:1.21
--- eggdrop1.9/src/bg.c:1.20	Wed Jun 23 16:12:57 2004
+++ eggdrop1.9/src/bg.c	Sun Sep 26 04:42:09 2004
@@ -20,7 +20,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: bg.c,v 1.20 2004/06/23 21:12:57 stdarg Exp $";
+static const char rcsid[] = "$Id: bg.c,v 1.21 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -57,20 +57,18 @@
 
 /* The child has to keep the parent's pid so it can send it a signal when it's
  * time to exit. */
-static pid_t parent_pid = -1, child_pid = -1;
-
-void wait_for_child(int sig)
-{
-	printf("Eggdrop launched successfully into the background, pid = %d.\n", child_pid);
-	exit(0);
-}
+static int pipefd[2];
 
 void bg_begin_split()
 {
+	pid_t parent_pid = -1, child_pid = -1;
 	int result;
+	char temp = 0;
 
 	parent_pid = getpid();
 
+	pipe(pipefd);
+
 	child_pid = fork();
 	if (child_pid == -1) fatal("CANNOT FORK PROCESS.");
 
@@ -79,24 +77,28 @@
 		/* Yes. Continue as normal. */
 		return;
 	}
-
 	/* We are the parent. Just hang around until the child is done. When
 	 * the child wants us to exit, it will send us the signal and trigger
 	 * wait_for_child. */
-	signal(SIGUSR1, wait_for_child);
-	waitpid(child_pid, &result, 0);
+	close(pipefd[1]);
+	result = read(pipefd[0], &temp, 1);
 
-	/* If we reach this point, that means the child process exited, so
-	 * there was an error. */
-	printf("Eggdrop exited abnormally!\n");
-	exit(1);
+	if (result <= 0) {
+		printf("Eggdrop exited abnormally!\n");
+		exit(1);
+	}
+	else {
+		printf("Eggdrop launched successfully into the background, pid = %d.\n", child_pid);
+		exit(0);
+	}
 }
 
 void bg_finish_split()
 {
-	/* Send parent the USR1 signal, which tells it to print a message
-	 * and exit. */
-	kill(parent_pid, SIGUSR1);
+	char temp = 0;
+	write(pipefd[1], &temp, 1);
+	close(pipefd[1]);
+	close(pipefd[0]);
 
 #if HAVE_SETPGID && !defined(CYGWIN_HACKS)
 	setpgid(0, 0);
Index: eggdrop1.9/src/core_config.c
diff -u eggdrop1.9/src/core_config.c:1.21 eggdrop1.9/src/core_config.c:1.22
--- eggdrop1.9/src/core_config.c:1.21	Mon Jun 28 12:36:34 2004
+++ eggdrop1.9/src/core_config.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: core_config.c,v 1.21 2004/06/28 17:36:34 wingman Exp $";
+static const char rcsid[] = "$Id: core_config.c,v 1.22 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <string.h>
@@ -31,55 +31,34 @@
 
 static config_var_t core_config_vars[] = {
 	/* General bot stuff. */
-	{"botname", &core_config.botname, CONFIG_STRING},		/* DDC	*/
-	{"userfile", &core_config.userfile, CONFIG_STRING},		/* DDC	*/
-	{"lockfile", &core_config.lockfile, CONFIG_STRING},		/* DDC	*/
+	{"botname", &core_config.botname, CONFIG_STRING},	/* DDC	*/
+	{"userfile", &core_config.userfile, CONFIG_STRING},	/* DDC	*/
+	{"lockfile", &core_config.lockfile, CONFIG_STRING},	/* DDC	*/
 
 	/* The owner. */
-	{"owner", &core_config.owner, CONFIG_STRING},			/* DDC	*/
-	{"admin", &core_config.admin, CONFIG_STRING},			/* DDC	*/
+	{"owner", &core_config.owner, CONFIG_STRING},		/* DDC	*/
+	{"admin", &core_config.admin, CONFIG_STRING},		/* DDC	*/
 
 	/* Paths. */
-	{"help_path", &core_config.help_path, CONFIG_STRING},		/* DDD	*/
-	{"temp_path", &core_config.temp_path, CONFIG_STRING},		/* DDD	*/
-	{"text_path", &core_config.text_path, CONFIG_STRING},		/* DDD	*/
-	{"module_path", &core_config.module_path, CONFIG_STRING},	/* DDD	*/
+	{"help_path", &core_config.help_path, CONFIG_STRING},	/* DDD	*/
+	{"temp_path", &core_config.temp_path, CONFIG_STRING},	/* DDD	*/
+	{"text_path", &core_config.text_path, CONFIG_STRING},	/* DDD	*/
+	{"module_path", &core_config.module_path, CONFIG_STRING},/* DDD	*/
 
 	/* Whois. */
-	{"whois_items", &core_config.whois_items, CONFIG_STRING},	/* DDD	*/
+	{"whois_items", &core_config.whois_items, CONFIG_STRING},/* DDD	*/
+
+	/* Logging. */
+	{"logging.keep_all", &core_config.logging.keep_all, CONFIG_INT},
+	{"logging.quick", &core_config.logging.quick, CONFIG_INT},
+	{"logging.max_size", &core_config.logging.max_size, CONFIG_INT},
+	{"logging.switch_at", &core_config.logging.switch_at, CONFIG_INT},
 
 	/* Other. */
-	{"die_on_sigterm", &core_config.die_on_sigterm, CONFIG_INT},	/* DDD	*/
+	{"die_on_sigterm", &core_config.die_on_sigterm, CONFIG_INT},/* DDD*/
 	{0}
 };
 
-config_variable_t loglevel_vars[] = {
-	{ "LOG_MISC",   LOG_MISC,   NULL },
-	{ "LOG_PUBLIC", LOG_PUBLIC, NULL }, 
-	{ "LOG_MSGS",   LOG_MSGS,   NULL },
-	{ "LOG_JOIN",   LOG_JOIN,   NULL },
-	{ 0, 0, 0 }
-};
-config_type_t loglevel_type = { "level", sizeof(int), loglevel_vars };
-
-config_variable_t logfile_vars[] = {
-	{ "@filename", CONFIG_NONE, &CONFIG_TYPE_STRING },
-	{ "@channel",  CONFIG_NONE, &CONFIG_TYPE_STRING },
-	{ NULL,        CONFIG_ENUM, &loglevel_type      },
-	{ 0, 0, 0 }
-};
-config_type_t logfile_type = { "logfile", sizeof(logfile_t), logfile_vars };
-
-config_variable_t logging_vars[] = {
-	{ "@keep_all",  CONFIG_NONE,  &CONFIG_TYPE_BOOL   },
-	{ "@quick",     CONFIG_NONE,  &CONFIG_TYPE_BOOL   },
-	{ "@max_size",  CONFIG_NONE,  &CONFIG_TYPE_INT    },
-	{ "@switch_at", CONFIG_NONE,  &CONFIG_TYPE_INT    },
-	{ "@suffix",    CONFIG_NONE,  &CONFIG_TYPE_STRING },
-	{ "logfiles",   CONFIG_ARRAY, &logfile_type       },	
-	{ 0, 0, 0 }
-};
-config_type_t logging_type = { "logging", sizeof(logging_t), logging_vars };
 
 int core_config_init(const char *fname)
 {
@@ -90,8 +69,7 @@
 	egg_setowner(&core_config.owner);
 
 	config_root = config_load(fname);
-	if (config_root == NULL)
-		return -1;
+	if (config_root == NULL) return -1;
 
 	config_set_root("eggdrop", config_root);
 	config_link_table(core_config_vars, config_root, "eggdrop", 0, NULL);
@@ -102,8 +80,6 @@
 
 	config_update_table(core_config_vars, config_root, "eggdrop", 0, NULL);
 
-	config2_link(0, &logging_type, &core_config.logging);
-
 	return (0);
 }
 
@@ -111,8 +87,6 @@
 {
 	config_update_table(core_config_vars, config_root, "eggdrop", 0, NULL);
 
-	config2_sync(0, &logging_type, &core_config.logging);
-
 	config_save("eggdrop", configfile);
 
 	return (0);
Index: eggdrop1.9/src/core_party.c
diff -u eggdrop1.9/src/core_party.c:1.39 eggdrop1.9/src/core_party.c:1.40
--- eggdrop1.9/src/core_party.c:1.39	Sat Jul 17 15:59:38 2004
+++ eggdrop1.9/src/core_party.c	Sun Sep 26 04:42:09 2004
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: core_party.c,v 1.39 2004/07/17 20:59:38 darko Exp $";
+static const char rcsid[] = "$Id: core_party.c,v 1.40 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -196,8 +196,7 @@
 	if (!uname(&un)) partymember_printf(p, _("OS: %1$s %2$s"), un.sysname, un.release);
 #endif
 	partymember_printf(p, _("Help path: %s (%d entries, %d sections)"),
-			core_config.help_path, help_count_entries(),
-			help_count_sections());
+			core_config.help_path, 0, 0);
 	partymember_printf(p, "");
 	check_bind_status(p, text);
 	return(0);
@@ -471,7 +470,7 @@
 
 static int party_help(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	return help_print_party(p, text);
+	return 0;
 }
 
 static int party_addlog(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
@@ -569,31 +568,37 @@
 /* Syntax: chhandle <old_handle> <new_handle> */
 static int party_chhandle(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
 {
-	char *old = NULL, *new = NULL;
+	char *old = NULL, *newh = NULL;
 	user_t *dest;
 
-	egg_get_args(text, NULL, &old, &new, NULL);
-	if (!old || !new || !*old || !*new) {
+	egg_get_args(text, NULL, &old, &newh, NULL);
+	if (!old || !newh || !*old || !*newh) {
+		if (old) free(old);
+		if (newh) free(newh);
 		partymember_printf(p, _("Syntax: chhandle <old_handle> <new_handle>"));
 		goto chhandleend;
 	}
 
 	dest = user_lookup_by_handle(old);
 	if (!dest) {
+		free(old);
+		free(newh);
 		partymember_printf(p, _("Error: User '%s' does not exist."), old);
 		goto chhandleend;
 	}
 
-	if (user_lookup_by_handle(new)) {
-		partymember_printf(p, _("Error: User '%s' already exists."), new);
-		goto chhandleend;
+	if (user_lookup_by_handle(newh)) {
+		free(old);
+		free(newh);
+		partymember_printf(p, _("Error: User '%s' already exists."), newh);
+		return 0;
 	}
 
-	if (user_change_handle(dest, old, new))
+	if (!user_change_handle(dest, newh))
 		partymember_printf(p, _("Ok, changed."));
 
 chhandleend:
-	free(new);
+	free(newh);
 	free(old);
 
 	return BIND_RET_LOG;
Index: eggdrop1.9/src/logfile.c
diff -u eggdrop1.9/src/logfile.c:1.47 eggdrop1.9/src/logfile.c:1.48
--- eggdrop1.9/src/logfile.c:1.47	Mon Jun 28 12:36:34 2004
+++ eggdrop1.9/src/logfile.c	Sun Sep 26 04:42:09 2004
@@ -19,7 +19,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: logfile.c,v 1.47 2004/06/28 17:36:34 wingman Exp $";
+static const char rcsid[] = "$Id: logfile.c,v 1.48 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #include <stdio.h>
@@ -31,6 +31,10 @@
 #include "terminal.h"					/* TERMINAL_NICK	*/
 #include "logfile.h"
 
+
+static logfile_t *logfiles = NULL;
+static int nlogfiles = 0;
+
 extern int backgrd, use_stderr, terminal_mode;
 int terminal_enabled = 0;
 extern time_t now;
@@ -50,31 +54,47 @@
 	{0}
 };
 
-static bind_list_t log_binds[] = {
-	{NULL, NULL, on_putlog},
-	{0}
-};
-
-static bind_list_t log_events[] = {
-	{NULL, "minutely", logfile_minutely},		/* DDD	*/
-	{NULL, "5minutely", logfile_5minutely},		/* DDD	*/
-	{0}
-};
-
 void logfile_init(void)
 {
+	void *root, *node;
+	char *filename, *chname, *mask;
+	int i;
+
 	script_create_commands(log_script_cmds);
-	bind_add_list("log", log_binds);
-	bind_add_list("event", log_events);
+	bind_add_simple("log", NULL, NULL, on_putlog);
+	bind_add_simple("event", NULL, "minutely", logfile_minutely);
+	bind_add_simple("event", NULL, "5minutely", logfile_5minutely);
+
+	root = config_get_root("eggdrop");
+	node = config_lookup_section(root, "eggdrop.logging.logfiles", 0, NULL);
+	for (i = 0; ; i++) {
+		config_get_str(&filename, node, "logfile", i, "filename", 0, NULL);
+		config_get_str(&chname, node, "logfile", i, "channel", 0, NULL);
+		config_get_str(&mask, node, "logfile", i, "mask", 0, NULL);
+		if (!filename || !chname || !mask) break;
+		logfile_add(mask, chname, filename);
+	}
 }
 
 void logfile_shutdown(void)
 {
+	void *root, *node;
+	int i;
+
 	flushlogs();
 	
+	root = config_get_root("eggdrop");
+	node = config_lookup_section(root, "eggdrop.logging.logfiles", 0, NULL);
+	for (i = 0; i < nlogfiles; i++) {
+		config_set_str(logfiles[i].filename, node, "logfile", i, "filename", 0, NULL);
+		config_set_str(logfiles[i].chname, node, "logfile", i, "channel", 0, NULL);
+		config_set_str("*", node, "logfile", i, "mask", 0, NULL);
+	}
+
+	bind_rem_simple("log", NULL, NULL, on_putlog);
+	bind_rem_simple("event", NULL, "minutely", logfile_minutely);
+	bind_rem_simple("event", NULL, "5minutely", logfile_5minutely);
 	script_delete_commands(log_script_cmds);
-	bind_rem_list("log", log_binds);
-	bind_rem_list("event", log_events);
 }
 
 static int logfile_minutely()
@@ -119,8 +139,8 @@
 		strftime(suffix, 32, core_config.logging.suffix, localtime(&now));
 	}
 
-	for (i = core_config.logging.nlogfiles - 1; i >= 0; i--) {
-		log = &core_config.logging.logfiles[i];
+	for (i = nlogfiles - 1; i >= 0; i--) {
+		log = &logfiles[i];
 
 		fclose(log->fp);
 
@@ -132,8 +152,7 @@
 		free(newfname);
 
 		log->fp = fopen(log->filename, "a");
-		if (!log->fp)
-			logfile_del(log->filename);
+		if (!log->fp) logfile_del(log->filename);
 	}
 	
 	return(0);
@@ -151,10 +170,9 @@
 	fp = fopen(fname, "a");
 	if (!fp) return("");
 	
-	core_config.logging.logfiles = realloc(core_config.logging.logfiles,
-			(core_config.logging.nlogfiles + 1) * sizeof(logfile_t));
+	logfiles = realloc(logfiles, (nlogfiles + 1) * sizeof(*logfiles));
 			
-	log = &core_config.logging.logfiles[core_config.logging.nlogfiles++];
+	log = &logfiles[nlogfiles++];
 	log->filename = strdup(fname);
 	log->chname = strdup(chan);
 	log->last_msg = strdup("");
@@ -170,15 +188,13 @@
 	int i;
 
 	log = NULL;
-	for (i = 0; i < core_config.logging.nlogfiles; i++) {
-		log = &core_config.logging.logfiles[i];
-		if (0 == strcmp(log->filename, filename))
-			break;
+	for (i = 0; i < nlogfiles; i++) {
+		log = &logfiles[i];
+		if (!strcmp(log->filename, filename)) break;
 		log = NULL;
 	}
 
-	if (log == NULL)
-		return (-1);
+	if (log == NULL) return(-1);
 		
 	if (log->fp) {
 		flushlog(log, timer_get_timestamp());
@@ -188,19 +204,15 @@
 	if (log->last_msg) free(log->last_msg);
 	if (log->filename) free(log->filename);
 
-	if (core_config.logging.nlogfiles == 1) {
-		free(core_config.logging.logfiles);
-		core_config.logging.logfiles = NULL;
+	if (nlogfiles == 1) {
+		free(logfiles);
+		logfiles = NULL;
 	} else {		
-		memmove(core_config.logging.logfiles + i,
-			core_config.logging.logfiles + i + 1,
-			(core_config.logging.nlogfiles - i - 1) * sizeof(logfile_t));
-		core_config.logging.logfiles = realloc(
-			core_config.logging.logfiles, 
-				(core_config.logging.nlogfiles - 1) * sizeof(logfile_t));
+		memmove(logfiles + i, logfiles + i + 1, (nlogfiles - i - 1) * sizeof(logfile_t));
+		logfiles = realloc(logfiles, (nlogfiles - 1) * sizeof(logfile_t));
 	}
 
-	core_config.logging.nlogfiles--;
+	nlogfiles--;
 
 	return(0);
 }
@@ -211,8 +223,8 @@
 	int i;
 
 	ts = timer_get_timestamp();
-	for (i = core_config.logging.nlogfiles - 1; i >= 0; i--) {
-		logfile_t *log = &core_config.logging.logfiles[i];
+	for (i = nlogfiles - 1; i >= 0; i--) {
+		logfile_t *log = &logfiles[i];
 		
 		/* If this log is disabled, skip it */
 		if (log->state != LOG_STATE_ENABLED)
@@ -223,8 +235,7 @@
 			continue;
 		}
 
-		if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname))
-			continue;
+		if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname)) continue;
 		
 		/* If it's a repeat message, don't write it again. */
 		if (log->last_msg && !strcasecmp(text, log->last_msg)) {
@@ -294,8 +305,8 @@
 
 	if (core_config.logging.keep_all || core_config.logging.max_size <= 0) return;
 
-	for (i = 0; i < core_config.logging.nlogfiles; i++) {
-		logfile_t *log = &core_config.logging.logfiles[i];
+	for (i = 0; i < nlogfiles; i++) {
+		logfile_t *log = &logfiles[i];
 		
 		size = ftell(log->fp) / 1024; /* Size in kilobytes. */
 		if (size < core_config.logging.max_size) continue;
@@ -330,7 +341,7 @@
 	int i;
 
 	ts = timer_get_timestamp();
-	for (i = 0; i < core_config.logging.nlogfiles; i++) {
-		flushlog(&core_config.logging.logfiles[i], ts);
+	for (i = 0; i < nlogfiles; i++) {
+		flushlog(&logfiles[i], ts);
 	}
 }
Index: eggdrop1.9/src/logfile.h
diff -u eggdrop1.9/src/logfile.h:1.11 eggdrop1.9/src/logfile.h:1.12
--- eggdrop1.9/src/logfile.h:1.11	Mon Jun 28 12:36:34 2004
+++ eggdrop1.9/src/logfile.h	Sun Sep 26 04:42:09 2004
@@ -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: logfile.h,v 1.11 2004/06/28 17:36:34 wingman Exp $
+ * $Id: logfile.h,v 1.12 2004/09/26 09:42:09 stdarg Exp $
  */
 
 #ifndef _EGG_LOGILE_H
@@ -49,9 +49,6 @@
 	int max_size;
 	int switch_at;
 	char *suffix;
-
-	logfile_t *logfiles;
-	int nlogfiles;
 } logging_t;
 
 extern void logfile_init(void); 
Index: eggdrop1.9/src/main.c
diff -u eggdrop1.9/src/main.c:1.183 eggdrop1.9/src/main.c:1.184
--- eggdrop1.9/src/main.c:1.183	Thu Aug 19 13:39:36 2004
+++ eggdrop1.9/src/main.c	Sun Sep 26 04:42:09 2004
@@ -19,7 +19,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: main.c,v 1.183 2004/08/19 18:39:36 darko Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.184 2004/09/26 09:42:09 stdarg Exp $";
 #endif
 
 #if HAVE_CONFIG_H
@@ -363,6 +363,9 @@
 
 	sv.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sv, NULL);
+
+	sv.sa_handler = SIG_IGN;
+	sigaction(SIGUSR1, &sv, NULL);
 }
 
 static void core_shutdown_or_restart()
@@ -373,15 +376,12 @@
 	putlog(LOG_MISC, "*", _("Saving user file..."));
 	user_save(core_config.userfile);
 
-	putlog(LOG_MISC, "*", _("Saving config file..."));
-	core_config_save();
-	
 	/* destroy terminal */
 	if (terminal_mode && runmode != RUNMODE_RESTART)
 		terminal_shutdown();
 
 	/* unload core help */
-	help_unload_by_module("core");
+	//help_unload_by_module("core");
 
 	/* shutdown core binds */
 	core_binds_shutdown();
@@ -389,6 +389,9 @@
 	/* shutdown logging */ 
 	logfile_shutdown();
 	
+	putlog(LOG_MISC, "*", _("Saving config file..."));
+	core_config_save();
+	
 	/* shutdown libeggdrop */
 	eggdrop_shutdown();
 
@@ -526,9 +529,6 @@
 		   we have a restart */
 	} while (runmode == RUNMODE_RESTART);
 
-	if (debug_run)
-		mem_dbg_stats();
-
 	return 0;
 }
 
@@ -594,7 +594,7 @@
 	core_party_init();
 
 	/* Load core help */
-	help_load_by_module ("core");
+	//help_load_by_module ("core");
 
 	/* Put the module directory in the ltdl search path. */
 	if (core_config.module_path)
----------------------- End of diff -----------------------



More information about the Changes mailing list