aboutsummaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/jabber/iq.c4
-rw-r--r--protocols/jabber/jabber.c7
-rw-r--r--protocols/jabber/jabber.h1
-rw-r--r--protocols/jabber/jabber_util.c26
-rw-r--r--protocols/jabber/message.c2
-rw-r--r--protocols/twitter/twitter.c44
-rw-r--r--protocols/twitter/twitter.h8
-rw-r--r--protocols/twitter/twitter_lib.c77
-rw-r--r--protocols/twitter/twitter_lib.h6
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);