diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/http_client.c | 52 | ||||
-rw-r--r-- | protocols/http_client.h | 2 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 46 | ||||
-rw-r--r-- | protocols/jabber/xmlparse.c | 25 | ||||
-rw-r--r-- | protocols/msn/msn.h | 5 | ||||
-rw-r--r-- | protocols/msn/msn_util.c | 14 | ||||
-rw-r--r-- | protocols/msn/ns.c | 51 | ||||
-rw-r--r-- | protocols/msn/sb.c | 8 | ||||
-rw-r--r-- | protocols/nogaim.c | 454 | ||||
-rw-r--r-- | protocols/nogaim.h | 131 | ||||
-rw-r--r-- | protocols/oscar/aim.h | 7 | ||||
-rw-r--r-- | protocols/oscar/chat.c | 14 | ||||
-rw-r--r-- | protocols/oscar/oscar.c | 33 | ||||
-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/ssl_openssl.c | 86 | ||||
-rw-r--r-- | protocols/yahoo/yahoo.c | 10 |
18 files changed, 474 insertions, 485 deletions
diff --git a/protocols/http_client.c b/protocols/http_client.c index 9417e200..5db31782 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 ) @@ -221,21 +252,24 @@ 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; + 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 ) diff --git a/protocols/http_client.h b/protocols/http_client.h index 53c6fcd6..860cdd86 100644 --- a/protocols/http_client.h +++ b/protocols/http_client.h @@ -38,6 +38,7 @@ struct http_request int status_code; char *reply_headers; char *reply_body; + int body_size; int finished; void *ssl; @@ -52,3 +53,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 ba652b8a..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); @@ -1231,9 +1231,7 @@ static void jabber_handleroster(gjconn gjc, xmlnode querynode) x = xmlnode_get_nextsibling(x); } - x = jutil_presnew(0, NULL, "Online"); - gjab_send(gjc, x); - xmlnode_free(x); + account_online(GJ_GC(gjc)); } static void jabber_handleauthresp(gjconn gjc, jpacket p) @@ -1249,7 +1247,6 @@ static void jabber_handleauthresp(gjconn gjc, jpacket p) gjab_auth(gjc); } else { gjab_reqroster(gjc); - account_online(GJ_GC(gjc)); ((struct jabber_data *)GJ_GC(gjc)->proto_data)->did_import = TRUE; } @@ -1551,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); @@ -1887,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 */ /*---------------------------------------*/ @@ -2340,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; @@ -2370,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.h b/protocols/msn/msn.h index 9727c537..0cd174f2 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -65,8 +65,11 @@ struct msn_data GSList *msgq; GSList *switchboards; - int buddycount; const struct msn_away_state *away_state; + + int buddycount; + int groupcount; + char **grouplist; }; struct msn_switchboard diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index e5f0b2c9..c3bd73cc 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -45,19 +45,8 @@ int msn_write( struct gaim_connection *gc, char *s, int len ) int msn_logged_in( struct gaim_connection *gc ) { - struct msn_data *md = gc->proto_data; - char buf[1024]; - account_online( gc ); - /* account_online() sets an away state if there is any, so only - execute this code if we're not away. */ - if( md->away_state == msn_away_state_list ) - { - g_snprintf( buf, sizeof( buf ), "CHG %d %s %d\r\n", ++md->trId, md->away_state->code, 0 ); - return( msn_write( gc, buf, strlen( buf ) ) ); - } - return( 0 ); } @@ -141,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 4ced58a0..90d525ef 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -256,6 +256,9 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) if( num_parts == 5 ) { md->buddycount = atoi( cmd[3] ); + md->groupcount = atoi( cmd[4] ); + if( md->groupcount > 0 ) + md->grouplist = g_new0( char *, md->groupcount ); if( !*cmd[3] || md->buddycount == 0 ) msn_logged_in( gc ); @@ -268,18 +271,6 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) msn_logged_in( gc ); } } - else if( strcmp( cmd[0], "GTC" ) == 0 ) - { - } - else if( strcmp( cmd[0], "BLP" ) == 0 ) - { - } - else if( strcmp( cmd[0], "PRP" ) == 0 ) - { - } - else if( strcmp( cmd[0], "LSG" ) == 0 ) - { - } else if( strcmp( cmd[0], "LST" ) == 0 ) { int list; @@ -296,7 +287,13 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) if( list & 1 ) /* FL */ { - add_buddy( gc, NULL, cmd[1], cmd[2] ); + char *group = NULL; + int num; + + if( cmd[4] != NULL && sscanf( cmd[4], "%d", &num ) == 1 ) + group = md->grouplist[num]; + + add_buddy( gc, group, cmd[1], cmd[2] ); } if( list & 2 ) /* AL */ { @@ -326,11 +323,22 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) } } } - else if( strcmp( cmd[0], "BPR" ) == 0 ) - { - } - else if( strcmp( cmd[0], "CHG" ) == 0 ) + else if( strcmp( cmd[0], "LSG" ) == 0 ) { + int num; + + if( num_parts != 4 ) + { + hide_login_progress_error( gc, "Syntax error" ); + signoff( gc ); + return( 0 ); + } + + http_decode( cmd[2] ); + num = atoi( cmd[1] ); + + if( num < md->groupcount ) + md->grouplist[num] = g_strdup( cmd[2] ); } else if( strcmp( cmd[0], "CHL" ) == 0 ) { @@ -356,12 +364,6 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) return( msn_write( gc, buf, strlen( buf ) ) ); } - else if( strcmp( cmd[0], "QRY" ) == 0 ) - { - } - else if( strcmp( cmd[0], "QNG" ) == 0 ) - { - } else if( strcmp( cmd[0], "ILN" ) == 0 ) { const struct msn_away_state *st; @@ -478,9 +480,6 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) msn_buddy_ask( gc, cmd[4], cmd[5] ); } } - else if( strcmp( cmd[0], "REM" ) == 0 ) - { - } else if( strcmp( cmd[0], "OUT" ) == 0 ) { if( cmd[1] && strcmp( cmd[1], "OTH" ) == 0 ) diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index deaceba1..234be1d6 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -201,9 +201,6 @@ void msn_sb_destroy( struct msn_switchboard *sb ) debug( "Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "" ); - if( sb->key ) g_free( sb->key ); - if( sb->who ) g_free( sb->who ); - if( sb->msgq ) { struct msn_message *m; @@ -221,9 +218,12 @@ void msn_sb_destroy( struct msn_switchboard *sb ) serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with " "unsent message to %s, you'll have to resend it.", - m->who ? m->who : "(unknown)" ); + sb->who ? sb->who : "(unknown)" ); } + if( sb->key ) g_free( sb->key ); + if( sb->who ) g_free( sb->who ); + if( sb->chat ) { serv_got_chat_left( gc, sb->chat->id ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 29ae860a..04d48236 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -13,7 +13,7 @@ * from scratch for BitlBee and doesn't contain any code from Gaim anymore * (except for the function names). * - * Copyright 2002-2004 Wilmer van der Gaast <lintux@lintux.cx> + * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net> and others */ /* @@ -36,19 +36,6 @@ #define BITLBEE_CORE #include "nogaim.h" #include <ctype.h> -#include <iconv.h> - -static char *proto_away_alias[7][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 }, - { NULL } -}; -static char *proto_away_alias_find( GList *gcm, char *away ); static int remove_chat_buddy_silent( struct conversation *b, char *handle ); @@ -157,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 ) @@ -304,36 +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[33]; - 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 ) - g_snprintf( acc_id, 32, "%s(%s)", gc->prpl->name, gc->username ); + irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text ); else - g_snprintf( acc_id, 32, "%s", gc->prpl->name ); + irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text ); - irc_usermsg( gc->irc, "%s - %s", acc_id, msg ); + g_free( text ); } static gboolean send_keepalive( gpointer d ) @@ -351,7 +254,7 @@ void account_online( struct gaim_connection *gc ) user_t *u; /* MSN servers sometimes redirect you to a different server and do - the whole login sequence again, so subsequent calls to this + the whole login sequence again, so these "late" calls to this function should be handled correctly. (IOW, ignored) */ if( gc->flags & OPT_LOGGED_IN ) return; @@ -363,18 +266,9 @@ void account_online( struct gaim_connection *gc ) gc->keepalive = g_timeout_add( 60000, send_keepalive, gc ); gc->flags |= OPT_LOGGED_IN; - if( u && u->away ) proto_away( gc, u->away ); - - if( !strcmp(gc->prpl->name, "icq") ) - { - 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." ); - } + /* Also necessary when we're not away, at least for some of the + protocols. */ + bim_set_away( gc, u->away ); } gboolean auto_reconnect( gpointer data ) @@ -393,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; @@ -469,16 +357,6 @@ void do_ask_dialog( struct gaim_connection *gc, char *msg, void *data, void *doi /* list.c */ -int bud_list_cache_exists( struct gaim_connection *gc ) -{ - return( 0 ); -} - -void do_import( struct gaim_connection *gc, void *null ) -{ - return; -} - void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *realname ) { user_t *u; @@ -514,7 +392,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 */ @@ -530,6 +415,7 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea u->gc = gc; u->handle = g_strdup( handle ); + if( group ) u->group = g_strdup( group ); u->send_handler = buddy_send_handler; u->last_typing_notice = 0; } @@ -553,11 +439,6 @@ struct buddy *find_buddy( struct gaim_connection *gc, char *handle ) return( b ); } -void do_export( struct gaim_connection *gc ) -{ - return; -} - void signoff_blocked( struct gaim_connection *gc ) { return; /* Make all blocked users look invisible (TODO?) */ @@ -567,22 +448,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 ); @@ -592,9 +465,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 +{ + 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 ) { - return; + 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 ); } @@ -624,7 +528,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; @@ -688,7 +593,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 ); @@ -730,10 +634,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; @@ -830,7 +730,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 ) @@ -843,10 +742,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 @@ -883,11 +778,6 @@ struct conversation *serv_got_joined_chat( struct gaim_connection *gc, int id, c return( c ); } -void serv_finish_login( struct gaim_connection *gc ) -{ - return; -} - /* buddy_chat.c */ @@ -972,20 +862,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 ) @@ -1064,89 +940,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 ); +} + +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 ); +} - iconv_close( cd ); - return( value ); +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 afc39a80..3721361c 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,24 @@ #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 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 - /* 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 +76,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; }; @@ -182,66 +161,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); - - /* file transfers */ - struct ft_send_req *(* req_send_file) (struct gaim_connection *, const char *file); - void (* send_file_part) (struct gaim_connection *, struct ft*, void *data, size_t length); - void (* accept_recv_file) (struct gaim_connection *, struct ft*, ft_recv_handler); - - 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); }; @@ -258,14 +212,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 ); @@ -277,9 +233,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 */ @@ -287,11 +242,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 ); @@ -301,7 +253,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 ); @@ -312,23 +264,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..8843b499 100644 --- a/protocols/oscar/chat.c +++ b/protocols/oscar/chat.c @@ -158,7 +158,19 @@ 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/oscar.c b/protocols/oscar/oscar.c index 4e552bce..5174f95c 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> * @@ -355,7 +357,9 @@ static void oscar_login(struct aim_user *user) { if (isdigit(*user->username)) { odata->icq = TRUE; - /* this is odd but it's necessary for a proper do_import and do_export */ + /* This is odd but it's necessary for a proper do_import and do_export. + We don't do those anymore, but let's stick with it, just in case + it accidentally fixes something else too... */ gc->password[8] = 0; } else { gc->flags |= OPT_CONN_HTML; @@ -380,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); @@ -1116,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); @@ -1147,7 +1152,7 @@ static void gaim_icq_authask(struct gaim_connection *gc, guint32 uin, char *msg) if (strlen(msg) > 6) reason = msg + 6; - dialog_msg = g_strdup_printf("The user %u wants to add you to their buddy list for the following reason:\n\n%s", uin, reason ? reason : "No reason given."); + dialog_msg = g_strdup_printf("The user %u wants to add you to their buddy list for the following reason: %s", uin, reason ? reason : "No reason given."); data->gc = gc; data->uin = uin; do_ask_dialog(gc, dialog_msg, data, gaim_icq_authgrant, gaim_icq_authdeny); @@ -1736,11 +1741,6 @@ static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) { odata->rights.maxpermits = (guint)maxpermits; odata->rights.maxdenies = (guint)maxdenies; -// serv_finish_login(gc); - - if (bud_list_cache_exists(gc)) - do_import(gc, NULL); - aim_clientready(sess, fr->conn); aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV); @@ -2059,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++; } } @@ -2073,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++; } } @@ -2095,8 +2093,6 @@ static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) { } /* End of switch on curitem->type */ } /* End of for loop */ - if (tmp) - do_export(gc); aim_ssi_enable(sess, fr->conn); /* Request offline messages, now that the buddy list is complete. */ @@ -2281,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); } @@ -2505,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))) @@ -2513,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.. */ @@ -2532,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); 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/ssl_openssl.c b/protocols/ssl_openssl.c index e62f95b9..b79088cc 100644 --- a/protocols/ssl_openssl.c +++ b/protocols/ssl_openssl.c @@ -4,7 +4,7 @@ * Copyright 2002-2004 Wilmer van der Gaast and others * \********************************************************************/ -/* SSL module - OpenTLS version */ +/* SSL module - OpenSSL version */ /* This program is free software; you can redistribute it and/or modify @@ -40,11 +40,13 @@ static gboolean initialized = FALSE; struct scd { - SslInputFunction func; + ssl_input_function func; gpointer data; int fd; gboolean established; + int inpa; + int lasterr; /* Necessary for SSL_get_error */ SSL *ssl; SSL_CTX *ssl_ctx; }; @@ -53,7 +55,7 @@ static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) -void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) +void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) { struct scd *conn = g_new0( struct scd, 1 ); SSL_METHOD *meth; @@ -92,19 +94,45 @@ void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) return( conn ); } +static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ); + static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) { struct scd *conn = data; if( source == -1 ) - goto ssl_connected_failure; + return ssl_handshake( data, -1, cond ); + /* Make it non-blocking at least during the handshake... */ + sock_make_nonblocking( conn->fd ); SSL_set_fd( conn->ssl, conn->fd ); - if( SSL_connect( conn->ssl ) < 0 ) - goto ssl_connected_failure; + return ssl_handshake( data, source, cond ); +} + +static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ) +{ + struct scd *conn = data; + int st; + + if( conn->inpa != -1 ) + { + gaim_input_remove( conn->inpa ); + conn->inpa = -1; + } + + if( ( st = SSL_connect( conn->ssl ) ) < 0 ) + { + conn->lasterr = SSL_get_error( conn->ssl, st ); + if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE ) + goto ssl_connected_failure; + + conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data ); + return; + } conn->established = TRUE; + sock_make_blocking( conn->fd ); /* For now... */ conn->func( conn->data, conn, cond ); return; @@ -126,24 +154,57 @@ ssl_connected_failure: int ssl_read( void *conn, char *buf, int len ) { + int st; + if( !((struct scd*)conn)->established ) - return( 0 ); + { + ssl_errno = SSL_NOHANDSHAKE; + return -1; + } + + st = SSL_read( ((struct scd*)conn)->ssl, buf, len ); - return( SSL_read( ((struct scd*)conn)->ssl, buf, len ) ); + ssl_errno = SSL_OK; + if( st <= 0 ) + { + ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); + if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) + ssl_errno = SSL_AGAIN; + } + + return st; } int ssl_write( void *conn, const char *buf, int len ) { + int st; + if( !((struct scd*)conn)->established ) - return( 0 ); + { + ssl_errno = SSL_NOHANDSHAKE; + return -1; + } + + st = SSL_write( ((struct scd*)conn)->ssl, buf, len ); - return( SSL_write( ((struct scd*)conn)->ssl, buf, len ) ); + ssl_errno = SSL_OK; + if( st <= 0 ) + { + ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); + if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) + ssl_errno = SSL_AGAIN; + } + + return st; } void ssl_disconnect( void *conn_ ) { struct scd *conn = conn_; + if( conn->inpa != -1 ) + gaim_input_remove( conn->inpa ); + if( conn->established ) SSL_shutdown( conn->ssl ); @@ -158,3 +219,8 @@ int ssl_getfd( void *conn ) { return( ((struct scd*)conn)->fd ); } + +GaimInputCondition ssl_getdirection( void *conn ) +{ + return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : 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 ); } |