diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2007-04-22 13:44:27 -0700 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2007-04-22 13:44:27 -0700 | 
| commit | e35d1a121d5fb2da3698fbe4a365fe38d0097665 (patch) | |
| tree | 390223f2df5aaaebb35c1bb118cbf2fbd69ecab9 /protocols | |
| parent | c737ba70c7b3510ffb6bed8f9373e63b1a150c1b (diff) | |
Read-only support for Jabber conferences (non-anonymous rooms only).
Just don't use this, you're really not going to like it. :-)
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/jabber/Makefile | 2 | ||||
| -rw-r--r-- | protocols/jabber/conference.c | 193 | ||||
| -rw-r--r-- | protocols/jabber/jabber.c | 22 | ||||
| -rw-r--r-- | protocols/jabber/jabber.h | 26 | ||||
| -rw-r--r-- | protocols/jabber/jabber_util.c | 35 | ||||
| -rw-r--r-- | protocols/jabber/message.c | 13 | ||||
| -rw-r--r-- | protocols/jabber/presence.c | 29 | ||||
| -rw-r--r-- | protocols/jabber/xmltree.c | 2 | ||||
| -rw-r--r-- | protocols/msn/sb.c | 2 | ||||
| -rw-r--r-- | protocols/nogaim.c | 21 | ||||
| -rw-r--r-- | protocols/nogaim.h | 6 | ||||
| -rw-r--r-- | protocols/oscar/oscar.c | 2 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo.c | 14 | 
13 files changed, 329 insertions, 38 deletions
| diff --git a/protocols/jabber/Makefile b/protocols/jabber/Makefile index 3c9e4949..1d5368b1 100644 --- a/protocols/jabber/Makefile +++ b/protocols/jabber/Makefile @@ -9,7 +9,7 @@  -include ../../Makefile.settings  # [SH] Program variables -objects = io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o +objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o  CFLAGS += -Wall  LFLAGS += -r diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c new file mode 100644 index 00000000..ffc4f844 --- /dev/null +++ b/protocols/jabber/conference.c @@ -0,0 +1,193 @@ +/***************************************************************************\ +*                                                                           * +*  BitlBee - An IRC to IM gateway                                           * +*  Jabber module - Conference rooms                                         * +*                                                                           * +*  Copyright 2007 Wilmer van der Gaast <wilmer@gaast.net>                   * +*                                                                           * +*  This program is free software; you can redistribute it and/or modify     * +*  it under the terms of the GNU General Public License as published by     * +*  the Free Software Foundation; either version 2 of the License, or        * +*  (at your option) any later version.                                      * +*                                                                           * +*  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            * +*  GNU General Public License for more details.                             * +*                                                                           * +*  You should have received a copy of the GNU General Public License along  * +*  with this program; if not, write to the Free Software Foundation, Inc.,  * +*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              * +*                                                                           * +\***************************************************************************/ + +#include "jabber.h" + +struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password ) +{ +	struct jabber_chat *jc; +	struct xt_node *node; +	struct groupchat *c; +	char *roomjid; +	 +	roomjid = g_strdup_printf( "%s/%s", room, nick ); +	node = xt_new_node( "x", NULL, NULL ); +	xt_add_attr( node, "xmlns", XMLNS_MUC ); +	node = jabber_make_packet( "presence", NULL, roomjid, node ); +	 +	if( !jabber_write_packet( ic, node ) ) +	{ +		g_free( roomjid ); +		xt_free_node( node ); +		return NULL; +	} +	xt_free_node( node ); +	 +	jc = g_new0( struct jabber_chat, 1 ); +	jc->name = jabber_normalize( room ); +	 +	if( ( jc->me = jabber_buddy_add( ic, roomjid ) ) == NULL ) +	{ +		g_free( roomjid ); +		g_free( jc->name ); +		g_free( jc ); +		return NULL; +	} +	g_free( roomjid ); +	 +	c = imcb_chat_new( ic, room ); +	c->data = jc; +	 +	return c; +} + +int jabber_chat_leave( struct groupchat *c, const char *reason ) +{ +	struct im_connection *ic = c->ic; +	struct jabber_chat *jc = c->data; +	struct xt_node *node; +	 +	node = xt_new_node( "x", NULL, NULL ); +	xt_add_attr( node, "xmlns", XMLNS_MUC ); +	node = jabber_make_packet( "presence", "unavailable", jc->me->full_jid, node ); +	 +	if( !jabber_write_packet( ic, node ) ) +	{ +		xt_free_node( node ); +		return 0; +	} +	xt_free_node( node ); +	 +	/* Remove all participants from jc->buddies and clean up our data. */ +	jabber_buddy_remove_bare( ic, jc->name ); +	g_free( jc->name ); +	g_free( jc ); +	 +	/* And the generic stuff. */ +	imcb_chat_free( c ); +	 +	return 1; +} + +/* Not really the same syntax as the normal pkt_ functions, but this isn't +   called by the xmltree parser exactly and this way I can add some extra +   parameters so we won't have to repeat too many things done by the caller +   already. */ +void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ) +{ +	struct groupchat *chat; +	struct xt_node *c; +	char *type = xt_find_attr( node, "type" ); +	struct jabber_chat *jc; +	char *s; +	 +	if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL ) +	{ +		/* How could this happen?? We could do kill( self, 11 ) +		   now or just wait for the OS to do it. :-) */ +		return; +	} +	 +	jc = chat->data; +	 +	if( type == NULL && !( bud->flags & JBFLAG_IS_CHATROOM ) ) +	{ +		bud->flags |= JBFLAG_IS_CHATROOM; +		/* If this one wasn't set yet, this buddy just joined the chat. +		   Slightly hackish way of finding out eh? ;-) */ +		 +		/* This is pretty messy... */ +		for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next ) +			if( ( s = xt_find_attr( c, "xmlns" ) ) && +			    ( strcmp( s, XMLNS_MUC_USER ) == 0 ) ) +			{ +				c = xt_find_node( c->children, "item" ); +				if( ( s = xt_find_attr( c, "jid" ) ) ) +				{ +					/* Yay, found what we need. :-) */ +					bud->orig_jid = g_strdup( s ); +					break; +				} +			} +		 +		/* Won't handle this for now. */ +		if( bud->orig_jid == NULL ) +			return; +		 +		s = strchr( bud->orig_jid, '/' ); +		if( s ) *s = 0; /* Should NEVER be NULL, but who knows... */ +		imcb_chat_add_buddy( chat, bud->orig_jid ); +		if( s ) *s = '/'; +	} +	else if( type ) /* This only gets called if type=="unavailable" */ +	{ +		/* Won't handle this for now. */ +		if( bud->orig_jid == NULL ) +			return; +		s = strchr( bud->orig_jid, '/' ); +		if( s ) *s = 0; /* Should NEVER be NULL, but who knows... */ +		imcb_chat_remove_buddy( chat, bud->orig_jid, NULL ); +		if( s ) *s = '/'; +		 +		if( bud == jc->me ) +		{ +			g_free( jc->name ); +			g_free( jc ); +			imcb_chat_free( chat ); +		} +	} +} + +void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ) +{ +	struct xt_node *body = xt_find_node( node->children, "body" ); +	struct groupchat *chat; +	char *s; +	 +	if( bud == NULL ) +	{ +		s = xt_find_attr( node, "from" ); /* pkt_message() already NULL-checked this one. */ +		if( strchr( s, '/' ) == NULL ) +			/* This is fine, the groupchat itself isn't in jd->buddies. */ +			imcb_log( ic, "System message from groupchat %s: %s", s, body? body->text : "NULL" ); +		else +			/* This, however, isn't fine! */ +			imcb_log( ic, "Groupchat message from unknown participant %s: %s", s, body ? body->text : "NULL" ); +		 +		return; +	} +	else if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL ) +	{ +		/* How could this happen?? We could do kill( self, 11 ) +		   now or just wait for the OS to do it. :-) */ +		return; +	} +	 +	if( body && body->text_len > 0 ) +	{ +		s = strchr( bud->orig_jid, '/' ); +		if( s ) *s = 0; +		imcb_chat_msg( chat, bud->orig_jid, body->text, 0, 0 ); +		if( s ) *s = '/'; +	} +} diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index edad5dbd..f9473015 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -323,6 +323,24 @@ static void jabber_remove_buddy( struct im_connection *ic, char *who, char *grou  		presence_send_request( ic, who, "unsubscribe" );  } +static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password ) +{ +	if( strchr( room, '@' ) == NULL ) +		imcb_error( ic, "Invalid room name: %s", room ); +	else if( jabber_chat_by_name( ic, room ) ) +		imcb_error( ic, "Already present in chat `%s'", room ); +	else +		return jabber_chat_join( ic, room, nick, password ); +	 +	return NULL; +} + +static void jabber_chat_leave_( struct groupchat *c ) +{ +	if( c ) +		jabber_chat_leave( c, NULL ); +} +  static void jabber_keepalive( struct im_connection *ic )  {  	/* Just any whitespace character is enough as a keepalive for XMPP sessions. */ @@ -395,8 +413,8 @@ void jabber_initmodule()  	ret->remove_buddy = jabber_remove_buddy;  //	ret->chat_msg = jabber_chat_msg;  //	ret->chat_invite = jabber_chat_invite; -//	ret->chat_leave = jabber_chat_leave; -//	ret->chat_open = jabber_chat_open; +	ret->chat_leave = jabber_chat_leave_; +	ret->chat_join = jabber_chat_join_;  	ret->keepalive = jabber_keepalive;  	ret->send_typing = jabber_send_typing;  	ret->handle_cmp = g_strcasecmp; diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 42f57ae1..dd771910 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -49,6 +49,8 @@ typedef enum  	                                   sure it gets sent only once. */  	JBFLAG_DOES_XEP85 = 2,		/* Set this when the resource seems to support  	                                   XEP85 (typing notification shite). */ +	JBFLAG_IS_CHATROOM = 4,		/* It's convenient to use this JID thingy for +	                                   groupchat state info too. */  } jabber_buddy_flags_t;  #define JABBER_PORT_DEFAULT "5222" @@ -100,6 +102,9 @@ struct jabber_buddy  	char *full_jid;  	char *resource; +	/* Groupchat-only */ +	char *orig_jid; +	  	int priority;  	struct jabber_away_state *away_state;  	char *away_message; @@ -110,6 +115,13 @@ struct jabber_buddy  	struct jabber_buddy *next;  }; +struct jabber_chat +{ +	int flags; +	char *name; +	struct jabber_buddy *me; +}; +  /* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the     first one should be used, but when storing a packet in the cache, a     "special" kind of ID is assigned to make it easier later to figure out @@ -133,6 +145,8 @@ struct jabber_buddy  #define XMLNS_VCARD        "vcard-temp"                         /* XEP-0054 */  #define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"  /* 0085 */  #define XMLNS_DISCOVER     "http://jabber.org/protocol/disco#info"  /* 0030 */ +#define XMLNS_MUC          "http://jabber.org/protocol/muc"     /* XEP-0045 */ +#define XMLNS_MUC_USER     "http://jabber.org/protocol/muc#user"/* XEP-0045 */  /* iq.c */  xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ); @@ -163,18 +177,20 @@ void jabber_cache_clean( struct im_connection *ic );  const struct jabber_away_state *jabber_away_state_by_code( char *code );  const struct jabber_away_state *jabber_away_state_by_name( char *name );  void jabber_buddy_ask( struct im_connection *ic, char *handle ); -char *jabber_normalize( char *orig ); +char *jabber_normalize( const char *orig );  typedef enum  {  	GET_BUDDY_CREAT = 1,	/* Try to create it, if necessary. */ -	GET_BUDDY_EXACT = 2,	/* Get an exact message (only makes sense with bare JIDs). */ +	GET_BUDDY_EXACT = 2,	/* Get an exact match (only makes sense with bare JIDs). */ +	GET_BUDDY_FIRST = 4,	/* No selection, simply get the first resource for this JID. */  } get_buddy_flags_t;  struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );  struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );  int jabber_buddy_remove( struct im_connection *ic, char *full_jid );  int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ); +struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );  extern const struct jabber_away_state jabber_away_state_list[]; @@ -192,4 +208,10 @@ xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data );  xt_status sasl_pkt_result( struct xt_node *node, gpointer data );  gboolean sasl_supported( struct im_connection *ic ); +/* conference.c */ +struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password ); +int jabber_chat_leave( struct groupchat *c, const char *reason ); +void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ); +void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ); +  #endif diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 3c0e71f4..86ddf7bc 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -47,7 +47,7 @@ char *set_eval_priority( set_t *set, char *value )  		   convenient, they have one disadvantage: If I would just  		   call p_s_u() now to send the new prio setting, it would  		   send the old setting because the set->value gets changed -		   when the eval returns a non-NULL value. +		   after the (this) eval returns a non-NULL value.  		   So now I can choose between implementing post-set  		   functions next to evals, or just do this little hack: */ @@ -128,7 +128,7 @@ struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond,  /* Cache a node/packet for later use. Mainly useful for IQ packets if you need     them when you receive the response. Use this BEFORE sending the packet so -   it'll get a new id= tag, and do NOT free() the packet after writing it! */ +   it'll get a new id= tag, and do NOT free() the packet after sending it! */  void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func )  {  	struct jabber_data *jd = ic->proto_data; @@ -251,7 +251,7 @@ void jabber_buddy_ask( struct im_connection *ic, char *handle )  }  /* Returns a new string. Don't leak it! */ -char *jabber_normalize( char *orig ) +char *jabber_normalize( const char *orig )  {  	int len, i;  	char *new; @@ -352,6 +352,8 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  	if( ( s = strchr( jid, '/' ) ) )  	{ +		int none_found = 0; +		  		*s = 0;  		if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )  		{ @@ -369,8 +371,16 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_,  						break;  			}  		} +		else +		{ +			/* This hack is there to make sure that O_CREAT will +			   work if there's already another resouce present +			   for this JID, even if it's an unknown buddy. This +			   is done to handle conferences properly. */ +			none_found = 1; +		} -		if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid ) ) +		if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) )  		{  			*s = '/';  			bud = jabber_buddy_add( ic, jid ); @@ -530,3 +540,20 @@ int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid_ )  		return 0;  	}  } + +struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name ) +{ +	char *normalized = jabber_normalize( name ); +	struct groupchat *ret; +	struct jabber_chat *jc; +	 +	for( ret = ic->groupchats; ret; ret = ret->next ) +	{ +		jc = ret->data; +		if( strcmp( normalized, jc->name ) == 0 ) +			break; +	} +	g_free( normalized ); +	 +	return ret; +} diff --git a/protocols/jabber/message.c b/protocols/jabber/message.c index 19edbdfd..8a4ecaf4 100644 --- a/protocols/jabber/message.c +++ b/protocols/jabber/message.c @@ -29,24 +29,29 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )  	char *from = xt_find_attr( node, "from" );  	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; +	if( !from ) +		return XT_HANDLED; /* Consider this packet corrupted. */ +	 +	bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ); +	  	if( type && strcmp( type, "error" ) == 0 )  	{  		/* Handle type=error packet. */  	} -	else if( type && strcmp( type, "groupchat" ) == 0 ) +	else if( type && from && strcmp( type, "groupchat" ) == 0 )  	{ -		/* TODO! */ +		jabber_chat_pkt_message( ic, bud, node );  	}  	else /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */  	{ -		struct jabber_buddy *bud = NULL;  		GString *fullmsg = g_string_new( "" );  		if( ( s = strchr( from, '/' ) ) )  		{ -			if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) ) +			if( bud )  				bud->last_act = time( NULL );  			else  				*s = 0; /* We need to generate a bare JID now. */ diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c index ef92740a..096b4fd5 100644 --- a/protocols/jabber/presence.c +++ b/protocols/jabber/presence.c @@ -30,11 +30,20 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )  	char *type = xt_find_attr( node, "type" );	/* NULL should mean the person is online. */  	struct xt_node *c;  	struct jabber_buddy *bud; +	int is_chat = 0;  	char *s;  	if( !from )  		return XT_HANDLED; +	if( ( s = strchr( from, '/' ) ) ) +	{ +		*s = 0; +		if( jabber_chat_by_name( ic, from ) ) +			is_chat = 1; +		*s = '/'; +	} +	  	if( type == NULL )  	{  		int is_away = 0; @@ -71,23 +80,35 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )  		else  			bud->priority = 0; -		if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) ) +		if( is_chat ) +			jabber_chat_pkt_presence( ic, bud, node ); +		else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )  			imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,  			                   ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,  			                   bud->away_message );  	}  	else if( strcmp( type, "unavailable" ) == 0 )  	{ -		if( jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) == NULL ) +		if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )  		{  			if( set_getbool( &ic->irc->set, "debug" ) )  				imcb_log( ic, "WARNING: Received presence information from unknown JID: %s", from );  			return XT_HANDLED;  		} +		/* Handle this before we delete the JID. */ +		if( is_chat ) +		{ +			jabber_chat_pkt_presence( ic, bud, node ); +		} +		  		jabber_buddy_remove( ic, from ); -		if( ( s = strchr( from, '/' ) ) ) +		if( is_chat ) +		{ +			/* Nothing else to do for now? */ +		} +		else if( ( s = strchr( from, '/' ) ) )  		{  			*s = 0; @@ -95,6 +116,8 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )  			   available anymore. */  			if( jabber_buddy_by_jid( ic, from, 0 ) == NULL )  				imcb_buddy_status( ic, from, 0, NULL, NULL ); +			/* FIXME: If this resource was not away and another resource is, +			   we should definitely send an update here. */  			*s = '/';  		} diff --git a/protocols/jabber/xmltree.c b/protocols/jabber/xmltree.c index 7a165a1e..c8bef362 100644 --- a/protocols/jabber/xmltree.c +++ b/protocols/jabber/xmltree.c @@ -187,6 +187,8 @@ int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth )  						/* If there's no parent, the handler should mention <root> as a parent. */  			                       g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )  			{ +				xt_print( node ); +				  				st = xt->handlers[i].func( node, xt->data );  				if( st == XT_ABORT ) diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 1693cb95..cb9e2cab 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -231,7 +231,7 @@ void msn_sb_destroy( struct msn_switchboard *sb )  	if( sb->chat )  	{ -		imcb_chat_removed( sb->chat ); +		imcb_chat_free( sb->chat );  	}  	if( sb->handler ) diff --git a/protocols/nogaim.c b/protocols/nogaim.c index a70d6eca..f3dbb0b8 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -553,8 +553,8 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags,  		irc_kill( ic->irc, u );  		u->online = 0; -		/* Remove him/her from the conversations to prevent PART messages after he/she QUIT already */ -		for( c = ic->conversations; c; c = c->next ) +		/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ +		for( c = ic->groupchats; c; c = c->next )  			remove_chat_buddy_silent( c, (char*) handle );  	} @@ -684,10 +684,10 @@ void imcb_buddy_typing( struct im_connection *ic, char *handle, u_int32_t flags  	}  } -void imcb_chat_removed( struct groupchat *c ) +void imcb_chat_free( struct groupchat *c )  {  	struct im_connection *ic = c->ic; -	struct groupchat *l = NULL; +	struct groupchat *l;  	GList *ir;  	if( set_getbool( &ic->irc->set, "debug" ) ) @@ -707,10 +707,13 @@ void imcb_chat_removed( struct groupchat *c )  			/* irc_part( ic->irc, u, c->channel ); */  		} +		/* Find the previous chat in the linked list. */ +		for( l = ic->groupchats; l && l->next != c; l = l->next ); +		  		if( l )  			l->next = c->next;  		else -			ic->conversations = c->next; +			ic->groupchats = c->next;  		for( ir = c->in_room; ir; ir = ir->next )  			g_free( ir->data ); @@ -748,13 +751,13 @@ struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )  	/* This one just creates the conversation structure, user won't see anything yet */ -	if( ic->conversations ) +	if( ic->groupchats )  	{ -		for( c = ic->conversations; c->next; c = c->next ); +		for( c = ic->groupchats; c->next; c = c->next );  		c = c->next = g_new0( struct groupchat, 1 );  	}  	else -		ic->conversations = c = g_new0( struct groupchat, 1 ); +		ic->groupchats = c = g_new0( struct groupchat, 1 );  	c->ic = ic;  	c->title = g_strdup( handle ); @@ -862,7 +865,7 @@ struct groupchat *chat_by_channel( char *channel )  	for( l = connections; l; l = l->next )  	{  		ic = l->data; -		for( c = ic->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next ); +		for( c = ic->groupchats; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );  		if( c )  			return c;  	} diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 59f9e870..b26cf73e 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -90,17 +90,15 @@ struct im_connection  	/* BitlBee */  	irc_t *irc; -	struct groupchat *conversations; +	struct groupchat *groupchats;  };  struct groupchat {  	struct im_connection *ic; -	/* stuff used just for chat */  	GList *in_room;  	GList *ignored; -	/* BitlBee */  	struct groupchat *next;  	char *channel;  	char *title; @@ -207,7 +205,7 @@ G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char  G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle );  G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason );  G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, char *who, char *msg, u_int32_t flags, time_t sent_at ); -G_MODULE_EXPORT void imcb_chat_removed( struct groupchat *c ); +G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );  struct groupchat *chat_by_channel( char *channel );  /* Actions, or whatever. */ diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 0c175df6..b72c683a 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -2512,7 +2512,7 @@ void oscar_chat_kill(struct im_connection *ic, struct chat_connection *cc)  	struct oscar_data *od = (struct oscar_data *)ic->proto_data;  	/* Notify the conversation window that we've left the chat */ -	imcb_chat_removed(cc->cnv); +	imcb_chat_free(cc->cnv);  	/* Destroy the chat_connection */  	od->oscar_chats = g_slist_remove(od->oscar_chats, cc); diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 69fc29bb..28a72877 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -144,8 +144,8 @@ static void byahoo_logout( struct im_connection *ic )  	struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;  	GSList *l; -	while( ic->conversations ) -		imcb_chat_removed( ic->conversations ); +	while( ic->groupchats ) +		imcb_chat_free( ic->groupchats );  	for( l = yd->buddygroups; l; l = l->next )  	{ @@ -317,7 +317,7 @@ static void byahoo_chat_leave( struct groupchat *c )  	struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data;  	yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title ); -	imcb_chat_removed( c ); +	imcb_chat_free( c );  }  static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who ) @@ -797,7 +797,7 @@ static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv )  static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv )  {  	yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" ); -	imcb_chat_removed( inv->c ); +	imcb_chat_free( inv->c );  	g_free( inv->name );  	g_free( inv );  } @@ -840,7 +840,7 @@ void ext_yahoo_conf_userjoin( int id, const char *ignored, const char *who, cons  	struct im_connection *ic = byahoo_get_ic_by_id( id );  	struct groupchat *c; -	for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next ); +	for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );  	if( c )  		imcb_chat_add_buddy( c, (char*) who ); @@ -852,7 +852,7 @@ void ext_yahoo_conf_userleave( int id, const char *ignored, const char *who, con  	struct im_connection *ic = byahoo_get_ic_by_id( id );  	struct groupchat *c; -	for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next ); +	for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );  	if( c )  		imcb_chat_remove_buddy( c, (char*) who, "" ); @@ -864,7 +864,7 @@ void ext_yahoo_conf_message( int id, const char *ignored, const char *who, const  	char *m = byahoo_strip( msg );  	struct groupchat *c; -	for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next ); +	for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );  	if( c )  		imcb_chat_msg( c, (char*) who, (char*) m, 0, 0 ); | 
