Changes in / [4a9c6b0:7a9d968]
- Files:
-
- 7 added
- 4 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r4a9c6b0 r7a9d968 32 32 bitlbee.service 33 33 bitlbee@.service 34 *.pyc -
configure
r4a9c6b0 r7a9d968 17 17 libdir='$prefix/lib/' 18 18 plugindir='$prefix/lib/bitlbee/' 19 rpcplugindir='$plugindir/rpc/' 19 20 includedir='$prefix/include/bitlbee/' 20 21 systemdsystemunitdir='' … … 39 40 twitter=1 40 41 purple=0 42 rpc=1 41 43 42 44 verbose=0 … … 124 126 --datadir=... $datadir 125 127 --plugindir=... $plugindir 128 --rpcplugindir=... $rpcplugindir 126 129 --systemdsystemunitdir=... $systemdsystemunitdir 127 130 --pidfile=... $pidfile … … 137 140 --purple=0/1 Disable/enable libpurple support $purple 138 141 (automatically disables other protocol modules) 142 --rpc=0/1 Disable/enable RPC plugin interface $rpc 139 143 140 144 --pam=0/1 Disable/enable PAM authentication $pam … … 176 180 libdir=$(eval echo "$libdir/" | sed 's/\/\{1,\}/\//g') 177 181 plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g') 182 rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g') 178 183 includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g') 179 184 libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g') … … 197 202 DATADIR=$datadir 198 203 PLUGINDIR=$plugindir 204 RPCPLUGINDIR=$rpcplugindir 199 205 CONFIG=$config 200 206 LIBDIR=$libdir … … 247 253 #define VARDIR "$datadir" 248 254 #define PLUGINDIR "$plugindir" 255 #define RPCPLUGINDIR "$rpcplugindir" 249 256 #define DATADIR "$datadir" 250 257 #define PIDFILE "$pidfile" … … 288 295 LDFLAGS="$LDFLAGS -fsanitize=address" 289 296 debug=1 297 fi 298 299 if [ "$tsan" = "1" ]; then 300 echo 301 echo "Threaded BitlBee? Have a nice tall glass of http://imgur.com/gallery/tX4qxzS" 302 echo "No need to sanitise threads in a single-threaded process!" 290 303 fi 291 304 … … 730 743 fi 731 744 745 if [ "$rpc" = 0 ]; then 746 # Somewhat pointless at this stage already but at least this keeps it 747 # out of bitlbee.pc which is probably a good thing. 748 rpcplugindir="" 749 fi 750 732 751 otrprefix="" 733 752 if [ "$otr" = "auto" ]; then … … 814 833 includedir=$includedir 815 834 plugindir=$plugindir 835 rpcplugindir=$rpcplugindir 816 836 libdir=$libdir 817 837 datadir=$datadir … … 899 919 protocols=$protocols'twitter ' 900 920 protoobjs=$protoobjs'twitter_mod.o ' 921 fi 922 923 if [ "$rpc" = 0 ]; then 924 echo '#undef WITH_RPC' >> config.h 925 else 926 echo '#define WITH_RPC' >> config.h 927 protocols=$protocols'rpc ' 928 protoobjs=$protoobjs'rpc_mod.o ' 901 929 fi 902 930 … … 990 1018 echo ' Using event handler: '$events 991 1019 echo ' Using SSL library: '$ssl 992 #echo ' Building with these storage backends: '$STORAGES993 1020 994 1021 if [ -n "$protocols" ]; then -
irc_channel.c
r4a9c6b0 r7a9d968 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
r4a9c6b0 r7a9d968 330 330 showed an error message, or is doing some work 331 331 before the join should be confirmed. (In the 332 latter case, the calle rshould take care of that332 latter case, the callee should take care of that 333 333 confirmation.) TRUE means all's good, let the 334 334 user join the channel right away. */ -
lib/Makefile
r4a9c6b0 r7a9d968 13 13 14 14 # [SH] Program variables 15 objects = arc.o base64.o canohost.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 canohost.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
r4a9c6b0 r7a9d968 386 386 } 387 387 388 int is_bool(c har *value)388 int is_bool(const char *value) 389 389 { 390 390 if (*value == 0) { … … 412 412 } 413 413 414 int bool2int(c har *value)414 int bool2int(const char *value) 415 415 { 416 416 int i; -
lib/misc.h
r4a9c6b0 r7a9d968 135 135 G_MODULE_EXPORT void random_bytes(unsigned char *buf, int count); 136 136 137 G_MODULE_EXPORT int is_bool(c har *value);138 G_MODULE_EXPORT int bool2int(c har *value);137 G_MODULE_EXPORT int is_bool(const char *value); 138 G_MODULE_EXPORT int bool2int(const char *value); 139 139 140 140 G_MODULE_EXPORT struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain); -
lib/oauth2.c
r4a9c6b0 r7a9d968 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
r4a9c6b0 r7a9d968 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); … … 469 465 return a->auto_reconnect_delay; 470 466 } 471 472 int protocol_account_islocal(const char* protocol)473 {474 const char** p = account_protocols_local;475 476 do {477 if (strcmp(*p, protocol) == 0) {478 return 1;479 }480 } while (*(++p));481 return 0;482 } -
protocols/account.h
r4a9c6b0 r7a9d968 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
r4a9c6b0 r7a9d968 259 259 extern void twitter_initmodule(); 260 260 extern void purple_initmodule(); 261 extern void rpc_initmodule(); 261 262 262 263 #ifdef WITH_MSN … … 278 279 #ifdef WITH_PURPLE 279 280 purple_initmodule(); 281 #endif 282 283 #ifdef WITH_RPC 284 rpc_initmodule(); 280 285 #endif 281 286 … … 443 448 } 444 449 445 if (ic->acc->flags & ACC_FLAG_LOCAL) { 450 if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) && 451 !(ic->flags & OPT_LOCAL_CONTACTS_SENT) && 452 ic->acc->prpl->add_buddy) { 446 453 GHashTableIter nicks; 447 gpointer k, v;454 gpointer handle; 448 455 g_hash_table_iter_init(&nicks, ic->acc->nicks); 449 while (g_hash_table_iter_next(&nicks, & k, &v)) {450 ic->acc->prpl->add_buddy(ic, (char *) k, NULL);456 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 457 ic->acc->prpl->add_buddy(ic, (char *) handle, NULL); 451 458 } 452 459 } … … 543 550 query_del_by_conn((irc_t *) ic->bee->ui_data, ic); 544 551 552 /* Throw away groupchats owned by this account. Historically this was only 553 ever done by IM modules which is a bug. But it gives them opportunity 554 to clean up protocol-specific bits as well so keep it that way, just 555 do another cleanup here as a fallback. Don't want to leave any dangling 556 pointers! */ 557 while (ic->groupchats) { 558 imcb_chat_free(ic->groupchats->data); 559 } 560 545 561 if (!a) { 546 562 /* Uhm... This is very sick. */ … … 641 657 } 642 658 659 /* Returns the local contacts for an IM account (based on assigned nicks). 660 Linked list should be freed, the strings themselves not! So look at it 661 like a GSList<const char*> I guess? Empty list means NULL retval (as 662 always with GSList). */ 663 GSList *imcb_get_local_contacts(struct im_connection *ic) 664 { 665 GHashTableIter nicks; 666 GSList *ret = NULL; 667 668 if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) { 669 /* Only allow protocols that indicate local contact list 670 support to use this function. */ 671 return ret; 672 } 673 674 g_hash_table_iter_init(&nicks, ic->acc->nicks); 675 gpointer handle; 676 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 677 ret = g_slist_prepend(ret, (char *) handle); 678 } 679 680 /* If the protocol asked for the list, assume we won't have to send it 681 anymore in imcb_connected(). */ 682 ic->flags |= OPT_LOCAL_CONTACTS_SENT; 683 684 return ret; 685 } 686 687 643 688 struct imcb_ask_cb_data { 644 689 struct im_connection *ic; … … 698 743 struct imcb_ask_cb_data *cbd = data; 699 744 700 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 745 if (cbd->ic->acc->prpl->add_buddy) { 746 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 747 } 701 748 702 749 imcb_ask_cb_free(data); -
protocols/nogaim.h
r4a9c6b0 r7a9d968 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
r4a9c6b0 r7a9d968 327 327 } 328 328 purple_accounts_remove(pa); 329 330 /* Last, some protocols want their contact lists locally. */ 331 if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) { 332 acc->flags |= ACC_FLAG_LOCAL_CONTACTS; 333 } 329 334 } 330 335 -
protocols/twitter/twitter_lib.c
r4a9c6b0 r7a9d968 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, "JSON 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("%" PRI d64, 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("%" PRIu64, 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("%" PRId64, c->u.integer));454 g_strdup_printf("%" PRId64, 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. Grab the 713 716 * full message and try to insert it when we run into the … … 722 725 723 726 if (extended_node) { 724 extended_entities = json_o _get(extended_node, "entities");725 if (extended_entities && extended_entities->type == json_object) {727 extended_entities = json_object_get_object(extended_node, "entities"); 728 if (extended_entities) { 726 729 entities = extended_entities; 727 730 } … … 731 734 int i; 732 735 733 if ( v->type != json_array) {736 if (json_type(v) != JSONArray) { 734 737 continue; 735 738 } … … 738 741 } 739 742 740 for (i = 0; i < v->u.array.length; i++) {743 for (i = 0; i < json_array_get_count(json_array(v)); i++) { 741 744 const char *format = "%s%s <%s>%s"; 742 743 if (v->u.array.values[i]->type != json_object) { 745 JSON_Object *r = json_array_get_object(json_array(v), i); 746 747 if (!r) { 744 748 continue; 745 749 } 746 750 747 const char *kort = json_o _str(v->u.array.values[i], "url");748 const char *disp = json_o _str(v->u.array.values[i], "display_url");749 const char *full = json_o _str(v->u.array.values[i], "expanded_url");751 const char *kort = json_object_get_string(r, "url"); 752 const char *disp = json_object_get_string(r, "display_url"); 753 const char *full = json_object_get_string(r, "expanded_url"); 750 754 char *pos, *new; 751 755 … … 779 783 * - the next_cursor. 780 784 */ 781 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,785 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node, 782 786 struct twitter_xml_list *txl) 783 787 { … … 788 792 txl->type = TXL_STATUS; 789 793 790 if ( node->type != json_array) {794 if (json_type(node) != JSONArray) { 791 795 return FALSE; 792 796 } … … 794 798 // The root <statuses> node should hold the list of statuses <status> 795 799 // Walk over the nodes children. 796 for (i = 0; i < node->u.array.length; i++) {797 txs = twitter_xt_get_status( node->u.array.values[i]);800 for (i = 0; i < json_array_get_count(json_array(node)); i++) { 801 txs = twitter_xt_get_status(json_array_get_object(json_array(node), i)); 798 802 if (!txs) { 799 803 continue; … … 1015 1019 } 1016 1020 1017 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter);1021 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter); 1018 1022 1019 1023 static void twitter_http_stream(struct http_request *req) … … 1021 1025 struct im_connection *ic = req->data; 1022 1026 struct twitter_data *td; 1023 json_value *parsed;1027 JSON_Value *parsed; 1024 1028 int len = 0; 1025 1029 char c, *nl; … … 1062 1066 req->reply_body[len] = '\0'; 1063 1067 1064 if ((parsed = json_parse (req->reply_body, req->body_size))) {1068 if ((parsed = json_parse_string(req->reply_body))) { 1065 1069 from_filter = (req == td->filter_stream); 1066 twitter_stream_handle_object(ic, parsed, from_filter);1070 twitter_stream_handle_object(ic, json_object(parsed), from_filter); 1067 1071 } 1068 1072 json_value_free(parsed); … … 1078 1082 } 1079 1083 1080 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value*o);1084 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o); 1081 1085 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 1082 1086 1083 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter)1087 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter) 1084 1088 { 1085 1089 struct twitter_data *td = ic->proto_data; 1086 1090 struct twitter_xml_status *txs; 1087 json_value*c;1091 JSON_Object *c; 1088 1092 1089 1093 if ((txs = twitter_xt_get_status(o))) { … … 1092 1096 txs_free(txs); 1093 1097 return ret; 1094 } else if ((c = json_o _get(o, "direct_message")) &&1098 } else if ((c = json_object_get_object(o, "direct_message")) && 1095 1099 (txs = twitter_xt_get_dm(c))) { 1096 1100 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { … … 1100 1104 txs_free(txs); 1101 1105 return TRUE; 1102 } else if ( (c = json_o_get(o, "event")) && c->type == json_string) {1106 } else if (json_object_get_string(o, "event")) { 1103 1107 twitter_stream_handle_event(ic, o); 1104 1108 return TRUE; 1105 } else if ((c = json_o _get(o, "disconnect")) && c->type == json_object) {1109 } else if ((c = json_object_get_object(o, "disconnect"))) { 1106 1110 /* HACK: Because we're inside an event handler, we can't just 1107 1111 disconnect here. Instead, just change the HTTP status string 1108 1112 into a Twitter status string. */ 1109 char *reason = json_o_strdup(c, "reason");1113 char *reason = g_strdup(json_object_get_string(c, "reason")); 1110 1114 if (reason) { 1111 1115 g_free(td->stream->status_string); … … 1146 1150 } 1147 1151 1148 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value*o)1152 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o) 1149 1153 { 1150 1154 struct twitter_data *td = ic->proto_data; 1151 json_value *source = json_o_get(o, "source");1152 json_value *target = json_o_get(o, "target");1153 const char *type = json_o _str(o, "event");1155 JSON_Object *source = json_object_get_object(o, "source"); 1156 JSON_Object *target = json_object_get_object(o, "target"); 1157 const char *type = json_object_get_string(o, "event"); 1154 1158 struct twitter_xml_user *us = NULL; 1155 1159 struct twitter_xml_user *ut = NULL; 1156 1160 1157 if (!type || !source || source->type != json_object 1158 || !target || target->type != json_object) { 1161 if (!type || !source || !target) { 1159 1162 return FALSE; 1160 1163 } … … 1285 1288 struct twitter_filter *tf; 1286 1289 GList *users = NULL; 1287 json_value *parsed; 1288 json_value *id; 1289 const char *name; 1290 JSON_Value *parsed; 1290 1291 GString *fstr; 1291 1292 GSList *l; … … 1312 1313 } 1313 1314 1314 if ( parsed->type != json_array) {1315 if (json_type(parsed) != JSONArray) { 1315 1316 goto finish; 1316 1317 } 1317 1318 1318 for (i = 0; i < parsed->u.array.length; i++) { 1319 id = json_o_get(parsed->u.array.values[i], "id"); 1320 name = json_o_str(parsed->u.array.values[i], "screen_name"); 1321 1322 if (!name || !id || id->type != json_integer) { 1319 for (i = 0; i < json_array_get_count(json_array(parsed)); i++) { 1320 JSON_Object *o = json_array_get_object(json_array(parsed), i); 1321 jint id = json_object_get_integer(o, "id"); 1322 const char *name = json_object_get_string(o, "screen_name"); 1323 1324 if (!name || !id) { 1323 1325 continue; 1324 1326 } … … 1328 1330 1329 1331 if (g_strcasecmp(tf->text, name) == 0) { 1330 tf->uid = id ->u.integer;1332 tf->uid = id; 1331 1333 users = g_list_delete_link(users, u); 1332 1334 break; … … 1573 1575 struct im_connection *ic = req->data; 1574 1576 struct twitter_data *td; 1575 json_value *parsed;1577 JSON_Value *parsed; 1576 1578 struct twitter_xml_list *txl; 1577 1579 … … 1613 1615 struct im_connection *ic = req->data; 1614 1616 struct twitter_data *td; 1615 json_value *parsed;1617 JSON_Value *parsed; 1616 1618 struct twitter_xml_list *txl; 1617 1619 … … 1654 1656 struct im_connection *ic = req->data; 1655 1657 struct twitter_data *td; 1656 json_value *parsed, *id; 1658 JSON_Value *parsed; 1659 jint id; 1657 1660 1658 1661 // Check if the connection is still active. … … 1668 1671 } 1669 1672 1670 if ((id = json_o _get(parsed, "id")) && id->type == json_integer) {1671 td->last_status_id = id ->u.integer;1673 if ((id = json_object_get_integer(json_object(parsed), "id"))) { 1674 td->last_status_id = id; 1672 1675 } 1673 1676 … … 1797 1800 { 1798 1801 struct im_connection *ic = req->data; 1799 json_value *parsed, *id; 1802 JSON_Value *parsed; 1803 uint64_t id; 1800 1804 const char *name; 1801 1805 … … 1809 1813 } 1810 1814 1811 /* for the parson branch:1812 1815 name = json_object_dotget_string(json_object(parsed), "user.screen_name"); 1813 1816 id = json_object_get_integer(json_object(parsed), "id"); 1814 */ 1815 1816 name = json_o_str(json_o_get(parsed, "user"), "screen_name"); 1817 id = json_o_get(parsed, "id"); 1818 1819 if (name && id && id->type == json_integer) { 1820 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer); 1817 1818 if (name && id) { 1819 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id); 1821 1820 } else { 1822 1821 twitter_log(ic, "Error: could not fetch tweet url."); -
root_commands.c
r4a9c6b0 r7a9d968 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
r4a9c6b0 r7a9d968 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.