diff options
Diffstat (limited to 'protocols/nogaim.c')
| -rw-r--r-- | protocols/nogaim.c | 433 | 
1 files changed, 207 insertions, 226 deletions
| diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 28f76fff..f95ddd8a 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -36,20 +36,6 @@  #define BITLBEE_CORE  #include "nogaim.h"  #include <ctype.h> -#include <iconv.h> - -static char *proto_away_alias[8][5] = -{ -	{ "Away from computer", "Away", "Extended away", NULL }, -	{ "NA", "N/A", "Not available", NULL }, -	{ "Busy", "Do not disturb", "DND", "Occupied", NULL }, -	{ "Be right back", "BRB", NULL }, -	{ "On the phone", "Phone", "On phone", NULL }, -	{ "Out to lunch", "Lunch", "Food", NULL }, -	{ "Invisible", "Hidden" }, -	{ NULL } -}; -static char *proto_away_alias_find( GList *gcm, char *away );  static int remove_chat_buddy_silent( struct conversation *b, char *handle ); @@ -158,83 +144,6 @@ void nogaim_init()  GSList *get_connections() { return connections; } -int proto_away( struct gaim_connection *gc, char *away ) -{ -	GList *m, *ms; -	char *s; -	 -	if( !away ) away = ""; -	ms = m = gc->prpl->away_states( gc ); -	 -	while( m ) -	{ -		if( *away ) -		{ -			if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 ) -				break; -		} -		else -		{ -			if( g_strcasecmp( m->data, "Available" ) == 0 ) -				break; -			if( g_strcasecmp( m->data, "Online" ) == 0 ) -				break; -		} -		m = m->next; -	} -	 -	if( m ) -	{ -		gc->prpl->set_away( gc, m->data, *away ? away : NULL ); -	} -	else -	{ -		s = proto_away_alias_find( ms, away ); -		if( s ) -		{ -			gc->prpl->set_away( gc, s, away ); -			if( set_getint( gc->irc, "debug" ) ) -				serv_got_crap( gc, "Setting away state to %s", s ); -		} -		else -			gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); -	} -	 -	g_list_free( ms ); -	 -	return( 1 ); -} - -static char *proto_away_alias_find( GList *gcm, char *away ) -{ -	GList *m; -	int i, j; -	 -	for( i = 0; *proto_away_alias[i]; i ++ ) -	{ -		for( j = 0; proto_away_alias[i][j]; j ++ ) -			if( g_strncasecmp( away, proto_away_alias[i][j], strlen( proto_away_alias[i][j] ) ) == 0 ) -				break; -		 -		if( !proto_away_alias[i][j] )	/* If we reach the end, this row */ -			continue;		/* is not what we want. Next!    */ -		 -		/* Now find an entry in this row which exists in gcm */ -		for( j = 0; proto_away_alias[i][j]; j ++ ) -		{ -			m = gcm; -			while( m ) -			{ -				if( g_strcasecmp( proto_away_alias[i][j], m->data ) == 0 ) -					return( proto_away_alias[i][j] ); -				m = m->next; -			} -		} -	} -	 -	return( NULL ); -} -  /* multi.c */  struct gaim_connection *new_gaim_conn( struct aim_user *user ) @@ -305,38 +214,29 @@ void hide_login_progress_error( struct gaim_connection *gc, char *msg )  void serv_got_crap( struct gaim_connection *gc, char *format, ... )  {  	va_list params; -	char text[1024], buf[1024], *acc_id; -	char *msg; +	char *text;  	account_t *a;  	va_start( params, format ); -	g_vsnprintf( text, sizeof( text ), format, params ); +	text = g_strdup_vprintf( format, params );  	va_end( params ); -	if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( "UTF8", set_getstr( gc->irc, "charset" ), text, buf, 0, 1024 ) != -1 ) -		msg = buf; -	else -		msg = text; -	  	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||  	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) ) -		strip_html( msg ); +		strip_html( text );  	/* Try to find a different connection on the same protocol. */  	for( a = gc->irc->accounts; a; a = a->next )  		if( a->prpl == gc->prpl && a->gc != gc )  			break; -	/* If we found one, add the screenname to the acc_id. */ +	/* If we found one, include the screenname in the message. */  	if( a ) -		acc_id = g_strdup_printf( "%s(%s)", gc->prpl->name, gc->username ); +		irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text );  	else -		acc_id = g_strdup( gc->prpl->name ); +		irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text ); -	irc_usermsg( gc->irc, "%s - %s", acc_id, msg ); -	 -	g_free( acc_id ); +	g_free( text );  }  static gboolean send_keepalive( gpointer d ) @@ -368,18 +268,7 @@ void account_online( struct gaim_connection *gc )  	/* Also necessary when we're not away, at least for some of the  	   protocols. */ -	proto_away( gc, u->away ); -	 - 	if( strcmp( gc->prpl->name, "ICQ" ) == 0 ) -	{ -		for( u = gc->irc->users; u; u = u->next ) -			if( u->gc == gc ) -				break; -		 -		if( u == NULL ) -			serv_got_crap( gc, "\x02""***\x02"" BitlBee now supports ICQ server-side contact lists. " -			                      "See \x02""help import_buddies\x02"" for more information." ); -	} +	bim_set_away( gc, u->away );  }  gboolean auto_reconnect( gpointer data ) @@ -398,12 +287,6 @@ void cancel_auto_reconnect( account_t *a )  	a->reconnect = 0;  } -void account_offline( struct gaim_connection *gc ) -{ -	gc->wants_to_die = TRUE; -	signoff( gc ); -} -  void signoff( struct gaim_connection *gc )  {  	irc_t *irc = gc->irc; @@ -411,7 +294,8 @@ void signoff( struct gaim_connection *gc )  	account_t *a;  	serv_got_crap( gc, "Signing off.." ); - +	gc->flags |= OPT_LOGGING_OUT; +	  	gaim_input_remove( gc->keepalive );  	gc->keepalive = 0;  	gc->prpl->close( gc ); @@ -509,7 +393,14 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea  	}  	else if( gc->user->proto_opt[0] && *gc->user->proto_opt[0] )  	{ -		u->host = g_strdup( gc->user->proto_opt[0] ); +		char *colon; +		 +		if( ( colon = strchr( gc->user->proto_opt[0], ':' ) ) ) +			u->host = g_strndup( gc->user->proto_opt[0], +			                     colon - gc->user->proto_opt[0] ); +		else +			u->host = g_strdup( gc->user->proto_opt[0] ); +		  		u->user = g_strdup( handle );  		/* s/ /_/ ... important for AOL screennames */ @@ -558,22 +449,14 @@ void signoff_blocked( struct gaim_connection *gc )  void serv_buddy_rename( struct gaim_connection *gc, char *handle, char *realname )  {  	user_t *u = user_findhandle( gc, handle ); -	char *name, buf[1024];  	if( !u ) return; -	/* Convert all UTF-8 */ -	if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( "UTF-8", set_getstr( gc->irc, "charset" ), realname, buf, 0, sizeof( buf ) ) != -1 ) -		name = buf; -	else -		name = realname; -	 -	if( g_strcasecmp( u->realname, name ) != 0 ) +	if( g_strcasecmp( u->realname, realname ) != 0 )  	{  		if( u->realname != u->nick ) g_free( u->realname ); -		u->realname = g_strdup( name ); +		u->realname = g_strdup( realname );  		if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) )  			serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname ); @@ -583,9 +466,40 @@ void serv_buddy_rename( struct gaim_connection *gc, char *handle, char *realname  /* prpl.c */ -void show_got_added( struct gaim_connection *gc, char *id, char *handle, const char *realname, const char *msg ) +struct show_got_added_data  { -	return; +	struct gaim_connection *gc; +	char *handle; +}; + +void show_got_added_no( gpointer w, struct show_got_added_data *data ) +{ +	g_free( data->handle ); +	g_free( data ); +} + +void show_got_added_yes( gpointer w, struct show_got_added_data *data ) +{ +	data->gc->prpl->add_buddy( data->gc, data->handle ); +	add_buddy( data->gc, NULL, data->handle, data->handle ); +	 +	return show_got_added_no( w, data ); +} + +void show_got_added( struct gaim_connection *gc, char *handle, const char *realname ) +{ +	struct show_got_added_data *data = g_new0( struct show_got_added_data, 1 ); +	char *s; +	 +	/* TODO: Make a setting for this! */ +	if( user_findhandle( gc, handle ) != NULL ) +		return; +	 +	s = g_strdup_printf( "The user %s is not in your buddy list yet. Do you want to add him/her now?", handle ); +	 +	data->gc = gc; +	data->handle = g_strdup( handle ); +	query_add( gc->irc, gc, s, show_got_added_yes, show_got_added_no, data );  } @@ -615,7 +529,8 @@ void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, in  			return;  		} -		return; +		/* Why did we have this here.... +		return; */  	}  	oa = u->away != NULL; @@ -679,7 +594,6 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f  {  	irc_t *irc = gc->irc;  	user_t *u; -	char buf[8192];  	u = user_findhandle( gc, handle ); @@ -721,10 +635,6 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f  	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )  		strip_html( msg ); -	if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( "UTF-8", set_getstr( irc, "charset" ), msg, buf, 0, 8192 ) != -1 ) -		msg = buf; -	  	while( strlen( msg ) > 425 )  	{  		char tmp, *nl; @@ -821,7 +731,6 @@ void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whispe  {  	struct conversation *c;  	user_t *u; -	char buf[8192];  	/* Gaim sends own messages through this too. IRC doesn't want this, so kill them */  	if( g_strcasecmp( who, gc->user->username ) == 0 ) @@ -834,10 +743,6 @@ void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whispe  	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )  		strip_html( msg ); -	if( g_strncasecmp( set_getstr( gc->irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( "UTF-8", set_getstr( gc->irc, "charset" ), msg, buf, 0, 8192 ) != -1 ) -		msg = buf; -	  	if( c && u )  		irc_privmsg( gc->irc, u, "PRIVMSG", c->channel, "", msg );  	else @@ -958,20 +863,6 @@ static int remove_chat_buddy_silent( struct conversation *b, char *handle )  } -/* prefs.c */ - -/* Necessary? */ -void build_block_list() -{ -	return; -} - -void build_allow_list() -{ -	return; -} - -  /* Misc. BitlBee stuff which shouldn't really be here */  struct conversation *conv_findchannel( char *channel ) @@ -1050,89 +941,179 @@ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )  	return( set_eval_bool( irc, set, value ) );  } -int serv_send_im( irc_t *irc, user_t *u, char *msg, int flags ) + + + +/* The plan is to not allow straight calls to prpl functions anymore, but do +   them all from some wrappers. We'll start to define some down here: */ + +int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flags )  { -	char buf[8192]; +	char *buf = NULL; +	int st; -	if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( set_getstr( irc, "charset" ), "UTF-8", msg, buf, 0, 8192 ) != -1 ) -		msg = buf; - -	if( ( u->gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) +	if( ( gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )  	{ -		char *html; -		 -		html = escape_html( msg ); -		strncpy( buf, html, 8192 ); -		g_free( html ); -		 +		buf = escape_html( msg );  		msg = buf;  	} -	return( ((struct gaim_connection *)u->gc)->prpl->send_im( u->gc, u->handle, msg, strlen( msg ), flags ) ); +	st = gc->prpl->send_im( gc, handle, msg, strlen( msg ), flags ); +	g_free( buf ); +	 +	return st;  } -int serv_send_chat( irc_t *irc, struct gaim_connection *gc, int id, char *msg ) +int bim_chat_msg( struct gaim_connection *gc, int id, char *msg )  { -	char buf[8192]; +	char *buf = NULL; +	int st; -	if( g_strncasecmp( set_getstr( irc, "charset" ), "none", 4 ) != 0 && -	    do_iconv( set_getstr( irc, "charset" ), "UTF-8", msg, buf, 0, 8192 ) != -1 ) +	if( ( gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) +	{ +		buf = escape_html( msg );  		msg = buf; - -	if( gc->flags & OPT_CONN_HTML) { -		char * html = escape_html(msg); -		strncpy(buf, html, 8192); -		g_free(html);  	} -	return( gc->prpl->chat_send( gc, id, msg ) ); +	st = gc->prpl->chat_send( gc, id, msg ); +	g_free( buf ); +	 +	return st;  } -/* Convert from one charset to another. -    -   from_cs, to_cs: Source and destination charsets -   src, dst: Source and destination strings -   size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though. -   maxbuf: Maximum number of bytes to write to dst -    -   Returns the number of bytes written to maxbuf or -1 on an error. -*/ -signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf ) +static char *bim_away_alias_find( GList *gcm, char *away ); + +int bim_set_away( struct gaim_connection *gc, char *away )  { -	iconv_t cd; -	size_t res; -	size_t inbytesleft, outbytesleft; -	char *inbuf = src; -	char *outbuf = dst; -	 -	cd = iconv_open( to_cs, from_cs ); -	if( cd == (iconv_t) -1 ) -		return( -1 ); -	 -	inbytesleft = size ? size : strlen( src ); -	outbytesleft = maxbuf - 1; -	res = iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); -	*outbuf = '\0'; -	iconv_close( cd ); -	 -	if( res == (size_t) -1 ) -		return( -1 ); +	GList *m, *ms; +	char *s; +	 +	if( !away ) away = ""; +	ms = m = gc->prpl->away_states( gc ); +	 +	while( m ) +	{ +		if( *away ) +		{ +			if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 ) +				break; +		} +		else +		{ +			if( g_strcasecmp( m->data, "Available" ) == 0 ) +				break; +			if( g_strcasecmp( m->data, "Online" ) == 0 ) +				break; +		} +		m = m->next; +	} +	 +	if( m ) +	{ +		gc->prpl->set_away( gc, m->data, *away ? away : NULL ); +	}  	else -		return( outbuf - dst ); +	{ +		s = bim_away_alias_find( ms, away ); +		if( s ) +		{ +			gc->prpl->set_away( gc, s, away ); +			if( set_getint( gc->irc, "debug" ) ) +				serv_got_crap( gc, "Setting away state to %s", s ); +		} +		else +			gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); +	} +	 +	g_list_free( ms ); +	 +	return( 1 );  } -char *set_eval_charset( irc_t *irc, set_t *set, char *value ) +static char *bim_away_alias_list[8][5] =  { -	iconv_t cd; +	{ "Away from computer", "Away", "Extended away", NULL }, +	{ "NA", "N/A", "Not available", NULL }, +	{ "Busy", "Do not disturb", "DND", "Occupied", NULL }, +	{ "Be right back", "BRB", NULL }, +	{ "On the phone", "Phone", "On phone", NULL }, +	{ "Out to lunch", "Lunch", "Food", NULL }, +	{ "Invisible", "Hidden" }, +	{ NULL } +}; -	if ( g_strncasecmp( value, "none", 4 ) == 0 ) -		return( value ); +static char *bim_away_alias_find( GList *gcm, char *away ) +{ +	GList *m; +	int i, j; +	 +	for( i = 0; *bim_away_alias_list[i]; i ++ ) +	{ +		for( j = 0; bim_away_alias_list[i][j]; j ++ ) +			if( g_strncasecmp( away, bim_away_alias_list[i][j], strlen( bim_away_alias_list[i][j] ) ) == 0 ) +				break; +		 +		if( !bim_away_alias_list[i][j] )	/* If we reach the end, this row */ +			continue;			/* is not what we want. Next!    */ +		 +		/* Now find an entry in this row which exists in gcm */ +		for( j = 0; bim_away_alias_list[i][j]; j ++ ) +		{ +			m = gcm; +			while( m ) +			{ +				if( g_strcasecmp( bim_away_alias_list[i][j], m->data ) == 0 ) +					return( bim_away_alias_list[i][j] ); +				m = m->next; +			} +		} +	} +	 +	return( NULL ); +} -	cd = iconv_open( "UTF-8", value ); -	if( cd == (iconv_t) -1 ) -		return( NULL ); +void bim_add_allow( struct gaim_connection *gc, char *handle ) +{ +	if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) +	{ +		gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) ); +	} +	 +	gc->prpl->add_permit( gc, handle ); +} -	iconv_close( cd ); -	return( value ); +void bim_rem_allow( struct gaim_connection *gc, char *handle ) +{ +	GSList *l; +	 +	if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) +	{ +		g_free( l->data ); +		gc->permit = g_slist_delete_link( gc->permit, l ); +	} +	 +	gc->prpl->rem_permit( gc, handle ); +} + +void bim_add_block( struct gaim_connection *gc, char *handle ) +{ +	if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) +	{ +		gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) ); +	} +	 +	gc->prpl->add_deny( gc, handle ); +} + +void bim_rem_block( struct gaim_connection *gc, char *handle ) +{ +	GSList *l; +	 +	if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) +	{ +		g_free( l->data ); +		gc->deny = g_slist_delete_link( gc->deny, l ); +	} +	 +	gc->prpl->rem_deny( gc, handle );  } | 
