diff --git a/source/chansrv.c b/source/chansrv.c
index d8c1af1..425cc81 100644
--- a/source/chansrv.c
+++ b/source/chansrv.c
@@ -1,2559 +1,2559 @@
 /*
  * Copyright (C) 1996 Darkbot Project.
 
  * This program is free software, you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2.  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 COPYING file for details.
  */
 
 
 #include "defines.h"
 #include "vars.h"
 #include "prototypes.h"
 
 // FIXME: When the command is invoked in a channel, target is the channel name, otherwise target is the bots name?
 //        Due to the original nature of this code, some of these routines assume the in channel case, others assume the /msg case.
 //        Also check the commands that can have a channel argument work the same in and out of channel.
 
 enum chanserv_command_type
 {
     INFO_COMMAND = 0,
     SAFE_COMMAND = 1,
     NORMAL_COMMAND = 2,
     DANGER_COMMAND = 3,
     PASSWORD_COMMAND = 4
 };
 
 struct chanserv_command
 {
     enum chanserv_command_type	 type;
     int                          access;
     int				 arg_count;
     int			         too_many; /* Check for too many args */
     struct chanserv_output 	*(*func) (char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost);
     char         		*command[5];
     char                        *syntax;
     char                        *summary;
 };
 
 
 static void show_output(char *source, char *target, struct chanserv_output *result, enum chanserv_invoke_type input_type, int question);
 struct chanserv_output *chanserv_show_help(char *cmd, long user_level);
 
 
 struct chanserv_output *chanserv_asprintf(struct chanserv_output *output, const char *format, ...)
 {
 	struct chanserv_output *result = NULL;
 	static char temp[BUFSIZ];	/* a temp buffer (8KB) */
 	va_list list;
 	int r;
 
 	va_start(list, format);
 	r = vsprintf(temp, format, list);
 	va_end(list);
 
 	if (r >= 0) 
 	{
 	    char *ptr;
 
 	    ptr = malloc(r + 1);
 	    if (ptr)
 	    {
 		result = malloc(sizeof(struct chanserv_output));
 		if (result)
 		{
 		    strncpy(ptr, temp, r);	/* copy at most n */
  		    ptr[r] = '\0';		/* ensure \0 at end */
 
 		    result->output = ptr;
 		    result->next = NULL;
 		    if (output)
 		    {
 			struct chanserv_output *next = output;
 
 			while (next->next)
 			    next = next->next;
 			next->next = result;
 			result = output;
 		    }
 		}
 		else
 		    free(ptr);
 	    }
 
 	}
 	if (result == NULL)
 	{
 	    ;// FIXME: Should bitch about lack of ram.
 	}
     return result;
 }
 
 void chanserv_output_free(struct chanserv_output *output)
 {
     while (output)
     {
 	struct chanserv_output *next = output->next;
 
 	free(output->output);
 	free(output);
 	output = next;
     }
 }
 
 
 struct chanserv_output *chanserv_add(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char str [STRING_LONG] = { 0 }, topic [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Add what?");
 		
 	/* Save topic since we're chopping args[0] off later. */
 	strncpy (topic, args[0], sizeof (topic));
 
 	/* Check to make sure the topic doesn't exist first. */
 	if (check_existing_url(source, topic, target) == 1)
 	{
 		return chanserv_asprintf(result, "%s \37%s\37\n", 
 					EXISTING_ENTRY, topic);
 	}
 
 	/* Cut off the first argument (the topic) */
 	args++;
 
 	if ((db_argstostr (str, args, 0, ' ')) < 1)
 		return chanserv_asprintf(result, "What info is to be added for %s?", topic);
 
 	// Fix for some segmentation fault problems
 	// concerning topics consisting entirely of
 	// wildcard characters.
 	if (strspn(topic, "*?") == strlen(topic))
 		return chanserv_asprintf(NULL, "Sorry, but support for that topic has been removed.");
 		
 	/* FIXME: If both things happen, result is overwritten with 
   	 * the second event, and the first truncation isn't displayed
 	 */
 	if (strlen(topic) > MAX_TOPIC_SIZE)
 	{
 		topic[MAX_TOPIC_SIZE] = '\0';
 		result = chanserv_asprintf(NULL, "Topic is over the limit, and has had characters truncated.");
 	}
 
 	if (strlen(str) > MAX_DATA_SIZE)
 	{
 		str[MAX_DATA_SIZE] = '\0';
 		result = chanserv_asprintf(NULL, "Data is over the limit, and has had characters truncated.");
 	}
 
 	strlwr(topic);
 
 	/* Don't allow the topic to be an rdb file name. */
 	if (*topic == '~')
 		return chanserv_asprintf(result, "Rdb files can only be called from the data of a topic, they cannot be used in the topic itself.");
 
 	if (LOG_ADD_DELETES)
 	    db_log(ADD_DELETES, "[%s] %s!%s ADD %s %s\n", date(), source, 
 				userhost, topic, str);
 
 	ADDITIONS++;
 	
 	if ((strspn (topic, "ilc")) == 3 ||
 	    (strspn (topic, "iln")) == 3)
 	{
 		db_log(URL2, "%s ([%s] %s!%s): %s\n", topic, date(), 
 			source, userhost, str);
 	}
 	else
 	{
 		db_log(URL2, "%s %s\n", topic, str);
 	}
 	return chanserv_asprintf(result, "Okay.");
 }
 
 struct chanserv_output *chanserv_add_user(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char temp[1024] = { 0 };
 	long level = 0;
 
 	if (!args || !args[0] || !args[1] || !args[2] || !args[3])
 		return result;
 	level = atoi(args[2]);
 	if (level > 10 || level <= 0)
 		return result;
 	if (strlen(args[1]) < 7)
 		return result;
 	snprintf(temp, sizeof (temp), "I haven't used \2%cSETINFO\2 yet!", *CMDCHAR);
 	add_helper(args[0], mask_from_nick(args[1], target), level, 0, temp, args[3], 0);
 	save_changes();
 
 	return chanserv_asprintf(NULL, "Added user: %s - level %d.", mask_from_nick(args[1], target), level);
 }
 
 struct chanserv_output *chanserv_alarm(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct 	chanserv_output *result = NULL;
 
 	char 	temp[1024] = { 0 };
 	time_t 	seconds = 0, unixtime = 0;
 	long	i = 0;
 
 	if (!args || !args[0] || !args[1] || (strlen(args[0]) < 2))
 		return chanserv_asprintf(NULL, "Syntax: <time type: \2d/h/m/s\2><time> <text to say>");
 
 	if (tolower(*args[0]) == 'd')
 	{
 		/* Days. */
 		seconds = 86400;
 		args[0]++;
 	}
 	else if (tolower(*args[0]) == 'h')
 	{
 		/* Hours */
 		seconds = 3600;
 		args[0]++;
 	}
 	else if (tolower(*args[0]) == 'm')
 	{
 		/* Minutes */
 		seconds = 60;
 		args[0]++;
 	}
 	else if (tolower(*args[0]) == 's')
 	{
 		/* Seconds */
 		seconds = 1;
 		args[0]++;
 	}
 	else
 	{
 		return chanserv_asprintf(NULL, "Syntax: <time type: \2d/h/m/s\2><time> <text to say>");
 	}
 	
 
 	snprintf(temp, sizeof (temp), "%s/%ld", 
 			DBTIMERS_PATH, 
 			(atoi (args[0]) * seconds) + time (NULL));
 	
 	db_log(temp, "PRIVMSG %s :\2ALARMCLOCK\2 by %s!%s: %s", source, source, userhost, args[1]);
 	
 	unixtime = atoi (args[0]) * seconds;
 	
 	if (unixtime > 86400)
 		result = chanserv_asprintf(NULL, "alarmclock set to go off in %d day%s, %02d:%02d.", 
 		   unixtime / 86400, 
 		   plural((unixtime / 86400)),
 		   (unixtime / 3600) % 24, 
 		   (unixtime / 60) % 60);
 	else if (unixtime > 3600)
 		result = chanserv_asprintf(NULL, "alarmclock set to go off in %d hour%s, %d min%s.",
 		   unixtime / 3600, 
 		   plural ((unixtime / 3600)),
 		   (unixtime / 60) % 60, 
 		   plural (((unixtime / 60) % 60)));
 	else
 		result = chanserv_asprintf(NULL, "alarm clock set to go off in %d minute%s, %d sec%s.",
 		   unixtime / 60, 
 		   unixtime / 60 == 1 ? "" : "s", 
 		   unixtime % 60,
 		   unixtime % 60 == 1 ? "" : "s");
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_autotopic(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	topic	[STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return result;
 	if (db_argstostr(topic, args, 0, ' ') < 1)
 		return result;
 
 	set_autotopic (source, target, topic);
 
 	return result;
 }
 #endif
 
 //#ifndef	WIN32
 struct chanserv_output *chanserv_backup(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	char temp[1024] = { 0 };
 	int ret;
 
 	snprintf(temp, sizeof (temp), "/bin/cp -f %s %s_`date +%%F_%%R.bak`\n", URL2, URL2);
 	ret = system(temp);
 
 	return chanserv_asprintf(NULL, "Backed up database.");
 }
 //#endif
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_ban_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return show_banlist(source);
 }
 #endif
 
 #ifdef	ENABLE_MATH
 struct chanserv_output *chanserv_calc(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result;
 	if (strlen(args[0]) > 200)
 		args[0][200] = '\0';
 	return do_math(source, target, args[0]);
 }
 #endif
 
 struct chanserv_output *chanserv_chan_info(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result;
 	else
 		/* If args[0] is not a valid channel name, just use the current channel */
 		result = show_chaninfo (source, ((*args[0] == '#' || *args[0] == '&' || *args[0] == '+') ? args[0] : target), target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_chan_users(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		result = show_chanusers (source, target);
 	else
 		/* If args[0] is not a valid channel name, just use the current channel. */
 		result = show_chanusers (source, ((*args[0] == '#' || *args[0] == '&' || *args[0] == '+') ? args[0] : target));
 
 	return result;
 }
 
 struct chanserv_output *chanserv_char(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result;
 
 	return chanserv_asprintf(NULL, "%c -> %d.", args[0][0], args[0][0]);
 }
 
 struct chanserv_output *chanserv_char_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "My command char is: %c.", *CMDCHAR);
 }
 
 struct chanserv_output *chanserv_cpu_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	getrusage(RUSAGE_SELF, &r_usage);
 
 	return chanserv_asprintf(NULL, "CPU usage: %ld.%06ld, System = %ld.%06ld.", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec, r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
 }
 
 struct chanserv_output *chanserv_cycle(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	/* Check for channel list parameter being specified. */
 	if (!args | !args[0])
 	{
 		S ("PART %s\n", target);
 		S ("JOIN %s\n", target);
 	}
 	else
 	{
 		result = chanserv_asprintf(NULL, "Cycling %s.", args[0]);
 		S("PART %s\n", args[0]);
 		S("JOIN %s\n", args[0]);
 	}
 
 	return result;
 }
 
 struct chanserv_output *chanserv_data_search(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "What should I be %sing for?", cmd);
 	printf ("args[0] = %s\n", args[0]);
 	datasearch (source, args[0], target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_date(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
     return chanserv_asprintf(NULL, "%s.", date());
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_delban(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Enter the user@host to purge!");
 	if (del_permban(source, args[0]) == 1)
 		S("MODE %s -b %s\n", target, args[0]);
 	else
 		result = chanserv_asprintf(NULL, "No such ban.");
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_delete(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "%s what?", cmd);
 	if (strlen (args[0]) > MAX_TOPIC_SIZE)
 		args[0][MAX_TOPIC_SIZE] = '\0';
 	if (LOG_ADD_DELETES)
 	    db_log (ADD_DELETES, "[%s] %s!%s DEL %s\n", date (), source, userhost, args[0]);
 	if (*args[0] == '~')
 	{	/* need level 2 to delete .rdb files */
 		if (invoked == MSG_INVOKE)
 		{
 		    if (check_access (userhost, "#*", 0, source) >= 2)
 			delete_url (source, args[0], source);
 		}
 		else
 		{
 		    if (check_access (userhost, target, 0, source) >= 2)
 			delete_url (source, args[0], target);
 		}
 		return result;
 	}
 	if (invoked == MSG_INVOKE)
 	    delete_url (source, args[0], source);
 	else
 	    delete_url (source, args[0], target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_deluser(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Enter the user@host to delete!");
 	delete_user_ram (source, args[0]);
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_deop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char 	users_to_deop [STRING_LONG] = {0}, chan[STRING_LONG] = {0};
 
 	/* Make sure first arg, which should be target chan, is there. */
 	if (!args || !args[0])
 	    return result;
 	
 	strncpy (chan, args[0], sizeof (chan));
 
 	/* Chop of first arg, since we have a copy as chan. */
 	args++;
 
 	db_argstostr (users_to_deop, args, 0, ' ');
 
 	if ((invoked == MSG_INVOKE) || (*chan == '#'))
 	{
 	    if (check_access (userhost, chan, 0, source) >= 3)
 	    {
 		if (users_to_deop[0] == '\0')
 			return result;
 		S ("MODE %s -oooooo %s\n", chan, users_to_deop);
 	    }
 	}
 	else
 	{
 	    if (users_to_deop[0] == '\0')
 		S ("MODE %s -oooooo %s\n", target, chan);
 	    else
 		S ("MODE %s -oooooo %s %s\n", target, chan, users_to_deop);
 	}
 
 	return result;
 }
 
 struct chanserv_output *chanserv_devoice(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char chan [STRING_LONG] = {0}, users_to_devoice [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 	    return result;
 
 	strncpy (chan, args[0], sizeof (chan));
 	args++;
 	db_argstostr (users_to_devoice, args, 0, ' ');
 
 	if ((invoked == MSG_INVOKE) || (*chan == '#'))
 	{
 	    if (check_access (userhost, chan, 0, source) >= 3)
 	    {
 		if (users_to_devoice[0] == '\0')
 			return result;
 		S ("MODE %s -vvvvvv %s\n", chan, users_to_devoice);
 	    }
 	}
 	else
 	{
 	    if (users_to_devoice[0] == '\0')
 		S ("MODE %s -vvvvvvv %s\n", target, chan);
 	    else
 		S ("MODE %s -vvvvvvv %s %s\n", target, chan, users_to_devoice);
 	}
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_die(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char 	 quit_message [STRING_LONG] = {0};
 	long	 unixtime = 0;
 
 	if (!args || !args[0])
 		Snow("QUIT :K\2\2illed (%s (cause I say so!))\n", source);
 	else
 	{
 		if ((db_argstostr (quit_message, args, 0, ' ')) < 1)
 			return result;
 		Snow("QUIT :K\2\2illed (%s (%s))\n", source, quit_message);
 	}
 
 	db_sleep (1);
 
 	printf ("\n\nGood-bye! %s (c) Jason Hamilton\n\n", dbVersion);
 	uptime = time (NULL) - uptime;
 	printf("Time elapsed: %ld hour%s, %ld min%s\n\n",
 		 uptime / 3600,
 		 uptime / 3600 == 1 ? "" : "s",
 		 (uptime / 60) % 60, (uptime / 60) % 60 == 1 ? "" : "s");
 	db_sleep (5);
 	exit (0);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_display(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	if (!args || !args[0])
 		return result;
 	result = display_url(target, source, args[0]);
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_down(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	S ("MODE %s -o %s\n", target, source);
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_darkbot(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (Sleep_Toggle == 1)
 		return result;
 	if (cf (userhost, source, target))
 		return result;
 
 	return chanserv_asprintf(NULL, "%s reporting! My cmdchar is %c.", dbVersion, *CMDCHAR);
 }
 
 struct chanserv_output *chanserv_help(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char command [STRING_LONG] = {0};
 	char *chan = NULL;
 	long user_level;
 
 	if (!args || !args[0])
 	{
 	    result = chanserv_asprintf(result, "I can be triggered by various forms of speech, all which must be addressed to me, in one of the following formats:  %s %s %s or even %s .  In my database, you can find a topic by saying my nick, <topic> .  eg; \37%s nuke\37 .  To do a search on a word, or partial text, just type: search <text> or dsearch <text> , eg; \37search nuke\37.", 
 		NICK_COMMA, COLON_NICK, BCOLON_NICK, Mynick, NICK_COMMA);
 	    if (cf (userhost, source, target))
 		return result;
 	    result = chanserv_asprintf(result, "I can also be triggered with even more human formats: \37%s who is bill gates?\37 .  You can also phrase it as a question: \37%s where is msie?\37 .  For a list of commands use \37help commands\37 .  For a list of setup parameters use \37help parameters\37 .  For more info about me, visit http://darkbot.sourceforge.net .",
 		NICK_COMMA, NICK_COMMA, NICK_COMMA);
 	    return (result);
 	}
 	
 	if ((db_argstostr (command, args, 0, ' ')) < 1)
 		return NULL;
 
 	chan = (invoked == MSG_INVOKE) ? "#*" : target;
 	user_level = check_access(userhost, chan, 0, source);
 	result = chanserv_show_help(command, user_level);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_idle(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	long unixtime = 0;
 
 	if (!args || !args[0])
 		return result;
 	if (strcasecmp (args[0], source) == 0)
 		return chanserv_asprintf(NULL, "Don't be lame.");
 	unixtime = return_useridle (target, args[0], 0);
 	if (unixtime == 0)
 		return chanserv_asprintf(NULL, "I do not see %s in %s.", args[0], target);
 	unixtime = time (NULL) - unixtime;
 	if (unixtime > 86400)
 		result = chanserv_asprintf(result, " %s has been idle %d day%s, %02d:%02d.",
 		   args[0], unixtime / 86400,
 		   (unixtime / 86400 == 1) ? "" : "s",
 		   (unixtime / 3600) % 24, (unixtime / 60) % 60);
 	else if (unixtime > 3600)
 		result = chanserv_asprintf(result, "%s has been idle %d hour%s, %d min%s.",
 		   args[0], unixtime / 3600,
 		   unixtime / 3600 == 1 ? "" : "s",
 		   (unixtime / 60) % 60, (unixtime / 60) % 60 == 1 ? "" : "s");
 	else
 		result = chanserv_asprintf(result, " %s has been idle %d minute%s, %d sec%s.",
 		   args[0], unixtime / 60,
 		   unixtime / 60 == 1 ? "" : "s", unixtime % 60, unixtime % 60 == 1 ? "" : "s");
 
 	return result;
 }
 
 struct chanserv_output *chanserv_ignore(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
     	    return chanserv_asprintf(NULL, "Ignore who?");
 	if ( add_ignore_user_ram(args[0]) > 0 )
     	    result = chanserv_asprintf(result, "Ignoring %s.", args[0]);
 	else
     	    result = chanserv_asprintf(result, "Unable to ignore %s.", args[0]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_info(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	info (source, (invoked == MSG_INVOKE) ? source : target);
 	return result;
 }
 
 struct chanserv_output *chanserv_info_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return show_info2((invoked == MSG_INVOKE) ? source : target, source, invoked);
 }
 
 struct chanserv_output *chanserv_info_size(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	struct stat statbuf;
 
 	if (stat (URL2, &statbuf) == 0)
 	    result = chanserv_asprintf(NULL, "My database file is presently %ld byte%s in size.", statbuf.st_size, ((statbuf.st_size == 1) ? "" : "s"));
 
 	return result;
 }
 
 struct chanserv_output *chanserv_isop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result;
 	result = chanserv_asprintf(NULL, "%s is %san op in channel %s.", args[0], is_op(args[0], target) ? "" : "not ", target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_join(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		S ("JOIN %s\n", target);
 	else
 	{
 		S ("JOIN %s\n", args[0]);
 		result = chanserv_asprintf(NULL, "Joining %s.", args[0]);
 	}
 
 	return result;
 }
 
 struct chanserv_output *chanserv_joins_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "I have seen %d joins thus far.", JOINs);
 }
 
 struct chanserv_output *chanserv_jump(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char server [STRING_LONG] = {0}, port_argument [STRING_LONG] = {0};
 	long port = 0;
 
 	if (!args || !args[0])
 		return result;
 
 	strncpy (server, args[0], sizeof (server));
 	args++;
 
 	if ((db_argstostr (port_argument, args, 0, ' ')) < 1)
 		port = 6667;
 	else
 		port = atoi(port_argument);
 
 	S ("QUIT :Jumping to %s:%d\n", server, port);
 	db_sleep (1);
 
 	strncpy (BS, server, sizeof (BS));
 	BP = port;
 
 	prepare_bot ();
 	register_bot ();
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_kick(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char 	chan[STRING_LONG] = {0}, nick[STRING_LONG] = {0},
 		reason [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 	    return chanserv_asprintf(NULL, "Specify a nick/channel!");
 
 	if (invoked == MSG_INVOKE)
 	{
 	    /* Copy channel variable and chuck it. */
 	    strncpy (chan, args[0], sizeof (chan));
 	    args++;
 
 	    /* Make sure first parameter is a channel name. */
 	    if ((*chan != '#') && (*chan != '&'))
 	    	return chanserv_asprintf (NULL, "You must specify a channel name first.");
 
      	    if (check_access (userhost, chan, 0, source) >= 3)
 	    {
 	        if (!args[0])
 	       	    return chanserv_asprintf(NULL, "You must specity a nickname to kick!");
 
 		strncpy (nick, args[0], sizeof (nick));
 		args++;
 
 		/* Remaining args are fed into reason. */
 		if ((db_argstostr (reason, args, 0, ' ')) < 1)
 		    S ("KICK %s %s %s\n", chan, nick, DEFAULT_KICK);
                 else
 		    S ("KICK %s %s :%s\n", chan, nick, reason);
 
 		return result;
 	    }
 	}
 	else
 	{
 		if (*args[0] != '#' && *args[0] != '&')
 		{
 			strncpy (nick, args[0], sizeof (nick));
 			args++;
 
 			if (strcasecmp (nick, Mynick) == 0)
 					S ("KICK %s %s :hah! As *IF*\n", target, source);
 			if ((db_argstostr (reason, args, 0, ' ')) < 1)
 				S ("KICK %s %s :\2%s\2'ed: %s\n", target, nick, cmd, DEFAULT_KICK);
 			else 
 				S ("KICK %s %s :\2%s\2'ed: %s\n", target, nick, cmd, reason);
 		}
 		else
 		{
 			if (!args[0] || !args[1])
 				return chanserv_asprintf(result, "You must specify a nickname to kick!");
 
 			strncpy (chan, args[0], sizeof chan);
 				args++;
 			strncpy (nick, args[0], sizeof nick);
 				args++;
 
 			if (strcasecmp (nick, Mynick) == 0)
 				S ("KICK %s %s :hah! As *IF*\n", target, nick);
 
 			if ((db_argstostr (reason, args, 0, ' ')) < 1)
 				S ("KICK %s %s :\2%s\2ed: %s\n", chan, nick, cmd, DEFAULT_KICK);
 			else
 				S ("KICK %s %s :\2%s\2ed: %s\n", chan, nick, cmd, reason);
 		}
 	}
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_language(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
-	return chanserv_asprintf(NULL, "I speak English.");
+	return chanserv_asprintf(NULL, I_SPEAK);
 }
 
 struct chanserv_output *chanserv_leave(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	chan	[STRING_LONG] = {0},
 		reason  [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		S ("PART %s\n", target);
 	else
 	{
 		strncpy (chan, args[0], sizeof chan);
 		args++;
 
 		/* Don't bother telling the channel we left about it. */
 		if ((strcasecmp (target, chan)) != 0)
 			result = chanserv_asprintf(result, "Leaving %s.", chan);
 
 		if ((db_argstostr (reason, args, 0, ' ')) < 1)
 			S ("PART %s :Requested!\n", chan);
 		else
 			S ("PART %s :%s\n", chan, reason);
 	}
 
 	return (result);
 }
 
 struct chanserv_output *chanserv_length(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	str	[STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return result;
 
 	if ((db_argstostr (str, args, 0, ' ')) == 0)
 		strcpy(str, args[0]);
 
 	return chanserv_asprintf(NULL, "It was %d characters long.", strlen (str));
 }
 
 struct chanserv_output *chanserv_level(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char *uh;
 
 	if (!args || !args[0])
 		return result;
 	uh = uh_from_nick(args[0], target);
 	if (uh)
 	    result = chanserv_asprintf(result, "%s is level %ld in channel %s.", args[0], check_access(uh, target, 0, args[0]), target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_location_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "There %s %d server%s in my server list. I am currently on server #%d.", (snr == 1) ? "is" : "are", snr, (snr == 1) ? "" : "s", spr);
 }
 
 struct chanserv_output *chanserv_login(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result;
 	do_login (source, args[0]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_mask(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if(!args || !args[0])
 		return result;
 
 	return chanserv_asprintf(NULL, " %s", 
 		(invoked == MSG_INVOKE) ? mask_from_nick(args[0], "#*") : mask_from_nick(args[0], target)); 
 }
 
 //#ifndef	WIN32
 struct chanserv_output *chanserv_memory(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	char command[1024] = { 0 };
 
 	snprintf(command, sizeof (command), "ps u -p %d\n", getpid());
 	
 	const char *ptr = run_program (command);
 	if (ptr == NULL)
 		return chanserv_asprintf(NULL, "Unable to gather data for mem output.\n");
 	else
 		return chanserv_asprintf(NULL, "ps: %s", ptr);
 }
 //#endif
 
 #ifdef ENABLE_METAR
 struct chanserv_output *chanserv_metar(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
         if(!args || !args[0])
             return chanserv_asprintf(NULL, "Metar what?");
         result = web_post_query (cmd, source, userhost, target, args[0], strlen(args[0]));
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_nick(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	// If no nick was specified...
 	if(!args || !args[0])
 		return chanserv_asprintf(NULL, "Specify a nick!");
 	
 	// If the nick specified contains illegal characters...
 	if(strspn(args[0], LEGAL_NICK_TEXT) != strlen(args[0]))
 		return chanserv_asprintf(NULL, "The nickname %s contains illegal characters.", args[0]);
 	if (isdigit(args[0][0]))
 		return chanserv_asprintf(NULL, "The nickname %s should not start with a digit.", args[0]);
 
 	S("NICK %s\n", args[0]);
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_op(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0};
 	int  ischan = 0;
 
 	if (!args[0])
 	    return chanserv_asprintf (NULL, "You must specify a nickname/channel!.");
 	
 	/* Check for channel name specified, set up args accordingly. */
 	if ((*args[0] == '#') || (*args[0] == '&'))
 	{
 		ischan = 1; /* channel specified */
 		strncpy (chan, args[0], sizeof chan);
 		args++;
 	}
 
 	if ((db_argstostr (nicks, args, 0, ' ')) < 1)
 		return chanserv_asprintf (NULL, "You must specify a nickname to op.");
 
 	if ((invoked == MSG_INVOKE) || (ischan == 1))
 	{
 	    /* If MSG_INVOKE, make sure chan == 1. This seems weird, but 
  	     * we could have MSG_INVOKE without channel specified. */
 	    if (ischan != 1)
 		return chanserv_asprintf (NULL, "You must specify a channel to deop people on.");
 
 	    if (check_access (userhost, chan, 0, source) >= 3)
 	    {
 		S ("MODE %s +oooooo %s\n", chan, nicks);
 		return result;
 	    }
 	}
 	else
 		S ("MODE %s +oooooo %s\n", target, nicks);
 		
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_os_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char command[1024] = { 0 };
 	char *reply = NULL;	
 
 #ifdef	WIN32
 	snprintf (command, sizeof (command), "cmd /c ver\n");
 #else				
 	snprintf (command, sizeof (command), "uname\n");
 #endif
 
 	return chanserv_asprintf(NULL, "I am running %s.", run_program(command));
 }
 
 struct chanserv_output *chanserv_password(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (args[0] == NULL || args[1] == NULL)
 		return result;
 	if (strlen(args[1]) > 25)
 		args[1][25] = '\0';
 	set_pass(source, userhost, args[0], args[1]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_performs(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	/* Set the default umodes */
 	S ("MODE %s %s\n", Mynick, DEFAULT_UMODE);
 	run_perform ();
 
 	return chanserv_asprintf(NULL, "Performs have been executed.");
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_perm_ban(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char   reason [STRING_LONG] = {0}, host [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return result = chanserv_asprintf(result, "Type !help permbans");
 
 	strncpy (host, args[0], sizeof host);
 	args++;
 
 	if ((db_argstostr (reason, args, 0, ' ')) < 1)
 		strncpy (reason, "Permbanned!", sizeof reason);
 				
 	add_permban(host, 0, reason);
 	result = chanserv_asprintf(result, "Added in permban #%d, %s; reason: %s.", 
 					PERMBAN_counter, host, reason);
 	save_permbans();
 	S("MODE %s +b %s\n", target, host);
 
 	/* FIXME: Scan for user in room and kick them with reason. */
 	return result;
 }
 
 struct chanserv_output *chanserv_perm_bans_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "There %s %d permban%s loaded into ram.", (PERMBAN_counter == 1) ? "is" : "are", PERMBAN_counter, (PERMBAN_counter == 1) ? "" : "s");
 }
 #endif
 
 #ifdef ENABLE_CTCP
 struct chanserv_output *chanserv_ping(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (cf(userhost, source, target))
 		return result;
 	if (cf(userhost, source, target))
 		return result;
 	if (args[0] != NULL)
 	{
 		if (strlen (args[0]) > 21)
 			args[0][21] = '\0';
 		S ("NOTICE %s :\1PING %s\n", source, args[0]);
  	}
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_ping2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "PONG!");
 }
 
 struct chanserv_output *chanserv_queue_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "There is currently %d item%s in queue.", get_sendq_count(2), (get_sendq_count(2) == 1) ? "" : "s");
 }
 
 #ifdef ENABLE_QUIZ
 struct chanserv_output *chanserv_quiz(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (quiz_halt == 0)
 		result = run_quiz_question (target);
 
 	return result;
 }
 #endif
 
 #ifdef ENABLE_RANDQ
 struct chanserv_output *chanserv_quote(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return do_randq(args[0], RANDQ_RAND, target, source);
 }
 
 struct chanserv_output *chanserv_random_quote(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	if (!args || !args[0])
 		return chanserv_asprintf (NULL, "You must specify a search string.");
 
 	// RANDQ_NORMAL
 	return do_randq(args[0], RANDQ_NORMAL, target, source);
 }
 
 struct chanserv_output *chanserv_random_quote_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	if (!args || !args[0])
 		return chanserv_asprintf (NULL, "You must specify a search string.");
 
 	// RANDQ_CASE
 	return do_randq(args[0], RANDQ_CASE, target, source);
 }
 #endif
 
 #ifdef ENABLE_RANDOM
 struct chanserv_output *chanserv_random_stuff(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	text_to_add	[STRING_LONG] = {0};
 
 	/* Fill argument buffer, if it's empty we return a message to 
  	 * the user asking for input. */
 	if (!args || !args[0])
 	    return chanserv_asprintf(NULL, "What do you want to add?");
 	
 	if ((db_argstostr (text_to_add, args, 0, ' ')) < 1)
 	    return result;
 
 	if (invoked == MSG_INVOKE)
 	{
 	    if (check_access (userhost, "#*", 0, source) >= RAND_LEVEL)
 	    {
 		if ((db_argstostr (text_to_add, args, 0, ' ')) < 1)
 			return chanserv_asprintf(NULL, "What do you want to add?");
 		add_randomstuff(source, source, text_to_add);
 	    }
 	}
 	else
 	    add_randomstuff(source, target, text_to_add);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_random_stuff_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "%d seconds left till randstuff.", Rand_Stuff);
 }
 #endif
 
 struct chanserv_output *chanserv_raw(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char 	rawdata [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return result;
 
 	if ((db_argstostr (rawdata, args, 0, ' ')) < 1)
 		return result;
 
 	Snow("%s\n", rawdata);
 
 	return result;
 }
 
 //#ifndef WIN32
 struct chanserv_output *chanserv_rdb(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char command[1024] = { 0 };
 	char str [STRING_LONG] = {0};
 
 	/* Check for arguments */
 
 	if (!args || !args[0])
 	{
 		snprintf(command, sizeof (command), "ls %s/*.rdb | wc\n", RDB_DIR);
 		result = chanserv_asprintf(result, "RDB: %s.", run_program(command));
 	}
 	else
 	{
 		if ((db_argstostr (str, args, 0, ' ')) < 1)
 			return result;
 		if (strspn(str, SAFE_LIST) != strlen(str))
 			return chanserv_asprintf(NULL, "Rdb files are made up of letters and or numbers, no other text is accepted.");
 		snprintf(command, sizeof (command), "cat %s/%s.rdb | wc -l\n", RDB_DIR, str);
 		result = chanserv_asprintf(result, "%s", run_program(command));
 	}
 
 	return result;
 }
 //#endif
 
 struct chanserv_output *chanserv_repeat(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	long delay = 0, count = 0;
 	char	rawdata [STRING_LONG] = {0};
 
 	if (!args || !args[0] || !args[1] || !args[2])
 		return result;
 	count = atoi (args[0]);
 	delay = atoi (args[1]);
 	if ((db_argstostr (rawdata, args, 2, ' ')) < 1)
 		return result;
 
 	while (count > 0)
 	{
 		S ("%s\n", rawdata);
 		db_sleep (delay);
 		count--;
 	}
 
 	return result;
 }
 
 struct chanserv_output *chanserv_replace(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char   topic [STRING_LONG] = {0}, text [STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Replace what?");
 
 	if (strlen(args[0]) > MAX_TOPIC_SIZE)
 		args[0][MAX_TOPIC_SIZE] = '\0';
 
 	/* Copy topic, and traverse args for data to be replaced. */
 	strncpy (topic, args[0], sizeof topic);
 	args++;
 
 	/* Make sure there's information to be replaced. */
 	if ((db_argstostr (text, args, 0, ' ')) < 1)
 		return chanserv_asprintf(NULL, "What info should replace %s?",
 						topic);
 
 	/* Don't let str go over MAX_DATA_SIZE characters. */
 	if (strlen(text) > MAX_DATA_SIZE)
 		text[MAX_DATA_SIZE] = '\0';
 
 	strlwr(topic);
 
 	if (check_existing_url(source, topic, target) != 1)
 		return chanserv_asprintf(NULL, "%s \37%s\37", NO_ENTRY, topic);
 
 	/* Replace the data. */
 	delete_url (source, topic, target);
 	if (LOG_ADD_DELETES)
 	    db_log (ADD_DELETES, "[%s] %s!%s REPLACE %s %s\n", date (), source, userhost, topic, text);
 
 	ADDITIONS++;
 
 	db_log (URL2, "%s %s\n", topic, text);
 
 	return chanserv_asprintf(NULL, "%s has been updated.", topic);
 }
 
 struct chanserv_output *chanserv_reserved_1(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
         if (!args || !args[0])
             return result;
         call_reserved_1(source, target, args[0]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_reserved_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
         if (!args || !args[0])
             return result;
         call_reserved_2(source, target, args[0]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_restart(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char command[1024] = { 0 };
 	int ret;
 
 	S("QUIT :Restarting %s ...\n", dbVersion);
 	db_sleep(2);
 	snprintf(command, sizeof (command), "%s", DARKBOT_BIN);
 	ret = system(command);
 	db_sleep(1);
 	exit(0);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_search(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 	{
 		if (strcasecmp(cmd, "FIND") == 0)
 			result = chanserv_asprintf(NULL, "%s?", TRY_FIND);
 		else
 			result = chanserv_asprintf(NULL, "What should I be %sing for?", cmd);
 		return result;
 	}
 	find_url(source, args[0], target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_seen(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 	{
 		count_seen(source, target);
 		return result;
 	}
 	if (return_useridle (target, args[0], 1) == 1)
 		return chanserv_asprintf(NULL, "%s is right here in the channel!", args[0]);
 	result = show_seen(args[0], source, target);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_set(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	struct setup_parameter *param = NULL;
 
 	if (!args || !args[0])
 		return result;
 
 	param = set_parameter(args[0]);
 	if (param)
 	{
 	    switch (param->type)
 	    {
 		case ST_BOOLEAN : 
 		{
 		    bool *variable = param->value;
 
 		    result = chanserv_asprintf(result, "Setting %s = %s", param->summary, (*variable) ? "true" : "false");
 		    break;
 		}
 
 		case ST_INTEGER : 
 		{
 		    long *variable = param->value;
 
 		    result = chanserv_asprintf(result, "Setting %s = %ld", param->summary, *variable);
 		    break;
 		}
 
 		case ST_STRING  : 
 		{
 		    char *variable = param->value;
 
 		    result = chanserv_asprintf(result, "Setting %s = %s", param->summary, variable);
 		    break;
 		}
 	    }
 	    save_setup();
 	}
 	else
 	    result = chanserv_asprintf(result, "Unknown parameter.");
 
 	return result;
 }
 
 struct chanserv_output *chanserv_setinfo(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	greeting [STRING_LONG] = {0};
 
 	if (!args)
 		return chanserv_asprintf (NULL, "My %s variables are: ^ nick, %% number of joins, & Channel, $ user@host. Example: !setinfo ^ has joined & %% times (also, if you make the first char of your %s a \"+\", the %s will be shown as an ACTION).", cmd, cmd, cmd);
 
 	if ((db_argstostr (greeting, args, 0, ' ')) < 1)
 		return NULL;
 	
 	update_setinfo (userhost, greeting, source);
 	return (result);
 }
 
 struct chanserv_output *chanserv_sleep(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char period [STRING_LONG] = {0};
 
 	Sleep_Toggle = 1;
 
 	/* Copy arguments to buffer, if there is one convert to long
 	 * and use it as the sleep time in seconds. */
 
 	if ((db_argstostr (period, args, 0, '\0')) < 1)
 		Sleep_Time = SLEEP_TIME;
 	else if ((Sleep_Time = strtol (period, (char **) NULL, 10)) < 1)
 		Sleep_Time = SLEEP_TIME;
 
 	strncpy (sleep_chan, target, sizeof (sleep_chan));
 
 	/* If the user has specified a custom length of time to sleep for, send
 	 * a notice reminding the user how long the bot will be asleep, in a
 	 * more readable format.
 	 */
 	if (Sleep_Time != SLEEP_TIME)
 	{
 		if (Sleep_Time > 86400)
 			result = chanserv_asprintf(result, "Sleeping for %ld day%s, %02ld:%02ld.",
 				Sleep_Time / 86400, 
 				(Sleep_Time / 86400 == 1) ? "" : "s",
 				(Sleep_Time / 3600) % 24, 
 				(Sleep_Time / 60) % 60);
 		else if (Sleep_Time > 3600)
 			result = chanserv_asprintf(result, "Sleeping for %ld hour%s, %ld min%s.",
 				Sleep_Time / 3600, 
 				Sleep_Time / 3600 == 1 ? "" : "s",
 				(Sleep_Time / 60) % 60, 
 				(Sleep_Time/ 60) % 60 == 1 ? "" : "s");
 		else
 			result = chanserv_asprintf(result, "Sleeping for %ld minute%s, %ld sec%s.",
 				Sleep_Time / 60,
 				Sleep_Time / 60 == 1 ? "" : "s",
 				Sleep_Time % 60,
 				Sleep_Time % 60 == 1 ? "" : "s");
 	}
 	else
 	    S ("PRIVMSG %s :%s\n", target, GOSLEEP_ACTION);
 
 	return result;
 }
 
 #ifdef ENABLE_STATS
 struct chanserv_output *chanserv_stats(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return result = chanserv_asprintf (NULL, "Syntax: %s <nick>", cmd);
 	result = get_stats(target, args[0]);
 	return result;
 }
 #endif
 
 #ifdef ENABLE_TAF
 struct chanserv_output *chanserv_taf(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
         if(!args || !args[0])
             return chanserv_asprintf(NULL, "Taf what?");
         result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
 
 	return result;
 }
 #endif
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_teaseop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Specify a nick!");
 	if (strcasecmp (args[0], Mynick) == 0)
 		result = chanserv_asprintf(result, "How about I not do that?");
 	else
 		S ("MODE %s +o-o+o-o+o-o %s %s %s %s %s %s\n", target, args[0], args[0], args[0], args[0], args[0], args[0]);
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_tell(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	topic	[STRING_LONG] = {0};
 
 	if (!args || !args[0])
 	    return chanserv_asprintf(NULL, "Tell who?");
 	if (!args[1])
 	    return chanserv_asprintf(NULL, "What do you want me to tell %s?", args[0]);
 	if (strcasecmp (args[1], Mynick) == 0)
 	    return result;			/* don't bother telling myself about stuff */
 
 	if (strcasecmp (args[1], "ABOUT") == 0)
 	{
 		if ((db_argstostr (topic, args, 2, '+')) < 1)
 		    return chanserv_asprintf(NULL, "Tell %s about what?", args[0]);
 	
 		strlwr(topic);
 		if (invoked == MSG_INVOKE)
 		    result = show_url (source, get_multiword_topic (topic), args[0], 1, 0, userhost, 1);
 		else
 		    result = show_url (args[0], get_multiword_topic (topic), target, 1, 0, userhost, 1);
 	}
 	else
 	{
 		if ((db_argstostr (topic, args, 1, '+')) < 1)
 		    return chanserv_asprintf (NULL, "Tell %s about what?", args[0]);
 
 		strlwr(topic);
 
 		if (invoked == MSG_INVOKE)
 		    result = show_url (source, get_multiword_topic (topic), args[0], 1, 0, userhost, 1);
 		else
 		    result = show_url (args[0], get_multiword_topic (topic), target, 1, 0, userhost, 1);
 	}
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_topic(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	str	[STRING_LONG] = {0};
 
 	if ((db_argstostr (str, args, 0, ' ')) < 1)
 		return chanserv_asprintf (NULL, "What do you want the topic changed to?");
 	else
 		S ("TOPIC %s :%s\n", target, str);
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_unignore(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
     	    return chanserv_asprintf(NULL, "Unignore who?");
 	if ( delete_ignore_user_ram (args[0]) > 0 )
     	    result = chanserv_asprintf(result, "Unignoring %s.", args[0]);
 	else
     	    result = chanserv_asprintf(result, "Unable to unignore %s. :(", args[0]);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_unixtime(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct 	chanserv_output *result = NULL;
 	time_t	 delta_t = 0, input_t = 0, cur_t = 0;
 	char	*things = NULL;
 	int	errno;
 
 	/* Make sure current time is available while acquiring it. */
 	if ((cur_t = time (NULL)) < 0)
 	{
 		result = chanserv_asprintf (result, "Unable to produce results because current system time is unavailable.");
 		return (result);
 	}
 
 	/* Print current time when no argument is given */
 	if (!args || !args[0])
 	{
 		result = chanserv_asprintf (result, "%ld", cur_t);
 		return result;
 	}
 
 	/* Convert input value to time_t. We check if the return value is
 	 * 0 here, but our main concern is if things is NULL, because that
 	 * would mean the function converted a string value "0", instead
 	 * of returning a failing code. Set errno to 0 first as for a
 	 * precautionary measure.
 	 */
 
 	errno = 0;
 
 	if ((input_t = (time_t) strtol (args[0], &things, 10)) == 0)
 	{
 		if (things == NULL)
 		{
 			result = chanserv_asprintf (result, "%s (things = %s)", strerror (errno), things);
 			return (result);
 		}
 		
 		/* things was not NULL, this is "0" converted to long.
 		 * So we continue as if nothing happened. */
 	}
 	
 	/* Check for out of range values, tell the user which range
          * was exceeded, perhaps for debugging purposes. */
 	if (errno == ERANGE)
 	{
 		result = chanserv_asprintf (result, "Your implementation does not support numeric ranges beyond %ld for this function.", 
 				input_t);		
 		return (result);
 	}
 
 	delta_t = input_t - cur_t;
 
 	if (delta_t > 86400)
 		result = chanserv_asprintf(result, "%d day%s, %02d:%02d.",
 		   delta_t / 86400,
 		   plural (delta_t / 86400),
 		   (delta_t / 3600) % 24,
 		   (delta_t / 60) % 60);
 	else if (delta_t > 3600)
 		result = chanserv_asprintf(result, "%d hour%s, %d min%s.",
 		   delta_t / 3600,
 		   plural(delta_t / 3600),
 		   (delta_t / 60) % 60,
 		   plural(delta_t / 60));
 	else
 		result = chanserv_asprintf(result, "%d minute%s, %d sec%s.",
 		   delta_t / 60,
 		   plural(delta_t / 60),
 		   delta_t % 60,
 		   plural(delta_t % 60));
 
 	return result;
 }
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_up(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	S ("MODE %s +o %s\n", target, source);
 	return result;
 }
 #endif
 
 //#ifndef	WIN32
 struct chanserv_output *chanserv_uptime(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	char command[1024] = { 0 };
 
 	snprintf(command, sizeof (command), "uptime\n");
 	return chanserv_asprintf(NULL, "Uptime: %s.", run_program(command));
 }
 //#endif
 
 struct chanserv_output *chanserv_user_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	int	i = 0;
 	
 	if (!args)
 	{
 		result = show_helper_list(result, source, 0);
 	}
 	else
 	{
 		int level = 0;
 
 		for (i = 0; args[i]; i++)
 			result = show_helper_list(result, source, atoi (args[i]));
 	}
 
 	return result;
 }
 
 #ifdef ENABLE_STATUS
 struct chanserv_output *chanserv_users_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	S ("LUSERS\n");
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_variables(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	return chanserv_asprintf(NULL, "Data variables are: N~ (Nick), C~ (Chan), T~ (Time/date) B~ (Botnick), Q~ (Question asked), R~ (random nick), !~ (command char), S~ (current Server), P~ (current port) V~ (botVer), W~ (db WWW site), H~ (u@h), t~ (unixtime), BAN (sets a ban), TEMPBAN (bans for 60 sec).");
 }
 
 #ifdef ENABLE_CTCP
 struct chanserv_output *chanserv_version(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (cf (userhost, source, target))
 		return result;
 	if (cf (userhost, source, target))
 		return result;
 
 	return chanserv_asprintf(NULL, "\1VERSION Hi, I'm a Darkbot. Download me from http://darkbot.sourceforge.net\1.");
 }
 #endif
 
 #ifdef ENABLE_CHANNEL
 struct chanserv_output *chanserv_voice(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char	nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0},
 		str   [STRING_LONG] = {0};
 	int	ischan = 0;
 
 	if (!args[0])
 	    return result;
 
 	db_argstostr (str, args, 0, ' ');
 
 	/* Check for channel name specified, set up args accordingly. */
 	if ((*args[0] == '#') || (*args[0] == '&'))
 	{
 		ischan = 1; /* channel specified */
 		strncpy (chan, args[0], sizeof chan);
 		args++;
 	}
 	
 	if ((db_argstostr (nicks, args, 0, ' ')) < 1)
 		return chanserv_asprintf (NULL, "You must specify a nickname to voice.");
 
 	if ((invoked == MSG_INVOKE) || (ischan == 1))
 	{
 		/* If MSG_INVOke, make sure chan ==1. This seems weird, 
 		 * but we could have MSG_INVOKE without a channel given,
 		 * and this is an error. */
 		if (ischan != 1)
 			return chanserv_asprintf (NULL, "You must specify a channel to give voice on.");
 
 		if (check_access (userhost, chan, 0, source) >= 3)
 		{
 			S ("MODE %s +vvvvvv %s\n", chan, nicks);
 			return result;
 		}
 	}
 	else
 		S ("MODE %s +vvvvvv %s\n", target, nicks);
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_wakeup(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	if (Sleep_Toggle == 0)
 		return result;
 	Sleep_Toggle = 0;
 	AIL4 = 0;
 	S ("PRIVMSG %s :%s\n", target, WAKEUP_ACTION);
 	if (strcasecmp (sleep_chan, target) != 0)
 		S ("PRIVMSG %s :%s\n", sleep_chan, WAKEUP_ACTION);
 
 	return result;
 }
 
 #ifdef ENABLE_WEATHER
 struct chanserv_output *chanserv_weather(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Show weather from where?");
 	result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
 
 	return result;
 }
 #endif
 
 #ifdef ENABLE_WEBSEARCH
 struct chanserv_output *chanserv_websearch(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 
 	if(!args || !args[0])
     	    return chanserv_asprintf(NULL, "Web search for what?");
 	result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
 
 	return result;
 }
 #endif
 
 struct chanserv_output *chanserv_where(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char topic [STRING_LONG] = {0};
 	char *ptr3 = NULL;
 
 	if (!args || !args[0])
 	    return chanserv_asprintf(NULL, "You were asking?");
 	if (args[1] == NULL)
 		return result;
 	strlwr (args[1]);
 	ptr3 = strchr (args[1], '?');
 	if (ptr3 != NULL)
 		memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
 	ptr3 = strchr (args[1], '!');
 	if (ptr3 != NULL)
 		memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
 	if (strcasecmp (args[1], "A") == 0 || strcasecmp (args[1], "AN") == 0)
 	{
 		if ((db_argstostr (topic, args, 2, ' ')) < 1)
 		    return chanserv_asprintf(NULL, "%s %s %s? Mind rephrasing that?  (Type %cHELP for syntax hints).", cmd, args[0], args[1], *CMDCHAR);
 		result = show_url (source, get_multiword_topic (topic), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
 	}
 	else
 		result = show_url (source, get_multiword_topic (args[1]), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
 
 	return result;
 }
 
 struct chanserv_output *chanserv_whisper(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
 {
 	struct chanserv_output *result = NULL;
 	char topic	[STRING_LONG] = {0};
 
 	if (!args || !args[0])
 		return chanserv_asprintf(NULL, "Whisper to who?");
 	if (args[1] == NULL)
 		return chanserv_asprintf(NULL, "What do you want me to whisper to %s?", args[0]);
 	if (strcasecmp (args[1], Mynick) == 0)
 		return result;		/* don't bother telling myself about stuff */
 	if (strcasecmp (args[1], "ABOUT") == 0)
 	{
 		if ((db_argstostr (topic, args, 2, ' ')) < 1)
 			return chanserv_asprintf(NULL, "Whisper to %s about what?", args[0]);
 		strlwr(topic);
 		result = show_url(source, get_multiword_topic(topic), args[0], 1, 0, userhost, 1);
 	}
 	else
 	{
 		strlwr (args[1]);
 		result = show_url(source, get_multiword_topic(args[1]), args[0], 1, 0, userhost, 1);
 	}
 
 	return result;
 }
 
 /* The help system uses the first alias for each command for the list of commands. 
  * So make the first alias the most meaningful, and keep the list sorted by that first alias.
  */
 struct chanserv_command chanserv_commands[] =
 {
     {NORMAL_COMMAND,  ADD_LEVEL, 1, 0, chanserv_add,	{"ADD", "REMEMBER", "SAVE", "STORE", NULL}, "<topic> <text>", "Add a topic and it's text."},
     {PASSWORD_COMMAND,  3, 4, 0, chanserv_add_user,	{"ADDUSER", NULL, NULL, NULL, NULL}, "<#channel|#*> <user@host> <level> [password]", "Add a user to the access list."},
     {SAFE_COMMAND,    2, 2, 0, chanserv_alarm,		{"ALARM", "ALARMCLOCK", NULL, NULL, NULL}, "<time type: d/h/m><time> <text to say>", "Set some text to be said by the bot at a later time."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_autotopic,		{"AUTOTOPIC", NULL, NULL, NULL, NULL}, "<channel topic>", "Refreshes the channel topic every thirty minutes (set to \"0\" to turn off)."},
 #endif
 //#ifndef	WIN32
     {DANGER_COMMAND,  3, 0, 0, chanserv_backup,		{"BACKUP", NULL, NULL, NULL, NULL}, NULL, "Create a backup of the database."},
 //#endif
 #ifdef ENABLE_CHANNEL
     {INFO_COMMAND,    1, 0, 0, chanserv_ban_list,		{"BANLIST", NULL, NULL, NULL, NULL}, NULL, "Displays permanent bans."},
 #endif
 #ifdef	ENABLE_MATH
     {INFO_COMMAND,    0, 1, 0, chanserv_calc,		{"CALC", "MATH", NULL, NULL, NULL}, "<expression>", "Very basic calculator."},
 #endif
     {INFO_COMMAND,    0, 1, 0, chanserv_chan_info,		{"CHANINFO", NULL, NULL, NULL, NULL}, "<#channel>", "Displays number of users in channel and in ram."},
     {INFO_COMMAND,    0, 1, 0, chanserv_chan_users,	{"CHANUSERS", NULL, NULL, NULL, NULL}, "<#channel>", "Displays names of users in channel."},
     {INFO_COMMAND,    0, 1, 0, chanserv_char,		{"CHAR", NULL, NULL, NULL, NULL}, "<character>", "Show the ascii code of the character."},
     {INFO_COMMAND,    0, 0, 1, chanserv_char_show,		{"CMDCHAR?", NULL, NULL, NULL, NULL}, NULL, "Show command character."},
     {INFO_COMMAND,    0, 0, 1, chanserv_cpu_show,		{"CPU?", NULL, NULL, NULL, NULL}, NULL, "Show the cpu usage of the bot."},
     {DANGER_COMMAND,  2, 0, 0, chanserv_cycle,		{"CYCLE", "CYC", NULL, NULL, NULL}, "[#channel]", "Leave and rejoin the channel."},
     {INFO_COMMAND,    0, 1, 0, chanserv_data_search,	{"DATASEARCH", "DSEARCH", "DFIND", NULL, NULL}, "<topic>", "Search in the replies."},
     {INFO_COMMAND,    0, 0, 0, chanserv_date,		{"DATE", "TIME", NULL, NULL, NULL}, NULL, "Show the current date and time."},
     {DANGER_COMMAND,  0, 1, 0, chanserv_reserved_2,	{RESERVED2, NULL, NULL, NULL, NULL}, "<>", ""},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_delban,		{"DELBAN", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the permanent ban list."},
 #endif
     {NORMAL_COMMAND,  DEL_LEVEL, 1, 0, chanserv_delete,	{"DELETE", "DEL", "REMOVE", "FORGET", NULL}, "<topic>", "Delete a topic."},
     {DANGER_COMMAND,  3, 1, 0, chanserv_deluser,		{"DELUSER", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the access list."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_deop,		{"DEOP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Remove channel operator status from users."},
     {NORMAL_COMMAND,  3, 1, 0, chanserv_devoice,		{"DEVOICE", "DV", "DEV", "DVOICE", NULL}, "[#channel] <nicks>", "Remove channel voice status from users."},
 #endif
     {DANGER_COMMAND,  3, 0, 0, chanserv_die,		{"DIE", "QUIT", NULL, NULL, NULL}, NULL, "Stop bot from running."},
     {INFO_COMMAND,    0, 1, 0, chanserv_display,		{"DISPLAY", NULL, NULL, NULL, NULL}, "<topic>", "Display the text for a topic."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  2, 0, 0, chanserv_down,		{"DOWN", NULL, NULL, NULL, NULL}, NULL, "Remove channel operator status from yourself."},
 #endif
     {INFO_COMMAND,    0, 0, 0, chanserv_darkbot,		{"\2\2DARKBOT", NULL, NULL, NULL, NULL}, NULL, ""},
     {DANGER_COMMAND,  0, 1, 0, chanserv_reserved_1,	{RESERVED1, NULL, NULL, NULL, NULL}, "<>", ""},
     {INFO_COMMAND,    0, 0, 0, chanserv_help,		{"HELP", NULL, NULL, NULL, NULL}, "[command]", "Show some help text to the user."},
     {INFO_COMMAND,    0, 1, 0, chanserv_idle,		{"IDLE", NULL, NULL, NULL, NULL}, "<nick>", "Shows how long the user has been idle."},
     {DANGER_COMMAND,  1, 1, 0, chanserv_ignore,		{"IGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to ignore a user."},
     {INFO_COMMAND,    0, 0, 1, chanserv_info,		{"INFO", NULL, NULL, NULL, NULL}, NULL, "Shows some information about bot and it's activity."},
     {INFO_COMMAND,    0, 0, 1, chanserv_info_2,		{"INFO2", NULL, NULL, NULL, NULL}, NULL, "Shows when the bot was compiled, and lines processed since startup."},
     {INFO_COMMAND,    2, 0, 1, chanserv_info_size,	{"INFOSIZE", "DBSIZE", NULL, NULL, NULL}, NULL, "Show size of the database."},
     {INFO_COMMAND,    0, 1, 0, chanserv_isop,		{"ISOP", NULL, NULL, NULL, NULL}, "<nick>", "Is user a channel op?"},
     {DANGER_COMMAND,  2, 1, 0, chanserv_join,		{"JOIN", "J", NULL, NULL, NULL}, "<#channel>", "Get bot to join a channel."},
     {INFO_COMMAND,    0, 0, 1, chanserv_joins_show,	{"JOINS?", NULL, NULL, NULL, NULL}, NULL, "Shows the number of user joins bot has seen in this channel since startup."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_kick,		{"KICK", "WHACK", "K", "NAIL", NULL}, "[#channel] <nick> [reason]", "Kick a user off the channel."},
 #endif
     {INFO_COMMAND,    0, 0, 0, chanserv_language,		{"LANGUAGE", "LANG", NULL, NULL, NULL}, NULL, "Shows the language that bot is currently speaking."},
     {DANGER_COMMAND,  2, 0, 0, chanserv_leave,		{"LEAVE", "PART", "L", "P", NULL}, "[#channel]", "Get bot to leave the channel."},
     {INFO_COMMAND,    0, 1, 0, chanserv_length,		{"LENGTH", NULL, NULL, NULL, NULL}, "<text>", "Show the length of the text."},
     {INFO_COMMAND,    0, 1, 0, chanserv_level,		{"LEVEL", NULL, NULL, NULL, NULL}, "<nick>", "Show users level."},
     {INFO_COMMAND,    0, 0, 0, chanserv_location_show,	{"LOCATION?", NULL, NULL, NULL, NULL}, NULL, "Shows what servers are available and in use."},
     {PASSWORD_COMMAND, 0, 1, 0, chanserv_login,		{"LOGIN", NULL, NULL, NULL, NULL}, "<password>", "Gives you access to high level bot commands if you are on the access list."},
 #ifdef ENABLE_STATUS
     {INFO_COMMAND,    1, 0, 0, chanserv_users_list,	{"LUSERS", NULL, NULL, NULL, NULL}, NULL, ""},
 #endif
     {INFO_COMMAND,    0, 1, 0, chanserv_mask,		{"MASK", NULL, NULL, NULL, NULL}, "<nick>", "Show the users user@host mask."},
 //#ifndef	WIN32
     {INFO_COMMAND,    3, 0, 1, chanserv_memory,		{"MEM", "RAM", NULL, NULL, NULL}, NULL, "Shows some memory usage and process statistics."},
 //#endif
 #ifdef ENABLE_METAR
     {NORMAL_COMMAND,  0, 1, 0, chanserv_metar,		{"METAR", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw METAR weather data."},
 #endif
     {DANGER_COMMAND,  3, 1, 0, chanserv_nick,		{"NICK", "N", NULL, NULL, NULL}, "<newnick>", "Change bot's nickname, but not the default."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_op,		{"OP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel operator status to users."},
 #endif
     {INFO_COMMAND,    0, 0, 1, chanserv_os_show,		{"OS", NULL, NULL, NULL, NULL}, NULL, "Show the operating system that bot is running on."},
     {PASSWORD_COMMAND, 0, 2, 0, chanserv_password,		{"PASSWORD", "PASS", "PASSWD", NULL, NULL}, "<old password> <new password>", "Change your bot access list password."},
     {DANGER_COMMAND,  3, 0, 0, chanserv_performs,		{"PERFORMS", NULL, NULL, NULL, NULL}, NULL, "Perform the tasks in the perform.ini startup script."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  3, 1, 0, chanserv_perm_ban,		{"PERMBAN", "SHITLIST", NULL, NULL, NULL}, "<user@host> [reason]", "Adds a user to the permanent ban list."},
     {INFO_COMMAND,    0, 0, 0, chanserv_perm_bans_list,	{"PERMBANS?", NULL, NULL, NULL, NULL}, NULL, "Shows how many permanent bans there are."},
 #endif
 #ifdef ENABLE_CTCP
     {INFO_COMMAND,    0, 1, 0, chanserv_ping,		{"\1PING", NULL, NULL, NULL, NULL}, "<>", ""},
 #endif
     {INFO_COMMAND,    0, 0, 0, chanserv_ping2,		{"PING", NULL, NULL, NULL, NULL}, NULL, "Replies with \"PONG\" to see how lagged the bot is.."},
     {INFO_COMMAND,    0, 0, 0, chanserv_queue_show,	{"SENDQ?", "QUE?", NULL, NULL, NULL}, NULL, "Shows how many items are ready to be displayed."},
 #ifdef ENABLE_QUIZ
     {SAFE_COMMAND,    0, 0, 0, chanserv_quiz,		{"QUIZ", NULL, NULL, NULL, NULL}, NULL, ""},
 #endif
 #ifdef ENABLE_RANDQ
     {NORMAL_COMMAND,  0, 1, 0, chanserv_quote,		{"QUOTE", NULL, NULL, NULL, NULL}, "[text]", "Shows a random quote."},
     {NORMAL_COMMAND,  0, 1, 0, chanserv_random_quote,	{"RANDQUOTE", "RANDQ", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
     {NORMAL_COMMAND,  0, 1, 0, chanserv_random_quote_2,	{"RANDQUOTE2", "RANDQ2", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
 #endif
 #ifdef ENABLE_RANDOM
     {NORMAL_COMMAND, RAND_LEVEL, 1, 0, chanserv_random_stuff, {"RANDOMSTUFF", "RANDSTUFF", "RS", "ZADD", NULL}, "<text>", "Add random stuff to say."},
     {INFO_COMMAND,    0, 0, 0, chanserv_random_stuff_list,	{"RANDOMSTUFF?", "RANDSTUFF?", NULL, NULL, NULL}, NULL, "Shows time until next random thing is said."},
 #endif
     {DANGER_COMMAND,  3, 1, 0, chanserv_raw,		{"RAW", NULL, NULL, NULL, NULL}, "<raw data>", "Get bot to send raw IRC data."},
 //#ifndef	WIN32
     {INFO_COMMAND,    0, 0, 0, chanserv_rdb,		{"RDB", NULL, NULL, NULL, NULL}, "[topic]", "Display information about the random databases."},
 //#endif
     {DANGER_COMMAND,  3, 3, 0, chanserv_repeat,		{"REPEAT", "TIMER", NULL, NULL, NULL}, "<number> <delay> <raw data>", "Get bot to send raw IRC data a number of times."},
     {NORMAL_COMMAND,  1, 1, 0, chanserv_replace,		{"REPLACE", NULL, NULL, NULL, NULL}, "<topic> <text>", "Replace the text of a topic."},
     {DANGER_COMMAND,  3, 0, 0, chanserv_restart,		{"RESTART", "REHASH", NULL, NULL, NULL}, NULL, "Restart the bot."},
     {INFO_COMMAND,    0, 1, 0, chanserv_search,		{"SEARCH", "LOOK", "FIND", NULL, NULL}, "<text>", "Search in the topics."},
     {INFO_COMMAND,    0, 1, 0, chanserv_seen,		{"SEEN", NULL, NULL, NULL, NULL}, "<nick>", "Show the last time a user was seen."},
     {DANGER_COMMAND,  3, 1, 0, chanserv_jump,		{"SERVER", "JUMP", NULL, NULL, NULL}, "<server> [port]", "Switch bot to a different server."},
     {DANGER_COMMAND,  3, 1, 0, chanserv_set,		{"SET", NULL, NULL, NULL, NULL}, "<parameter>[=<new value>]", "Set or show the value of a setup.ini parameter.  Usually requires a restart."},
     {DANGER_COMMAND,  1, 1, 0, chanserv_setinfo,		{"SETINFO", NULL, NULL, NULL, NULL}, "<new user greeting|0>", "Set your greeting from the bot when you join a channel."},
     {SAFE_COMMAND, SLEEP_LEVEL, 1, 1, chanserv_sleep,	{"SLEEP", "HUSH", NULL, NULL, NULL}, "[period]", "Deactivate bot for a period."},
 #ifdef ENABLE_STATS
     {INFO_COMMAND,    0, 0, 0, chanserv_stats,		{"STATS", NULL, NULL, NULL, NULL}, "[nick]", "Shows statistics about questions answered."},
 #endif
 #ifdef ENABLE_TAF
     {NORMAL_COMMAND,  0, 1, 0, chanserv_taf,		{"TAF", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw TAF weather data."},
 #endif
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  2, 1, 0, chanserv_teaseop,		{"TEASEOP", "TO", NULL, NULL, NULL}, "<nick>", "Tease a user with channel operator status."},
 #endif
     {INFO_COMMAND,    0, 2, 0, chanserv_tell,		{"TELL", NULL, NULL, NULL, NULL}, "<nick> [ABOUT] <topic>", "Get bot to recall a topic to a user."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  2, 0, 0, chanserv_topic,		{"TOPIC", "T", NULL, NULL, NULL}, "<channel topic>", "Change the channels topic."},
 #endif
     {DANGER_COMMAND,  1, 1, 0, chanserv_unignore,		{"UNIGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to stop ignoring a user."},
     {INFO_COMMAND,    0, 1, 0, chanserv_unixtime,		{"UNIXTIME", NULL, NULL, NULL, NULL}, "<time>", "Shows unixtime."},
 #ifdef ENABLE_CHANNEL
     {DANGER_COMMAND,  2, 0, 0, chanserv_up,		{"UP", NULL, NULL, NULL, NULL}, NULL, "Add channel operator status to yourself."},
 #endif
 //#ifndef	WIN32
     {INFO_COMMAND,    0, 0, 0, chanserv_uptime,		{"UPTIME", NULL, NULL, NULL, NULL}, NULL, "Shows the uptime statistics for the computer the bot is running on."},
 //#endif
     {INFO_COMMAND,    1, 0, 0, chanserv_user_list,		{"USERLIST", "HLIST", "ACCESS", NULL, NULL}, NULL, "Show the bot's access list."},
     {INFO_COMMAND,    0, 0, 0, chanserv_variables,		{"VARIABLES", NULL, NULL, NULL, NULL}, NULL, "Displays variables you can use."},
 #ifdef ENABLE_CTCP
     {INFO_COMMAND,    0, 0, 0, chanserv_version,		{"\1VERSION\1", NULL, NULL, NULL, NULL}, NULL, ""},
 #endif
 #ifdef ENABLE_CHANNEL
     {NORMAL_COMMAND,  3, 1, 0, chanserv_voice,		{"VOICE", "V", NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel voice status to users."},
 #endif
     {SAFE_COMMAND, SLEEP_LEVEL, 0, 0, chanserv_wakeup,	{"WAKEUP", NULL, NULL, NULL, NULL}, NULL, "Reactivates bot from sleep mode."},
 #ifdef ENABLE_WEATHER
     {NORMAL_COMMAND,  0, 1, 0, chanserv_weather,		{"WEATHER", NULL, NULL, NULL, NULL}, "<city or code>", "Get decoded weather data."},
 #endif
 #ifdef ENABLE_WEBSEARCH
     {NORMAL_COMMAND,  0, 1, 0, chanserv_websearch,	{"WEBSEARCH", NULL, NULL, NULL, NULL}, "<text>", "Look up the text on the web using duckduckgo.com."},
 #endif
     {SAFE_COMMAND,    0, 2, 0, chanserv_where,		{"WHAT", "WHO", "WHERE", NULL, NULL}, "<IS> [A|AN] <topic>", "Recall a topic."},
     {SAFE_COMMAND,    0, 2, 0, chanserv_whisper,		{"WHISPER", NULL, NULL, NULL, NULL}, "<nick> [ABOUT] <topic>", "Get bot to recall a topic to a user privately."},
     {INFO_COMMAND,    4, 0, 0, NULL, {NULL, NULL, NULL, NULL, NULL}, NULL, NULL}
 };
 
 void chanserv(char *source, char *target, char *buf)
 {
 	struct chanserv_output *result = NULL;
 	char *cmd = NULL, *userhost = NULL, oldbuf[BUFSIZ] = {"NULL"},
 	     *ptr = NULL, *chan = NULL;
 	int i = 0, j = 0, found = -1, command = 0, wakeup = 0, exempt = 0,
 	    more_needed = 0, too_many = 0, check_too_many = 0, arg_count = 0,
 	    command_access = 0;
 	enum chanserv_invoke_type input_type = DIRECT_INVOKE;
 	enum chanserv_command_type command_type = NORMAL_COMMAND;
 
 #ifdef ENABLE_RANDOM
 	if (strcasecmp (target, CHAN) == 0)
 		Rand_Idle = 0;
 #endif
 	stripline (buf);
 	stripline (source);
 	if (buf == NULL || target == NULL || source == NULL)
 	    return;
 
 	/* Make a copy of the original buffer in a safe location for
 	 * later use. Strip the : if there is one.
 	 */
 
 	strncpy (oldbuf, buf, sizeof (oldbuf));
 
 	/* Pointer to oldbuf */
 	ptr = oldbuf; 
 
 	if (*ptr == ':')
 		ptr++;
 
 	cmd = strtok (buf, " ");
 
 	if (!cmd)
 	    return;
 	if (*cmd == ':')
 	    cmd++;
 
 	if ((userhost = strchr (source, '!')) != NULL)
 	    *userhost++ = '\0';
 
 	if (check_ignore_user_ram(source) > 0)
     	    return;
 
 	if (*target != '#' && *target != '&' && *target != '+')
 	{
 		input_type = MSG_INVOKE;
 	}
 	else if (strcasecmp (cmd, NICK_COMMA) == 0 || 
                  strcasecmp (cmd, COLON_NICK) == 0 || 
                  strcasecmp (cmd, BCOLON_NICK) == 0 || 
                  strcasecmp (cmd, Mynick) == 0)
 	{
 		input_type = ADDRESS_INVOKE;
 		cmd = strtok (NULL, " ");
 	}
 
 	if (cmd)
 	{
 	    if (*cmd == *CMDCHAR)
             {
                cmd++;
                command = 1;
                input_type = CHAR_INVOKE;
             }
             
 	    strupr (cmd);
     	    for (i = 0; chanserv_commands[i].func != NULL; i++)
 	    {
 		for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
 		{
 		    if (strcmp(cmd, chanserv_commands[i].command[j]) == 0)
 		    {
 			found = i;
 			command_type = chanserv_commands[found].type;
 			check_too_many = chanserv_commands[found].too_many;
 			if (strcmp(cmd, "WAKEUP") == 0)
 			    wakeup = 1;
 	    		break;
 		    }
 		}
 		if (found != -1)
 		    break;
 	    }
 	}
 
 	if (input_type != MSG_INVOKE)
 	{
 	    if (((Sleep_Toggle == 1) && (wakeup != 1)) || (cf(userhost, source, target)))
 		return;
     	    add_user(target, source, userhost, 0);	/* Unidle */
 	}
 
 	if (found != -1)
 	{
 	    /*
 	     * password related commands can ONLY be done privately.
 	     * Every             command can be done by /msg   bot  !command.
 	     * Every             command can be done by /query bot  !command.
 	     * Every             command can be done by /msg   bot  !command.
 	     * Every danger      command can be done by        bot: !command.
 	     * Every danger      command can be done by             !command.
 	     * Every normal      command can be done by /query bot   command.
 	     * Every normal      command can be done by /msg   bot   command.
 	     * Every safe        command can be done by        bot:  command.
 	     * Every information command can be done by              command.
 	     */
 
 	    switch (command_type)
 	    {
 		case INFO_COMMAND :
 			break;
 
 		case SAFE_COMMAND :
 		    {
 			if (input_type == DIRECT_INVOKE)
 			    return;
 			break;
 		    }
 
 		case NORMAL_COMMAND :
 		    {
 			if (input_type == DIRECT_INVOKE) 
 				return;
 			break;
 		    }
 
 		case DANGER_COMMAND :
 		    {
 			if (command != 1)
 			    return;
 			break;
 		    }
 
 		case PASSWORD_COMMAND :
 		    {
 			if (input_type != MSG_INVOKE)
 			    return;
 			break;
 		    }
 	    }
 
 		chan = (input_type == MSG_INVOKE) ? "#*" : target;
 		command_access = chanserv_commands[found].access;
 	    if (check_access(userhost, chan, 0, source) >= (long)command_access)
 	    {
 		char **args = NULL;
 		int k = 0;
 
 		/* Use the char count of spaces in our oldbuf ptr. Since 
 		 * it has the cmd tacked on the beginning, the number of 
 		 * spaces gives us an accurate early number of arguments
 		 * supplied by the user, because the count of spaces will
 		 * return one more than the actual number of args supplied.
 		 * The first word is the cmd, so we don't want this counted.
 		 * This is sort of a lazy way of counting arguments before 
 		 * they're actually read into a buffer and dealt with.
 		 *
 		 * This allows us to "break out" of the command routine if
 		 * we've entered accidentally by user input. Such instances
 		 * may be if the user says "info things stuff", the bot 
 		 * realizes this is not a command, but normal conversation,
 		 * and will respond if the topic is in it's database. If it's 
 		 * not found, the bot either ignores it or responds with a
 		 * whut reply if addressed directly.  This code is only 
 		 * intended for commands which have no arguments.  
 		 */
 
 		if (*ptr == '!')
 			ptr++;
 		
 		/* Actual number of arguments supplied. */
 		k = count_char (ptr, ' ');
 
 		/* Number of arguments expected. */
 		arg_count = chanserv_commands[found].arg_count;
 
 		if (k > 0)
 		{
 		    args = calloc(k + 1, sizeof(char *));
 		    if (args)
 		    {
 			for (i = 0; i < k; i++)
 			{
 			    args[i] = strtok(NULL, " ");
 			}
 			args[i++] = NULL;
 
 	   	        /* Check for more arguments needed, but don't
 			 * bail out, we'll take care of it later. */
 			 if (i < arg_count)
 			     more_needed = 1;
 		     }
 		     else
 			return;
 
 		   /* Check for too many args on special cases. */
 		   if (check_too_many == 1)
 		   {
 		      if ((input_type == ADDRESS_INVOKE) && (k > (arg_count+1)))
 		   	  too_many = 1;
 		      if ((k > arg_count) && (input_type == DIRECT_INVOKE))
 			  too_many = 1;
 		      if ((k > arg_count) && (input_type == MSG_INVOKE))
 			  too_many = 1;
 		      if ((k > arg_count) && (input_type == CHAR_INVOKE))
 			  return;
 		   }
 		}
 		else
 		{
 		    args = calloc(1, sizeof(char *));
 		    if (args)
 		    {
 			args[0] = NULL;
 			if (0 < arg_count)
 			    more_needed = 1;
 		    }
 		    else
 			return;
 		}
 
 		if (too_many == 1)
 		{
 			int i = 0;
 			char *ptr2 = NULL;
 
 			strlwr (ptr);
 	
 			for (i = 0; i < strlen (ptr); i++)
 			{
 				if (ptr[i] == ' ')
 					ptr[i] = '+';
 			}
 			
 				
 			/* Strip the bot's nickname if ADDRESS_INVOKE */
 
 			if (input_type == ADDRESS_INVOKE)
 			{
 				ptr2 = strtok (ptr, "+");
 				ptr = strtok (NULL, "");
 			}
 
 			/* Output only if the topic exists. If the bot was 
 			 * addressed by nickname (ADDRESS_INVOKE), output 
 			 * anyway because show_url will supply a DUNNO 
 			 * response. 
 
 			 * If the input_type was MSG_INVOKE, we use the 
 			 * source as a target, because the target ends up 
 			 * being set to the bot's own nickname due to the 
 			 * parsing under certain conditions.
 			 */
 
 			if (check_existing_url(source, ptr, target) == 1)
 //				|| (input_type == ADDRESS_INVOKE)
 //				|| (input_type == MSG_INVOKE))
 			{	
 				result = show_url(source, ptr, 
 					((input_type == MSG_INVOKE) 
 					? source : target), 1, 0, userhost, 0);
 			}
 			else
 			/* No matching database entry. */
 				return;
 		}
 		else if ((more_needed == 1) && chanserv_commands[found].syntax)
 		{
 			chan = (input_type == MSG_INVOKE) ? "#*" : target;
 			result = chanserv_show_help(cmd, check_access(userhost, chan, 0, source));
 		}
 		else
 		{
 			/* We call this to give the command a chance to supply
 			 * a custom error msg if there are not enough 
 			 * arguments. Because it fell through the loop 
 			 * this far, we assume it's a normal command with
 			 * arguments to be parsed.
 			 */
 			result = chanserv_commands[found].func(source, target, cmd, args, input_type, userhost);
 		}
 
 		if (result)
 		{
 			i = 1;
 			show_output(source, target, result, input_type, 0);
 			result = NULL;
 		}
 		free(args);
 	    }
 	}
 	else if (input_type != CHAR_INVOKE)
 	{
 	    if ((input_type == ADDRESS_INVOKE) && (cmd == NULL))
 	    {
 		if (RANDOM_WHUT == true)
 		    do_randomtopic(WHUTR, target, WHUT_FILE, source, cmd);
 		else
 		{
 		    if (input_type == MSG_INVOKE)
 			S("NOTICE %s :%s\n", source, WHUT);
 		    else
 			S("PRIVMSG %s :%s: %s\n", target, source, WHUT);
 		}
 	    }
 	    else if ((GENERAL_QUESTIONS) && (cmd))
 	    {
 		result = show_url(source, get_multiword_topic(cmd), 
 		    (input_type == MSG_INVOKE) ? source : target, 
 		    (! (input_type == DIRECT_INVOKE)), 
 		    (input_type == DIRECT_INVOKE), 
 		    userhost, 0);
 		if (result)
 		{
 			show_output(source, (input_type == MSG_INVOKE) ? source : target, result, input_type, 1);
 			result = NULL;
 		}
 	    }
 	}
 }
 
 static void show_output(char *source, char *target, struct chanserv_output *result, enum chanserv_invoke_type input_type, int question)
 {
     struct chanserv_output *output = result;
 
 // TODO - This is not working for actions.
     while (output)
     {
 	char *s, *s2, c;
 	int length, len;
 
 /* RFC2812 says max packet length is 512, including CR-LF at end.
  * Also a colon and a space at the beginning.
  */
 //#define MAX_IRC_LEN 507  // This doesn't work.
 #define MAX_IRC_LEN 475    // This works.
 
 	s = output->output;
 	length = strlen(s);
 	if (input_type == MSG_INVOKE)
 	{
 	    len = 12 + strlen(source);
 	    while ((len + length) > MAX_IRC_LEN)
 	    {
 	        c = s[MAX_IRC_LEN - len];
 		s[MAX_IRC_LEN - len] = '\0';
 		s2 = strrchr(s, ' ');
 		*s2 = '\0';
 		S("NOTICE %s :%s\n", source, s);
 		db_sleep(2);
 		*s2 = ' ';
 		s[MAX_IRC_LEN - len] = c;
 		s = s2 + 1;
 		length = strlen(s);
 	    }
 	    S("NOTICE %s :%s\n", source, s);
 	}
 	else
 	{
 	    len = 16 + strlen(target) + strlen(source);
 	    while ((len + length) > MAX_IRC_LEN)
 	    {
 	        c = s[MAX_IRC_LEN - len];
 		s[MAX_IRC_LEN - len] = '\0';
 		s2 = strrchr(s, ' ');
 		*s2 = '\0';
 		if ((('#' == target[0]) && (ADDRESS_INVOKE != input_type)) || (question))
 		    S("PRIVMSG %s :%s\n", target, s);
 		else
 		    S("PRIVMSG %s :%s: %s\n", target, source, s);
 		db_sleep(2);
 		*s2 = ' ';
 		s[MAX_IRC_LEN - len] = c;
 		s = s2 + 1;
 		length = strlen(s);
 	    }
 	    if ((('#' == target[0]) && (ADDRESS_INVOKE != input_type)) || (question))
 		S("PRIVMSG %s :%s\n", target, s);
 	    else
 		S("PRIVMSG %s :%s: %s\n", target, source, s);
 	}
 	output = output->next;
     }
     chanserv_output_free(result);
 }
 
 struct chanserv_output *chanserv_show_help(char *cmd, long user_level)
 {
 	struct chanserv_output *result = NULL;
 	char temp[10 * 1024] = { 0 }, cmdchar[2] = "\0\0";
 	int i, j, found = -1;
 
 	if (*cmd == *CMDCHAR)
 	    cmd++;
 	strupr(cmd);
     	for (i = 0; chanserv_commands[i].func != NULL; i++)
 	{
 	    for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
 	    {
 		if (strcmp(cmd, chanserv_commands[i].command[j]) == 0)
 		{
 		    found = i;
 	    	    break;
 		}
 	    }
 	    if (found != -1)
 		break;
 	}
 
 	if (found != -1)
 	{
 	    if (chanserv_commands[found].type == DANGER_COMMAND)
 		cmdchar[0] = *CMDCHAR;
 	    else
 		cmdchar[0] = '\0';
 	    for (j = 0; chanserv_commands[found].command[j] != NULL; j++)
 	    {
 		if (j)
 		    strcat(temp, " | ");
 		if (chanserv_commands[i].type == DANGER_COMMAND)
 		    strcat(temp, cmdchar);
 		strcat(temp, chanserv_commands[found].command[j]);
 	    }
 	    result = chanserv_asprintf(result, "%s [level %d] - %s  SYNTAX - %s%s %s", temp, chanserv_commands[found].access, chanserv_commands[found].summary, cmdchar, cmd, 
 		(chanserv_commands[found].syntax != NULL) ? chanserv_commands[found].syntax : "");
 	}
 	else if (strcmp(cmd, "COMMANDS") == 0)
 	{
 	    cmdchar[0] = *CMDCHAR;
     	    for (i = 0; chanserv_commands[i].func != NULL; i++)
 	    {
 		if (chanserv_commands[i].access <= user_level)
 		{
 		    if (chanserv_commands[i].command[0][0] > 10)
 		    {
 			if (i)
 			    strcat(temp, " ");
 			if (chanserv_commands[i].type == DANGER_COMMAND)
 			    strcat(temp, cmdchar);
 			strcat(temp, chanserv_commands[i].command[0]);
 		    }
 		}
 	    }
 	    result = chanserv_asprintf(result, "%s", temp);
 	}
 	else if (strcmp(cmd, "PARAMETERS") == 0)
 	{
     	    for (i = 0; parameters[i].parameter[0] != NULL; i++)
 	    {
 		if (parameters[i].access <= user_level)
 		{
 		    if (i)
 			strcat(temp, " ");
 		    strcat(temp, parameters[i].parameter[0]);
 		}
 	    }
 	    result = chanserv_asprintf(result, "%s", temp);
 	}
 	else
 	{
     	    for (i = 0; parameters[i].parameter[0] != NULL; i++)
 	    {
 		for (j = 0; parameters[i].parameter[j] != NULL; j++)
 		{
 		    if (strcmp(cmd, parameters[i].parameter[j]) == 0)
 		    {
 			found = i;
 	    		break;
 		    }
 		}
 		if (found != -1)
 		    break;
 	    }
 
 	    if (found != -1)
 	    {
 		for (j = 0; parameters[found].parameter[j] != NULL; j++)
 		{
 		    if (j)
 			strcat(temp, " | ");
 		    strcat(temp, parameters[found].parameter[j]);
 		}
 
 		switch (parameters[found].type)
 		{
 		    case ST_BOOLEAN : 
 	    	    {
 			    bool *variable = parameters[found].value;
 
 			    result = chanserv_asprintf(result, "%s [level %d] - %s  VALUE - %s = %s", temp, parameters[found].access, parameters[found].summary, cmd, (*variable) ? "true" : "false");
 			    break;
 	    	    }
 
 	    	    case ST_INTEGER : 
 	    	    {
 			    long *variable = parameters[found].value;
 
 			    result = chanserv_asprintf(result, "%s [level %d] - %s  VALUE - %s = %ld", temp, parameters[found].access, parameters[found].summary, cmd, *variable);
 			    break;
 	    	    }
 
 	    	    case ST_STRING  : 
 	    	    {
 			    char *variable = parameters[found].value;
 
 			    result = chanserv_asprintf(result, "%s [level %d] - %s  VALUE - %s = %s", temp, parameters[found].access, parameters[found].summary, cmd, variable);
 			    break;
 	    	    }
 		}
 	    }
 	}
 
 	return result;
 }
 
 int	check_exempt	(char *cmd)
 {
 	int i = 0;
 	int j = 0; 
 	int k = 0;
 	
 	char *exempt_items[] = {
 		"CYCLE",
 		"HELP",
 #ifdef ENABLE_STATS
 		"STATS", 
 #endif
 	        NULL
 	};
 
 	strupr(cmd);
 
 	for (i = 0; chanserv_commands[i].func != NULL; i++)
 	{
 		for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
 		{
 			if (strcmp (cmd, chanserv_commands[i].command[j]) == 0)
 			{
 				for (k = 0; exempt_items[k] != NULL; k++)
 				{
 						if (strcmp (chanserv_commands[i].command[j], exempt_items[k]) == 0)
 						{
 							strlwr(cmd);	
 							return 1;
 						}
 				}
 			}
 		}
 	}
 	
 	strlwr(cmd);
 	return 0;
 }