Index: irc.h
===================================================================
--- irc.h	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ irc.h	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -120,4 +120,5 @@
 {
 	gboolean (*privmsg)( irc_user_t *iu, const char *msg );
+	gboolean (*ctcp)( irc_user_t *iu, char * const* ctcp );
 };
 
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ irc_commands.c	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -255,7 +255,18 @@
 	{
 		irc_send_num( irc, 412, ":No text to send" );
-	}
-	else if( irc_channel_name_ok( cmd[1] ) &&
-	         ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
+		return;
+	}
+	
+	/* Don't treat CTCP actions as real CTCPs, just convert them right now. */
+	if( g_strncasecmp( cmd[2], "\001ACTION", 7 ) == 0 )
+	{
+		cmd[2] += 4;
+		strcpy( cmd[2], "/me" );
+		if( cmd[2][strlen(cmd[2])-1] == '\001' )
+			cmd[2][strlen(cmd[2])-1] = '\0';
+	}
+	
+	if( irc_channel_name_ok( cmd[1] ) &&
+	    ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
 	{
 		if( ic->f->privmsg )
@@ -264,5 +275,17 @@
 	else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
 	{
-		if( iu->f->privmsg )
+		if( cmd[2][0] == '\001' )
+		{
+			char **ctcp;
+			
+			if( iu->f->ctcp == NULL )
+				return;
+			if( cmd[2][strlen(cmd[2])-1] == '\001' )
+				cmd[2][strlen(cmd[2])-1] = '\0';
+			
+			ctcp = split_command_parts( cmd[2] + 1 );
+			iu->f->ctcp( iu, ctcp );
+		}
+		else if( iu->f->privmsg )
 			iu->f->privmsg( iu, cmd[2] );
 	}
Index: irc_user.c
===================================================================
--- irc_user.c	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ irc_user.c	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -147,6 +147,16 @@
 }
 
+static gboolean root_ctcp( irc_user_t *iu, char * const *ctcp )
+{
+	if( g_strcasecmp( ctcp[0], "VERSION" ) == 0 )
+	{
+	}
+	
+	return TRUE;
+}
+
 const struct irc_user_funcs irc_user_root_funcs = {
 	root_privmsg,
+	root_ctcp,
 };
 
Index: lib/misc.c
===================================================================
--- lib/misc.c	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ lib/misc.c	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -614,2 +614,47 @@
 	return ret;
 }
+
+char **split_command_parts( char *command )
+{
+	static char *cmd[IRC_MAX_ARGS+1];
+	char *s, q = 0;
+	int k;
+	
+	memset( cmd, 0, sizeof( cmd ) );
+	cmd[0] = command;
+	k = 1;
+	for( s = command; *s && k < IRC_MAX_ARGS; s ++ )
+		if( *s == ' ' && !q )
+		{
+			*s = 0;
+			while( *++s == ' ' );
+			if( *s == '"' || *s == '\'' )
+			{
+				q = *s;
+				s ++;
+			}
+			if( *s )
+			{
+				cmd[k++] = s;
+				s --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
+		{
+			char *cpy;
+			
+			for( cpy = s; *cpy; cpy ++ )
+				cpy[0] = cpy[1];
+		}
+		else if( *s == q )
+		{
+			q = *s = 0;
+		}
+	cmd[k] = NULL;
+	
+	return cmd;
+}
Index: lib/misc.h
===================================================================
--- lib/misc.h	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ lib/misc.h	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -68,3 +68,5 @@
 G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
 
+G_MODULE_EXPORT char **split_command_parts( char *command );
+
 #endif
Index: root_commands.c
===================================================================
--- root_commands.c	(revision e21c0f8b276cc3ca177bcf6217eba9c634d410f7)
+++ root_commands.c	(revision 24b8bbb2616d685006a279e46a4bd2e8e7cf6694)
@@ -34,46 +34,5 @@
 void root_command_string( irc_t *irc, char *command )
 {
-	char *cmd[IRC_MAX_ARGS];
-	char *s;
-	int k;
-	char q = 0;
-	
-	memset( cmd, 0, sizeof( cmd ) );
-	cmd[0] = command;
-	k = 1;
-	for( s = command; *s && k < ( IRC_MAX_ARGS - 1 ); s ++ )
-		if( *s == ' ' && !q )
-		{
-			*s = 0;
-			while( *++s == ' ' );
-			if( *s == '"' || *s == '\'' )
-			{
-				q = *s;
-				s ++;
-			}
-			if( *s )
-			{
-				cmd[k++] = s;
-				s --;
-			}
-			else
-			{
-				break;
-			}
-		}
-		else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
-		{
-			char *cpy;
-			
-			for( cpy = s; *cpy; cpy ++ )
-				cpy[0] = cpy[1];
-		}
-		else if( *s == q )
-		{
-			q = *s = 0;
-		}
-	cmd[k] = NULL;
-	
-	root_command( irc, cmd );
+	root_command( irc, split_command_parts( command ) );
 }
 
