Index: irc_im.c
===================================================================
--- irc_im.c	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ irc_im.c	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -276,4 +276,25 @@
 	else
 		return FALSE;
+	
+	return TRUE;
+}
+
+static gboolean bee_irc_user_action_response( bee_t *bee, bee_user_t *bu, const char *action, char * const args[], void *data )
+{
+	irc_t *irc = (irc_t *) bee->ui_data;
+	GString *msg = g_string_new( "\001" );
+	
+	g_string_append( msg, action );
+	while( *args )
+	{
+		if( strchr( *args, ' ' ) )
+			g_string_append_printf( msg, " \"%s\"", *args );
+		else
+			g_string_append_printf( msg, " %s", *args );
+		args ++;
+	}
+	g_string_append_c( msg, '\001' );
+	
+	irc_send_msg( (irc_user_t *) bu->ui_data, "NOTICE", irc->user->nick, msg->str, NULL );
 	
 	return TRUE;
@@ -492,4 +513,8 @@
 		}
 	}
+	else if( iu->bu && iu->bu->ic && iu->bu->ic->acc->prpl->buddy_action )
+	{
+		iu->bu->ic->acc->prpl->buddy_action( iu->bu, ctcp[0], ctcp + 1, NULL );
+	}
 	
 	return FALSE;
@@ -1041,4 +1066,5 @@
 	bee_irc_user_msg,
 	bee_irc_user_typing,
+	bee_irc_user_action_response,
 	
 	bee_irc_chat_new,
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/bee.h	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -111,4 +111,6 @@
 	/* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */
 	gboolean (*user_typing)( bee_t *bee, bee_user_t *bu, guint32 flags );
+	/* CTCP-like stuff (buddy action) response */
+	gboolean (*user_action_response)( bee_t *bee, bee_user_t *bu, const char *action, char * const args[], void *data );
 	
 	/* Called at creation time. Don't show to the user until s/he is
Index: protocols/bee_user.c
===================================================================
--- protocols/bee_user.c	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/bee_user.c	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -281,2 +281,8 @@
 	}
 }
+
+void imcb_buddy_action_response( bee_user_t *bu, const char *action, char * const args[], void *data )
+{
+	if( bu->bee->ui->user_action_response )
+		bu->bee->ui->user_action_response( bu->bee, bu, action, args, data );
+}
Index: protocols/jabber/iq.c
===================================================================
--- protocols/jabber/iq.c	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/jabber/iq.c	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -794,2 +794,50 @@
 	return XT_HANDLED;
 }
+
+static xt_status jabber_iq_version_response( struct im_connection *ic,
+	struct xt_node *node, struct xt_node *orig );
+
+void jabber_iq_version_send( struct im_connection *ic, struct jabber_buddy *bud, void *data )
+{
+	struct xt_node *node, *query;
+	
+	node = xt_new_node( "query", NULL, NULL );
+	xt_add_attr( node, "xmlns", XMLNS_VERSION );
+	query = jabber_make_packet( "iq", "get", bud->full_jid, node );
+	jabber_cache_add( ic, query, jabber_iq_version_response );
+
+	jabber_write_packet( ic, query );
+}
+
+static xt_status jabber_iq_version_response( struct im_connection *ic,
+	struct xt_node *node, struct xt_node *orig )
+{
+	struct xt_node *query;
+	GString *rets;
+	char *s;
+	char *ret[2] = {};
+	bee_user_t *bu;
+	struct jabber_buddy *bud = NULL;
+	
+	if( ( s = xt_find_attr( node, "from" ) ) &&
+	    ( bud = jabber_buddy_by_jid( ic, s, 0 ) ) &&
+	    ( query = xt_find_node( node->children, "query" ) ) &&
+	    ( bu = bee_user_by_handle( ic->bee, ic, bud->bare_jid ) ) )
+	{
+		rets = g_string_new( "Resource " );
+		g_string_append( rets, bud->resource );
+	}
+	else
+		return XT_HANDLED;
+	
+	for( query = query->children; query; query = query->next )
+		if( query->text_len > 0 )
+			g_string_append_printf( rets, " %s: %s,", query->name, query->text );
+	
+	g_string_truncate( rets, rets->len - 1 );
+	ret[0] = rets->str;
+	imcb_buddy_action_response( bu, "VERSION", ret, NULL );
+	g_string_free( rets, TRUE );
+	
+	return XT_HANDLED;
+}
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/jabber/jabber.c	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -564,4 +564,35 @@
 }
 
+GList *jabber_buddy_action_list( bee_user_t *bu )
+{
+	static GList *ret = NULL;
+	
+	if( ret == NULL )
+	{
+		struct buddy_action ba[2] = {
+			{ "VERSION", "Get client (version) information" },
+		};
+		
+		ret = g_list_prepend( ret, ba + 0 );
+	}
+	
+	return ret;
+}
+
+void *jabber_buddy_action( struct bee_user *bu, const char *action, char * const args[], void *data )
+{
+	if( g_strcasecmp( action, "VERSION" ) == 0 )
+	{
+		struct jabber_buddy *bud;
+		
+		if( ( bud = jabber_buddy_by_ext_jid( bu->ic, bu->handle, 0 ) ) == NULL )
+			bud = jabber_buddy_by_jid( bu->ic, bu->handle, GET_BUDDY_FIRST );
+		for( ; bud; bud = bud->next )
+			jabber_iq_version_send( bu->ic, bud, data );
+	}
+	
+	return NULL;
+}
+
 void jabber_initmodule()
 {
@@ -591,4 +622,6 @@
 	ret->handle_cmp = g_strcasecmp;
 	ret->transfer_request = jabber_si_transfer_request;
+	ret->buddy_action_list = jabber_buddy_action_list;
+	ret->buddy_action = jabber_buddy_action;
 
 	register_protocol( ret );
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/jabber/jabber.h	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -241,4 +241,5 @@
 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid );
 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns );
+void jabber_iq_version_send( struct im_connection *ic, struct jabber_buddy *bud, void *data );
 
 /* si.c */
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision a429907207d5b8b05463c72a9b8c880ba03ad921)
+++ protocols/nogaim.h	(revision d88c92a40438e0ac8e897beb3ead44c4404050b3)
@@ -136,4 +136,9 @@
 };
 
+struct buddy_action {
+	char *name;
+	char *description;
+};
+
 struct prpl {
 	int options;
@@ -257,4 +262,7 @@
 	void (* buddy_data_free) (struct bee_user *bu);
 	
+	GList *(* buddy_action_list) (struct bee_user *bu);
+	void *(* buddy_action) (struct bee_user *bu, const char *action, char * const args[], void *data);
+	
 	/* Some placeholders so eventually older plugins may cooperate with newer BitlBees. */
 	void *resv1;
@@ -316,4 +324,5 @@
 G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname );
 G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick );
+G_MODULE_EXPORT void imcb_buddy_action_response( bee_user_t *bu, const char *action, char * const args[], void *data );
 
 G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, const char *handle, uint32_t flags );
