Changeset ec86b22
- Timestamp:
- 2010-05-15T23:28:16Z (14 years ago)
- Branches:
- master
- Children:
- 2309152
- Parents:
- ca0981a (diff), 6e6b3d7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
rca0981a rec86b22 79 79 To send tweets yourself, send them to the twitter_(yourusername) contact, or just write in the groupchat channel if you enabled that option. 80 80 </para> 81 82 <para> 83 Since Twitter now requires OAuth authentication, you should not enter your Twitter password into BitlBee. Just type a bogus password. The first time you log in, BitlBee will start OAuth authentication. (See <emphasis>help set oauth</emphasis>.) 84 </para> 81 85 </description> 82 86 </bitlbee-command> … … 659 663 </bitlbee-setting> 660 664 665 <bitlbee-setting name="message_length" type="integer" scope="account"> 666 <default>140</default> 667 668 <description> 669 <para> 670 Since Twitter rejects messages longer than 140 characters, BitlBee can count message length and emit a warning instead of waiting for Twitter to reject it. 671 </para> 672 673 <para> 674 You can change this limit here but this won't disable length checks on Twitter's side. You can also set it to 0 to disable the check in case you believe BitlBee doesn't count the characters correctly. 675 </para> 676 </description> 677 678 </bitlbee-setting> 679 661 680 <bitlbee-setting name="mode" type="string" scope="account"> 662 681 <possible-values>one, many, chat</possible-values> … … 703 722 </bitlbee-setting> 704 723 724 <bitlbee-setting name="oauth" type="boolean" scope="account"> 725 <default>true</default> 726 727 <description> 728 <para> 729 This enables OAuth authentication for Twitter accounts. From June 2010 this will be mandatory. 730 </para> 731 732 <para> 733 With OAuth enabled, you shouldn't tell BitlBee your Twitter password. Just add your account with a bogus password and type <emphasis>account on</emphasis>. BitlBee will then give you a URL to authenticate with Twitter. If this succeeds, Twitter will return a PIN code which you can give back to BitlBee to finish the process. 734 </para> 735 736 <para> 737 The resulting access token will be saved permanently, so you have to do this only once. 738 </para> 739 </description> 740 741 </bitlbee-setting> 742 705 743 <bitlbee-setting name="ops" type="string" scope="global"> 706 744 <default>both</default> … … 834 872 <para> 835 873 Can be set for Jabber- and OSCAR-connections. For Jabber, you might have to set this if the servername isn't equal to the part after the @ in the Jabber handle. For OSCAR this shouldn't be necessary anymore in recent BitlBee versions. 874 </para> 875 </description> 876 </bitlbee-setting> 877 878 <bitlbee-setting name="show_offline" type="boolean" scope="global"> 879 <default>false</default> 880 881 <description> 882 <para> 883 If enabled causes BitlBee to also show offline users in Channel. Online-users will get op, away-users voice and offline users none of both. This option takes effect as soon as you reconnect. 836 884 </para> 837 885 </description> -
irc.c
rca0981a rec86b22 202 202 s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 203 203 s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 204 s = set_add( &irc->set, "show_offline", "false", set_eval_bool, irc ); 204 205 s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); 205 206 s = set_add( &irc->set, "status", NULL, set_eval_away_status, irc ); -
lib/Makefile
rca0981a rec86b22 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ftutil.o12 objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 13 13 14 14 CFLAGS += -Wall -
lib/misc.c
rca0981a rec86b22 306 306 for( i = j = 0; t[i]; i ++, j ++ ) 307 307 { 308 /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */ 309 if( !isalnum( t[i] ) ) 308 if( !isalnum( t[i] ) && !strchr( "._-~", t[i] ) ) 310 309 { 311 310 sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] ); -
lib/url.c
rca0981a rec86b22 27 27 28 28 /* Convert an URL to a url_t structure */ 29 int url_set( url_t *url, c har *set_url )29 int url_set( url_t *url, const char *set_url ) 30 30 { 31 31 char s[MAX_STRING+1]; -
lib/url.h
rca0981a rec86b22 42 42 } url_t; 43 43 44 int url_set( url_t *url, c har *set_url );44 int url_set( url_t *url, const char *set_url ); -
lib/xmltree.c
rca0981a rec86b22 449 449 while( node ) 450 450 { 451 if( g_strcasecmp( node->name, name ) == 0 ) 451 char *colon; 452 453 if( g_strcasecmp( node->name, name ) == 0 || 454 ( ( colon = strchr( node->name, ':' ) ) && 455 g_strcasecmp( colon + 1, name ) == 0 ) ) 452 456 break; 453 457 … … 461 465 { 462 466 int i; 467 char *colon; 463 468 464 469 if( !node ) … … 468 473 if( g_strcasecmp( node->attr[i].key, key ) == 0 ) 469 474 break; 475 476 /* This is an awful hack that only takes care of namespace prefixes 477 inside a tag. Since IMHO excessive namespace usage in XMPP is 478 massive overkill anyway (this code exists for almost four years 479 now and never really missed it): Meh. */ 480 if( !node->attr[i].key && strcmp( key, "xmlns" ) == 0 && 481 ( colon = strchr( node->name, ':' ) ) ) 482 { 483 *colon = '\0'; 484 for( i = 0; node->attr[i].key; i ++ ) 485 if( strncmp( node->attr[i].key, "xmlns:", 6 ) == 0 && 486 strcmp( node->attr[i].key + 6, node->name ) == 0 ) 487 break; 488 *colon = ':'; 489 } 470 490 471 491 return node->attr[i].value; -
protocols/jabber/conference.c
rca0981a rec86b22 272 272 } 273 273 274 if( bud != jc->me ) 275 { 274 if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) 275 { 276 /* If JIDs are anonymized, add them to the local 277 list for the duration of this chat. */ 276 278 imcb_add_buddy( ic, bud->ext_jid, NULL ); 277 279 imcb_buddy_nick_hint( ic, bud->ext_jid, bud->resource ); -
protocols/msn/sb.c
rca0981a rec86b22 334 334 struct msn_data *md = ic->proto_data; 335 335 336 if( msn_handler( sb->handler ) == -1 ) 336 if( msn_handler( sb->handler ) != -1 ) 337 return TRUE; 338 339 if( sb->msgq != NULL ) 337 340 { 338 341 time_t now = time( NULL ); 342 char buf[1024]; 339 343 340 344 if( now - md->first_sb_failure > 600 ) … … 353 357 "There might be problems delivering your messages." ); 354 358 355 if( sb->msgq != NULL ) 356 { 357 char buf[1024]; 358 359 if( md->msgq == NULL ) 360 { 361 md->msgq = sb->msgq; 362 } 363 else 364 { 365 GSList *l; 366 367 for( l = md->msgq; l->next; l = l->next ); 368 l->next = sb->msgq; 369 } 370 sb->msgq = NULL; 371 372 debug( "Moved queued messages back to the main queue, creating a new switchboard to retry." ); 373 g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); 374 if( !msn_write( ic, buf, strlen( buf ) ) ) 375 return FALSE; 376 } 377 378 msn_sb_destroy( sb ); 379 380 return FALSE; 381 } 382 else 383 { 384 return TRUE; 385 } 359 if( md->msgq == NULL ) 360 { 361 md->msgq = sb->msgq; 362 } 363 else 364 { 365 GSList *l; 366 367 for( l = md->msgq; l->next; l = l->next ); 368 l->next = sb->msgq; 369 } 370 sb->msgq = NULL; 371 372 debug( "Moved queued messages back to the main queue, " 373 "creating a new switchboard to retry." ); 374 g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); 375 if( !msn_write( ic, buf, strlen( buf ) ) ) 376 return FALSE; 377 } 378 379 msn_sb_destroy( sb ); 380 return FALSE; 386 381 } 387 382 -
protocols/nogaim.c
rca0981a rec86b22 665 665 u->away = u->status_msg = NULL; 666 666 667 if( ( flags & OPT_LOGGED_IN ) && !u->online ) 668 { 667 if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online ) 668 { 669 /* always set users as online */ 669 670 irc_spawn( ic->irc, u ); 670 671 u->online = 1; 672 if( !( flags & OPT_LOGGED_IN ) ) 673 { 674 /* set away message if user isn't really online */ 675 u->away = g_strdup( "User is offline" ); 676 } 677 } 678 else if( ( flags & OPT_LOGGED_IN ) && !u->online ) 679 { 680 irc_spawn( ic->irc, u ); 681 u->online = 1; 671 682 } 672 683 else if( !( flags & OPT_LOGGED_IN ) && u->online ) … … 674 685 struct groupchat *c; 675 686 676 irc_kill( ic->irc, u ); 677 u->online = 0; 678 679 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 680 for( c = ic->groupchats; c; c = c->next ) 681 remove_chat_buddy_silent( c, handle ); 682 } 683 687 if( set_getbool( &ic->irc->set, "show_offline" ) ) 688 { 689 /* keep offline users in channel and set away message to "offline" */ 690 u->away = g_strdup( "User is offline" ); 691 692 /* Keep showing him/her in the control channel but not in groupchats. */ 693 for( c = ic->groupchats; c; c = c->next ) 694 { 695 if( remove_chat_buddy_silent( c, handle ) && c->joined ) 696 irc_part( c->ic->irc, u, c->channel ); 697 } 698 } 699 else 700 { 701 /* kill offline users */ 702 irc_kill( ic->irc, u ); 703 u->online = 0; 704 705 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 706 for( c = ic->groupchats; c; c = c->next ) 707 remove_chat_buddy_silent( c, handle ); 708 } 709 } 710 684 711 if( flags & OPT_AWAY ) 685 712 { … … 706 733 } 707 734 708 /* LISPy... */ 709 if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 710 ( u->online ) && /* Don't touch offline people */ 711 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 712 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 735 /* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */ 736 if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) ) 713 737 { 714 738 char *from; … … 723 747 ic->irc->myhost ); 724 748 } 725 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, 726 u->away?'-':'+', u->nick ); 727 g_free( from ); 749 750 /* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */ 751 if( flags & OPT_LOGGED_IN ) 752 { 753 /* user is "online" (either really online or away) */ 754 irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel, 755 u->away?'+':'-', u->away?'-':'+', u->nick, u->nick ); 756 } 757 else 758 { 759 /* user is offline */ 760 irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick ); 761 } 762 } 763 else 764 { 765 /* LISPy... */ 766 if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 767 ( u->online ) && /* Don't touch offline people */ 768 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 769 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 770 { 771 char *from; 772 773 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 774 { 775 from = g_strdup( ic->irc->myhost ); 776 } 777 else 778 { 779 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 780 ic->irc->myhost ); 781 } 782 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, 783 u->away?'-':'+', u->nick ); 784 g_free( from ); 785 } 728 786 } 729 787 } … … 1202 1260 return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d " 1203 1261 "%02d:%02d:%02d\x02]\x02 ", 1204 msg.tm_year + 1900, msg.tm_mon , msg.tm_mday,1262 msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday, 1205 1263 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1206 1264 } -
protocols/oscar/oscar.c
rca0981a rec86b22 205 205 static int gaim_icbm_param_info (aim_session_t *, aim_frame_t *, ...); 206 206 static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...); 207 static int gaim_memrequest (aim_session_t *, aim_frame_t *, ...);208 207 static int gaim_selfinfo (aim_session_t *, aim_frame_t *, ...); 209 208 static int gaim_offlinemsg (aim_session_t *, aim_frame_t *, ...); … … 570 569 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ERROR, gaim_parse_genericerr, 0); 571 570 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BOS, AIM_CB_BOS_ERROR, gaim_parse_genericerr, 0); 572 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x1f, gaim_memrequest, 0);573 571 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SELFINFO, gaim_selfinfo, 0); 574 572 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0); … … 604 602 } 605 603 606 struct pieceofcrap {607 struct im_connection *ic;608 unsigned long offset;609 unsigned long len;610 char *modname;611 int fd;612 aim_conn_t *conn;613 unsigned int inpa;614 };615 616 static gboolean damn_you(gpointer data, gint source, b_input_condition c)617 {618 struct pieceofcrap *pos = data;619 struct oscar_data *od = pos->ic->proto_data;620 char in = '\0';621 int x = 0;622 unsigned char m[17];623 624 while (read(pos->fd, &in, 1) == 1) {625 if (in == '\n')626 x++;627 else if (in != '\r')628 x = 0;629 if (x == 2)630 break;631 in = '\0';632 }633 if (in != '\n') {634 imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."635 " You may be disconnected shortly.");636 b_event_remove(pos->inpa);637 closesocket(pos->fd);638 g_free(pos);639 return FALSE;640 }641 /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */642 read(pos->fd, m, 16);643 m[16] = '\0';644 b_event_remove(pos->inpa);645 closesocket(pos->fd);646 aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH);647 g_free(pos);648 649 return FALSE;650 }651 652 static gboolean straight_to_hell(gpointer data, gint source, b_input_condition cond) {653 struct pieceofcrap *pos = data;654 char buf[BUF_LONG];655 656 if (source < 0) {657 imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."658 " You may be disconnected shortly.");659 if (pos->modname)660 g_free(pos->modname);661 g_free(pos);662 return FALSE;663 }664 665 g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA666 "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n",667 pos->offset, pos->len, pos->modname ? pos->modname : "");668 write(pos->fd, buf, strlen(buf));669 if (pos->modname)670 g_free(pos->modname);671 pos->inpa = b_input_add(pos->fd, B_EV_IO_READ, damn_you, pos);672 return FALSE;673 }674 675 604 /* size of icbmui.ocm, the largest module in AIM 3.5 */ 676 605 #define AIM_MAX_FILE_SIZE 98304 677 678 int gaim_memrequest(aim_session_t *sess, aim_frame_t *fr, ...) {679 va_list ap;680 struct pieceofcrap *pos;681 guint32 offset, len;682 char *modname;683 int fd;684 685 va_start(ap, fr);686 offset = (guint32)va_arg(ap, unsigned long);687 len = (guint32)va_arg(ap, unsigned long);688 modname = va_arg(ap, char *);689 va_end(ap);690 691 if (len == 0) {692 aim_sendmemblock(sess, fr->conn, offset, len, NULL,693 AIM_SENDMEMBLOCK_FLAG_ISREQUEST);694 return 1;695 }696 /* uncomment this when you're convinced it's right. remember, it's been wrong before.697 if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) {698 char *buf;699 int i = 8;700 if (modname)701 i += strlen(modname);702 buf = g_malloc(i);703 i = 0;704 if (modname) {705 memcpy(buf, modname, strlen(modname));706 i += strlen(modname);707 }708 buf[i++] = offset & 0xff;709 buf[i++] = (offset >> 8) & 0xff;710 buf[i++] = (offset >> 16) & 0xff;711 buf[i++] = (offset >> 24) & 0xff;712 buf[i++] = len & 0xff;713 buf[i++] = (len >> 8) & 0xff;714 buf[i++] = (len >> 16) & 0xff;715 buf[i++] = (len >> 24) & 0xff;716 aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);717 g_free(buf);718 return 1;719 }720 */721 722 pos = g_new0(struct pieceofcrap, 1);723 pos->ic = sess->aux_data;724 pos->conn = fr->conn;725 726 pos->offset = offset;727 pos->len = len;728 pos->modname = modname ? g_strdup(modname) : NULL;729 730 fd = proxy_connect("gaim.sourceforge.net", 80, straight_to_hell, pos);731 if (fd < 0) {732 if (pos->modname)733 g_free(pos->modname);734 g_free(pos);735 imcb_error(sess->aux_data, "Gaim was unable to get a valid hash for logging into AIM."736 " You may be disconnected shortly.");737 }738 pos->fd = fd;739 740 return 1;741 }742 606 743 607 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { … … 2651 2515 char * chatname; 2652 2516 2653 chatname = g_strdup_printf("%s%d", ic->acc->user, chat_id++); 2517 chatname = g_strdup_printf("%s%s_%d", isdigit(*ic->acc->user) ? "icq_" : "", 2518 ic->acc->user, chat_id++); 2654 2519 2655 2520 ret = oscar_chat_join(ic, chatname, NULL, NULL); -
protocols/twitter/twitter.c
rca0981a rec86b22 23 23 24 24 #include "nogaim.h" 25 #include "oauth.h" 25 26 #include "twitter.h" 26 27 #include "twitter_http.h" 27 28 #include "twitter_lib.h" 28 29 29 30 30 /** … … 50 50 return (ic->flags & OPT_LOGGED_IN) == OPT_LOGGED_IN; 51 51 } 52 53 static void twitter_main_loop_start( struct im_connection *ic ) 54 { 55 struct twitter_data *td = ic->proto_data; 56 57 imcb_log( ic, "Connecting to Twitter" ); 58 59 // Run this once. After this queue the main loop function. 60 twitter_main_loop(ic, -1, 0); 61 62 // Queue the main_loop 63 // Save the return value, so we can remove the timeout on logout. 64 td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); 65 } 66 67 68 static const struct oauth_service twitter_oauth = 69 { 70 "http://api.twitter.com/oauth/request_token", 71 "http://api.twitter.com/oauth/access_token", 72 "http://api.twitter.com/oauth/authorize", 73 .consumer_key = "xsDNKJuNZYkZyMcu914uEA", 74 .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo", 75 }; 76 77 static gboolean twitter_oauth_callback( struct oauth_info *info ); 78 79 static void twitter_oauth_start( struct im_connection *ic ) 80 { 81 struct twitter_data *td = ic->proto_data; 82 83 imcb_log( ic, "Requesting OAuth request token" ); 84 85 td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic ); 86 } 87 88 static gboolean twitter_oauth_callback( struct oauth_info *info ) 89 { 90 struct im_connection *ic = info->data; 91 struct twitter_data *td; 92 93 if( !g_slist_find( twitter_connections, ic ) ) 94 return FALSE; 95 96 td = ic->proto_data; 97 if( info->stage == OAUTH_REQUEST_TOKEN ) 98 { 99 char name[strlen(ic->acc->user)+9], *msg; 100 101 if( info->request_token == NULL ) 102 { 103 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 104 imc_logout( ic, TRUE ); 105 return FALSE; 106 } 107 108 sprintf( name, "twitter_%s", ic->acc->user ); 109 msg = g_strdup_printf( "To finish OAuth authentication, please visit " 110 "%s and respond with the resulting PIN code.", 111 info->auth_url ); 112 imcb_buddy_msg( ic, name, msg, 0, 0 ); 113 g_free( msg ); 114 } 115 else if( info->stage == OAUTH_ACCESS_TOKEN ) 116 { 117 if( info->token == NULL || info->token_secret == NULL ) 118 { 119 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 120 imc_logout( ic, TRUE ); 121 return FALSE; 122 } 123 124 /* IM mods didn't do this so far and it's ugly but I should 125 be able to get away with it... */ 126 g_free( ic->acc->pass ); 127 ic->acc->pass = oauth_to_string( info ); 128 129 twitter_main_loop_start( ic ); 130 } 131 132 return TRUE; 133 } 134 52 135 53 136 static char *set_eval_mode( set_t *set, char *value ) … … 61 144 } 62 145 146 static gboolean twitter_length_check( struct im_connection *ic, gchar *msg ) 147 { 148 int max = set_getint( &ic->acc->set, "message_length" ), len; 149 150 if( max == 0 || ( len = g_utf8_strlen( msg, -1 ) ) <= max ) 151 return TRUE; 152 153 imcb_error( ic, "Maximum message length exceeded: %d > %d", len, max ); 154 155 return FALSE; 156 } 157 63 158 static void twitter_init( account_t *acc ) 64 159 { 65 160 set_t *s; 161 162 s = set_add( &acc->set, "message_length", "140", set_eval_int, acc ); 66 163 67 164 s = set_add( &acc->set, "mode", "one", set_eval_mode, acc ); 68 165 s->flags |= ACC_SET_OFFLINE_ONLY; 166 167 s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc ); 69 168 } 70 169 … … 80 179 81 180 twitter_connections = g_slist_append( twitter_connections, ic ); 82 181 ic->proto_data = td; 182 ic->flags |= OPT_DOES_HTML; 183 83 184 td->user = acc->user; 84 td->pass = acc->pass; 185 if( !set_getbool( &acc->set, "oauth" ) ) 186 td->pass = g_strdup( acc->pass ); 187 else if( strstr( acc->pass, "oauth_token=" ) ) 188 td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth ); 85 189 td->home_timeline_id = 0; 86 87 ic->proto_data = td;88 89 imcb_log( ic, "Connecting to Twitter" );90 91 // Run this once. After this queue the main loop function.92 twitter_main_loop(ic, -1, 0);93 94 // Queue the main_loop95 // Save the return value, so we can remove the timeout on logout.96 td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);97 190 98 191 sprintf( name, "twitter_%s", acc->user ); 99 192 imcb_add_buddy( ic, name, NULL ); 100 193 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 194 195 if( td->pass || td->oauth_info ) 196 twitter_main_loop_start( ic ); 197 else 198 twitter_oauth_start( ic ); 101 199 } 102 200 … … 119 217 if( td ) 120 218 { 219 oauth_info_free( td->oauth_info ); 220 g_free( td->pass ); 121 221 g_free( td ); 122 222 } … … 130 230 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) 131 231 { 232 struct twitter_data *td = ic->proto_data; 233 132 234 if (g_strncasecmp(who, "twitter_", 8) == 0 && 133 235 g_strcasecmp(who + 8, ic->acc->user) == 0) 134 twitter_post_status(ic, message); 236 { 237 if( set_getbool( &ic->acc->set, "oauth" ) && 238 td->oauth_info && td->oauth_info->token == NULL ) 239 { 240 if( !oauth_access_token( message, td->oauth_info ) ) 241 { 242 imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); 243 imc_logout( ic, TRUE ); 244 return FALSE; 245 } 246 } 247 else if( twitter_length_check(ic, message) ) 248 twitter_post_status(ic, message); 249 } 135 250 else 251 { 136 252 twitter_direct_messages_new(ic, who, message); 137 253 } 138 254 return( 0 ); 139 255 } … … 160 276 static void twitter_chat_msg( struct groupchat *c, char *message, int flags ) 161 277 { 162 if( c && message )278 if( c && message && twitter_length_check(c->ic, message)) 163 279 twitter_post_status(c->ic, message); 164 280 } -
protocols/twitter/twitter.h
rca0981a rec86b22 37 37 char* user; 38 38 char* pass; 39 struct oauth_info *oauth_info; 39 40 guint64 home_timeline_id; 40 41 gint main_loop_id; -
protocols/twitter/twitter_http.c
rca0981a rec86b22 29 29 ****************************************************************************/ 30 30 31 #include "twitter_http.h"32 31 #include "twitter.h" 33 32 #include "bitlbee.h" … … 35 34 #include "misc.h" 36 35 #include "base64.h" 36 #include "oauth.h" 37 37 #include <ctype.h> 38 38 #include <errno.h> 39 40 #include "twitter_http.h" 39 41 40 42 … … 45 47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c 46 48 */ 47 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len)49 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) 48 50 { 49 51 url_t *url = g_new0( url_t, 1 ); … … 110 112 111 113 // If a pass and user are given we append them to the request. 112 if (userpass_base64) 114 if (oi) 115 { 116 char *full_header; 117 118 full_header = oauth_http_header(oi, is_post ? "POST" : "GET", 119 url_string, url_arguments); 120 121 tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); 122 g_free(request); 123 g_free(full_header); 124 request = tmp; 125 } 126 else if (userpass_base64) 113 127 { 114 128 tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64); -
protocols/twitter/twitter_http.h
rca0981a rec86b22 28 28 #include "http_client.h" 29 29 30 struct oauth_info; 31 30 32 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, 31 char* user, char* pass, char** arguments, int arguments_len);33 char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len); 32 34 33 35 #endif //_TWITTER_HTTP_H -
protocols/twitter/twitter_lib.c
rca0981a rec86b22 130 130 args[0] = "cursor"; 131 131 args[1] = g_strdup_printf ("%d", next_cursor); 132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2);132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 133 133 134 134 g_free(args[1]); … … 396 396 } 397 397 398 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2);398 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); 399 399 400 400 g_free(args[1]); … … 510 510 { 511 511 td->http_fails = 0; 512 if (! ic->flags & OPT_LOGGED_IN)512 if (!(ic->flags & OPT_LOGGED_IN)) 513 513 imcb_connected(ic); 514 514 } … … 620 620 args[1] = g_strdup_printf ("%d", next_cursor); 621 621 622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2);622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 623 623 624 624 g_free(args[1]); … … 654 654 args[0] = "status"; 655 655 args[1] = msg; 656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2);656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2); 657 657 // g_free(args[1]); 658 658 } … … 672 672 args[3] = msg; 673 673 // Use the same callback as for twitter_post_status, since it does basically the same. 674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4);674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4); 675 675 // g_free(args[1]); 676 676 // g_free(args[3]); -
protocols/yahoo/yahoo.c
rca0981a rec86b22 138 138 struct im_connection *ic = imcb_new( acc ); 139 139 struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 ); 140 char *s; 140 141 141 142 yd->logged_in = FALSE; 142 143 yd->current_status = YAHOO_STATUS_AVAILABLE; 144 145 if( ( s = strchr( acc->user, '@' ) ) && g_strcasecmp( s, "@yahoo.com" ) == 0 ) 146 imcb_error( ic, "Your Yahoo! username should just be a username. " 147 "Do not include any @domain part." ); 143 148 144 149 imcb_log( ic, "Connecting" ); … … 828 833 YList *m; 829 834 835 if( g_strcasecmp( who, ic->acc->user ) == 0 ) 836 /* WTF, Yahoo! seems to echo these now? */ 837 return; 838 830 839 inv = g_malloc( sizeof( struct byahoo_conf_invitation ) ); 831 840 memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
Note: See TracChangeset
for help on using the changeset viewer.