From 508c340d1d12d3ca932001d7ee1dea1a4c81bf02 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 26 Apr 2010 01:42:37 +0100 Subject: Successfully posted a tweet! Twitter's tricky. It returns vars (user_id, screen_name) in the access token that, the way I read the spec, should be included in all subsequent queries. However, stuff only started to work when I dropped those vars. This code's definitely not pretty ATM. Need to clean up now that it actually works. --- protocols/twitter/twitter.c | 7 ++++++- protocols/twitter/twitter.h | 1 + protocols/twitter/twitter_http.c | 18 ++++++++++++++++-- protocols/twitter/twitter_http.h | 2 +- protocols/twitter/twitter_lib.c | 10 +++++----- 5 files changed, 29 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 726c7cb1..ead03c56 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -81,7 +81,10 @@ static void twitter_login( account_t *acc ) twitter_connections = g_slist_append( twitter_connections, ic ); td->user = acc->user; - td->pass = acc->pass; + if( strstr( acc->pass, "oauth_token=" ) == NULL ) + td->pass = g_strdup( acc->pass ); + else + td->oauth = g_strdup( acc->pass ); td->home_timeline_id = 0; ic->proto_data = td; @@ -118,6 +121,8 @@ static void twitter_logout( struct im_connection *ic ) if( td ) { + g_free( td->pass ); + g_free( td->oauth ); g_free( td ); } diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h index 88caa104..16620e1d 100644 --- a/protocols/twitter/twitter.h +++ b/protocols/twitter/twitter.h @@ -36,6 +36,7 @@ struct twitter_data { char* user; char* pass; + char* oauth; guint64 home_timeline_id; gint main_loop_id; struct groupchat *home_timeline_gc; diff --git a/protocols/twitter/twitter_http.c b/protocols/twitter/twitter_http.c index 3632140f..93e315fa 100644 --- a/protocols/twitter/twitter_http.c +++ b/protocols/twitter/twitter_http.c @@ -34,6 +34,7 @@ #include "url.h" #include "misc.h" #include "base64.h" +#include "oauth.h" #include #include @@ -44,7 +45,7 @@ char *twitter_url_append(char *url, char *key, char* value); * Do a request. * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c */ -void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len) +void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* oauth_token, char** arguments, int arguments_len) { url_t *url = g_new0( url_t, 1 ); char *tmp; @@ -109,7 +110,20 @@ void *twitter_http(char *url_string, http_input_function func, gpointer data, in is_post ? "POST" : "GET", url->file, url->host ); // If a pass and user are given we append them to the request. - if (userpass_base64) + if (oauth_token) + { + char *full_header; + + full_header = oauth_http_header(oauth_token, + is_post ? "POST" : "GET", + url_string, url_arguments); + + tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); + g_free(request); + g_free(full_header); + request = tmp; + } + else if (userpass_base64) { tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64); g_free(request); diff --git a/protocols/twitter/twitter_http.h b/protocols/twitter/twitter_http.h index ec4a0b7c..1e29fb99 100644 --- a/protocols/twitter/twitter_http.h +++ b/protocols/twitter/twitter_http.h @@ -28,7 +28,7 @@ #include "http_client.h" void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, - char* user, char* pass, char** arguments, int arguments_len); + char* user, char* pass, char *oauth_token, char** arguments, int arguments_len); #endif //_TWITTER_HTTP_H diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index d58afd73..c91f8bbf 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -129,7 +129,7 @@ void twitter_get_friends_ids(struct im_connection *ic, int next_cursor) char* args[2]; args[0] = "cursor"; args[1] = g_strdup_printf ("%d", next_cursor); - twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2); + twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth, args, 2); g_free(args[1]); } @@ -395,7 +395,7 @@ void twitter_get_home_timeline(struct im_connection *ic, int next_cursor) args[3] = g_strdup_printf ("%llu", (long long unsigned int) td->home_timeline_id); } - twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2); + twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth, args, td->home_timeline_id ? 4 : 2); g_free(args[1]); if (td->home_timeline_id) { @@ -619,7 +619,7 @@ void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor) args[0] = "cursor"; args[1] = g_strdup_printf ("%d", next_cursor); - twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2); + twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth, args, 2); g_free(args[1]); } @@ -653,7 +653,7 @@ void twitter_post_status(struct im_connection *ic, char* msg) char* args[2]; args[0] = "status"; args[1] = msg; - twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2); + twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 2); // g_free(args[1]); } @@ -671,7 +671,7 @@ void twitter_direct_messages_new(struct im_connection *ic, char *who, char *msg) args[2] = "text"; args[3] = msg; // Use the same callback as for twitter_post_status, since it does basically the same. - twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4); + twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 4); // g_free(args[1]); // g_free(args[3]); } -- cgit v1.2.3 From 713d6111cd754ff9eae4cfa1e6de82c9824d16db Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 26 Apr 2010 22:50:48 +0100 Subject: Twitter module now generates authorize URLs. --- protocols/twitter/twitter.c | 64 +++++++++++++++++++++++++++++++++++---------- protocols/twitter/twitter.h | 4 +++ 2 files changed, 54 insertions(+), 14 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index ead03c56..e2a5986b 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -22,6 +22,7 @@ ****************************************************************************/ #include "nogaim.h" +#include "oauth.h" #include "twitter.h" #include "twitter_http.h" #include "twitter_lib.h" @@ -50,6 +51,44 @@ gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond) return (ic->flags & OPT_LOGGED_IN) == OPT_LOGGED_IN; } +static void twitter_main_loop_start( struct im_connection *ic ) +{ + struct twitter_data *td = ic->proto_data; + + imcb_log( ic, "Connecting to Twitter" ); + + // Run this once. After this queue the main loop function. + twitter_main_loop(ic, -1, 0); + + // Queue the main_loop + // Save the return value, so we can remove the timeout on logout. + td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); +} + +static void twitter_oauth_callback( struct oauth_info *info ); + +static void twitter_oauth_start( struct im_connection *ic ) +{ + oauth_request_token( TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); +} + +static void twitter_oauth_callback( struct oauth_info *info ) +{ + struct im_connection *ic = info->data; + + if( info->request_token && info->access_token == NULL ) + { + char name[strlen(ic->acc->user)+9], *msg; + + sprintf( name, "twitter_%s", ic->acc->user ); + msg = g_strdup_printf( "To finish OAuth authentication, please visit " + "%s?%s and respond with the resulting PIN code.", + TWITTER_OAUTH_AUTHORIZE, info->auth_params ); + imcb_buddy_msg( ic, name, msg, 0, 0 ); + g_free( msg ); + } +} + static char *set_eval_mode( set_t *set, char *value ) { if( g_strcasecmp( value, "one" ) == 0 || @@ -66,6 +105,8 @@ static void twitter_init( account_t *acc ) s = set_add( &acc->set, "mode", "one", set_eval_mode, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; + + s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc ); } /** @@ -79,28 +120,23 @@ static void twitter_login( account_t *acc ) char name[strlen(acc->user)+9]; twitter_connections = g_slist_append( twitter_connections, ic ); - + ic->proto_data = td; + td->user = acc->user; - if( strstr( acc->pass, "oauth_token=" ) == NULL ) + if( !set_getbool( &acc->set, "oauth" ) ) td->pass = g_strdup( acc->pass ); - else + else if( strstr( acc->pass, "oauth_token=" ) ) td->oauth = g_strdup( acc->pass ); td->home_timeline_id = 0; - - ic->proto_data = td; - - imcb_log( ic, "Connecting to Twitter" ); - - // Run this once. After this queue the main loop function. - twitter_main_loop(ic, -1, 0); - - // Queue the main_loop - // Save the return value, so we can remove the timeout on logout. - td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); sprintf( name, "twitter_%s", acc->user ); imcb_add_buddy( ic, name, NULL ); imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); + + if( td->pass || td->oauth ) + twitter_main_loop_start( ic ); + else + twitter_oauth_start( ic ); } /** diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h index 16620e1d..f1937bd0 100644 --- a/protocols/twitter/twitter.h +++ b/protocols/twitter/twitter.h @@ -50,4 +50,8 @@ struct twitter_data */ GSList *twitter_connections; +#define TWITTER_OAUTH_REQUEST_TOKEN "http://api.twitter.com/oauth/request_token" +#define TWITTER_OAUTH_ACCESS_TOKEN "http://api.twitter.com/oauth/access_token" +#define TWITTER_OAUTH_AUTHORIZE "http://api.twitter.com/oauth/authorize" + #endif //_TWITTER_H -- cgit v1.2.3 From c42e8b907817fc76df4dc3b48d85858555102654 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 26 Apr 2010 23:40:11 +0100 Subject: OAuth, it lives! --- protocols/twitter/twitter.c | 39 ++++++++++++++++++++++++++++++++++++--- protocols/twitter/twitter.h | 1 + 2 files changed, 37 insertions(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index e2a5986b..eb05d9d5 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -69,17 +69,29 @@ static void twitter_oauth_callback( struct oauth_info *info ); static void twitter_oauth_start( struct im_connection *ic ) { + imcb_log( ic, "Requesting OAuth request token" ); + oauth_request_token( TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); } static void twitter_oauth_callback( struct oauth_info *info ) { struct im_connection *ic = info->data; + struct twitter_data *td = ic->proto_data; - if( info->request_token && info->access_token == NULL ) + if( info->stage == OAUTH_REQUEST_TOKEN ) { char name[strlen(ic->acc->user)+9], *msg; + if( info->request_token == NULL ) + { + imcb_error( ic, "OAuth error: %s", info->http->status_string ); + imc_logout( ic, TRUE ); + return; + } + + td->oauth_info = info; + sprintf( name, "twitter_%s", ic->acc->user ); msg = g_strdup_printf( "To finish OAuth authentication, please visit " "%s?%s and respond with the resulting PIN code.", @@ -87,6 +99,19 @@ static void twitter_oauth_callback( struct oauth_info *info ) imcb_buddy_msg( ic, name, msg, 0, 0 ); g_free( msg ); } + else if( info->stage == OAUTH_ACCESS_TOKEN ) + { + if( info->access_token == NULL ) + { + imcb_error( ic, "OAuth error: %s", info->http->status_string ); + imc_logout( ic, TRUE ); + return; + } + + td->oauth = g_strdup( info->access_token ); + + twitter_main_loop_start( ic ); + } } static char *set_eval_mode( set_t *set, char *value ) @@ -170,12 +195,20 @@ static void twitter_logout( struct im_connection *ic ) */ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) { + struct twitter_data *td = ic->proto_data; + if (g_strncasecmp(who, "twitter_", 8) == 0 && g_strcasecmp(who + 8, ic->acc->user) == 0) - twitter_post_status(ic, message); + { + if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth == NULL ) + oauth_access_token( TWITTER_OAUTH_ACCESS_TOKEN, message, td->oauth_info ); + else + twitter_post_status(ic, message); + } else + { twitter_direct_messages_new(ic, who, message); - + } return( 0 ); } diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h index f1937bd0..9c046b66 100644 --- a/protocols/twitter/twitter.h +++ b/protocols/twitter/twitter.h @@ -37,6 +37,7 @@ struct twitter_data char* user; char* pass; char* oauth; + struct oauth_info *oauth_info; guint64 home_timeline_id; gint main_loop_id; struct groupchat *home_timeline_gc; -- cgit v1.2.3 From 288b215ca64d09ea6a49cf9ff1fcc7682b7607ec Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 26 Apr 2010 23:50:25 +0100 Subject: Save the OAuth token in the acct structs so it doesn't have to be rerequested every time. --- protocols/twitter/twitter.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index eb05d9d5..54bee2f1 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -110,6 +110,11 @@ static void twitter_oauth_callback( struct oauth_info *info ) td->oauth = g_strdup( info->access_token ); + /* IM mods didn't do this so far and it's ugly but I should + be able to get away with it... */ + g_free( ic->acc->pass ); + ic->acc->pass = g_strdup( info->access_token ); + twitter_main_loop_start( ic ); } } -- cgit v1.2.3 From 18dbb20242719f7537ad1a18a9a3befa2eefd502 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 27 Apr 2010 23:42:07 +0100 Subject: Valgrind cleanup. --- protocols/twitter/twitter.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 54bee2f1..8ea1a56e 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -65,20 +65,27 @@ static void twitter_main_loop_start( struct im_connection *ic ) td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); } -static void twitter_oauth_callback( struct oauth_info *info ); +static gboolean twitter_oauth_callback( struct oauth_info *info ); static void twitter_oauth_start( struct im_connection *ic ) { + struct twitter_data *td = ic->proto_data; + imcb_log( ic, "Requesting OAuth request token" ); - oauth_request_token( TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); + td->oauth_info = oauth_request_token( + TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); } -static void twitter_oauth_callback( struct oauth_info *info ) +static gboolean twitter_oauth_callback( struct oauth_info *info ) { struct im_connection *ic = info->data; - struct twitter_data *td = ic->proto_data; + struct twitter_data *td; + if( !g_slist_find( twitter_connections, ic ) ) + return FALSE; + + td = ic->proto_data; if( info->stage == OAUTH_REQUEST_TOKEN ) { char name[strlen(ic->acc->user)+9], *msg; @@ -87,11 +94,9 @@ static void twitter_oauth_callback( struct oauth_info *info ) { imcb_error( ic, "OAuth error: %s", info->http->status_string ); imc_logout( ic, TRUE ); - return; + return FALSE; } - td->oauth_info = info; - sprintf( name, "twitter_%s", ic->acc->user ); msg = g_strdup_printf( "To finish OAuth authentication, please visit " "%s?%s and respond with the resulting PIN code.", @@ -105,7 +110,7 @@ static void twitter_oauth_callback( struct oauth_info *info ) { imcb_error( ic, "OAuth error: %s", info->http->status_string ); imc_logout( ic, TRUE ); - return; + return FALSE; } td->oauth = g_strdup( info->access_token ); @@ -117,6 +122,8 @@ static void twitter_oauth_callback( struct oauth_info *info ) twitter_main_loop_start( ic ); } + + return TRUE; } static char *set_eval_mode( set_t *set, char *value ) @@ -187,6 +194,8 @@ static void twitter_logout( struct im_connection *ic ) if( td ) { + oauth_info_free( td->oauth_info ); + g_free( td->pass ); g_free( td->oauth ); g_free( td ); @@ -205,8 +214,11 @@ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message if (g_strncasecmp(who, "twitter_", 8) == 0 && g_strcasecmp(who + 8, ic->acc->user) == 0) { - if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth == NULL ) + if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth_info ) + { oauth_access_token( TWITTER_OAUTH_ACCESS_TOKEN, message, td->oauth_info ); + td->oauth_info = NULL; + } else twitter_post_status(ic, message); } -- cgit v1.2.3 From a7c6d0e9a9d985534dc18d450399d6a7ece6c592 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 30 Apr 2010 23:51:18 +0100 Subject: Set HTML-flag on Twitter accounts so </> and all get converted back. (Probably also fixes potential problems with outgoing messages.) --- protocols/twitter/twitter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 8ea1a56e..f5baeeea 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -158,6 +158,7 @@ static void twitter_login( account_t *acc ) twitter_connections = g_slist_append( twitter_connections, ic ); ic->proto_data = td; + ic->flags |= OPT_DOES_HTML; td->user = acc->user; if( !set_getbool( &acc->set, "oauth" ) ) -- cgit v1.2.3 From c2ecadc08daa5163f4c90aef36de0e33d0d44f16 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 May 2010 14:53:59 +0100 Subject: Cleaned up OAuth stuff: consumer key/secret should *not* be in lib/oauth.c. Keep it in the Twitter module, and use the oauth_info struct through the whole session to keep all this together. --- protocols/twitter/twitter.c | 46 ++++++++++++++++++++++++---------------- protocols/twitter/twitter.h | 5 ----- protocols/twitter/twitter_http.c | 10 ++++----- protocols/twitter/twitter_http.h | 4 +++- protocols/twitter/twitter_lib.c | 12 +++++------ 5 files changed, 42 insertions(+), 35 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index f5baeeea..6d43d819 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -27,7 +27,6 @@ #include "twitter_http.h" #include "twitter_lib.h" - /** * Main loop function */ @@ -65,6 +64,16 @@ static void twitter_main_loop_start( struct im_connection *ic ) td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); } + +static struct oauth_service twitter_oauth = +{ + "http://api.twitter.com/oauth/request_token", + "http://api.twitter.com/oauth/access_token", + "http://api.twitter.com/oauth/authorize", + .consumer_key = "xsDNKJuNZYkZyMcu914uEA", + .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo", +}; + static gboolean twitter_oauth_callback( struct oauth_info *info ); static void twitter_oauth_start( struct im_connection *ic ) @@ -73,8 +82,7 @@ static void twitter_oauth_start( struct im_connection *ic ) imcb_log( ic, "Requesting OAuth request token" ); - td->oauth_info = oauth_request_token( - TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); + td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic ); } static gboolean twitter_oauth_callback( struct oauth_info *info ) @@ -99,26 +107,24 @@ static gboolean twitter_oauth_callback( struct oauth_info *info ) sprintf( name, "twitter_%s", ic->acc->user ); msg = g_strdup_printf( "To finish OAuth authentication, please visit " - "%s?%s and respond with the resulting PIN code.", - TWITTER_OAUTH_AUTHORIZE, info->auth_params ); + "%s and respond with the resulting PIN code.", + info->auth_url ); imcb_buddy_msg( ic, name, msg, 0, 0 ); g_free( msg ); } else if( info->stage == OAUTH_ACCESS_TOKEN ) { - if( info->access_token == NULL ) + if( info->token == NULL ) { imcb_error( ic, "OAuth error: %s", info->http->status_string ); imc_logout( ic, TRUE ); return FALSE; } - td->oauth = g_strdup( info->access_token ); - /* IM mods didn't do this so far and it's ugly but I should be able to get away with it... */ - g_free( ic->acc->pass ); - ic->acc->pass = g_strdup( info->access_token ); + //g_free( ic->acc->pass ); + //ic->acc->pass = g_strdup( info->access_token ); twitter_main_loop_start( ic ); } @@ -126,6 +132,7 @@ static gboolean twitter_oauth_callback( struct oauth_info *info ) return TRUE; } + static char *set_eval_mode( set_t *set, char *value ) { if( g_strcasecmp( value, "one" ) == 0 || @@ -163,15 +170,15 @@ static void twitter_login( account_t *acc ) td->user = acc->user; if( !set_getbool( &acc->set, "oauth" ) ) td->pass = g_strdup( acc->pass ); - else if( strstr( acc->pass, "oauth_token=" ) ) - td->oauth = g_strdup( acc->pass ); + //else if( strstr( acc->pass, "oauth_token=" ) ) + // td->oauth = g_strdup( acc->pass ); td->home_timeline_id = 0; sprintf( name, "twitter_%s", acc->user ); imcb_add_buddy( ic, name, NULL ); imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); - if( td->pass || td->oauth ) + if( td->pass || td->oauth_info ) twitter_main_loop_start( ic ); else twitter_oauth_start( ic ); @@ -196,9 +203,7 @@ static void twitter_logout( struct im_connection *ic ) if( td ) { oauth_info_free( td->oauth_info ); - g_free( td->pass ); - g_free( td->oauth ); g_free( td ); } @@ -215,10 +220,15 @@ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message if (g_strncasecmp(who, "twitter_", 8) == 0 && g_strcasecmp(who + 8, ic->acc->user) == 0) { - if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth_info ) + if( set_getbool( &ic->acc->set, "oauth" ) && + td->oauth_info && td->oauth_info->token == NULL ) { - oauth_access_token( TWITTER_OAUTH_ACCESS_TOKEN, message, td->oauth_info ); - td->oauth_info = NULL; + if( !oauth_access_token( message, td->oauth_info ) ) + { + imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); + imc_logout( ic, TRUE ); + return FALSE; + } } else twitter_post_status(ic, message); diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h index 9c046b66..24f61e42 100644 --- a/protocols/twitter/twitter.h +++ b/protocols/twitter/twitter.h @@ -36,7 +36,6 @@ struct twitter_data { char* user; char* pass; - char* oauth; struct oauth_info *oauth_info; guint64 home_timeline_id; gint main_loop_id; @@ -51,8 +50,4 @@ struct twitter_data */ GSList *twitter_connections; -#define TWITTER_OAUTH_REQUEST_TOKEN "http://api.twitter.com/oauth/request_token" -#define TWITTER_OAUTH_ACCESS_TOKEN "http://api.twitter.com/oauth/access_token" -#define TWITTER_OAUTH_AUTHORIZE "http://api.twitter.com/oauth/authorize" - #endif //_TWITTER_H diff --git a/protocols/twitter/twitter_http.c b/protocols/twitter/twitter_http.c index 93e315fa..51f437df 100644 --- a/protocols/twitter/twitter_http.c +++ b/protocols/twitter/twitter_http.c @@ -28,7 +28,6 @@ * * ****************************************************************************/ -#include "twitter_http.h" #include "twitter.h" #include "bitlbee.h" #include "url.h" @@ -38,6 +37,8 @@ #include #include +#include "twitter_http.h" + char *twitter_url_append(char *url, char *key, char* value); @@ -45,7 +46,7 @@ char *twitter_url_append(char *url, char *key, char* value); * Do a request. * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c */ -void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* oauth_token, char** arguments, int arguments_len) +void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, struct oauth_info* oi, char** arguments, int arguments_len) { url_t *url = g_new0( url_t, 1 ); char *tmp; @@ -110,12 +111,11 @@ void *twitter_http(char *url_string, http_input_function func, gpointer data, in is_post ? "POST" : "GET", url->file, url->host ); // If a pass and user are given we append them to the request. - if (oauth_token) + if (oi) { char *full_header; - full_header = oauth_http_header(oauth_token, - is_post ? "POST" : "GET", + full_header = oauth_http_header(oi, is_post ? "POST" : "GET", url_string, url_arguments); tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); diff --git a/protocols/twitter/twitter_http.h b/protocols/twitter/twitter_http.h index 1e29fb99..5ef2530f 100644 --- a/protocols/twitter/twitter_http.h +++ b/protocols/twitter/twitter_http.h @@ -27,8 +27,10 @@ #include "nogaim.h" #include "http_client.h" +struct oauth_info; + void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, - char* user, char* pass, char *oauth_token, char** arguments, int arguments_len); + char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len); #endif //_TWITTER_HTTP_H diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index c91f8bbf..ee6e39fe 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -129,7 +129,7 @@ void twitter_get_friends_ids(struct im_connection *ic, int next_cursor) char* args[2]; args[0] = "cursor"; args[1] = g_strdup_printf ("%d", next_cursor); - twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth, args, 2); + twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2); g_free(args[1]); } @@ -395,7 +395,7 @@ void twitter_get_home_timeline(struct im_connection *ic, int next_cursor) args[3] = g_strdup_printf ("%llu", (long long unsigned int) td->home_timeline_id); } - twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth, args, td->home_timeline_id ? 4 : 2); + twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth_info, args, td->home_timeline_id ? 4 : 2); g_free(args[1]); if (td->home_timeline_id) { @@ -509,7 +509,7 @@ static void twitter_http_get_home_timeline(struct http_request *req) if (req->status_code == 200) { td->http_fails = 0; - if (!ic->flags & OPT_LOGGED_IN) + if (!(ic->flags & OPT_LOGGED_IN)) imcb_connected(ic); } else if (req->status_code == 401) @@ -619,7 +619,7 @@ void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor) args[0] = "cursor"; args[1] = g_strdup_printf ("%d", next_cursor); - twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth, args, 2); + twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2); g_free(args[1]); } @@ -653,7 +653,7 @@ void twitter_post_status(struct im_connection *ic, char* msg) char* args[2]; args[0] = "status"; args[1] = msg; - twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 2); + twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2); // g_free(args[1]); } @@ -671,7 +671,7 @@ void twitter_direct_messages_new(struct im_connection *ic, char *who, char *msg) args[2] = "text"; args[3] = msg; // Use the same callback as for twitter_post_status, since it does basically the same. - twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 4); + twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4); // g_free(args[1]); // g_free(args[3]); } -- cgit v1.2.3 From f4b0911d037c02f8b9190518b5efda4368dcc25b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 May 2010 15:10:32 +0100 Subject: Save the credentials again. --- protocols/twitter/twitter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 6d43d819..589f2088 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -123,8 +123,8 @@ static gboolean twitter_oauth_callback( struct oauth_info *info ) /* IM mods didn't do this so far and it's ugly but I should be able to get away with it... */ - //g_free( ic->acc->pass ); - //ic->acc->pass = g_strdup( info->access_token ); + g_free( ic->acc->pass ); + ic->acc->pass = oauth_to_string( info ); twitter_main_loop_start( ic ); } @@ -170,8 +170,8 @@ static void twitter_login( account_t *acc ) td->user = acc->user; if( !set_getbool( &acc->set, "oauth" ) ) td->pass = g_strdup( acc->pass ); - //else if( strstr( acc->pass, "oauth_token=" ) ) - // td->oauth = g_strdup( acc->pass ); + else if( strstr( acc->pass, "oauth_token=" ) ) + td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth ); td->home_timeline_id = 0; sprintf( name, "twitter_%s", acc->user ); -- cgit v1.2.3 From 4273158e2bd219602e502d593040cccb234d4805 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 May 2010 15:16:26 +0100 Subject: Oops. rt_mon start at 0=Jan, causing off-by-a-month timestamps shown to the user. Temporary work-around: set timezone to +720 or so. :-P --- protocols/nogaim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index fca8b302..98325c89 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -1193,7 +1193,7 @@ static char *format_timestamp( irc_t *irc, time_t msg_ts ) else return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d " "%02d:%02d:%02d\x02]\x02 ", - msg.tm_year + 1900, msg.tm_mon, msg.tm_mday, + msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday, msg.tm_hour, msg.tm_min, msg.tm_sec ); } -- cgit v1.2.3 From 839189b091ee82937666bcaa328a7d3ecd1c573b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 2 May 2010 22:06:25 +0100 Subject: Applied show-offline patch from Florian E.J. Fruth, adapted for a few changes that happened since 1.2.4. --- protocols/nogaim.c | 90 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 16 deletions(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 98325c89..2248d11e 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -656,7 +656,18 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, g_free( u->status_msg ); u->away = u->status_msg = NULL; - if( ( flags & OPT_LOGGED_IN ) && !u->online ) + if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online ) + { + /* always set users as online */ + irc_spawn( ic->irc, u ); + u->online = 1; + if( !( flags & OPT_LOGGED_IN ) ) + { + /* set away message if user isn't really online */ + u->away = g_strdup( "User is offline" ); + } + } + else if( ( flags & OPT_LOGGED_IN ) && !u->online ) { irc_spawn( ic->irc, u ); u->online = 1; @@ -665,14 +676,30 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, { struct groupchat *c; - irc_kill( ic->irc, u ); - u->online = 0; - - /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ - for( c = ic->groupchats; c; c = c->next ) - remove_chat_buddy_silent( c, handle ); + if( set_getbool( &ic->irc->set, "show_offline" ) ) + { + /* keep offline users in channel and set away message to "offline" */ + u->away = g_strdup( "User is offline" ); + + /* Keep showing him/her in the control channel but not in groupchats. */ + for( c = ic->groupchats; c; c = c->next ) + { + if( remove_chat_buddy_silent( c, handle ) && c->joined ) + irc_part( c->ic->irc, u, c->channel ); + } + } + else + { + /* kill offline users */ + irc_kill( ic->irc, u ); + u->online = 0; + + /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ + for( c = ic->groupchats; c; c = c->next ) + remove_chat_buddy_silent( c, handle ); + } } - + if( flags & OPT_AWAY ) { if( state && message ) @@ -697,11 +724,8 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, u->status_msg = g_strdup( message ); } - /* LISPy... */ - if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ - ( u->online ) && /* Don't touch offline people */ - ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ - ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ + /* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */ + if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) ) { char *from; @@ -714,9 +738,43 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, ic->irc->myhost ); } - irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, - u->away?'-':'+', u->nick ); - g_free( from ); + + /* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */ + if( flags & OPT_LOGGED_IN ) + { + /* user is "online" (either really online or away) */ + irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel, + u->away?'+':'-', u->away?'-':'+', u->nick, u->nick ); + } + else + { + /* user is offline */ + irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick ); + } + } + else + { + /* LISPy... */ + if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ + ( u->online ) && /* Don't touch offline people */ + ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ + ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ + { + char *from; + + if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) + { + from = g_strdup( ic->irc->myhost ); + } + else + { + from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, + ic->irc->myhost ); + } + irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, + u->away?'-':'+', u->nick ); + g_free( from ); + } } } -- cgit v1.2.3 From 999769119e85518cc46b3ed64cb8781695fefbdc Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 3 May 2010 22:36:43 +0100 Subject: Check Tweet length on the BitlBee side already. --- protocols/twitter/twitter.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 9c7b060c..98e85641 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -143,10 +143,24 @@ static char *set_eval_mode( set_t *set, char *value ) return NULL; } +static gboolean twitter_length_check( struct im_connection *ic, gchar *msg ) +{ + int max = set_getint( &ic->acc->set, "message_length" ), len; + + if( max == 0 || ( len = g_utf8_strlen( msg, -1 ) ) <= max ) + return TRUE; + + imcb_error( ic, "Maximum message length exceeded: %d > %d", len, max ); + + return FALSE; +} + static void twitter_init( account_t *acc ) { set_t *s; + s = set_add( &acc->set, "message_length", "140", set_eval_int, acc ); + s = set_add( &acc->set, "mode", "one", set_eval_mode, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; @@ -230,7 +244,7 @@ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message return FALSE; } } - else + else if( twitter_length_check(ic, message) ) twitter_post_status(ic, message); } else @@ -261,7 +275,7 @@ static void twitter_remove_buddy( struct im_connection *ic, char *who, char *gro static void twitter_chat_msg( struct groupchat *c, char *message, int flags ) { - if( c && message ) + if( c && message && twitter_length_check(c->ic, message)) twitter_post_status(c->ic, message); } -- cgit v1.2.3 From aa7ce1b3dd961e948e907460bd42bf1592ea1717 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 9 May 2010 00:50:12 +0100 Subject: Yahoo! seems to echo conference room invitations now, huh? No idea what this is but let's ignore them. --- protocols/yahoo/yahoo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'protocols') diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index b61f6ff9..922ac17b 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -827,6 +827,10 @@ void ext_yahoo_got_conf_invite( int id, const char *ignored, char txt[1024]; YList *m; + if( g_strcasecmp( who, ic->acc->user ) == 0 ) + /* WTF, Yahoo! seems to echo these now? */ + return; + inv = g_malloc( sizeof( struct byahoo_conf_invitation ) ); memset( inv, 0, sizeof( struct byahoo_conf_invitation ) ); inv->name = g_strdup( room ); -- cgit v1.2.3 From 5a599a1550c670649dba681e702864d55d2e3795 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 9 May 2010 01:40:03 +0100 Subject: Room names on OSCAR can't start with digits, this broke the "chat with" command on ICQ so far. Just prepend "icq_" and it'll work. --- protocols/oscar/oscar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index e0c32257..5d23c36a 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -2650,7 +2650,8 @@ struct groupchat *oscar_chat_with(struct im_connection * ic, char *who) static int chat_id = 0; char * chatname; - chatname = g_strdup_printf("%s%d", ic->acc->user, chat_id++); + chatname = g_strdup_printf("%s%s_%d", isdigit(*ic->acc->user) ? "icq_" : "", + ic->acc->user, chat_id++); ret = oscar_chat_join(ic, chatname, NULL, NULL); -- cgit v1.2.3 From 7ee07c3191d1eb21d1d8317f7bfc3d9d98359ab1 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 9 May 2010 17:06:19 +0100 Subject: It looks like AIM mem requests (implemented as damn_you() and straight_to_hell() back in the days - and still more or less the same in libpurple it seems) are no longer necessary; the script no longer exists at the location used in the source and nobody complained. Nice try, AOL. And hats of to the Gaim developer who thought of this clever way around it. --- protocols/oscar/oscar.c | 136 ------------------------------------------------ 1 file changed, 136 deletions(-) (limited to 'protocols') diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 5d23c36a..00c5e5ef 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -204,7 +204,6 @@ static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); static int gaim_parse_locerr (aim_session_t *, aim_frame_t *, ...); static int gaim_icbm_param_info (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...); -static int gaim_memrequest (aim_session_t *, aim_frame_t *, ...); static int gaim_selfinfo (aim_session_t *, aim_frame_t *, ...); static int gaim_offlinemsg (aim_session_t *, aim_frame_t *, ...); static int gaim_offlinemsgdone (aim_session_t *, aim_frame_t *, ...); @@ -569,7 +568,6 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_ERROR, gaim_parse_genericerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ERROR, gaim_parse_genericerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BOS, AIM_CB_BOS_ERROR, gaim_parse_genericerr, 0); - aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x1f, gaim_memrequest, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SELFINFO, gaim_selfinfo, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, gaim_offlinemsgdone, 0); @@ -603,143 +601,9 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { return 1; } -struct pieceofcrap { - struct im_connection *ic; - unsigned long offset; - unsigned long len; - char *modname; - int fd; - aim_conn_t *conn; - unsigned int inpa; -}; - -static gboolean damn_you(gpointer data, gint source, b_input_condition c) -{ - struct pieceofcrap *pos = data; - struct oscar_data *od = pos->ic->proto_data; - char in = '\0'; - int x = 0; - unsigned char m[17]; - - while (read(pos->fd, &in, 1) == 1) { - if (in == '\n') - x++; - else if (in != '\r') - x = 0; - if (x == 2) - break; - in = '\0'; - } - if (in != '\n') { - imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM." - " You may be disconnected shortly."); - b_event_remove(pos->inpa); - closesocket(pos->fd); - g_free(pos); - return FALSE; - } - /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */ - read(pos->fd, m, 16); - m[16] = '\0'; - b_event_remove(pos->inpa); - closesocket(pos->fd); - aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH); - g_free(pos); - - return FALSE; -} - -static gboolean straight_to_hell(gpointer data, gint source, b_input_condition cond) { - struct pieceofcrap *pos = data; - char buf[BUF_LONG]; - - if (source < 0) { - imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM." - " You may be disconnected shortly."); - if (pos->modname) - g_free(pos->modname); - g_free(pos); - return FALSE; - } - - g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA - "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", - pos->offset, pos->len, pos->modname ? pos->modname : ""); - write(pos->fd, buf, strlen(buf)); - if (pos->modname) - g_free(pos->modname); - pos->inpa = b_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); - return FALSE; -} - /* size of icbmui.ocm, the largest module in AIM 3.5 */ #define AIM_MAX_FILE_SIZE 98304 -int gaim_memrequest(aim_session_t *sess, aim_frame_t *fr, ...) { - va_list ap; - struct pieceofcrap *pos; - guint32 offset, len; - char *modname; - int fd; - - va_start(ap, fr); - offset = (guint32)va_arg(ap, unsigned long); - len = (guint32)va_arg(ap, unsigned long); - modname = va_arg(ap, char *); - va_end(ap); - - if (len == 0) { - aim_sendmemblock(sess, fr->conn, offset, len, NULL, - AIM_SENDMEMBLOCK_FLAG_ISREQUEST); - return 1; - } - /* uncomment this when you're convinced it's right. remember, it's been wrong before. - if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) { - char *buf; - int i = 8; - if (modname) - i += strlen(modname); - buf = g_malloc(i); - i = 0; - if (modname) { - memcpy(buf, modname, strlen(modname)); - i += strlen(modname); - } - buf[i++] = offset & 0xff; - buf[i++] = (offset >> 8) & 0xff; - buf[i++] = (offset >> 16) & 0xff; - buf[i++] = (offset >> 24) & 0xff; - buf[i++] = len & 0xff; - buf[i++] = (len >> 8) & 0xff; - buf[i++] = (len >> 16) & 0xff; - buf[i++] = (len >> 24) & 0xff; - aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST); - g_free(buf); - return 1; - } - */ - - pos = g_new0(struct pieceofcrap, 1); - pos->ic = sess->aux_data; - pos->conn = fr->conn; - - pos->offset = offset; - pos->len = len; - pos->modname = modname ? g_strdup(modname) : NULL; - - fd = proxy_connect("gaim.sourceforge.net", 80, straight_to_hell, pos); - if (fd < 0) { - if (pos->modname) - g_free(pos->modname); - g_free(pos); - imcb_error(sess->aux_data, "Gaim was unable to get a valid hash for logging into AIM." - " You may be disconnected shortly."); - } - pos->fd = fd; - - return 1; -} - static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { #if 0 struct client_info_s info = {"gaim", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x04b}; -- cgit v1.2.3 From e73a501ce0cf49d8073d7d25656561400f2aca79 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 11 May 2010 00:35:58 +0100 Subject: Fixed a long-standing bug where non-anonymous Jabber chatrooms could cause full JIDs to be added to the local contact list, but not removed when leaving the room, eventually triggering errors like the one in #499. People kept sending me these dumps and I finally took time to make what turned out to be this one-line fix. This error should never appear again unless people are doing really crazy stuff. --- protocols/jabber/conference.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index f434c58a..affe8aef 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -271,8 +271,10 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu bud->flags |= JBFLAG_IS_ANONYMOUS; } - if( bud != jc->me ) + if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) { + /* If JIDs are anonymized, add them to the local + list for the duration of this chat. */ imcb_add_buddy( ic, bud->ext_jid, NULL ); imcb_buddy_nick_hint( ic, bud->ext_jid, bud->resource ); } -- cgit v1.2.3 From f8cb76dea3554fd82c01c5cae61f35d2b6cb0936 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 11 May 2010 22:33:37 +0100 Subject: Stop those "Many switchboard failures" messages. No point in showing them unless the lost switchboard actually had something queued. --- protocols/msn/sb.c | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index e2ee8570..49eed601 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -327,9 +327,13 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c struct im_connection *ic = sb->ic; struct msn_data *md = ic->proto_data; - if( msn_handler( sb->handler ) == -1 ) + if( msn_handler( sb->handler ) != -1 ) + return TRUE; + + if( sb->msgq != NULL ) { time_t now = time( NULL ); + char buf[1024]; if( now - md->first_sb_failure > 600 ) { @@ -346,37 +350,28 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c imcb_log( ic, "Warning: Many switchboard failures on MSN connection. " "There might be problems delivering your messages." ); - if( sb->msgq != NULL ) + if( md->msgq == NULL ) { - char buf[1024]; - - if( md->msgq == NULL ) - { - md->msgq = sb->msgq; - } - else - { - GSList *l; - - for( l = md->msgq; l->next; l = l->next ); - l->next = sb->msgq; - } - sb->msgq = NULL; + md->msgq = sb->msgq; + } + else + { + GSList *l; - debug( "Moved queued messages back to the main queue, creating a new switchboard to retry." ); - g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); - if( !msn_write( ic, buf, strlen( buf ) ) ) - return FALSE; + for( l = md->msgq; l->next; l = l->next ); + l->next = sb->msgq; } + sb->msgq = NULL; - msn_sb_destroy( sb ); - - return FALSE; - } - else - { - return TRUE; + debug( "Moved queued messages back to the main queue, " + "creating a new switchboard to retry." ); + g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); + if( !msn_write( ic, buf, strlen( buf ) ) ) + return FALSE; } + + msn_sb_destroy( sb ); + return FALSE; } static int msn_sb_command( gpointer data, char **cmd, int num_parts ) -- cgit v1.2.3 From 6e6b3d7c7300c5cf5cf7f1538154925fd2fe3953 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 14 May 2010 01:09:29 +0100 Subject: Add a warning when the user included a domain part in his/her Yahoo! username. --- protocols/yahoo/yahoo.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'protocols') diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 922ac17b..e4d541d5 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -137,10 +137,15 @@ static void byahoo_login( account_t *acc ) { struct im_connection *ic = imcb_new( acc ); struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 ); + char *s; yd->logged_in = FALSE; yd->current_status = YAHOO_STATUS_AVAILABLE; + if( ( s = strchr( acc->user, '@' ) ) && g_strcasecmp( s, "@yahoo.com" ) == 0 ) + imcb_error( ic, "Your Yahoo! username should just be a username. " + "Do not include any @domain part." ); + imcb_log( ic, "Connecting" ); yd->y2_id = yahoo_init( acc->user, acc->pass ); yahoo_login( yd->y2_id, yd->current_status ); -- cgit v1.2.3