Changes in / [5a8afc3:3f44e43]
- Files:
-
- 7 added
- 4 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r5a8afc3 r3f44e43 32 32 bitlbee.service 33 33 bitlbee@.service 34 *.pyc -
configure
r5a8afc3 r3f44e43 16 16 config='/var/lib/bitlbee/' 17 17 plugindir='$prefix/lib/bitlbee/' 18 rpcplugindir='$plugindir/rpc/' 18 19 includedir='$prefix/include/bitlbee/' 19 20 systemdsystemunitdir='' … … 38 39 twitter=1 39 40 purple=0 41 rpc=1 40 42 41 43 doc=1 … … 122 124 --datadir=... $datadir 123 125 --plugindir=... $plugindir 126 --rpcplugindir=... $rpcplugindir 124 127 --systemdsystemunitdir=... $systemdsystemunitdir 125 128 --pidfile=... $pidfile … … 133 136 --purple=0/1 Disable/enable libpurple support $purple 134 137 (automatically disables other protocol modules) 138 --rpc=0/1 Disable/enable RPC plugin interface $rpc 135 139 136 140 --pam=0/1 Disable/enable PAM authentication $pam … … 171 175 config=$(eval echo "$config/" | sed 's/\/\{1,\}/\//g') 172 176 plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g') 177 rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g') 173 178 includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g') 174 179 libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g') … … 192 197 DATADIR=$datadir 193 198 PLUGINDIR=$plugindir 199 RPCPLUGINDIR=$rpcplugindir 194 200 CONFIG=$config 195 201 INCLUDEDIR=$includedir … … 241 247 #define VARDIR "$datadir" 242 248 #define PLUGINDIR "$plugindir" 249 #define RPCPLUGINDIR "$rpcplugindir" 243 250 #define PIDFILE "$pidfile" 244 251 #define IPCSOCKET "$ipcsocket" … … 281 288 LDFLAGS="$LDFLAGS -fsanitize=address" 282 289 debug=1 290 fi 291 292 if [ "$tsan" = "1" ]; then 293 echo 294 echo "Threaded BitlBee? Have a nice tall glass of http://imgur.com/gallery/tX4qxzS" 295 echo "No need to sanitise threads in a single-threaded process!" 283 296 fi 284 297 … … 704 717 fi 705 718 719 if [ "$rpc" = 0 ]; then 720 # Somewhat pointless at this stage already but at least this keeps it 721 # out of bitlbee.pc which is probably a good thing. 722 rpcplugindir="" 723 fi 724 706 725 otrprefix="" 707 726 if [ "$otr" = "auto" ]; then … … 782 801 includedir=$includedir 783 802 plugindir=$plugindir 803 rpcplugindir=$rpcplugindir 784 804 785 805 Name: bitlbee … … 865 885 protocols=$protocols'twitter ' 866 886 protoobjs=$protoobjs'twitter_mod.o ' 887 fi 888 889 if [ "$rpc" = 0 ]; then 890 echo '#undef WITH_RPC' >> config.h 891 else 892 echo '#define WITH_RPC' >> config.h 893 protocols=$protocols'rpc ' 894 protoobjs=$protoobjs'rpc_mod.o ' 867 895 fi 868 896 … … 954 982 echo ' Using event handler: '$events 955 983 echo ' Using SSL library: '$ssl 956 #echo ' Building with these storage backends: '$STORAGES957 984 958 985 if [ -n "$protocols" ]; then -
irc_channel.c
r5a8afc3 r3f44e43 757 757 } 758 758 759 if (!bu->ic->acc->prpl->add_buddy) { 760 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name); 761 return FALSE; 762 } 763 759 764 bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle, 760 765 icc->group ? icc->group->name : NULL); … … 774 779 if (icc->type != IRC_CC_TYPE_GROUP) { 775 780 irc_send_num(ic->irc, 482, "%s :Kicks are only possible to fill_by=group channels", ic->name); 781 return; 782 } 783 784 if (!bu->ic->acc->prpl->remove_buddy) { 785 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name); 776 786 return; 777 787 } -
irc_commands.c
r5a8afc3 r3f44e43 287 287 showed an error message, or is doing some work 288 288 before the join should be confirmed. (In the 289 latter case, the calle rshould take care of that289 latter case, the callee should take care of that 290 290 confirmation.) TRUE means all's good, let the 291 291 user join the channel right away. */ -
lib/Makefile
r5a8afc3 r3f44e43 13 13 14 14 # [SH] Program variables 15 objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o json.o json_util.o md5.o misc.o oauth.o oauth2.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ns_parse.o15 objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o oauth2.o parson.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ns_parse.o 16 16 17 17 LFLAGS += -r -
lib/misc.c
r5a8afc3 r3f44e43 431 431 } 432 432 433 int is_bool(c har *value)433 int is_bool(const char *value) 434 434 { 435 435 if (*value == 0) { … … 457 457 } 458 458 459 int bool2int(c har *value)459 int bool2int(const char *value) 460 460 { 461 461 int i; -
lib/misc.h
r5a8afc3 r3f44e43 137 137 G_MODULE_EXPORT void random_bytes(unsigned char *buf, int count); 138 138 139 G_MODULE_EXPORT int is_bool(c har *value);140 G_MODULE_EXPORT int bool2int(c har *value);139 G_MODULE_EXPORT int is_bool(const char *value); 140 G_MODULE_EXPORT int bool2int(const char *value); 141 141 142 142 G_MODULE_EXPORT struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain); -
lib/oauth2.c
r5a8afc3 r3f44e43 42 42 #include "oauth2.h" 43 43 #include "oauth.h" 44 #include "json.h" 45 #include "json_util.h" 44 #include "parson.h" 46 45 #include "url.h" 46 47 #define JSON_O_FOREACH(o, k, v) \ 48 const char *k; const JSON_Value *v; int __i; \ 49 for (__i = 0; json_object_get_tuple(o, __i, &k, &v); __i++) 47 50 48 51 char *oauth2_url(const struct oauth2_service *sp) … … 113 116 } 114 117 115 static char* oauth2_parse_error( json_value *e)118 static char* oauth2_parse_error(const JSON_Value *e) 116 119 { 117 120 /* This does a reasonable job with some of the flavours of error 118 121 responses I've seen. Because apparently it's not standardised. */ 119 122 120 if ( e->type == json_object) {123 if (json_type(e) == JSONObject) { 121 124 /* Facebook style */ 122 const char *msg = json_o_str(e, "message"); 123 const char *type = json_o_str(e, "type"); 124 json_value *code_o = json_o_get(e, "code"); 125 int code = 0; 126 127 if (code_o && code_o->type == json_integer) { 128 code = code_o->u.integer; 129 } 130 125 const char *msg = json_object_get_string(json_object(e), "message"); 126 const char *type = json_object_get_string(json_object(e), "type"); 127 JSON_Value *code_o = json_object_get_value(json_object(e), "code"); 128 int code = json_value_get_integer(code_o); 131 129 return g_strdup_printf("Error %d: %s", code, msg ? msg : type ? type : "Unknown error"); 132 } else if ( e->type == json_string) {133 return g_strdup( e->u.string.ptr);130 } else if (json_type(e) == JSONString) { 131 return g_strdup(json_string(e)); 134 132 } 135 133 return NULL; … … 156 154 if (content_type && (strstr(content_type, "application/json") || 157 155 strstr(content_type, "text/javascript"))) { 158 json_value *js = json_parse(req->reply_body, req->body_size);159 if (js && js ->type == json_object) {160 JSON_O_FOREACH(js , k, v){156 JSON_Value *js = json_parse_string(req->reply_body); 157 if (js && json_type(js) == JSONObject) { 158 JSON_O_FOREACH(json_object(js), k, v){ 161 159 if (strcmp(k, "error") == 0) { 162 160 error = oauth2_parse_error(v); 163 161 } 164 if ( v->type != json_string) {162 if (json_type(v) != JSONString) { 165 163 continue; 166 164 } 167 165 if (strcmp(k, "access_token") == 0) { 168 atoken = g_strdup( v->u.string.ptr);166 atoken = g_strdup(json_string(v)); 169 167 } 170 168 if (strcmp(k, "refresh_token") == 0) { 171 rtoken = g_strdup( v->u.string.ptr);169 rtoken = g_strdup(json_string(v)); 172 170 } 173 171 } -
protocols/account.c
r5a8afc3 r3f44e43 27 27 #include "bitlbee.h" 28 28 #include "account.h" 29 30 static const char* account_protocols_local[] = {31 "gg", "whatsapp", NULL32 };33 29 34 30 static char *set_eval_nick_source(set_t *set, char *value); … … 466 462 return a->auto_reconnect_delay; 467 463 } 468 469 int protocol_account_islocal(const char* protocol)470 {471 const char** p = account_protocols_local;472 473 do {474 if (strcmp(*p, protocol) == 0) {475 return 1;476 }477 } while (*(++p));478 return 0;479 } -
protocols/account.h
r5a8afc3 r3f44e43 58 58 int account_reconnect_delay(account_t *a); 59 59 60 int protocol_account_islocal(const char* protocol);61 62 60 typedef enum { 63 61 ACC_SET_OFFLINE_ONLY = 0x02, /* Allow changes only if the acct is offline. */ … … 70 68 ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */ 71 69 ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */ 72 ACC_FLAG_LOCAL = 0x08,/* Contact list is local. */70 ACC_FLAG_LOCAL_CONTACTS = 0x08, /* Contact list is local. */ 73 71 ACC_FLAG_LOCKED = 0x10, /* Account is locked (cannot be deleted, certain settings can't changed) */ 74 72 } account_flag_t; -
protocols/nogaim.c
r5a8afc3 r3f44e43 241 241 extern void twitter_initmodule(); 242 242 extern void purple_initmodule(); 243 extern void rpc_initmodule(); 243 244 244 245 #ifdef WITH_MSN … … 260 261 #ifdef WITH_PURPLE 261 262 purple_initmodule(); 263 #endif 264 265 #ifdef WITH_RPC 266 rpc_initmodule(); 262 267 #endif 263 268 … … 425 430 } 426 431 427 if (ic->acc->flags & ACC_FLAG_LOCAL) { 432 if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) && 433 !(ic->flags & OPT_LOCAL_CONTACTS_SENT) && 434 ic->acc->prpl->add_buddy) { 428 435 GHashTableIter nicks; 429 gpointer k, v;436 gpointer handle; 430 437 g_hash_table_iter_init(&nicks, ic->acc->nicks); 431 while (g_hash_table_iter_next(&nicks, & k, &v)) {432 ic->acc->prpl->add_buddy(ic, (char *) k, NULL);438 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 439 ic->acc->prpl->add_buddy(ic, (char *) handle, NULL); 433 440 } 434 441 } … … 525 532 query_del_by_conn((irc_t *) ic->bee->ui_data, ic); 526 533 534 /* Throw away groupchats owned by this account. Historically this was only 535 ever done by IM modules which is a bug. But it gives them opportunity 536 to clean up protocol-specific bits as well so keep it that way, just 537 do another cleanup here as a fallback. Don't want to leave any dangling 538 pointers! */ 539 while (ic->groupchats) { 540 imcb_chat_free(ic->groupchats->data); 541 } 542 527 543 if (!a) { 528 544 /* Uhm... This is very sick. */ … … 623 639 } 624 640 641 /* Returns the local contacts for an IM account (based on assigned nicks). 642 Linked list should be freed, the strings themselves not! So look at it 643 like a GSList<const char*> I guess? Empty list means NULL retval (as 644 always with GSList). */ 645 GSList *imcb_get_local_contacts(struct im_connection *ic) 646 { 647 GHashTableIter nicks; 648 GSList *ret = NULL; 649 650 if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) { 651 /* Only allow protocols that indicate local contact list 652 support to use this function. */ 653 return ret; 654 } 655 656 g_hash_table_iter_init(&nicks, ic->acc->nicks); 657 gpointer handle; 658 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 659 ret = g_slist_prepend(ret, (char *) handle); 660 } 661 662 /* If the protocol asked for the list, assume we won't have to send it 663 anymore in imcb_connected(). */ 664 ic->flags |= OPT_LOCAL_CONTACTS_SENT; 665 666 return ret; 667 } 668 669 625 670 struct imcb_ask_cb_data { 626 671 struct im_connection *ic; … … 680 725 struct imcb_ask_cb_data *cbd = data; 681 726 682 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 727 if (cbd->ic->acc->prpl->add_buddy) { 728 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 729 } 683 730 684 731 imcb_ask_cb_free(data); -
protocols/nogaim.h
r5a8afc3 r3f44e43 57 57 58 58 /* Sharing flags between all kinds of things. I just hope I won't hit any 59 limits before 32-bit machines become extinct. ;-) */ 59 limits before 32-bit machines become extinct. ;-) 60 61 Argh! This needs to be renamed to be more clear which field they're used 62 for. As said it's currently mixed which is nonsense. Some are for the 63 im_connection flags field, some for imcb_buddy_status(), some for typing 64 notifications, and who knows what else... */ 60 65 #define OPT_LOGGED_IN 0x00000001 61 66 #define OPT_LOGGING_OUT 0x00000002 … … 70 75 #define OPT_PONGS 0x00010000 /* Service sends us keep-alives */ 71 76 #define OPT_PONGED 0x00020000 /* Received a keep-alive during last interval */ 77 #define OPT_LOCAL_CONTACTS_SENT 0x00040000 /* Protocol already requested local contact list, so don't send it after finishing login. */ 72 78 #define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */ 73 79 … … 372 378 G_MODULE_EXPORT void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick); 373 379 G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data); 380 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic); 374 381 375 382 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags); -
protocols/purple/purple.c
r5a8afc3 r3f44e43 298 298 } 299 299 purple_accounts_remove(pa); 300 301 /* Last, some protocols want their contact lists locally. */ 302 if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) { 303 acc->flags |= ACC_FLAG_LOCAL_CONTACTS; 304 } 300 305 } 301 306 -
protocols/twitter/twitter_lib.c
r5a8afc3 r3f44e43 36 36 #include "base64.h" 37 37 #include "twitter_lib.h" 38 #include " json_util.h"38 #include "parson.h" 39 39 #include <ctype.h> 40 40 #include <errno.h> … … 64 64 gboolean from_filter; 65 65 }; 66 67 #define JSON_O_FOREACH(o, k, v) \ 68 const char *k; const JSON_Value *v; int __i; \ 69 for (__i = 0; json_object_get_tuple(o, __i, &k, &v); __i++) 66 70 67 71 /** … … 166 170 { 167 171 static char *ret = NULL; 168 json_value *root, *err;172 JSON_Value *root, *err; 169 173 170 174 g_free(ret); … … 172 176 173 177 if (req->body_size > 0) { 174 root = json_parse(req->reply_body, req->body_size); 175 err = json_o_get(root, "errors"); 176 if (err && err->type == json_array && (err = err->u.array.values[0]) && 177 err->type == json_object) { 178 const char *msg = json_o_str(err, "message"); 178 root = json_parse_string(req->reply_body); 179 err = json_object_get_value(json_object(root), "errors"); 180 if (err && json_type(err) == JSONArray && 181 (err = json_array_get_value(json_array(err), 0)) && 182 json_type(err) == JSONObject) { 183 const char *msg = json_object_get_string(json_object(err), "message"); 179 184 if (msg) { 180 185 ret = g_strdup_printf("%s (%s)", req->status_string, msg); … … 189 194 /* WATCH OUT: This function might or might not destroy your connection. 190 195 Sub-optimal indeed, but just be careful when this returns NULL! */ 191 static json_value *twitter_parse_response(struct im_connection *ic, struct http_request *req)196 static JSON_Value *twitter_parse_response(struct im_connection *ic, struct http_request *req) 192 197 { 193 198 gboolean logging_in = !(ic->flags & OPT_LOGGED_IN); 194 199 gboolean periodic; 195 200 struct twitter_data *td = ic->proto_data; 196 json_value *ret;201 JSON_Value *ret; 197 202 char path[64] = "", *s; 198 203 … … 232 237 } 233 238 234 if ((ret = json_parse (req->reply_body, req->body_size)) == NULL) {239 if ((ret = json_parse_string(req->reply_body)) == NULL) { 235 240 imcb_error(ic, "Could not retrieve %s: %s", 236 241 path, "XML parse error"); … … 289 294 * Fill a list of ids. 290 295 */ 291 static gboolean twitter_xt_get_friends_id_list( json_value *node, struct twitter_xml_list *txl)292 { 293 json_value*c;296 static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl) 297 { 298 JSON_Array *c; 294 299 int i; 295 300 … … 297 302 txl->type = TXL_ID; 298 303 299 c = json_o_get(node, "ids"); 300 if (!c || c->type != json_array) { 304 if (!(c = json_object_get_array(json_object(node), "ids"))) { 301 305 return FALSE; 302 306 } 303 307 304 for (i = 0; i < c->u.array.length; i++) { 305 if (c->u.array.values[i]->type != json_integer) { 306 continue; 307 } 308 for (i = 0; i < json_array_get_count(c); i++) { 309 jint id = json_array_get_integer(c, i); 308 310 309 311 txl->list = g_slist_prepend(txl->list, 310 g_strdup_printf("% " PRIu64, c->u.array.values[i]->u.integer));311 } 312 313 c = json_o_get(node, "next_cursor");314 if ( c && c->type == json_integer) {315 txl->next_cursor = c->u.integer;312 g_strdup_printf("%lld", id)); 313 } 314 315 JSON_Value *next = json_object_get_value(json_object(node), "next_cursor"); 316 if (next && json_type(next) == JSONInteger) { 317 txl->next_cursor = json_integer(next); 316 318 } else { 317 319 txl->next_cursor = -1; … … 329 331 { 330 332 struct im_connection *ic; 331 json_value *parsed;333 JSON_Value *parsed; 332 334 struct twitter_xml_list *txl; 333 335 struct twitter_data *td; … … 373 375 { 374 376 struct im_connection *ic = req->data; 375 json_value *parsed;377 JSON_Value *parsed; 376 378 struct twitter_xml_list *txl; 377 379 struct twitter_data *td; … … 418 420 { 419 421 struct im_connection *ic = req->data; 420 json_value *parsed;422 JSON_Value *parsed; 421 423 struct twitter_xml_list *txl; 422 424 struct twitter_data *td; … … 444 446 // Process the retweet ids 445 447 txl->type = TXL_ID; 446 if (parsed->type == json_array) { 448 if (json_type(parsed) == JSONArray) { 449 JSON_Array *arr = json_array(parsed); 447 450 unsigned int i; 448 for (i = 0; i < parsed->u.array.length; i++) { 449 json_value *c = parsed->u.array.values[i]; 450 if (c->type != json_integer) { 451 continue; 452 } 451 for (i = 0; i < json_array_get_count(arr); i++) { 452 jint id = json_array_get_integer(arr, i); 453 453 txl->list = g_slist_prepend(txl->list, 454 g_strdup_printf("% "PRIu64, c->u.integer));454 g_strdup_printf("%lld", id)); 455 455 } 456 456 } … … 463 463 } 464 464 465 static gboolean twitter_xt_get_users( json_value *node, struct twitter_xml_list *txl);465 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl); 466 466 static void twitter_http_get_users_lookup(struct http_request *req); 467 467 … … 504 504 { 505 505 struct im_connection *ic = req->data; 506 json_value *parsed;506 JSON_Value *parsed; 507 507 struct twitter_xml_list *txl; 508 508 GSList *l = NULL; … … 537 537 } 538 538 539 struct twitter_xml_user *twitter_xt_get_user(const json_value*node)539 struct twitter_xml_user *twitter_xt_get_user(const JSON_Object *node) 540 540 { 541 541 struct twitter_xml_user *txu; 542 json_value *jv; 542 543 if (!node) 544 return NULL; 543 545 544 546 txu = g_new0(struct twitter_xml_user, 1); 545 txu->name = g_strdup(json_o_str(node, "name")); 546 txu->screen_name = g_strdup(json_o_str(node, "screen_name")); 547 548 jv = json_o_get(node, "id"); 549 txu->uid = jv->u.integer; 547 txu->name = g_strdup(json_object_get_string(node, "name")); 548 txu->screen_name = g_strdup(json_object_get_string(node, "screen_name")); 549 txu->uid = json_object_get_integer(node, "id"); 550 550 551 551 return txu; … … 557 557 * - all <user>s from the <users> element. 558 558 */ 559 static gboolean twitter_xt_get_users( json_value *node, struct twitter_xml_list *txl)559 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl) 560 560 { 561 561 struct twitter_xml_user *txu; … … 565 565 txl->type = TXL_USER; 566 566 567 if ( !node || node->type != json_array) {567 if (json_type(node) != JSONArray) { 568 568 return FALSE; 569 569 } 570 570 571 571 // The root <users> node should hold the list of users <user> 572 572 // Walk over the nodes children. 573 for (i = 0; i < node->u.array.length; i++) { 574 txu = twitter_xt_get_user(node->u.array.values[i]); 573 JSON_Array *arr = json_array(node); 574 for (i = 0; i < json_array_get_count(arr); i++) { 575 JSON_Object *o = json_array_get_object(arr, i); 576 if (!o) 577 continue; 578 txu = twitter_xt_get_user(o); 575 579 if (txu) { 576 580 txl->list = g_slist_prepend(txl->list, txu); … … 587 591 #endif 588 592 589 static void expand_entities(char **text, const json_value *node, const json_value*extended_node);593 static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node); 590 594 591 595 /** … … 597 601 * - the user in a twitter_xml_user struct. 598 602 */ 599 static struct twitter_xml_status *twitter_xt_get_status(const json_value*node)603 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node) 600 604 { 601 605 struct twitter_xml_status *txs = {0}; 602 const json_value*rt = NULL;603 const json_value *text_value = NULL;604 const json_value*extended_node = NULL;605 606 if ( node->type != json_object) {606 const JSON_Object *rt = NULL; 607 const JSON_Value *text_value = NULL; 608 const JSON_Object *extended_node = NULL; 609 610 if (!node) { 607 611 return FALSE; 608 612 } … … 610 614 611 615 JSON_O_FOREACH(node, k, v) { 612 if (strcmp("text", k) == 0 && v->type == json_string && text_value == NULL) {616 if (strcmp("text", k) == 0 && json_type(v) == JSONString && text_value == NULL) { 613 617 text_value = v; 614 } else if (strcmp("full_text", k) == 0 && v->type == json_string) {618 } else if (strcmp("full_text", k) == 0 && json_type(v) == JSONString) { 615 619 text_value = v; 616 } else if (strcmp("extended_tweet", k) == 0 && v->type == json_object) {617 text_value = json_o _get(v, "full_text");618 extended_node = v;619 } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {620 rt = v;621 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {620 } else if (strcmp("extended_tweet", k) == 0 && json_type(v) == JSONObject) { 621 text_value = json_object_get_value(json_object(v), "full_text"); 622 extended_node = json_object(v); 623 } else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) { 624 // Handling below. 625 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) { 622 626 struct tm parsed; 623 627 … … 625 629 this field. :-( Also assumes the timezone used 626 630 is UTC since C time handling functions suck. */ 627 if (strptime( v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {631 if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) { 628 632 txs->created_at = mktime_utc(&parsed); 629 633 } 630 } else if (strcmp("user", k) == 0 && v->type == json_object) {631 txs->user = twitter_xt_get_user( v);632 } else if (strcmp("id", k) == 0 && v->type == json_integer) {633 txs->rt_id = txs->id = v->u.integer;634 } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {635 txs->reply_to = v->u.integer;634 } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) { 635 txs->user = twitter_xt_get_user(json_object(v)); 636 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) { 637 txs->rt_id = txs->id = json_integer(v); 638 } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) { 639 txs->reply_to = json_integer(v); 636 640 } 637 641 } … … 646 650 txs_free(rtxs); 647 651 } 648 } else if (text_value && text_value->type == json_string) {649 txs->text = g_ memdup(text_value->u.string.ptr, text_value->u.string.length + 1);652 } else if (text_value && json_type(text_value) == JSONString) { 653 txs->text = g_strdup(json_string(text_value)); 650 654 strip_html(txs->text); 651 655 expand_entities(&txs->text, node, extended_node); … … 663 667 * Function to fill a twitter_xml_status struct (DM variant). 664 668 */ 665 static struct twitter_xml_status *twitter_xt_get_dm(const json_value*node)669 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node) 666 670 { 667 671 struct twitter_xml_status *txs; 668 672 669 if ( node->type != json_object) {673 if (!node) { 670 674 return FALSE; 671 675 } … … 673 677 674 678 JSON_O_FOREACH(node, k, v) { 675 if (strcmp("text", k) == 0 && v->type == json_string) { 676 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); 679 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) { 677 680 strip_html(txs->text); 678 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {681 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) { 679 682 struct tm parsed; 680 683 … … 682 685 this field. :-( Also assumes the timezone used 683 686 is UTC since C time handling functions suck. */ 684 if (strptime( v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {687 if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) { 685 688 txs->created_at = mktime_utc(&parsed); 686 689 } 687 } else if (strcmp("sender", k) == 0 && v->type == json_object) {688 txs->user = twitter_xt_get_user( v);689 } else if (strcmp("id", k) == 0 && v->type == json_integer) {690 txs->id = v->u.integer;690 } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) { 691 txs->user = twitter_xt_get_user(json_object(v)); 692 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) { 693 txs->id = json_integer(v); 691 694 } 692 695 } … … 702 705 } 703 706 704 static void expand_entities(char **text, const json_value *node, const json_value*extended_node)705 { 706 json_value*entities, *extended_entities, *quoted;707 static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node) 708 { 709 JSON_Object *entities, *extended_entities, *quoted; 707 710 char *quote_url = NULL, *quote_text = NULL; 708 711 709 if (!( (entities = json_o_get(node, "entities")) && entities->type == json_object))710 return; 711 if ((quoted = json_o _get(node, "quoted_status")) && quoted->type == json_object) {712 if (!(entities = json_object_get_object(node, "entities"))) 713 return; 714 if ((quoted = json_object_get_object(node, "quoted_status"))) { 712 715 /* New "retweets with comments" feature. Note that this info 713 716 * seems to be included in the streaming API only! Grab the … … 723 726 724 727 if (extended_node) { 725 extended_entities = json_o _get(extended_node, "entities");726 if (extended_entities && extended_entities->type == json_object) {728 extended_entities = json_object_get_object(extended_node, "entities"); 729 if (extended_entities) { 727 730 entities = extended_entities; 728 731 } … … 732 735 int i; 733 736 734 if ( v->type != json_array) {737 if (json_type(v) != JSONArray) { 735 738 continue; 736 739 } … … 739 742 } 740 743 741 for (i = 0; i < v->u.array.length; i++) {744 for (i = 0; i < json_array_get_count(json_array(v)); i++) { 742 745 const char *format = "%s%s <%s>%s"; 743 744 if (v->u.array.values[i]->type != json_object) { 746 JSON_Object *r = json_array_get_object(json_array(v), i); 747 748 if (!r) { 745 749 continue; 746 750 } 747 751 748 const char *kort = json_o _str(v->u.array.values[i], "url");749 const char *disp = json_o _str(v->u.array.values[i], "display_url");750 const char *full = json_o _str(v->u.array.values[i], "expanded_url");752 const char *kort = json_object_get_string(r, "url"); 753 const char *disp = json_object_get_string(r, "display_url"); 754 const char *full = json_object_get_string(r, "expanded_url"); 751 755 char *pos, *new; 752 756 … … 777 781 * - the next_cursor. 778 782 */ 779 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,783 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node, 780 784 struct twitter_xml_list *txl) 781 785 { … … 786 790 txl->type = TXL_STATUS; 787 791 788 if ( node->type != json_array) {792 if (json_type(node) != JSONArray) { 789 793 return FALSE; 790 794 } … … 792 796 // The root <statuses> node should hold the list of statuses <status> 793 797 // Walk over the nodes children. 794 for (i = 0; i < node->u.array.length; i++) {795 txs = twitter_xt_get_status( node->u.array.values[i]);798 for (i = 0; i < json_array_get_count(json_array(node)); i++) { 799 txs = twitter_xt_get_status(json_array_get_object(json_array(node), i)); 796 800 if (!txs) { 797 801 continue; … … 978 982 979 983 /* Check this is not a tweet that should be muted */ 980 uid_str = g_strdup_printf("%" PRIu64, status->user->uid);984 uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, status->user->uid); 981 985 982 986 if (g_slist_find_custom(td->mutes_ids, uid_str, (GCompareFunc)strcmp)) { … … 1013 1017 } 1014 1018 1015 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter);1019 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter); 1016 1020 1017 1021 static void twitter_http_stream(struct http_request *req) … … 1019 1023 struct im_connection *ic = req->data; 1020 1024 struct twitter_data *td; 1021 json_value *parsed;1025 JSON_Value *parsed; 1022 1026 int len = 0; 1023 1027 char c, *nl; … … 1060 1064 req->reply_body[len] = '\0'; 1061 1065 1062 if ((parsed = json_parse (req->reply_body, req->body_size))) {1066 if ((parsed = json_parse_string(req->reply_body))) { 1063 1067 from_filter = (req == td->filter_stream); 1064 twitter_stream_handle_object(ic, parsed, from_filter);1068 twitter_stream_handle_object(ic, json_object(parsed), from_filter); 1065 1069 } 1066 1070 json_value_free(parsed); … … 1076 1080 } 1077 1081 1078 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value*o);1082 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o); 1079 1083 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 1080 1084 1081 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter)1085 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter) 1082 1086 { 1083 1087 struct twitter_data *td = ic->proto_data; 1084 1088 struct twitter_xml_status *txs; 1085 json_value*c;1089 JSON_Object *c; 1086 1090 1087 1091 if ((txs = twitter_xt_get_status(o))) { … … 1090 1094 txs_free(txs); 1091 1095 return ret; 1092 } else if ((c = json_o _get(o, "direct_message")) &&1096 } else if ((c = json_object_get_object(o, "direct_message")) && 1093 1097 (txs = twitter_xt_get_dm(c))) { 1094 1098 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { … … 1098 1102 txs_free(txs); 1099 1103 return TRUE; 1100 } else if ( (c = json_o_get(o, "event")) && c->type == json_string) {1104 } else if (json_object_get_string(o, "event")) { 1101 1105 twitter_stream_handle_event(ic, o); 1102 1106 return TRUE; 1103 } else if ((c = json_o _get(o, "disconnect")) && c->type == json_object) {1107 } else if ((c = json_object_get_object(o, "disconnect"))) { 1104 1108 /* HACK: Because we're inside an event handler, we can't just 1105 1109 disconnect here. Instead, just change the HTTP status string 1106 1110 into a Twitter status string. */ 1107 char *reason = json_o_strdup(c, "reason");1111 char *reason = g_strdup(json_object_get_string(c, "reason")); 1108 1112 if (reason) { 1109 1113 g_free(td->stream->status_string); … … 1144 1148 } 1145 1149 1146 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value*o)1150 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o) 1147 1151 { 1148 1152 struct twitter_data *td = ic->proto_data; 1149 json_value *source = json_o_get(o, "source");1150 json_value *target = json_o_get(o, "target");1151 const char *type = json_o _str(o, "event");1153 JSON_Object *source = json_object_get_object(o, "source"); 1154 JSON_Object *target = json_object_get_object(o, "target"); 1155 const char *type = json_object_get_string(o, "event"); 1152 1156 struct twitter_xml_user *us = NULL; 1153 1157 struct twitter_xml_user *ut = NULL; 1154 1158 1155 if (!type || !source || source->type != json_object 1156 || !target || target->type != json_object) { 1159 if (!type || !source || !target) { 1157 1160 return FALSE; 1158 1161 } … … 1168 1171 char *uid_str; 1169 1172 ut = twitter_xt_get_user(target); 1170 uid_str = g_strdup_printf("%" PRIu64, ut->uid);1173 uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid); 1171 1174 if (!(found = g_slist_find_custom(td->mutes_ids, uid_str, 1172 1175 (GCompareFunc)strcmp))) { … … 1175 1178 twitter_log(ic, "Muted user %s", ut->screen_name); 1176 1179 if (getenv("BITLBEE_DEBUG")) { 1177 fprintf(stderr, "New mute: %s %" PRIu64"\n",1180 fprintf(stderr, "New mute: %s %"G_GUINT64_FORMAT"\n", 1178 1181 ut->screen_name, ut->uid); 1179 1182 } … … 1182 1185 char *uid_str; 1183 1186 ut = twitter_xt_get_user(target); 1184 uid_str = g_strdup_printf("%" PRIu64, ut->uid);1187 uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid); 1185 1188 if ((found = g_slist_find_custom(td->mutes_ids, uid_str, 1186 1189 (GCompareFunc)strcmp))) { … … 1192 1195 twitter_log(ic, "Unmuted user %s", ut->screen_name); 1193 1196 if (getenv("BITLBEE_DEBUG")) { 1194 fprintf(stderr, "New unmute: %s %" PRIu64"\n",1197 fprintf(stderr, "New unmute: %s %"G_GUINT64_FORMAT"\n", 1195 1198 ut->screen_name, ut->uid); 1196 1199 } … … 1283 1286 struct twitter_filter *tf; 1284 1287 GList *users = NULL; 1285 json_value *parsed; 1286 json_value *id; 1287 const char *name; 1288 JSON_Value *parsed; 1288 1289 GString *fstr; 1289 1290 GSList *l; … … 1310 1311 } 1311 1312 1312 if ( parsed->type != json_array) {1313 if (json_type(parsed) != JSONArray) { 1313 1314 goto finish; 1314 1315 } 1315 1316 1316 for (i = 0; i < parsed->u.array.length; i++) { 1317 id = json_o_get(parsed->u.array.values[i], "id"); 1318 name = json_o_str(parsed->u.array.values[i], "screen_name"); 1319 1320 if (!name || !id || id->type != json_integer) { 1317 for (i = 0; i < json_array_get_count(json_array(parsed)); i++) { 1318 JSON_Object *o = json_array_get_object(json_array(parsed), i); 1319 jint id = json_object_get_integer(o, "id"); 1320 const char *name = json_object_get_string(o, "screen_name"); 1321 1322 if (!name || !id) { 1321 1323 continue; 1322 1324 } … … 1326 1328 1327 1329 if (g_strcasecmp(tf->text, name) == 0) { 1328 tf->uid = id ->u.integer;1330 tf->uid = id; 1329 1331 users = g_list_delete_link(users, u); 1330 1332 break; … … 1571 1573 struct im_connection *ic = req->data; 1572 1574 struct twitter_data *td; 1573 json_value *parsed;1575 JSON_Value *parsed; 1574 1576 struct twitter_xml_list *txl; 1575 1577 … … 1611 1613 struct im_connection *ic = req->data; 1612 1614 struct twitter_data *td; 1613 json_value *parsed;1615 JSON_Value *parsed; 1614 1616 struct twitter_xml_list *txl; 1615 1617 … … 1652 1654 struct im_connection *ic = req->data; 1653 1655 struct twitter_data *td; 1654 json_value *parsed, *id; 1656 JSON_Value *parsed; 1657 jint id; 1655 1658 1656 1659 // Check if the connection is still active. … … 1666 1669 } 1667 1670 1668 if ((id = json_o _get(parsed, "id")) && id->type == json_integer) {1669 td->last_status_id = id ->u.integer;1671 if ((id = json_object_get_integer(json_object(parsed), "id"))) { 1672 td->last_status_id = id; 1670 1673 } 1671 1674 … … 1788 1791 { 1789 1792 struct im_connection *ic = req->data; 1790 json_value *parsed, *id; 1793 JSON_Value *parsed; 1794 uint64_t id; 1791 1795 const char *name; 1792 1796 … … 1800 1804 } 1801 1805 1802 /* for the parson branch:1803 1806 name = json_object_dotget_string(json_object(parsed), "user.screen_name"); 1804 1807 id = json_object_get_integer(json_object(parsed), "id"); 1805 */ 1806 1807 name = json_o_str(json_o_get(parsed, "user"), "screen_name"); 1808 id = json_o_get(parsed, "id"); 1809 1810 if (name && id && id->type == json_integer) { 1811 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer); 1808 1809 if (name && id) { 1810 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id); 1812 1811 } else { 1813 1812 twitter_log(ic, "Error: could not fetch tweet url."); -
root_commands.c
r5a8afc3 r3f44e43 509 509 con = ""; 510 510 } 511 512 511 if (a->prpl == &protocol_missing) { 513 512 protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name")); … … 701 700 irc_rootmsg(irc, "That account is not on-line"); 702 701 return; 702 } else if (add_on_server && !a->prpl->add_buddy) { 703 irc_rootmsg(irc, "IM protocol does not support contact list modification"); 704 return; 705 } 706 707 if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' && 708 (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) { 709 /* If there's no @ or it's the last char, append the user's 710 domain name now. Exclude handles starting with a _ so 711 adding _xmlconsole will keep working. */ 712 if (s) { 713 *s = '\0'; 714 } 715 if ((s = strchr(a->user, '@'))) { 716 cmd[2] = handle = g_strconcat(cmd[2], s, NULL); 717 } 703 718 } 704 719 … … 715 730 } 716 731 717 if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' &&718 (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) {719 /* If there's no @ or it's the last char, append the user's720 domain name now. Exclude handles starting with a _ so721 adding _xmlconsole will keep working. */722 if (s) {723 *s = '\0';724 }725 if ((s = strchr(a->user, '@'))) {726 cmd[2] = handle = g_strconcat(cmd[2], s, NULL);727 }728 }729 730 732 if (add_on_server) { 731 733 irc_channel_t *ic; … … 771 773 s = g_strdup(bu->handle); 772 774 773 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 775 if (bu->ic->acc->prpl->remove_buddy) { 776 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 777 } else { 778 irc_rootmsg(irc, "IM protocol does not support contact list modification, " 779 "removal will likely not be permanent"); 780 } 781 774 782 nick_del(bu); 775 783 if (g_slist_find(irc->users, iu)) { -
storage_xml.c
r5a8afc3 r3f44e43 114 114 char *pass_b64 = NULL; 115 115 unsigned char *pass_cr = NULL; 116 int pass_len , local = 0;116 int pass_len; 117 117 struct prpl *prpl = NULL; 118 118 account_t *acc; … … 133 133 prpl = (struct prpl*) &protocol_missing; 134 134 } 135 local = protocol_account_islocal(protocol);136 135 } 137 136 … … 161 160 if (tag) { 162 161 set_setstr(&acc->set, "tag", tag); 163 }164 if (local) {165 acc->flags |= ACC_FLAG_LOCAL;166 162 } 167 163 if (locked && !g_strcasecmp(locked, "true")) {
Note: See TracChangeset
for help on using the changeset viewer.