aboutsummaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-05-16 00:28:16 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-05-16 00:28:16 +0100
commitec86b2232da72f7b0c1c0a217d94b6e15698c795 (patch)
tree008111e5ae7d47ba5547be974769bd0751ee9fd0 /protocols
parentca0981ad1e427644a33fc31fe78d63ea834f0fa0 (diff)
parent6e6b3d7c7300c5cf5cf7f1538154925fd2fe3953 (diff)
Mainline merge. (Probably mostly irrelevant for this branch, oh well.)
Diffstat (limited to 'protocols')
-rw-r--r--protocols/jabber/conference.c4
-rw-r--r--protocols/msn/sb.c49
-rw-r--r--protocols/nogaim.c92
-rw-r--r--protocols/oscar/oscar.c139
-rw-r--r--protocols/twitter/twitter.c150
-rw-r--r--protocols/twitter/twitter.h1
-rw-r--r--protocols/twitter/twitter_http.c20
-rw-r--r--protocols/twitter/twitter_http.h4
-rw-r--r--protocols/twitter/twitter_lib.c12
-rw-r--r--protocols/yahoo/yahoo.c9
10 files changed, 271 insertions, 209 deletions
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 );
}
diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c
index e23acc09..1614f69f 100644
--- a/protocols/msn/sb.c
+++ b/protocols/msn/sb.c
@@ -333,9 +333,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 )
{
@@ -352,37 +356,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 )
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 6be6b9ba..cd57a289 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -664,7 +664,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;
@@ -673,14 +684,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 )
@@ -705,11 +732,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;
@@ -722,9 +746,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 );
+ }
}
}
@@ -1201,7 +1259,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 );
}
diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c
index e8e4a027..5633d399 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, B_EV_IO_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};
@@ -2650,7 +2514,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);
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c
index 726c7cb1..98e85641 100644
--- a/protocols/twitter/twitter.c
+++ b/protocols/twitter/twitter.c
@@ -22,11 +22,11 @@
****************************************************************************/
#include "nogaim.h"
+#include "oauth.h"
#include "twitter.h"
#include "twitter_http.h"
#include "twitter_lib.h"
-
/**
* Main loop function
*/
@@ -50,6 +50,89 @@ 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 const 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 )
+{
+ struct twitter_data *td = ic->proto_data;
+
+ imcb_log( ic, "Requesting OAuth request token" );
+
+ td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic );
+}
+
+static gboolean twitter_oauth_callback( struct oauth_info *info )
+{
+ struct im_connection *ic = info->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;
+
+ if( info->request_token == NULL )
+ {
+ imcb_error( ic, "OAuth error: %s", info->http->status_string );
+ imc_logout( ic, TRUE );
+ return FALSE;
+ }
+
+ sprintf( name, "twitter_%s", ic->acc->user );
+ msg = g_strdup_printf( "To finish OAuth authentication, please visit "
+ "%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->token == NULL || info->token_secret == NULL )
+ {
+ imcb_error( ic, "OAuth error: %s", info->http->status_string );
+ imc_logout( ic, TRUE );
+ return FALSE;
+ }
+
+ /* 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 = oauth_to_string( info );
+
+ twitter_main_loop_start( ic );
+ }
+
+ return TRUE;
+}
+
+
static char *set_eval_mode( set_t *set, char *value )
{
if( g_strcasecmp( value, "one" ) == 0 ||
@@ -60,12 +143,28 @@ 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;
+
+ s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc );
}
/**
@@ -79,25 +178,24 @@ 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;
+ ic->flags |= OPT_DOES_HTML;
+
td->user = acc->user;
- td->pass = acc->pass;
+ if( !set_getbool( &acc->set, "oauth" ) )
+ td->pass = 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;
-
- 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_info )
+ twitter_main_loop_start( ic );
+ else
+ twitter_oauth_start( ic );
}
/**
@@ -118,6 +216,8 @@ static void twitter_logout( struct im_connection *ic )
if( td )
{
+ oauth_info_free( td->oauth_info );
+ g_free( td->pass );
g_free( td );
}
@@ -129,12 +229,28 @@ 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_info && td->oauth_info->token == 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 if( twitter_length_check(ic, message) )
+ twitter_post_status(ic, message);
+ }
else
+ {
twitter_direct_messages_new(ic, who, message);
-
+ }
return( 0 );
}
@@ -159,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);
}
diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h
index 88caa104..24f61e42 100644
--- a/protocols/twitter/twitter.h
+++ b/protocols/twitter/twitter.h
@@ -36,6 +36,7 @@ struct twitter_data
{
char* user;
char* pass;
+ struct oauth_info *oauth_info;
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..51f437df 100644
--- a/protocols/twitter/twitter_http.c
+++ b/protocols/twitter/twitter_http.c
@@ -28,15 +28,17 @@
* *
****************************************************************************/
-#include "twitter_http.h"
#include "twitter.h"
#include "bitlbee.h"
#include "url.h"
#include "misc.h"
#include "base64.h"
+#include "oauth.h"
#include <ctype.h>
#include <errno.h>
+#include "twitter_http.h"
+
char *twitter_url_append(char *url, char *key, char* value);
@@ -44,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** 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;
@@ -109,7 +111,19 @@ 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 (oi)
+ {
+ char *full_header;
+
+ 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);
+ 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..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** 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 d58afd73..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, 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, 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, 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, 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, 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]);
}
diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c
index b3d6ea1b..c3ec7bff 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 );
@@ -827,6 +832,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 );