diff options
| -rw-r--r-- | irc_im.c | 26 | ||||
| -rw-r--r-- | protocols/bee.h | 2 | ||||
| -rw-r--r-- | protocols/bee_user.c | 6 | ||||
| -rw-r--r-- | protocols/jabber/iq.c | 48 | ||||
| -rw-r--r-- | protocols/jabber/jabber.c | 33 | ||||
| -rw-r--r-- | protocols/jabber/jabber.h | 1 | ||||
| -rw-r--r-- | protocols/nogaim.h | 9 | 
7 files changed, 125 insertions, 0 deletions
| @@ -279,6 +279,27 @@ static gboolean bee_irc_user_typing( bee_t *bee, bee_user_t *bu, uint32_t flags  	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; +} +  static gboolean bee_irc_user_nick_update( irc_user_t *iu );  static gboolean bee_irc_user_fullname( bee_t *bee, bee_user_t *bu ) @@ -491,6 +512,10 @@ static gboolean bee_irc_user_ctcp( irc_user_t *iu, char *const *ctcp )  			return TRUE;  		}  	} +	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;  } @@ -1040,6 +1065,7 @@ const struct bee_ui_funcs irc_ui_funcs = {  	bee_irc_user_status,  	bee_irc_user_msg,  	bee_irc_user_typing, +	bee_irc_user_action_response,  	bee_irc_chat_new,  	bee_irc_chat_free, diff --git a/protocols/bee.h b/protocols/bee.h index 077c3661..49ea6fb5 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -110,6 +110,8 @@ typedef struct bee_ui_funcs  	gboolean (*user_msg)( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at );  	/* 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  	   added using chat_add_user().  UI state can be stored via c->data. */ diff --git a/protocols/bee_user.c b/protocols/bee_user.c index 4ea538a9..0b118853 100644 --- a/protocols/bee_user.c +++ b/protocols/bee_user.c @@ -280,3 +280,9 @@ void imcb_buddy_typing( struct im_connection *ic, const char *handle, uint32_t f  		ic->bee->ui->user_typing( ic->bee, bu, flags );  	}  } + +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 ); +} diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 82c90d39..a9b69788 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -793,3 +793,51 @@ xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_n  	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; +} diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index 2655d89e..e5bc3c14 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -563,6 +563,37 @@ void jabber_chat_free_settings( account_t *acc, set_t **head )  	set_del( head, "password" );  } +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()  {  	struct prpl *ret = g_new0( struct prpl, 1 ); @@ -590,6 +621,8 @@ void jabber_initmodule()  	ret->send_typing = jabber_send_typing;  	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 );  } diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 1523e096..ff46e12f 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -240,6 +240,7 @@ int jabber_add_to_roster( struct im_connection *ic, const char *handle, const ch  int jabber_remove_from_roster( struct im_connection *ic, char *handle );  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 */  int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 62d49e30..a98b7054 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -135,6 +135,11 @@ struct buddy {  	struct im_connection *ic; /* the connection it belongs to */  }; +struct buddy_action { +	char *name; +	char *description; +}; +  struct prpl {  	int options;  	/* You should set this to the name of your protocol. @@ -256,6 +261,9 @@ struct prpl {  	void (* buddy_data_add) (struct bee_user *bu);  	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;  	void *resv2; @@ -315,6 +323,7 @@ G_MODULE_EXPORT void imcb_remove_buddy( struct im_connection *ic, const char *ha  G_MODULE_EXPORT struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle );  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 );  G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ); | 
