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