diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/http_client.c | 115 | ||||
| -rw-r--r-- | protocols/http_client.h | 3 | ||||
| -rw-r--r-- | protocols/jabber/jabber.c | 41 | ||||
| -rw-r--r-- | protocols/jabber/xmlparse.c | 25 | ||||
| -rw-r--r-- | protocols/msn/msn_util.c | 3 | ||||
| -rw-r--r-- | protocols/msn/ns.c | 9 | ||||
| -rw-r--r-- | protocols/msn/passport.c | 32 | ||||
| -rw-r--r-- | protocols/msn/passport.h | 1 | ||||
| -rw-r--r-- | protocols/msn/sb.c | 10 | ||||
| -rw-r--r-- | protocols/msn/tables.c | 2 | ||||
| -rw-r--r-- | protocols/nogaim.c | 433 | ||||
| -rw-r--r-- | protocols/nogaim.h | 132 | ||||
| -rw-r--r-- | protocols/oscar/aim.h | 7 | ||||
| -rw-r--r-- | protocols/oscar/chat.c | 16 | ||||
| -rw-r--r-- | protocols/oscar/im.c | 2 | ||||
| -rw-r--r-- | protocols/oscar/oscar.c | 28 | ||||
| -rw-r--r-- | protocols/oscar/oscar_util.c | 4 | ||||
| -rw-r--r-- | protocols/oscar/service.c | 5 | ||||
| -rw-r--r-- | protocols/ssl_nss.c | 12 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo.c | 10 | 
20 files changed, 459 insertions, 431 deletions
| diff --git a/protocols/http_client.c b/protocols/http_client.c index 9417e200..c793d9d4 100644 --- a/protocols/http_client.c +++ b/protocols/http_client.c @@ -70,6 +70,37 @@ void *http_dorequest( char *host, int port, int ssl, char *request, http_input_f  	return( req );  } +void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ) +{ +	url_t *url = g_new0( url_t, 1 ); +	char *request; +	void *ret; +	 +	if( !url_set( url, url_string ) ) +	{ +		g_free( url ); +		return NULL; +	} +	 +	if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS ) +	{ +		g_free( url ); +		return NULL; +	} +	 +	request = g_strdup_printf( "GET %s HTTP/1.0\r\n" +	                           "Host: %s\r\n" +	                           "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n" +	                           "\r\n", url->file, url->host ); +	 +	ret = http_dorequest( url->host, url->port, +	                      url->proto == PROTO_HTTPS, request, func, data ); +	 +	g_free( url ); +	g_free( request ); +	return ret; +} +  /* This one is actually pretty simple... Might get more calls if we can't write      the whole request at once. */  static void http_connected( gpointer data, int source, GaimInputCondition cond ) @@ -125,6 +156,8 @@ static void http_connected( gpointer data, int source, GaimInputCondition cond )  	return;  error: +	req->status_string = g_strdup( "Error while writing HTTP request" ); +	  	req->func( req );  	g_free( req->request ); @@ -184,6 +217,7 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co  		{  			if( !sockerr_again() )  			{ +				req->status_string = g_strdup( strerror( errno ) );  				goto cleanup;  			}  		} @@ -208,6 +242,14 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co  	return;  got_reply: +	/* Maybe if the webserver is overloaded, or when there's bad SSL +	   support... */ +	if( req->bytes_read == 0 ) +	{ +		req->status_string = g_strdup( "Empty HTTP reply" ); +		goto cleanup; +	} +	  	/* Zero termination is very convenient. */  	req->reply_headers[req->bytes_read] = 0; @@ -221,28 +263,53 @@ got_reply:  		end1 = end2 + 1;  		evil_server = 1;  	} -	else +	else if( end1 )  	{  		end1 += 2;  	} -	 -	if( end1 ) +	else  	{ -		*end1 = 0; -		 -		if( evil_server ) -			req->reply_body = end1 + 1; -		else -			req->reply_body = end1 + 2; +		req->status_string = g_strdup( "Malformed HTTP reply" ); +		goto cleanup;  	} +	*end1 = 0; +	 +	if( evil_server ) +		req->reply_body = end1 + 1; +	else +		req->reply_body = end1 + 2; +	 +	req->body_size = req->reply_headers + req->bytes_read - req->reply_body; +	  	if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )  	{  		if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 ) +		{ +			req->status_string = g_strdup( "Can't parse status code" );  			req->status_code = -1; +		} +		else +		{ +			char *eol; +			 +			if( evil_server ) +				eol = strchr( end1, '\n' ); +			else +				eol = strchr( end1, '\r' ); +			 +			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 ); +			 +			/* Just to be sure... */ +			if( ( eol = strchr( req->status_string, '\r' ) ) ) +				*eol = 0; +			if( ( eol = strchr( req->status_string, '\n' ) ) ) +				*eol = 0; +		}  	}  	else  	{ +		req->status_string = g_strdup( "Can't locate status code" );  		req->status_code = -1;  	} @@ -251,9 +318,16 @@ got_reply:  		char *loc, *new_request, *new_host;  		int error = 0, new_port, new_proto; +		/* We might fill it again, so let's not leak any memory. */ +		g_free( req->status_string ); +		req->status_string = NULL; +		  		loc = strstr( req->reply_headers, "\nLocation: " );  		if( loc == NULL ) /* We can't handle this redirect... */ +		{ +			req->status_string = g_strdup( "Can't locate Location: header" );  			goto cleanup; +		}  		loc += 11;  		while( *loc == ' ' ) @@ -270,6 +344,8 @@ got_reply:  			/* Since we don't cache the servername, and since we  			   don't need this yet anyway, I won't implement it. */ +			req->status_string = g_strdup( "Can't handle recursive redirects" ); +			  			goto cleanup;  		}  		else @@ -287,6 +363,7 @@ got_reply:  			if( !url_set( url, loc ) )  			{ +				req->status_string = g_strdup( "Malformed redirect URL" );  				g_free( url );  				goto cleanup;  			} @@ -297,28 +374,18 @@ got_reply:  			/* So, now I just allocated enough memory, so I'm  			   going to use strcat(), whether you like it or not. :-) */ -			/* First, find the GET/POST/whatever from the original request. */ -			s = strchr( req->request, ' ' ); -			if( s == NULL ) -			{ -				g_free( new_request ); -				g_free( url ); -				goto cleanup; -			} -			 -			*s = 0; -			sprintf( new_request, "%s %s HTTP/1.0\r\n", req->request, url->file ); -			*s = ' '; +			sprintf( new_request, "GET %s HTTP/1.0", url->file );  			s = strstr( req->request, "\r\n" );  			if( s == NULL )  			{ +				req->status_string = g_strdup( "Error while rebuilding request string" );  				g_free( new_request );  				g_free( url );  				goto cleanup;  			} -			strcat( new_request, s + 2 ); +			strcat( new_request, s );  			new_host = g_strdup( url->host );  			new_port = url->port;  			new_proto = url->proto; @@ -332,7 +399,7 @@ got_reply:  			closesocket( req->fd );  		req->fd = -1; -		req->ssl = 0; +		req->ssl = NULL;  		if( new_proto == PROTO_HTTPS )  		{ @@ -350,6 +417,7 @@ got_reply:  		if( error )  		{ +			req->status_string = g_strdup( "Connection problem during redirect" );  			g_free( new_request );  			goto cleanup;  		} @@ -378,5 +446,6 @@ cleanup:  	g_free( req->request );  	g_free( req->reply_headers ); +	g_free( req->status_string );  	g_free( req );  } diff --git a/protocols/http_client.h b/protocols/http_client.h index 53c6fcd6..50ee80cf 100644 --- a/protocols/http_client.h +++ b/protocols/http_client.h @@ -36,8 +36,10 @@ struct http_request  	char *request;  	int request_length;  	int status_code; +	char *status_string;  	char *reply_headers;  	char *reply_body; +	int body_size;  	int finished;  	void *ssl; @@ -52,3 +54,4 @@ struct http_request  };  void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data ); +void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ); diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index 224762ce..ac6481a1 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -1044,7 +1044,7 @@ static void jabber_accept_add(gpointer w, struct jabber_add_permit *jap)  	 * ask if we want him or her added.  	 */  	if(find_buddy(GJ_GC(jap->gjc), jap->user) == NULL) { -		show_got_added(GJ_GC(jap->gjc), NULL, jap->user, NULL, NULL); +		show_got_added(GJ_GC(jap->gjc), jap->user, NULL);  	}  	g_free(jap->user);  	g_free(jap); @@ -1548,7 +1548,9 @@ static gboolean jabber_free(gpointer data)  	if(jd->gjc != NULL) {  		gjab_delete(jd->gjc); +		/* YAY for modules with their own memory pool managers!...  		g_free(jd->gjc->sid); +		And a less sarcastic yay for valgrind. :-) */  		jd->gjc = NULL;  	}  	g_free(jd); @@ -1884,24 +1886,11 @@ static void jabber_set_away(struct gaim_connection *gc, char *state, char *messa  	xmlnode_free(x);  } -static void jabber_set_idle(struct gaim_connection *gc, int idle) { -	struct jabber_data *jd = (struct jabber_data *)gc->proto_data; -   	jd->idle = idle ? time(NULL) - idle : idle; -} -  static void jabber_keepalive(struct gaim_connection *gc) {  	struct jabber_data *jd = (struct jabber_data *)gc->proto_data;  	gjab_send_raw(jd->gjc, "  \t  ");  } -static void jabber_buddy_free(struct buddy *b) -{ -	while (b->proto_data) { -		g_free(((GSList *)b->proto_data)->data); -		b->proto_data = g_slist_remove(b->proto_data, ((GSList *)b->proto_data)->data); -	} -} -  /*---------------------------------------*/  /* Jabber "set info" (vCard) support     */  /*---------------------------------------*/ @@ -2337,29 +2326,12 @@ static void jabber_handlevcard(gjconn gjc, xmlnode querynode, char *from)  	g_string_free(str, TRUE);  } - -static GList *jabber_actions() -{ -	GList *m = NULL; - -	m = g_list_append(m, _("Set User Info")); -	/* -	m = g_list_append(m, _("Set Dir Info")); -	m = g_list_append(m, _("Change Password")); -	 */ - -	return m; -} - -  void jabber_init()  {  	struct prpl *ret = g_new0(struct prpl, 1); -	/* the NULL's aren't required but they're nice to have */  	ret->name = "jabber";  	ret->away_states = jabber_away_states; -	ret->actions = jabber_actions;  	ret->login = jabber_login;  	ret->close = jabber_close;  	ret->send_im = jabber_send_im; @@ -2367,16 +2339,9 @@ void jabber_init()  	ret->get_info = jabber_get_info;  	ret->set_away = jabber_set_away;  	ret->get_away = jabber_get_away_msg; -	ret->set_idle = jabber_set_idle;  	ret->add_buddy = jabber_add_buddy;  	ret->remove_buddy = jabber_remove_buddy; -	ret->add_permit = NULL; -	ret->add_deny = NULL; -	ret->rem_permit = NULL; -	ret->rem_deny = NULL; -	ret->set_permit_deny = NULL;  	ret->keepalive = jabber_keepalive; -	ret->buddy_free = jabber_buddy_free;  	ret->alias_buddy = jabber_roster_update;  	ret->group_buddy = jabber_group_change;  	ret->cmp_buddynames = g_strcasecmp; diff --git a/protocols/jabber/xmlparse.c b/protocols/jabber/xmlparse.c index 492da948..bbef7d59 100644 --- a/protocols/jabber/xmlparse.c +++ b/protocols/jabber/xmlparse.c @@ -1460,7 +1460,7 @@ initializeEncoding(XML_Parser parser)  #else  s = protocolEncodingName;  #endif -    if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) +    if (ns ? XmlInitEncodingNS(&initEncoding, &encoding, s) : XmlInitEncoding(&initEncoding, &encoding, s))          return XML_ERROR_NONE;      return handleUnknownEncoding(parser, protocolEncodingName);  } @@ -1474,8 +1474,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,      const char *version;      int standalone = -1;      if (!(ns -            ? XmlParseXmlDeclNS -            : XmlParseXmlDecl)(isGeneralTextEntity, +            ? XmlParseXmlDeclNS(isGeneralTextEntity,                                 encoding,                                 s,                                 next, @@ -1483,7 +1482,16 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,                                 &version,                                 &encodingName,                                 &newEncoding, -                               &standalone)) +                               &standalone) +            : XmlParseXmlDecl(isGeneralTextEntity, +                               encoding, +                               s, +                               next, +                               &eventPtr, +                               &version, +                               &encodingName, +                               &newEncoding, +                               &standalone)))          return XML_ERROR_SYNTAX;      if (!isGeneralTextEntity && standalone == 1)          dtd.standalone = 1; @@ -1536,11 +1544,14 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)                  return XML_ERROR_NO_MEMORY;              }              enc = (ns -                   ? XmlInitUnknownEncodingNS -                   : XmlInitUnknownEncoding)(unknownEncodingMem, +                   ? XmlInitUnknownEncodingNS(unknownEncodingMem, +                                             info.map, +                                             info.convert, +                                             info.data) +                   : XmlInitUnknownEncoding(unknownEncodingMem,                                               info.map,                                               info.convert, -                                             info.data); +                                             info.data));              if (enc) {                  unknownEncodingData = info.data;                  unknownEncodingRelease = info.release; diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index 5cda9f1c..c3bd73cc 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -130,6 +130,9 @@ static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla )  {  	msn_buddy_list_add( bla->gc, "AL", bla->handle, bla->realname ); +	if( find_buddy( bla->gc, bla->handle ) == NULL ) +		show_got_added( bla->gc, bla->handle, NULL ); +	  	g_free( bla->handle );  	g_free( bla->realname );  	g_free( bla ); diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 90d525ef..523de0ae 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -649,8 +649,15 @@ static void msn_auth_got_passport_id( struct passport_reply *rep )  	if( key == NULL )  	{ -		hide_login_progress( gc, "Error during Passport authentication" ); +		char *err; +		 +		err = g_strdup_printf( "Error during Passport authentication (%s)", +		                       rep->error_string ? rep->error_string : "Unknown error" ); +		 +		hide_login_progress( gc, err );  		signoff( gc ); +		 +		g_free( err );  	}  	else  	{ diff --git a/protocols/msn/passport.c b/protocols/msn/passport.c index 34703432..dd1d9b6f 100644 --- a/protocols/msn/passport.c +++ b/protocols/msn/passport.c @@ -68,8 +68,7 @@ static int passport_get_id_real( gpointer func, gpointer data, char *header )  		return( 0 );  	} -	reqs = g_malloc( strlen( header ) + strlen( dummy ) + 128 ); -	sprintf( reqs, "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); +	reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );  	*dummy = 0;  	req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep ); @@ -87,13 +86,13 @@ static void passport_get_id_ready( struct http_request *req )  {  	struct passport_reply *rep = req->data; -	if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers ) +	if( !g_slist_find( msn_connections, rep->data ) )  	{  		destroy_reply( rep );  		return;  	} -	if( req->status_code == 200 ) +	if( req->finished && req->reply_headers && req->status_code == 200 )  	{  		char *dummy; @@ -108,6 +107,15 @@ static void passport_get_id_ready( struct http_request *req )  			rep->result = g_strdup( dummy );  		} +		else +		{ +			rep->error_string = g_strdup( "Could not parse Passport server response" ); +		} +	} +	else +	{ +		rep->error_string = g_strdup_printf( "HTTP error: %s", +		                      req->status_string ? req->status_string : "Unknown error" );  	}  	rep->func( rep ); @@ -144,7 +152,6 @@ static char *passport_create_header( char *cookie, char *email, char *pwd )  	return( buffer );  } -#define PPR_REQUEST "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n"  static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )  {  	struct passport_reply *rep = g_new0( struct passport_reply, 1 ); @@ -154,7 +161,7 @@ static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header  	rep->func = func;  	rep->header = header; -	req = http_dorequest( "nexus.passport.com", 443, 1, PPR_REQUEST, passport_retrieve_dalogin_ready, rep ); +	req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );  	if( !req )  		destroy_reply( rep ); @@ -168,16 +175,26 @@ static void passport_retrieve_dalogin_ready( struct http_request *req )  	char *dalogin;  	char *urlend; -	if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers ) +	if( !g_slist_find( msn_connections, rep->data ) )  	{  		destroy_reply( rep );  		return;  	} +	if( !req->finished || !req->reply_headers || req->status_code != 200 ) +	{ +		rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s", +		                        req->status_string ? req->status_string : "Unknown error" ); +		goto failure; +	} +	  	dalogin = strstr( req->reply_headers, "DALogin=" );	  	if( !dalogin ) +	{ +		rep->error_string = g_strdup( "Parse error while fetching DALogin" );  		goto failure; +	}  	dalogin += strlen( "DALogin=" );  	urlend = strchr( dalogin, ',' ); @@ -207,5 +224,6 @@ static void destroy_reply( struct passport_reply *rep )  {  	g_free( rep->result );  	g_free( rep->header ); +	g_free( rep->error_string );  	g_free( rep );  } diff --git a/protocols/msn/passport.h b/protocols/msn/passport.h index f7e6ebb6..9fd81a82 100644 --- a/protocols/msn/passport.h +++ b/protocols/msn/passport.h @@ -38,6 +38,7 @@ struct passport_reply  	void *data;  	char *result;  	char *header; +	char *error_string;  };  int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ); diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 234be1d6..34b0a30a 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -522,14 +522,14 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  		if( err->flags & STATUS_SB_FATAL )  		{  			msn_sb_destroy( sb ); -			return( 0 ); +			return 0;  		} -		if( err->flags & STATUS_FATAL ) +		else if( err->flags & STATUS_FATAL )  		{  			signoff( gc ); -			return( 0 ); +			return 0;  		} -		if( err->flags & STATUS_SB_IM_SPARE ) +		else if( err->flags & STATUS_SB_IM_SPARE )  		{  			if( sb->who )  			{ @@ -552,6 +552,8 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  				g_slist_free( sb->msgq );  				sb->msgq = NULL;  			} +			 +			/* Do NOT return 0 here, we want to keep this sb. */  		}  	}  	else diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c index f8e98350..5ba9ea73 100644 --- a/protocols/msn/tables.c +++ b/protocols/msn/tables.c @@ -126,7 +126,7 @@ const struct msn_status_code msn_status_code_list[] =  	{ 800, "Changing too rapidly",                                  0 },  	{ 910, "Server is busy",                                        STATUS_FATAL }, -	{ 911, "Authentication failed",                                 STATUS_FATAL }, +	{ 911, "Authentication failed",                                 STATUS_SB_FATAL | STATUS_FATAL },  	{ 912, "Server is busy",                                        STATUS_FATAL },  	{ 913, "Not allowed when hiding",                               0 },  	{ 914, "Server is unavailable",                                 STATUS_FATAL }, 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 );  } diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 3d45d0a0..b143440a 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -14,7 +14,7 @@   *   * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>   *                          (and possibly other members of the Gaim team) - * Copyright 2002-2004 Wilmer van der Gaast <lintux@lintux.cx> + * Copyright 2002-2004 Wilmer van der Gaast <wilmer@gaast.net>   */  /* @@ -51,31 +51,26 @@  #define SELF_ALIAS_LEN 400  #define BUDDY_ALIAS_MAXLEN 388   /* because MSN names can be 387 characters */ -#define PERMIT_ALL      1 -#define PERMIT_NONE     2 -#define PERMIT_SOME     3 -#define DENY_SOME       4 - -#define WEBSITE "http://www.bitlee.org/" +#define WEBSITE "http://www.bitlbee.org/"  #define IM_FLAG_AWAY 0x0020 -#define OPT_CONN_HTML 0x00000001 -#define OPT_LOGGED_IN 0x00010000  #define GAIM_AWAY_CUSTOM "Custom" -#define GAIM_LOGO	0 -#define GAIM_ERROR	1 -#define GAIM_WARNING	2 -#define GAIM_INFO	3 +#define OPT_CONN_HTML   0x00000001 +#define OPT_LOGGED_IN   0x00010000 +#define OPT_LOGGING_OUT 0x00020000  /* ok. now the fun begins. first we create a connection structure */ -struct gaim_connection { -	/* we need to do either oscar or TOC */ -	/* we make this as an int in case if we want to add more protocols later */ +struct gaim_connection +{  	struct prpl *prpl;  	guint32 flags; +	/* each connection then can have its own protocol-specific data */ +	void *proto_data; +	  	/* all connections need an input watcher */  	int inpa; +	guint keepalive;  	/* buddy list stuff. there is still a global groups for the buddy list, but  	 * we need to maintain our own set of buddies, and our own permit/deny lists */ @@ -83,33 +78,19 @@ struct gaim_connection {  	GSList *deny;  	int permdeny; -	/* all connections need a list of chats, even if they don't have chat */ -	GSList *buddy_chats; -	 -	/* each connection then can have its own protocol-specific data */ -	void *proto_data; -	  	struct aim_user *user;  	char username[64];  	char displayname[128];  	char password[32]; -	guint keepalive; -	/* stuff needed for per-connection idle times */ -	guint idle_timer; -	time_t login_time; -	time_t lastsent; -	int is_idle;  	char *away; -	int is_auto_away;  	int evil;  	gboolean wants_to_die; /* defaults to FALSE */  	/* BitlBee */  	irc_t *irc; -	int lstitems;  /* added for msnP8 */  	struct conversation *conversations;  }; @@ -163,61 +144,41 @@ struct prpl {  	int options;  	const char *name; -	/* for ICQ and Yahoo, who have off/on per-conversation options */ -	/* char *checkbox; this should be per-connection */ - -	GList *(* away_states)(struct gaim_connection *gc); -	GList *(* actions)(); -	void   (* do_action)(struct gaim_connection *, char *); -	/* user_opts returns a GList* of g_malloc'd struct proto_user_opts */ -	GList *(* user_opts)(); -	GList *(* chat_info)(struct gaim_connection *); - -	/* all the server-related functions */ - -	/* a lot of these (like get_dir) are protocol-dependent and should be removed. ones like -	 * set_dir (which is also protocol-dependent) can stay though because there's a dialog -	 * (i.e. the prpl says you can set your dir info, the ui shows a dialog and needs to call -	 * set_dir in order to set it) */ -  	void (* login)		(struct aim_user *); +	void (* keepalive)	(struct gaim_connection *);  	void (* close)		(struct gaim_connection *); +	  	int  (* send_im)	(struct gaim_connection *, char *who, char *message, int len, int away); -	int  (* send_typing)	(struct gaim_connection *, char *who, int typing); -	void (* set_info)	(struct gaim_connection *, char *info); -	void (* get_info)	(struct gaim_connection *, char *who);  	void (* set_away)	(struct gaim_connection *, char *state, char *message);  	void (* get_away)       (struct gaim_connection *, char *who); -	void (* set_idle)	(struct gaim_connection *, int idletime); +	int  (* send_typing)	(struct gaim_connection *, char *who, int typing); +	  	void (* add_buddy)	(struct gaim_connection *, char *name); +	void (* group_buddy)	(struct gaim_connection *, char *who, char *old_group, char *new_group);  	void (* remove_buddy)	(struct gaim_connection *, char *name, char *group);  	void (* add_permit)	(struct gaim_connection *, char *name);  	void (* add_deny)	(struct gaim_connection *, char *name);  	void (* rem_permit)	(struct gaim_connection *, char *name);  	void (* rem_deny)	(struct gaim_connection *, char *name);  	void (* set_permit_deny)(struct gaim_connection *); +	 +	void (* set_info)	(struct gaim_connection *, char *info); +	void (* get_info)	(struct gaim_connection *, char *who); +	void (* alias_buddy)	(struct gaim_connection *, char *who);	/* save/store buddy's alias on server list/roster */ +	 +	/* Group chat stuff. */  	void (* join_chat)	(struct gaim_connection *, GList *data);  	void (* chat_invite)	(struct gaim_connection *, int id, char *who, char *message);  	void (* chat_leave)	(struct gaim_connection *, int id); -	void (* chat_whisper)	(struct gaim_connection *, int id, char *who, char *message);  	int  (* chat_send)	(struct gaim_connection *, int id, char *message);  	int  (* chat_open)	(struct gaim_connection *, char *who); -	void (* keepalive)	(struct gaim_connection *); - -	/* get "chat buddy" info and away message */ -	void (* get_cb_info)	(struct gaim_connection *, int, char *who); -	void (* get_cb_away)	(struct gaim_connection *, int, char *who); - -	/* save/store buddy's alias on server list/roster */ -	void (* alias_buddy)	(struct gaim_connection *, char *who); - -	/* change a buddy's group on a server list/roster */ -	void (* group_buddy)	(struct gaim_connection *, char *who, char *old_group, char *new_group); - -	void (* buddy_free)	(struct buddy *); - +	 +	/* DIE! */  	char *(* get_status_string) (struct gaim_connection *gc, int stat); - +	 +	GList *(* away_states)(struct gaim_connection *gc); +	 +	/* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* */  	int (* cmp_buddynames) (const char *who1, const char *who2);  }; @@ -234,14 +195,16 @@ G_MODULE_EXPORT struct prpl *find_protocol(const char *name);  G_MODULE_EXPORT void register_protocol(struct prpl *);  /* nogaim.c */ -int serv_send_im(irc_t *irc, user_t *u, char *msg, int flags); -int serv_send_chat(irc_t *irc, struct gaim_connection *gc, int id, char *msg ); +int bim_set_away( struct gaim_connection *gc, char *away ); +int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flags ); +int bim_chat_msg( struct gaim_connection *gc, int id, char *msg ); -G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf ); -char *set_eval_charset( irc_t *irc, set_t *set, char *value ); +void bim_add_allow( struct gaim_connection *gc, char *handle ); +void bim_rem_allow( struct gaim_connection *gc, char *handle ); +void bim_add_block( struct gaim_connection *gc, char *handle ); +void bim_rem_block( struct gaim_connection *gc, char *handle );  void nogaim_init(); -int proto_away( struct gaim_connection *gc, char *away );  char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value );  gboolean auto_reconnect( gpointer data ); @@ -253,9 +216,8 @@ G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc );  G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg );  G_MODULE_EXPORT void hide_login_progress( struct gaim_connection *gc, char *msg );  G_MODULE_EXPORT void hide_login_progress_error( struct gaim_connection *gc, char *msg ); -G_MODULE_EXPORT void serv_got_crap( struct gaim_connection *gc, char *format, ... ); +G_MODULE_EXPORT void serv_got_crap( struct gaim_connection *gc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );  G_MODULE_EXPORT void account_online( struct gaim_connection *gc ); -G_MODULE_EXPORT void account_offline( struct gaim_connection *gc );  G_MODULE_EXPORT void signoff( struct gaim_connection *gc );  /* dialogs.c */ @@ -263,11 +225,8 @@ G_MODULE_EXPORT void do_error_dialog( struct gaim_connection *gc, char *msg, cha  G_MODULE_EXPORT void do_ask_dialog( struct gaim_connection *gc, char *msg, void *data, void *doit, void *dont );  /* list.c */ -G_MODULE_EXPORT int bud_list_cache_exists( struct gaim_connection *gc ); -G_MODULE_EXPORT void do_import( struct gaim_connection *gc, void *null );  G_MODULE_EXPORT void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *realname );  G_MODULE_EXPORT struct buddy *find_buddy( struct gaim_connection *gc, char *handle ); -G_MODULE_EXPORT void do_export( struct gaim_connection *gc );  G_MODULE_EXPORT void signoff_blocked( struct gaim_connection *gc );  G_MODULE_EXPORT void serv_buddy_rename( struct gaim_connection *gc, char *handle, char *realname ); @@ -277,7 +236,7 @@ G_MODULE_EXPORT void add_chat_buddy( struct conversation *b, char *handle );  G_MODULE_EXPORT void remove_chat_buddy( struct conversation *b, char *handle, char *reason );  /* prpl.c */ -G_MODULE_EXPORT void show_got_added( struct gaim_connection *gc, char *id, char *handle, const char *realname, const char *msg ); +G_MODULE_EXPORT void show_got_added( struct gaim_connection *gc, char *handle, const char *realname );  /* server.c */                      G_MODULE_EXPORT void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, int evil, time_t signon, time_t idle, int type, guint caps ); @@ -288,23 +247,6 @@ G_MODULE_EXPORT struct conversation *serv_got_joined_chat( struct gaim_connectio  G_MODULE_EXPORT void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t mtime );  G_MODULE_EXPORT void serv_got_chat_left( struct gaim_connection *gc, int id ); -/* util.c */ -G_MODULE_EXPORT void strip_linefeed( gchar *text ); -G_MODULE_EXPORT char *add_cr( char *text ); -G_MODULE_EXPORT char *tobase64( const char *text ); -G_MODULE_EXPORT char *normalize( const char *s ); -G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec ); -G_MODULE_EXPORT void strip_html( char *msg ); -G_MODULE_EXPORT char *escape_html( const char *html ); -G_MODULE_EXPORT void info_string_append(GString *str, char *newline, char *name, char *value); -G_MODULE_EXPORT char *ipv6_wrap( char *src ); -G_MODULE_EXPORT char *ipv6_unwrap( char *src ); - -/* prefs.c */ -G_MODULE_EXPORT void build_block_list(); -G_MODULE_EXPORT void build_allow_list(); -  struct conversation *conv_findchannel( char *channel ); -  #endif diff --git a/protocols/oscar/aim.h b/protocols/oscar/aim.h index 24cd7730..93887103 100644 --- a/protocols/oscar/aim.h +++ b/protocols/oscar/aim.h @@ -727,8 +727,11 @@ struct aim_chat_exchangeinfo {  	char *lang2;  }; -#define AIM_CHATFLAGS_NOREFLECT 0x0001 -#define AIM_CHATFLAGS_AWAY      0x0002 +#define AIM_CHATFLAGS_NOREFLECT 	0x0001 +#define AIM_CHATFLAGS_AWAY      	0x0002 +#define AIM_CHATFLAGS_UNICODE		0x0004 +#define AIM_CHATFLAGS_ISO_8859_1	0x0008 +  int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen);  int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);  int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance); diff --git a/protocols/oscar/chat.c b/protocols/oscar/chat.c index 033c2577..df535c4f 100644 --- a/protocols/oscar/chat.c +++ b/protocols/oscar/chat.c @@ -158,7 +158,21 @@ int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const  	 */  	if (flags & AIM_CHATFLAGS_AWAY)  		aim_addtlvtochain_noval(&otl, 0x0007); - +	 +	/* [WvG] This wasn't there originally, but we really should send +	         the right charset flags, as we also do with normal +	         messages. Hope this will work. :-) */ +	/* +	if (flags & AIM_CHATFLAGS_UNICODE) +		aimbs_put16(&fr->data, 0x0002); +	else if (flags & AIM_CHATFLAGS_ISO_8859_1) +		aimbs_put16(&fr->data, 0x0003); +	else +		aimbs_put16(&fr->data, 0x0000); +	 +	aimbs_put16(&fr->data, 0x0000); +	*/ +	  	/*  	 * SubTLV: Type 1: Message  	 */ diff --git a/protocols/oscar/im.c b/protocols/oscar/im.c index c829d409..7cccabc7 100644 --- a/protocols/oscar/im.c +++ b/protocols/oscar/im.c @@ -1468,7 +1468,7 @@ static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod              case AIM_MTYPE_AUTOFFC:  	    case 0x9c:	/* ICQ 5 seems to send this */                  aim_send_im_ch2_statusmessage(sess, userinfo->sn, args->cookie, -                        gc->away, sess->aim_icq_state, dc); +                        gc->away ? gc->away : "", sess->aim_icq_state, dc);                  break;          } diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 97384afb..c2716c6b 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -1,6 +1,8 @@  /*   * gaim   * + * Some code copyright (C) 2002-2006, Jelmer Vernooij <jelmer@samba.org> + *                                    and the BitlBee team.   * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net>   * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx>   * @@ -135,9 +137,9 @@ static char *extract_name(const char *name) {  	char *tmp;  	int i, j;  	char *x = strchr(name, '-'); -	if (!x) return NULL; +	if (!x) return g_strdup(name);  	x = strchr(++x, '-'); -	if (!x) return NULL; +	if (!x) return g_strdup(name);  	tmp = g_strdup(++x);  	for (i = 0, j = 0; x[i]; i++) { @@ -382,7 +384,7 @@ static void oscar_login(struct aim_user *user) {  	if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 &&  	    g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) { -		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails."); +		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]);  	}  	g_snprintf(buf, sizeof(buf), _("Signon: %s"), gc->username); @@ -1118,7 +1120,8 @@ static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) {  	message = 0;  	aim_ssi_auth_reply(od->sess, od->conn, uin, 1, "");  	// aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message); -	show_got_added(data->gc, NULL, uin, NULL, NULL); +	if(find_buddy(data->gc, uin) == NULL) +		show_got_added(data->gc, uin, NULL);  	g_free(uin);  	g_free(data); @@ -2056,7 +2059,6 @@ static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) {  						char *name;  						name = g_strdup(normalize(curitem->name));  						gc->permit = g_slist_append(gc->permit, name); -						build_allow_list();  						tmp++;  					}  				} @@ -2070,7 +2072,6 @@ static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) {  						char *name;  						name = g_strdup(normalize(curitem->name));  						gc->deny = g_slist_append(gc->deny, name); -						build_block_list();  						tmp++;  					}  				} @@ -2276,7 +2277,7 @@ static int gaim_icqinfo(aim_session_t *sess, aim_frame_t *fr, ...)                  struct tm tm;                  tm.tm_mday = (int)info->birthday;                  tm.tm_mon = (int)info->birthmonth-1; -                tm.tm_year = (int)info->birthyear-1900; +                tm.tm_year = (int)info->birthyear%100;                  strftime(date, sizeof(date), "%Y-%m-%d", &tm);                  info_string_append(str, "\n", _("Birthday"), date);          } @@ -2500,6 +2501,7 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  	struct chat_connection * ccon;  	int ret;  	guint8 len = strlen(message); +	guint16 flags;  	char *s;  	if(!(ccon = find_oscar_chat(gc, id))) @@ -2508,15 +2510,19 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  	for (s = message; *s; s++)  		if (*s & 128)  			break; -	  	 +	 +	flags = AIM_CHATFLAGS_NOREFLECT; +	  	/* Message contains high ASCII chars, time for some translation! */  	if (*s) {  		s = g_malloc(BUF_LONG);  		/* Try if we can put it in an ISO8859-1 string first.  		   If we can't, fall back to UTF16. */  		if ((ret = do_iconv("UTF-8", "ISO8859-1", message, s, len, BUF_LONG)) >= 0) { +			flags |= AIM_CHATFLAGS_ISO_8859_1;  			len = ret;  		} else if ((ret = do_iconv("UTF-8", "UNICODEBIG", message, s, len, BUF_LONG)) >= 0) { +			flags |= AIM_CHATFLAGS_UNICODE;  			len = ret;  		} else {  			/* OOF, translation failed... Oh well.. */ @@ -2527,7 +2533,7 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  		s = message;  	} -	ret = aim_chat_send_im(od->sess, ccon->conn, AIM_CHATFLAGS_NOREFLECT, s, len); +	ret = aim_chat_send_im(od->sess, ccon->conn, flags, s, len);  	if (s != message) {	  		g_free(s); @@ -2600,9 +2606,9 @@ int oscar_chat_open(struct gaim_connection * gc, char *who)  	struct oscar_data * od = (struct oscar_data *)gc->proto_data;  	int ret;  	static int chat_id = 0; -	char * chatname = g_new0(char, strlen(gc->username)+4); +	char * chatname; -	g_snprintf(chatname, strlen(gc->username) + 4, "%s%d", gc->username, chat_id++); +	chatname = g_strdup_printf("%s%d", gc->username, chat_id++);  	ret = oscar_chat_join(gc, chatname); diff --git a/protocols/oscar/oscar_util.c b/protocols/oscar/oscar_util.c index 1bb27559..0ce06bd9 100644 --- a/protocols/oscar/oscar_util.c +++ b/protocols/oscar/oscar_util.c @@ -108,7 +108,7 @@ static int aim_snlen(const char *sn)  		return 0;  	curPtr = sn; -	while ( (*curPtr) != (char) NULL) { +	while ( (*curPtr) != (char) '\0') {  		if ((*curPtr) != ' ')  		i++;  		curPtr++; @@ -139,7 +139,7 @@ int aim_sncmp(const char *sn1, const char *sn2)  	curPtr1 = sn1;  	curPtr2 = sn2; -	while ( (*curPtr1 != (char) NULL) && (*curPtr2 != (char) NULL) ) { +	while ( (*curPtr1 != (char) '\0') && (*curPtr2 != (char) '\0') ) {  		if ( (*curPtr1 == ' ') || (*curPtr2 == ' ') ) {  			if (*curPtr1 == ' ')  				curPtr1++; diff --git a/protocols/oscar/service.c b/protocols/oscar/service.c index 573e1983..4596974f 100644 --- a/protocols/oscar/service.c +++ b/protocols/oscar/service.c @@ -732,7 +732,7 @@ int aim_setextstatus(aim_session_t *sess, aim_conn_t *conn, guint32 status)  	guint32 data;  	int tlvlen; -	data = AIM_ICQ_STATE_WEBAWARE | AIM_ICQ_STATE_HIDEIP | status; /* yay for error checking ;^) */ +	data = AIM_ICQ_STATE_HIDEIP | status; /* yay for error checking ;^) */  	tlvlen = aim_addtlvtochain32(&tl, 0x0006, data); @@ -880,13 +880,14 @@ int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, guint32 offset, guin  			aimbs_put32(&fr->data, 0xa46d3b39);  #endif +/* len can't be 0 here anyway...  		} else if ((offset == 0x00001000) && (len == 0x00000000)) {  			aimbs_put32(&fr->data, 0xd41d8cd9);  			aimbs_put32(&fr->data, 0x8f00b204);  			aimbs_put32(&fr->data, 0xe9800998);  			aimbs_put32(&fr->data, 0xecf8427e); - +*/  		} else  			do_error_dialog(sess->aux_data, "WARNING: unknown hash request", "Gaim"); diff --git a/protocols/ssl_nss.c b/protocols/ssl_nss.c index dfd32622..00d32834 100644 --- a/protocols/ssl_nss.c +++ b/protocols/ssl_nss.c @@ -121,10 +121,10 @@ static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )  	if( source == -1 )  		goto ssl_connected_failure; - - - +	/* Until we find out how to handle non-blocking I/O with NSS... */ +	sock_make_blocking( conn->fd ); +	  	conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));  	SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);  	SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); @@ -180,3 +180,9 @@ int ssl_getfd( void *conn )  {  	return( ((struct scd*)conn)->fd );  } + +GaimInputCondition ssl_getdirection( void *conn ) +{ +	/* Just in case someone calls us, let's return the most likely case: */ +	return GAIM_INPUT_READ; +} diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 4f257d99..1c3c73d9 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -226,16 +226,11 @@ static void byahoo_set_away( struct gaim_connection *gc, char *state, char *msg  			yd->current_status = YAHOO_STATUS_INVISIBLE;  		else if( g_strcasecmp( state, GAIM_AWAY_CUSTOM ) == 0 )  		{ -			if (gc->is_idle) -				yd->current_status = YAHOO_STATUS_IDLE; -			else -				yd->current_status = YAHOO_STATUS_AVAILABLE; +			yd->current_status = YAHOO_STATUS_AVAILABLE;  			gc->away = NULL;  		}  	} -	else if( gc->is_idle ) -		yd->current_status = YAHOO_STATUS_IDLE;  	else  		yd->current_status = YAHOO_STATUS_AVAILABLE; @@ -614,7 +609,8 @@ void ext_yahoo_status_changed( int id, char *who, int stat, char *msg, int away  {  	struct gaim_connection *gc = byahoo_get_gc_by_id( id ); -	serv_got_update( gc, who, stat != YAHOO_STATUS_OFFLINE, 0, 0, 0, +	serv_got_update( gc, who, stat != YAHOO_STATUS_OFFLINE, 0, 0, +	                 ( stat == YAHOO_STATUS_IDLE ) ? away : 0,  	                 ( stat != YAHOO_STATUS_AVAILABLE ) | ( stat << 1 ), 0 );  } | 
