Changeset eb6df6a
- Timestamp:
- 2010-07-11T17:21:21Z (14 years ago)
- Branches:
- master
- Children:
- be999a5
- Parents:
- 3759849 (diff), 00540d4 (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:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
bitlbee.h
r3759849 reb6df6a 38 38 39 39 #define PACKAGE "BitlBee" 40 #define BITLBEE_VERSION "1.2. 7"40 #define BITLBEE_VERSION "1.2.8" 41 41 #define VERSION BITLBEE_VERSION 42 42 #define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 43 #define BITLBEE_VERSION_CODE BITLBEE_VER(1, 2, 7)43 #define BITLBEE_VERSION_CODE BITLBEE_VER(1, 2, 8) 44 44 45 45 #define MAX_STRING 511 -
doc/CHANGES
r3759849 reb6df6a 3 3 4 4 http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on 5 6 Version 1.2.8: 7 - Now always using the AIM-style authentication method for OSCAR connections, 8 even when connecting to ICQ. This solves login issues some people were 9 having. (If you have problems, try changing the old_icq_auth setting.) 10 - Twitter: 11 * Allow changing the Twitter API base URL so the module can also be used 12 for identi.ca or any other compatible network. 13 * Fetch the full list of Twitter contacts instead of slowly adding all 14 contacts as they post a message. 15 * Fixed message length counting. 16 * Allow following/unfollowing people using the usual add/remove commands. 17 * Better error reporting. 18 - Added a user_agent setting to the Jabber module to get around artificial 19 client restrictions. 20 - Allow nick changes (although only before register/identify). 21 - Some more minor bugfixes/etc. 22 23 Finished 4 Jul 2010 5 24 6 25 Version 1.2.7: -
doc/user-guide/commands.xml
r3759849 reb6df6a 633 633 </bitlbee-setting> 634 634 635 <bitlbee-setting name="base_url" type="string" scope="account"> 636 <default>http://twitter.com</default> 637 638 <description> 639 <para> 640 There are more services that understand the Twitter API than just Twitter.com. BitlBee can connect to all Twitter API implementations. 641 </para> 642 643 <para> 644 For example, set this setting to <emphasis>http://identi.ca/api</emphasis> to use Identi.ca. 645 </para> 646 647 <para> 648 Keep two things in mind: When not using Twitter, you <emphasis>must</emphasis> also disable the <emphasis>oauth</emphasis> setting as it currently only works with Twitter. If you're still having issues, make sure there is <emphasis>no</emphasis> slash at the end of the URL you enter here. 649 </para> 650 </description> 651 </bitlbee-setting> 652 635 653 <bitlbee-setting name="buddy_sendbuffer" type="boolean" scope="global"> 636 654 <default>false</default> … … 1231 1249 </bitlbee-setting> 1232 1250 1251 <bitlbee-setting name="user_agent" type="string" scope="account"> 1252 <default>BitlBee</default> 1253 1254 <description> 1255 <para> 1256 Some Jabber servers are configured to only allow a few (or even just one) kinds of XMPP clients to connect to them. 1257 </para> 1258 1259 <para> 1260 You can change this setting to make BitlBee present itself as a different client, so that you can still connect to these servers. 1261 </para> 1262 </description> 1263 </bitlbee-setting> 1264 1233 1265 <bitlbee-setting name="voice_buddies" type="string" scope="global"> 1234 1266 <default>notaway</default> … … 1244 1276 </para> 1245 1277 </description> 1246 1247 1278 </bitlbee-setting> 1248 1279 -
protocols/jabber/iq.c
r3759849 reb6df6a 65 65 if( strcmp( s, XMLNS_VERSION ) == 0 ) 66 66 { 67 xt_add_child( reply, xt_new_node( "name", "BitlBee", NULL ) );67 xt_add_child( reply, xt_new_node( "name", set_getstr( &ic->acc->set, "user_agent" ), NULL ) ); 68 68 xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) ); 69 69 xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) ); … … 105 105 xt_add_attr( c, "category", "client" ); 106 106 xt_add_attr( c, "type", "pc" ); 107 xt_add_attr( c, "name", "BitlBee");107 xt_add_attr( c, "name", set_getstr( &ic->acc->set, "user_agent" ) ); 108 108 xt_add_child( reply, c ); 109 109 -
protocols/jabber/jabber.c
r3759849 reb6df6a 79 79 s = set_add( &acc->set, "tls", "try", set_eval_tls, acc ); 80 80 s->flags |= ACC_SET_OFFLINE_ONLY; 81 82 s = set_add( &acc->set, "user_agent", "BitlBee", NULL, acc ); 81 83 82 84 s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc ); … … 286 288 g_hash_table_destroy( jd->node_cache ); 287 289 290 jabber_buddy_remove_all( ic ); 291 288 292 xt_free( jd->xt ); 289 293 … … 470 474 { 471 475 /* Just any whitespace character is enough as a keepalive for XMPP sessions. */ 472 jabber_write( ic, "\n", 1 ); 476 if( !jabber_write( ic, "\n", 1 ) ) 477 return; 473 478 474 479 /* This runs the garbage collection every minute, which means every packet -
protocols/jabber/jabber.h
r3759849 reb6df6a 230 230 int jabber_buddy_remove( struct im_connection *ic, char *full_jid ); 231 231 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ); 232 void jabber_buddy_remove_all( struct im_connection *ic ); 232 233 time_t jabber_get_timestamp( struct xt_node *xt ); 233 234 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns ); -
protocols/jabber/jabber_util.c
r3759849 reb6df6a 665 665 } 666 666 667 static gboolean jabber_buddy_remove_all_cb( gpointer key, gpointer value, gpointer data ) 668 { 669 struct jabber_buddy *bud, *next; 670 671 bud = value; 672 while( bud ) 673 { 674 next = bud->next; 675 g_free( bud->ext_jid ); 676 g_free( bud->full_jid ); 677 g_free( bud->away_message ); 678 g_free( bud ); 679 bud = next; 680 } 681 682 return TRUE; 683 } 684 685 void jabber_buddy_remove_all( struct im_connection *ic ) 686 { 687 struct jabber_data *jd = ic->proto_data; 688 689 g_hash_table_foreach_remove( jd->buddies, jabber_buddy_remove_all_cb, NULL ); 690 g_hash_table_destroy( jd->buddies ); 691 } 692 667 693 time_t jabber_get_timestamp( struct xt_node *xt ) 668 694 { -
protocols/jabber/message.c
r3759849 reb6df6a 55 55 struct xt_node *inv, *reason; 56 56 57 if( strcmp( ns, XMLNS_MUC_USER ) == 0 &&57 if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 && 58 58 ( inv = xt_find_node( c->children, "invite" ) ) ) 59 59 { -
protocols/twitter/twitter.c
r3759849 reb6df6a 40 40 return 0; 41 41 42 // If the user uses multiple private message windows we need to get the43 // users buddies.44 if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "many") == 0)45 twitter_get_statuses_friends(ic, -1);46 47 42 // Do stuff.. 48 43 twitter_get_home_timeline(ic, -1); … … 56 51 struct twitter_data *td = ic->proto_data; 57 52 58 imcb_log( ic, " Connecting to Twitter" );53 imcb_log( ic, "Getting initial statuses" ); 59 54 60 55 // Run this once. After this queue the main loop function. … … 66 61 } 67 62 63 static void twitter_oauth_start( struct im_connection *ic ); 64 65 void twitter_login_finish( struct im_connection *ic ) 66 { 67 struct twitter_data *td = ic->proto_data; 68 69 if( set_getbool( &ic->acc->set, "oauth" ) && !td->oauth_info ) 70 twitter_oauth_start( ic ); 71 else if( g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "one" ) != 0 && 72 !( td->flags & TWITTER_HAVE_FRIENDS ) ) 73 { 74 imcb_log( ic, "Getting contact list" ); 75 twitter_get_statuses_friends( ic, -1 ); 76 } 77 else 78 twitter_main_loop_start( ic ); 79 } 68 80 69 81 static const struct oauth_service twitter_oauth = … … 128 140 ic->acc->pass = oauth_to_string( info ); 129 141 130 twitter_ main_loop_start( ic );142 twitter_login_finish( ic ); 131 143 } 132 144 … … 211 223 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 212 224 213 if( td->oauth_info || !set_getbool( &acc->set, "oauth" ) ) 214 twitter_main_loop_start( ic ); 215 else 216 twitter_oauth_start( ic ); 225 imcb_log( ic, "Connecting" ); 226 227 twitter_login_finish( ic ); 217 228 } 218 229 … … 236 247 { 237 248 oauth_info_free( td->oauth_info ); 249 g_free( td->url_host ); 250 g_free( td->url_path ); 238 251 g_free( td->pass ); 239 252 g_free( td ); … … 256 269 td->oauth_info && td->oauth_info->token == NULL ) 257 270 { 258 if( !oauth_access_token( message, td->oauth_info ) ) 271 char pin[strlen(message)+1], *s; 272 273 strcpy( pin, message ); 274 for( s = pin + sizeof( pin ) - 2; s > pin && isspace( *s ); s -- ) 275 *s = '\0'; 276 for( s = pin; *s && isspace( *s ); s ++ ) {} 277 278 if( !oauth_access_token( s, td->oauth_info ) ) 259 279 { 260 280 imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); -
protocols/twitter/twitter.h
r3759849 reb6df6a 33 33 #endif 34 34 35 typedef enum 36 { 37 TWITTER_HAVE_FRIENDS = 1, 38 } twitter_flags_t; 39 35 40 struct twitter_data 36 41 { … … 42 47 struct groupchat *home_timeline_gc; 43 48 gint http_fails; 49 twitter_flags_t flags; 44 50 45 51 gboolean url_ssl; … … 56 62 GSList *twitter_connections; 57 63 64 void twitter_login_finish( struct im_connection *ic ); 65 58 66 #endif //_TWITTER_H -
protocols/twitter/twitter_lib.c
r3759849 reb6df6a 42 42 struct twitter_xml_list { 43 43 int type; 44 intnext_cursor;44 gint64 next_cursor; 45 45 GSList *list; 46 46 gpointer data; … … 58 58 guint64 id; 59 59 }; 60 61 static void twitter_groupchat_init(struct im_connection *ic); 60 62 61 63 /** … … 153 155 * Get the friends ids. 154 156 */ 155 void twitter_get_friends_ids(struct im_connection *ic, intnext_cursor)157 void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor) 156 158 { 157 159 // Primitive, but hey! It works... 158 160 char* args[2]; 159 161 args[0] = "cursor"; 160 args[1] = g_strdup_printf ("% d",next_cursor);162 args[1] = g_strdup_printf ("%lld", (long long) next_cursor); 161 163 twitter_http(ic, TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, args, 2); 162 164 … … 169 171 static xt_status twitter_xt_next_cursor( struct xt_node *node, struct twitter_xml_list *txl ) 170 172 { 171 // Do something with the cursor. 172 txl->next_cursor = node->text != NULL ? atoi(node->text) : -1; 173 char *end = NULL; 174 175 if( node->text ) 176 txl->next_cursor = g_ascii_strtoll( node->text, &end, 10 ); 177 if( end == NULL ) 178 txl->next_cursor = -1; 173 179 174 180 return XT_HANDLED; … … 413 419 * Get the timeline. 414 420 */ 415 void twitter_get_home_timeline(struct im_connection *ic, intnext_cursor)421 void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) 416 422 { 417 423 struct twitter_data *td = ic->proto_data; … … 419 425 char* args[4]; 420 426 args[0] = "cursor"; 421 args[1] = g_strdup_printf ("% d",next_cursor);427 args[1] = g_strdup_printf ("%lld", (long long) next_cursor); 422 428 if (td->home_timeline_id) { 423 429 args[2] = "since_id"; … … 431 437 g_free(args[3]); 432 438 } 439 } 440 441 static void twitter_groupchat_init(struct im_connection *ic) 442 { 443 char *name_hint; 444 struct groupchat *gc; 445 struct twitter_data *td = ic->proto_data; 446 447 td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); 448 449 name_hint = g_strdup_printf( "Twitter_%s", ic->acc->user ); 450 imcb_chat_name_hint( gc, name_hint ); 451 g_free( name_hint ); 433 452 } 434 453 … … 445 464 // Create a new groupchat if it does not exsist. 446 465 if (!td->home_timeline_gc) 447 { 448 char *name_hint = g_strdup_printf( "Twitter_%s", ic->acc->user ); 449 td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); 450 imcb_chat_name_hint( gc, name_hint ); 451 g_free( name_hint ); 452 // Add the current user to the chat... 466 twitter_groupchat_init(ic); 467 468 gc = td->home_timeline_gc; 469 if (!gc->joined) 453 470 imcb_chat_add_buddy( gc, ic->acc->user ); 454 }455 else456 {457 gc = td->home_timeline_gc;458 }459 471 460 472 for ( l = list; l ; l = g_slist_next(l) ) … … 604 616 605 617 // Check if the HTTP request went well. 606 if (req->status_code != 200) { 618 if (req->status_code == 401) 619 { 620 imcb_error( ic, "Authentication failure" ); 621 imc_logout( ic, FALSE ); 622 return; 623 } else if (req->status_code != 200) { 607 624 // It didn't go well, output the error and return. 608 if (++td->http_fails >= 5) 609 imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req)); 610 625 imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req)); 626 imc_logout( ic, TRUE ); 611 627 return; 612 628 } else { 613 629 td->http_fails = 0; 614 630 } 631 632 if( !td->home_timeline_gc && 633 g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "chat" ) == 0 ) 634 twitter_groupchat_init( ic ); 615 635 616 636 txl = g_new0(struct twitter_xml_list, 1); … … 634 654 // if the next_cursor is set to something bigger then 0 there are more friends to gather. 635 655 if (txl->next_cursor > 0) 656 { 636 657 twitter_get_statuses_friends(ic, txl->next_cursor); 637 658 } 659 else 660 { 661 td->flags |= TWITTER_HAVE_FRIENDS; 662 twitter_login_finish(ic); 663 } 664 638 665 // Free the structure. 639 666 txl_free(txl); … … 644 671 * Get the friends. 645 672 */ 646 void twitter_get_statuses_friends(struct im_connection *ic, intnext_cursor)673 void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor) 647 674 { 648 675 char* args[2]; 649 676 args[0] = "cursor"; 650 args[1] = g_strdup_printf ("% d",next_cursor);677 args[1] = g_strdup_printf ("%lld", (long long) next_cursor); 651 678 652 679 twitter_http(ic, TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, args, 2); -
protocols/twitter/twitter_lib.h
r3759849 reb6df6a 76 76 #define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/" 77 77 78 void twitter_get_friends_ids(struct im_connection *ic, intnext_cursor);79 void twitter_get_home_timeline(struct im_connection *ic, intnext_cursor);80 void twitter_get_statuses_friends(struct im_connection *ic, intnext_cursor);78 void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor); 79 void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor); 80 void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor); 81 81 82 82 void twitter_post_status(struct im_connection *ic, char *msg); -
storage_xml.c
r3759849 reb6df6a 60 60 char *given_pass; 61 61 xml_pass_st pass_st; 62 int unknown_tag; 62 63 }; 63 64 … … 87 88 irc_t *irc = xd->irc; 88 89 89 if( g_strcasecmp( element_name, "user" ) == 0 ) 90 if( xd->unknown_tag > 0 ) 91 { 92 xd->unknown_tag ++; 93 } 94 else if( g_strcasecmp( element_name, "user" ) == 0 ) 90 95 { 91 96 char *nick = xml_attr( attr_names, attr_values, "nick" ); … … 225 230 else 226 231 { 232 xd->unknown_tag ++; 233 irc_usermsg( irc, "Warning: Unknown XML tag found in configuration file (%s). " 234 "This may happen when downgrading BitlBee versions. " 235 "This tag will be skipped and the information will be lost " 236 "once you save your settings.", element_name ); 237 /* 227 238 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, 228 239 "Unkown element: %s", element_name ); 240 */ 229 241 } 230 242 } … … 234 246 struct xml_parsedata *xd = data; 235 247 236 if( g_strcasecmp( element_name, "setting" ) == 0 && xd->current_setting ) 248 if( xd->unknown_tag > 0 ) 249 { 250 xd->unknown_tag --; 251 } 252 else if( g_strcasecmp( element_name, "setting" ) == 0 && xd->current_setting ) 237 253 { 238 254 g_free( xd->current_setting ); … … 404 420 return STORAGE_ALREADY_EXISTS; 405 421 406 strcat( path, " ~" );407 if( ( fd = open( path, O_WRONLY | O_CREAT | O_TRUNC, 0600) ) < 0 )422 strcat( path, ".XXXXXX" ); 423 if( ( fd = mkstemp( path ) ) < 0 ) 408 424 { 409 425 irc_usermsg( irc, "Error while opening configuration file." ); … … 499 515 close( fd ); 500 516 501 path2 = g_strndup( path, strlen( path ) - 1);517 path2 = g_strndup( path, strlen( path ) - 7 ); 502 518 if( rename( path, path2 ) != 0 ) 503 519 {
Note: See TracChangeset
for help on using the changeset viewer.