diff options
| author | Wilmer van der Gaast <wilmer@google.com> | 2010-08-23 11:34:36 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@google.com> | 2010-08-23 11:34:36 +0100 | 
| commit | 1aa74f559af18e06195f34b721d65d69c29fcc0f (patch) | |
| tree | bd3dbb8bd3e86c1d885e2d3ef245ec6091c31040 | |
| parent | 241f9f6d9135048578ad603485740b73402edd8a (diff) | |
Process incoming XMPP groupchat invites in a saner way: Create a temporary
channel the user can easily /join.
| -rw-r--r-- | irc.h | 1 | ||||
| -rw-r--r-- | irc_im.c | 58 | ||||
| -rw-r--r-- | irc_send.c | 8 | ||||
| -rw-r--r-- | protocols/bee.h | 2 | ||||
| -rw-r--r-- | protocols/bee_chat.c | 8 | ||||
| -rw-r--r-- | protocols/jabber/message.c | 16 | 
6 files changed, 86 insertions, 7 deletions
| @@ -281,6 +281,7 @@ void irc_send_msg_f( irc_user_t *iu, const char *type, const char *dst, const ch  void irc_send_nick( irc_user_t *iu, const char *new );  void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu,                                        irc_channel_user_flags_t old, irc_channel_user_flags_t new ); +void irc_send_invite( irc_user_t *iu, irc_channel_t *ic );  /* irc_user.c */  irc_user_t *irc_user_new( irc_t *irc, const char *nick ); @@ -612,6 +612,63 @@ static gboolean bee_irc_chat_name_hint( bee_t *bee, struct groupchat *c, const c  	return TRUE;  } +static gboolean bee_irc_chat_invite( bee_t *bee, bee_user_t *bu, const char *name, const char *msg ) +{ +	char *channel, *s; +	irc_t *irc = bee->ui_data; +	irc_user_t *iu = bu->ui_data; +	irc_channel_t *chan; +	 +	if( strchr( CTYPES, name[0] ) ) +		channel = g_strdup( name ); +	else +		channel = g_strdup_printf( "#%s", name ); +	 +	if( ( s = strchr( channel, '@' ) ) ) +		*s = '\0'; +	 +	if( strlen( channel ) > MAX_NICK_LENGTH ) +	{ +		/* If the channel name is very long (like those insane GTalk +		   UUID names), try if we can use the inviter's nick. */ +		s = g_strdup_printf( "#%s", iu->nick ); +		if( irc_channel_by_name( irc, s ) == NULL ) +		{ +			g_free( channel ); +			channel = s; +		} +	} +	 +	if( ( chan = irc_channel_new( irc, channel ) ) && +	    set_setstr( &chan->set, "type", "chat" ) && +	    set_setstr( &chan->set, "chat_type", "room" ) && +	    set_setstr( &chan->set, "account", bu->ic->acc->tag ) && +	    set_setstr( &chan->set, "room", (char*) name ) ) +	{ +		/* I'm assuming that if the user didn't "chat add" the room +		   himself but got invited, it's temporary, so make this a +		   temporary mapping that is removed as soon as we /PART. */ +		chan->flags |= IRC_CHANNEL_TEMP; +	} +	else +	{ +		irc_channel_free( chan ); +		chan = NULL; +	} +	g_free( channel ); +	 +	irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "<< \002BitlBee\002 - Invitation to chatroom %s >>", name ); +	if( msg ) +		irc_send_msg( iu, "PRIVMSG", irc->user->nick, msg, NULL ); +	if( chan ) +	{ +		irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "To join the room, just /join %s", chan->name ); +		irc_send_invite( iu, chan ); +	} +	 +	return TRUE; +} +  /* IRC->IM */  static gboolean bee_irc_channel_chat_privmsg_cb( gpointer data, gint fd, b_input_condition cond ); @@ -908,6 +965,7 @@ const struct bee_ui_funcs irc_ui_funcs = {  	bee_irc_chat_remove_user,  	bee_irc_chat_topic,  	bee_irc_chat_name_hint, +	bee_irc_chat_invite,  	bee_irc_ft_in_start,  	bee_irc_ft_out_start, @@ -397,3 +397,11 @@ void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu,  	if( *changes )  		irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes );  } + +void irc_send_invite( irc_user_t *iu, irc_channel_t *ic ) +{ +	irc_t *irc = iu->irc; +	 +	irc_write( iu->irc, ":%s!%s@%s INVITE %s :%s", +	           iu->nick, iu->user, iu->host, irc->user->nick, ic->name ); +} diff --git a/protocols/bee.h b/protocols/bee.h index 2fd3562e..b99c8de7 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -122,6 +122,7 @@ typedef struct bee_ui_funcs  	gboolean (*chat_remove_user)( bee_t *bee, struct groupchat *c, bee_user_t *bu );  	gboolean (*chat_topic)( bee_t *bee, struct groupchat *c, const char *new, bee_user_t *bu );  	gboolean (*chat_name_hint)( bee_t *bee, struct groupchat *c, const char *name ); +	gboolean (*chat_invite)( bee_t *bee, bee_user_t *bu, const char *name, const char *msg );  	struct file_transfer* (*ft_in_start)( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size );  	gboolean (*ft_out_start)( struct im_connection *ic, struct file_transfer *ft ); @@ -174,5 +175,6 @@ G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *c, const char *handl  G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason );  G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags );  G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title ); +G_MODULE_EXPORT void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg );  #endif /* __BEE_H__ */ diff --git a/protocols/bee_chat.c b/protocols/bee_chat.c index 3be6f189..0314cae5 100644 --- a/protocols/bee_chat.c +++ b/protocols/bee_chat.c @@ -232,3 +232,11 @@ struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const  	return NULL;  } + +void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg ) +{ +	bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who ); +	 +	if( bu && ic->bee->ui->chat_invite ) +		ic->bee->ui->chat_invite( ic->bee, bu, name, msg ); +} diff --git a/protocols/jabber/message.c b/protocols/jabber/message.c index ce5017fb..6e40e521 100644 --- a/protocols/jabber/message.c +++ b/protocols/jabber/message.c @@ -30,7 +30,7 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )  	char *type = xt_find_attr( node, "type" );  	struct xt_node *body = xt_find_node( node->children, "body" ), *c;  	struct jabber_buddy *bud = NULL; -	char *s; +	char *s, *room = NULL, *reason = NULL;  	if( !from )  		return XT_HANDLED; /* Consider this packet corrupted. */ @@ -51,19 +51,19 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )  		for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )  		{ -			char *ns = xt_find_attr( c, "xmlns" ), *room; -			struct xt_node *inv, *reason; +			char *ns = xt_find_attr( c, "xmlns" ); +			struct xt_node *inv;  			if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 &&  			    ( inv = xt_find_node( c->children, "invite" ) ) )  			{ +				/* This is an invitation. Set some vars which +				   will be passed to imcb_chat_invite() below. */  				room = from;  				if( ( from = xt_find_attr( inv, "from" ) ) == NULL )  					from = room; - -				g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room ); -				if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 ) -					g_string_append( fullmsg, reason->text ); +				if( ( inv = xt_find_node( inv->children, "reason" ) ) && inv->text_len > 0 ) +					reason = inv->text;  			}  		} @@ -103,6 +103,8 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )  		if( fullmsg->len > 0 )  			imcb_buddy_msg( ic, from, fullmsg->str,  			                0, jabber_get_timestamp( node ) ); +		if( room ) +			imcb_chat_invite( ic, room, from, reason );  		g_string_free( fullmsg, TRUE ); | 
