diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/jabber/iq.c | 4 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 7 | ||||
-rw-r--r-- | protocols/jabber/jabber.h | 1 | ||||
-rw-r--r-- | protocols/jabber/jabber_util.c | 26 | ||||
-rw-r--r-- | protocols/jabber/message.c | 2 | ||||
-rw-r--r-- | protocols/twitter/twitter.c | 44 | ||||
-rw-r--r-- | protocols/twitter/twitter.h | 8 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.c | 77 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.h | 6 |
9 files changed, 131 insertions, 44 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 95b21e1e..68777b0b 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -64,7 +64,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) /* Of course this is a very essential query to support. ;-) */ if( strcmp( s, XMLNS_VERSION ) == 0 ) { - xt_add_child( reply, xt_new_node( "name", "BitlBee", NULL ) ); + xt_add_child( reply, xt_new_node( "name", set_getstr( &ic->acc->set, "user_agent" ), NULL ) ); xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) ); xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) ); } @@ -104,7 +104,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) c = xt_new_node( "identity", NULL, NULL ); xt_add_attr( c, "category", "client" ); xt_add_attr( c, "type", "pc" ); - xt_add_attr( c, "name", "BitlBee" ); + xt_add_attr( c, "name", set_getstr( &ic->acc->set, "user_agent" ) ); xt_add_child( reply, c ); for( f = features; *f; f ++ ) diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index 2841c0db..5cc00c9f 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -79,6 +79,8 @@ static void jabber_init( account_t *acc ) s = set_add( &acc->set, "tls", "try", set_eval_tls, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; + s = set_add( &acc->set, "user_agent", "BitlBee", NULL, acc ); + s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; @@ -285,6 +287,8 @@ static void jabber_logout( struct im_connection *ic ) if( jd->node_cache ) g_hash_table_destroy( jd->node_cache ); + jabber_buddy_remove_all( ic ); + xt_free( jd->xt ); g_free( jd->away_message ); @@ -469,7 +473,8 @@ static void jabber_chat_invite_( struct groupchat *c, char *who, char *msg ) static void jabber_keepalive( struct im_connection *ic ) { /* Just any whitespace character is enough as a keepalive for XMPP sessions. */ - jabber_write( ic, "\n", 1 ); + if( !jabber_write( ic, "\n", 1 ) ) + return; /* This runs the garbage collection every minute, which means every packet is in the cache for about a minute (which should be enough AFAIK). */ diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 40cf3957..3f4144b8 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -229,6 +229,7 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, g struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags ); int jabber_buddy_remove( struct im_connection *ic, char *full_jid ); int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ); +void jabber_buddy_remove_all( struct im_connection *ic ); time_t jabber_get_timestamp( struct xt_node *xt ); struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns ); void jabber_error_free( struct jabber_error *err ); diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index b8b625f7..651b7068 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -664,6 +664,32 @@ int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ) } } +static gboolean jabber_buddy_remove_all_cb( gpointer key, gpointer value, gpointer data ) +{ + struct jabber_buddy *bud, *next; + + bud = value; + while( bud ) + { + next = bud->next; + g_free( bud->ext_jid ); + g_free( bud->full_jid ); + g_free( bud->away_message ); + g_free( bud ); + bud = next; + } + + return TRUE; +} + +void jabber_buddy_remove_all( struct im_connection *ic ) +{ + struct jabber_data *jd = ic->proto_data; + + g_hash_table_foreach_remove( jd->buddies, jabber_buddy_remove_all_cb, NULL ); + g_hash_table_destroy( jd->buddies ); +} + time_t jabber_get_timestamp( struct xt_node *xt ) { struct xt_node *c; diff --git a/protocols/jabber/message.c b/protocols/jabber/message.c index e8161029..fa915bd8 100644 --- a/protocols/jabber/message.c +++ b/protocols/jabber/message.c @@ -54,7 +54,7 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data ) char *ns = xt_find_attr( c, "xmlns" ), *room; struct xt_node *inv, *reason; - if( strcmp( ns, XMLNS_MUC_USER ) == 0 && + if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 && ( inv = xt_find_node( c->children, "invite" ) ) ) { room = from; diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 90fca1fa..fca619c3 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -39,11 +39,6 @@ gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond) if (!g_slist_find( twitter_connections, ic )) return 0; - // If the user uses multiple private message windows we need to get the - // users buddies. - if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "many") == 0) - twitter_get_statuses_friends(ic, -1); - // Do stuff.. twitter_get_home_timeline(ic, -1); @@ -55,7 +50,7 @@ static void twitter_main_loop_start( struct im_connection *ic ) { struct twitter_data *td = ic->proto_data; - imcb_log( ic, "Connecting to Twitter" ); + imcb_log( ic, "Getting initial statuses" ); // Run this once. After this queue the main loop function. twitter_main_loop(ic, -1, 0); @@ -65,6 +60,23 @@ 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_start( struct im_connection *ic ); + +void twitter_login_finish( struct im_connection *ic ) +{ + struct twitter_data *td = ic->proto_data; + + if( set_getbool( &ic->acc->set, "oauth" ) && !td->oauth_info ) + twitter_oauth_start( ic ); + else if( g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "one" ) != 0 && + !( td->flags & TWITTER_HAVE_FRIENDS ) ) + { + imcb_log( ic, "Getting contact list" ); + twitter_get_statuses_friends( ic, -1 ); + } + else + twitter_main_loop_start( ic ); +} static const struct oauth_service twitter_oauth = { @@ -127,7 +139,7 @@ static gboolean twitter_oauth_callback( struct oauth_info *info ) g_free( ic->acc->pass ); ic->acc->pass = oauth_to_string( info ); - twitter_main_loop_start( ic ); + twitter_login_finish( ic ); } return TRUE; @@ -210,10 +222,9 @@ static void twitter_login( account_t *acc ) imcb_add_buddy( ic, name, NULL ); imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); - if( td->oauth_info || !set_getbool( &acc->set, "oauth" ) ) - twitter_main_loop_start( ic ); - else - twitter_oauth_start( ic ); + imcb_log( ic, "Connecting" ); + + twitter_login_finish( ic ); } /** @@ -235,6 +246,8 @@ static void twitter_logout( struct im_connection *ic ) if( td ) { oauth_info_free( td->oauth_info ); + g_free( td->url_host ); + g_free( td->url_path ); g_free( td->pass ); g_free( td ); } @@ -255,7 +268,14 @@ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth_info && td->oauth_info->token == NULL ) { - if( !oauth_access_token( message, td->oauth_info ) ) + char pin[strlen(message)+1], *s; + + strcpy( pin, message ); + for( s = pin + sizeof( pin ) - 2; s > pin && isspace( *s ); s -- ) + *s = '\0'; + for( s = pin; *s && isspace( *s ); s ++ ) {} + + if( !oauth_access_token( s, td->oauth_info ) ) { imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); imc_logout( ic, TRUE ); diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h index 614919f9..e61d32be 100644 --- a/protocols/twitter/twitter.h +++ b/protocols/twitter/twitter.h @@ -32,6 +32,11 @@ #define debug( text... ) #endif +typedef enum +{ + TWITTER_HAVE_FRIENDS = 1, +} twitter_flags_t; + struct twitter_data { char* user; @@ -41,6 +46,7 @@ struct twitter_data gint main_loop_id; struct groupchat *home_timeline_gc; gint http_fails; + twitter_flags_t flags; gboolean url_ssl; int url_port; @@ -55,4 +61,6 @@ struct twitter_data */ GSList *twitter_connections; +void twitter_login_finish( struct im_connection *ic ); + #endif //_TWITTER_H diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 585bdd43..d1b65c26 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -41,7 +41,7 @@ struct twitter_xml_list { int type; - int next_cursor; + gint64 next_cursor; GSList *list; gpointer data; }; @@ -58,6 +58,8 @@ struct twitter_xml_status { guint64 id; }; +static void twitter_groupchat_init(struct im_connection *ic); + /** * Frees a twitter_xml_user struct. */ @@ -152,12 +154,12 @@ static void twitter_http_get_friends_ids(struct http_request *req); /** * Get the friends ids. */ -void twitter_get_friends_ids(struct im_connection *ic, int next_cursor) +void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor) { // Primitive, but hey! It works... char* args[2]; args[0] = "cursor"; - args[1] = g_strdup_printf ("%d", next_cursor); + args[1] = g_strdup_printf ("%lld", (long long) next_cursor); twitter_http(ic, TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, args, 2); g_free(args[1]); @@ -168,8 +170,12 @@ void twitter_get_friends_ids(struct im_connection *ic, int next_cursor) */ static xt_status twitter_xt_next_cursor( struct xt_node *node, struct twitter_xml_list *txl ) { - // Do something with the cursor. - txl->next_cursor = node->text != NULL ? atoi(node->text) : -1; + char *end = NULL; + + if( node->text ) + txl->next_cursor = g_ascii_strtoll( node->text, &end, 10 ); + if( end == NULL ) + txl->next_cursor = -1; return XT_HANDLED; } @@ -412,13 +418,13 @@ static void twitter_http_get_home_timeline(struct http_request *req); /** * Get the timeline. */ -void twitter_get_home_timeline(struct im_connection *ic, int next_cursor) +void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) { struct twitter_data *td = ic->proto_data; char* args[4]; args[0] = "cursor"; - args[1] = g_strdup_printf ("%d", next_cursor); + args[1] = g_strdup_printf ("%lld", (long long) next_cursor); if (td->home_timeline_id) { args[2] = "since_id"; args[3] = g_strdup_printf ("%llu", (long long unsigned int) td->home_timeline_id); @@ -432,6 +438,19 @@ void twitter_get_home_timeline(struct im_connection *ic, int next_cursor) } } +static void twitter_groupchat_init(struct im_connection *ic) +{ + char *name_hint; + struct groupchat *gc; + struct twitter_data *td = ic->proto_data; + + td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); + + name_hint = g_strdup_printf( "Twitter_%s", ic->acc->user ); + imcb_chat_name_hint( gc, name_hint ); + g_free( name_hint ); +} + /** * Function that is called to see the statuses in a groupchat window. */ @@ -444,18 +463,11 @@ static void twitter_groupchat(struct im_connection *ic, GSList *list) // Create a new groupchat if it does not exsist. if (!td->home_timeline_gc) - { - char *name_hint = g_strdup_printf( "Twitter_%s", ic->acc->user ); - td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); - imcb_chat_name_hint( gc, name_hint ); - g_free( name_hint ); - // Add the current user to the chat... + twitter_groupchat_init(ic); + + gc = td->home_timeline_gc; + if (!gc->joined) imcb_chat_add_buddy( gc, ic->acc->user ); - } - else - { - gc = td->home_timeline_gc; - } for ( l = list; l ; l = g_slist_next(l) ) { @@ -603,15 +615,23 @@ static void twitter_http_get_statuses_friends(struct http_request *req) td = ic->proto_data; // Check if the HTTP request went well. - if (req->status_code != 200) { + if (req->status_code == 401) + { + imcb_error( ic, "Authentication failure" ); + imc_logout( ic, FALSE ); + return; + } else if (req->status_code != 200) { // It didn't go well, output the error and return. - if (++td->http_fails >= 5) - imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req)); - + imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req)); + imc_logout( ic, TRUE ); return; } else { td->http_fails = 0; } + + if( !td->home_timeline_gc && + g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "chat" ) == 0 ) + twitter_groupchat_init( ic ); txl = g_new0(struct twitter_xml_list, 1); txl->list = NULL; @@ -633,8 +653,15 @@ static void twitter_http_get_statuses_friends(struct http_request *req) // if the next_cursor is set to something bigger then 0 there are more friends to gather. if (txl->next_cursor > 0) + { twitter_get_statuses_friends(ic, txl->next_cursor); - + } + else + { + td->flags |= TWITTER_HAVE_FRIENDS; + twitter_login_finish(ic); + } + // Free the structure. txl_free(txl); g_free(txl); @@ -643,11 +670,11 @@ static void twitter_http_get_statuses_friends(struct http_request *req) /** * Get the friends. */ -void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor) +void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor) { char* args[2]; args[0] = "cursor"; - args[1] = g_strdup_printf ("%d", next_cursor); + args[1] = g_strdup_printf ("%lld", (long long) next_cursor); twitter_http(ic, TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, args, 2); diff --git a/protocols/twitter/twitter_lib.h b/protocols/twitter/twitter_lib.h index 65a596cc..6b90f9bb 100644 --- a/protocols/twitter/twitter_lib.h +++ b/protocols/twitter/twitter_lib.h @@ -75,9 +75,9 @@ #define TWITTER_BLOCKS_CREATE_URL "/blocks/create/" #define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/" -void twitter_get_friends_ids(struct im_connection *ic, int next_cursor); -void twitter_get_home_timeline(struct im_connection *ic, int next_cursor); -void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor); +void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor); +void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor); +void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor); void twitter_post_status(struct im_connection *ic, char *msg); void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message); |