Changes in / [2f99f23:b75671d]
- Files:
-
- 7 added
- 4 deleted
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r2f99f23 rb75671d 32 32 bitlbee.service 33 33 bitlbee@.service 34 *.pyc -
configure
r2f99f23 rb75671d 32 32 jabber="default-on" 33 33 oscar="default-on" 34 rpc="rpc-on" 34 35 yahoo="default-on" 35 36 … … 130 131 --purple=0/1 Disable/enable libpurple support $purple 131 132 (automatically disables other protocol modules) 133 --rpc=0/1 Disable/enable RPC interface $rpc 132 134 133 135 --doc=0/1 Disable/enable help.txt generation $doc … … 820 822 protocols=$protocols'twitter ' 821 823 protoobjs=$protoobjs'twitter_mod.o ' 824 fi 825 826 if [ "$rpc" = 0 ]; then 827 echo '#undef WITH_RPC' >> config.h 828 else 829 echo '#define WITH_RPC' >> config.h 830 protocols=$protocols'rpc ' 831 protoobjs=$protoobjs'rpc_mod.o ' 822 832 fi 823 833 -
irc_channel.c
r2f99f23 rb75671d 724 724 } 725 725 726 if (!bu->ic->acc->prpl->add_buddy) { 727 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name); 728 return FALSE; 729 } 730 726 731 bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle, 727 732 icc->group ? icc->group->name : NULL); … … 741 746 if (icc->type != IRC_CC_TYPE_GROUP) { 742 747 irc_send_num(ic->irc, 482, "%s :Kicks are only possible to fill_by=group channels", ic->name); 748 return; 749 } 750 751 if (!bu->ic->acc->prpl->remove_buddy) { 752 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name); 743 753 return; 744 754 } -
lib/Makefile
r2f99f23 rb75671d 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
r2f99f23 rb75671d 427 427 } 428 428 429 int is_bool(c har *value)429 int is_bool(const char *value) 430 430 { 431 431 if (*value == 0) { … … 453 453 } 454 454 455 int bool2int(c har *value)455 int bool2int(const char *value) 456 456 { 457 457 int i; -
lib/misc.h
r2f99f23 rb75671d 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
r2f99f23 rb75671d 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
r2f99f23 rb75671d 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); … … 463 459 return a->auto_reconnect_delay; 464 460 } 465 466 int protocol_account_islocal(const char* protocol)467 {468 const char** p = account_protocols_local;469 470 do {471 if (strcmp(*p, protocol) == 0) {472 return 1;473 }474 } while (*(++p));475 return 0;476 } -
protocols/account.h
r2f99f23 rb75671d 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. */ … … 69 67 ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */ 70 68 ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */ 71 ACC_FLAG_LOCAL = 0x08,/* Contact list is local. */69 ACC_FLAG_LOCAL_CONTACTS = 0x08, /* Contact list is local. */ 72 70 } account_flag_t; 73 71 -
protocols/nogaim.c
r2f99f23 rb75671d 132 132 extern void twitter_initmodule(); 133 133 extern void purple_initmodule(); 134 extern void rpc_initmodule(); 134 135 135 136 #ifdef WITH_MSN … … 155 156 #ifdef WITH_PURPLE 156 157 purple_initmodule(); 158 #endif 159 160 #ifdef WITH_RPC 161 rpc_initmodule(); 157 162 #endif 158 163 … … 307 312 } 308 313 309 if (ic->acc->flags & ACC_FLAG_LOCAL) { 314 if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) && 315 !(ic->flags & OPT_LOCAL_CONTACTS_SENT) && 316 ic->acc->prpl->add_buddy) { 310 317 GHashTableIter nicks; 311 gpointer k, v;318 gpointer handle; 312 319 g_hash_table_iter_init(&nicks, ic->acc->nicks); 313 while (g_hash_table_iter_next(&nicks, & k, &v)) {314 ic->acc->prpl->add_buddy(ic, (char *) k, NULL);320 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 321 ic->acc->prpl->add_buddy(ic, (char *) handle, NULL); 315 322 } 316 323 } … … 492 499 } 493 500 501 /* Returns the local contacts for an IM account (based on assigned nicks). 502 Linked list should be freed, the strings themselves not! So look at it 503 like a GSList<const char*> I guess? Empty list means NULL retval (as 504 always with GSList). */ 505 GSList *imcb_get_local_contacts(struct im_connection *ic) 506 { 507 GHashTableIter nicks; 508 GSList *ret = NULL; 509 510 if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) { 511 /* Only allow protocols that indicate local contact list 512 support to use this function. */ 513 return ret; 514 } 515 516 g_hash_table_iter_init(&nicks, ic->acc->nicks); 517 gpointer handle; 518 while (g_hash_table_iter_next(&nicks, &handle, NULL)) { 519 ret = g_slist_prepend(ret, (char *) handle); 520 } 521 522 /* If the protocol asked for the list, assume we won't have to send it 523 anymore in imcb_connected(). */ 524 ic->flags |= OPT_LOCAL_CONTACTS_SENT; 525 526 return ret; 527 } 528 494 529 495 530 struct imcb_ask_cb_data { … … 550 585 struct imcb_ask_cb_data *cbd = data; 551 586 552 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 587 if (cbd->ic->acc->prpl->add_buddy) { 588 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 589 } 553 590 554 591 imcb_ask_cb_free(data); -
protocols/nogaim.h
r2f99f23 rb75671d 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 73 79 /* ok. now the fun begins. first we create a connection structure */ … … 324 330 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); 325 331 G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data); 332 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic); 326 333 327 334 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags); -
protocols/purple/purple.c
r2f99f23 rb75671d 264 264 } 265 265 purple_accounts_remove(pa); 266 267 /* Last, some protocols want their contact lists locally. */ 268 if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) { 269 acc->flags |= ACC_FLAG_LOCAL_CONTACTS; 270 } 266 271 } 267 272 -
protocols/twitter/twitter_lib.c
r2f99f23 rb75671d 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"); … … 259 264 * Fill a list of ids. 260 265 */ 261 static gboolean twitter_xt_get_friends_id_list( json_value *node, struct twitter_xml_list *txl)262 { 263 json_value*c;266 static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl) 267 { 268 JSON_Array *c; 264 269 int i; 265 270 … … 267 272 txl->type = TXL_ID; 268 273 269 c = json_o_get(node, "ids"); 270 if (!c || c->type != json_array) { 274 if (!(c = json_object_get_array(json_object(node), "ids"))) { 271 275 return FALSE; 272 276 } 273 277 274 for (i = 0; i < c->u.array.length; i++) { 275 if (c->u.array.values[i]->type != json_integer) { 276 continue; 277 } 278 for (i = 0; i < json_array_get_count(c); i++) { 279 jint id = json_array_get_integer(c, i); 278 280 279 281 txl->list = g_slist_prepend(txl->list, 280 g_strdup_printf("% " PRIu64, c->u.array.values[i]->u.integer));281 } 282 283 c = json_o_get(node, "next_cursor");284 if ( c && c->type == json_integer) {285 txl->next_cursor = c->u.integer;282 g_strdup_printf("%lld", id)); 283 } 284 285 JSON_Value *next = json_object_get_value(json_object(node), "next_cursor"); 286 if (next && json_type(next) == JSONInteger) { 287 txl->next_cursor = json_integer(next); 286 288 } else { 287 289 txl->next_cursor = -1; … … 299 301 { 300 302 struct im_connection *ic; 301 json_value *parsed;303 JSON_Value *parsed; 302 304 struct twitter_xml_list *txl; 303 305 struct twitter_data *td; … … 337 339 } 338 340 339 static gboolean twitter_xt_get_users( json_value *node, struct twitter_xml_list *txl);341 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl); 340 342 static void twitter_http_get_users_lookup(struct http_request *req); 341 343 … … 378 380 { 379 381 struct im_connection *ic = req->data; 380 json_value *parsed;382 JSON_Value *parsed; 381 383 struct twitter_xml_list *txl; 382 384 GSList *l = NULL; … … 410 412 } 411 413 412 struct twitter_xml_user *twitter_xt_get_user(const json_value*node)414 struct twitter_xml_user *twitter_xt_get_user(const JSON_Object *node) 413 415 { 414 416 struct twitter_xml_user *txu; 415 json_value *jv; 417 418 if (!node) 419 return NULL; 416 420 417 421 txu = g_new0(struct twitter_xml_user, 1); 418 txu->name = g_strdup(json_o_str(node, "name")); 419 txu->screen_name = g_strdup(json_o_str(node, "screen_name")); 420 421 jv = json_o_get(node, "id"); 422 txu->uid = jv->u.integer; 422 txu->name = g_strdup(json_object_get_string(node, "name")); 423 txu->screen_name = g_strdup(json_object_get_string(node, "screen_name")); 424 txu->uid = json_object_get_integer(node, "id"); 423 425 424 426 return txu; … … 430 432 * - all <user>s from the <users> element. 431 433 */ 432 static gboolean twitter_xt_get_users( json_value *node, struct twitter_xml_list *txl)434 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl) 433 435 { 434 436 struct twitter_xml_user *txu; … … 438 440 txl->type = TXL_USER; 439 441 440 if ( !node || node->type != json_array) {442 if (json_type(node) != JSONArray) { 441 443 return FALSE; 442 444 } 443 445 444 446 // The root <users> node should hold the list of users <user> 445 447 // Walk over the nodes children. 446 for (i = 0; i < node->u.array.length; i++) { 447 txu = twitter_xt_get_user(node->u.array.values[i]); 448 JSON_Array *arr = json_array(node); 449 for (i = 0; i < json_array_get_count(arr); i++) { 450 JSON_Object *o = json_array_get_object(arr, i); 451 if (!o) 452 continue; 453 txu = twitter_xt_get_user(o); 448 454 if (txu) { 449 455 txl->list = g_slist_prepend(txl->list, txu); … … 460 466 #endif 461 467 462 static void expand_entities(char **text, const json_value*node);468 static void expand_entities(char **text, const JSON_Object *node); 463 469 464 470 /** … … 470 476 * - the user in a twitter_xml_user struct. 471 477 */ 472 static struct twitter_xml_status *twitter_xt_get_status(const json_value*node)478 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node) 473 479 { 474 480 struct twitter_xml_status *txs; 475 const json_value*rt = NULL;476 477 if ( node->type != json_object) {481 const JSON_Object *rt = NULL; 482 483 if (!node) { 478 484 return FALSE; 479 485 } … … 481 487 482 488 JSON_O_FOREACH(node, k, v) { 483 if (strcmp("text", k) == 0 && v->type == json_string) {484 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);489 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) { 490 // TODO: Huh strip html? In json? Not sure whether I have to.. 485 491 strip_html(txs->text); 486 } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {487 rt = v;488 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {492 } else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) { 493 // Handling below. 494 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) { 489 495 struct tm parsed; 490 496 … … 492 498 this field. :-( Also assumes the timezone used 493 499 is UTC since C time handling functions suck. */ 494 if (strptime( v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {500 if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) { 495 501 txs->created_at = mktime_utc(&parsed); 496 502 } 497 } else if (strcmp("user", k) == 0 && v->type == json_object) {498 txs->user = twitter_xt_get_user( v);499 } else if (strcmp("id", k) == 0 && v->type == json_integer) {500 txs->rt_id = txs->id = v->u.integer;501 } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {502 txs->reply_to = v->u.integer;503 } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) { 504 txs->user = twitter_xt_get_user(json_object(v)); 505 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) { 506 txs->rt_id = txs->id = json_integer(v); 507 } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) { 508 txs->reply_to = json_integer(v); 503 509 } 504 510 } … … 529 535 * Function to fill a twitter_xml_status struct (DM variant). 530 536 */ 531 static struct twitter_xml_status *twitter_xt_get_dm(const json_value*node)537 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node) 532 538 { 533 539 struct twitter_xml_status *txs; 534 540 535 if ( node->type != json_object) {541 if (!node) { 536 542 return FALSE; 537 543 } … … 539 545 540 546 JSON_O_FOREACH(node, k, v) { 541 if (strcmp("text", k) == 0 && v->type == json_string) { 542 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); 547 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) { 543 548 strip_html(txs->text); 544 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {549 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) { 545 550 struct tm parsed; 546 551 … … 548 553 this field. :-( Also assumes the timezone used 549 554 is UTC since C time handling functions suck. */ 550 if (strptime( v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {555 if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) { 551 556 txs->created_at = mktime_utc(&parsed); 552 557 } 553 } else if (strcmp("sender", k) == 0 && v->type == json_object) {554 txs->user = twitter_xt_get_user( v);555 } else if (strcmp("id", k) == 0 && v->type == json_integer) {556 txs->id = v->u.integer;558 } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) { 559 txs->user = twitter_xt_get_user(json_object(v)); 560 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) { 561 txs->id = json_integer(v); 557 562 } 558 563 } … … 568 573 } 569 574 570 static void expand_entities(char **text, const json_value*node)571 { 572 json_value*entities, *quoted;575 static void expand_entities(char **text, const JSON_Object *node) 576 { 577 JSON_Object *entities, *quoted; 573 578 char *quote_url = NULL, *quote_text = NULL; 574 579 575 if (!( (entities = json_o_get(node, "entities")) && entities->type == json_object))576 return; 577 if ((quoted = json_o _get(node, "quoted_status")) && quoted->type == json_object) {580 if (!(entities = json_object_get_object(node, "entities"))) 581 return; 582 if ((quoted = json_object_get_object(node, "quoted_status"))) { 578 583 /* New "retweets with comments" feature. Note that this info 579 584 * seems to be included in the streaming API only! Grab the … … 591 596 int i; 592 597 593 if ( v->type != json_array) {598 if (json_type(v) != JSONArray) { 594 599 continue; 595 600 } … … 598 603 } 599 604 600 for (i = 0; i < v->u.array.length; i++) {605 for (i = 0; i < json_array_get_count(json_array(v)); i++) { 601 606 const char *format = "%s%s <%s>%s"; 602 603 if (v->u.array.values[i]->type != json_object) { 607 JSON_Object *r = json_array_get_object(json_array(v), i); 608 609 if (!r) { 604 610 continue; 605 611 } 606 612 607 const char *kort = json_o _str(v->u.array.values[i], "url");608 const char *disp = json_o _str(v->u.array.values[i], "display_url");609 const char *full = json_o _str(v->u.array.values[i], "expanded_url");613 const char *kort = json_object_get_string(r, "url"); 614 const char *disp = json_object_get_string(r, "display_url"); 615 const char *full = json_object_get_string(r, "expanded_url"); 610 616 char *pos, *new; 611 617 … … 636 642 * - the next_cursor. 637 643 */ 638 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,644 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node, 639 645 struct twitter_xml_list *txl) 640 646 { … … 645 651 txl->type = TXL_STATUS; 646 652 647 if ( node->type != json_array) {653 if (json_type(node) != JSONArray) { 648 654 return FALSE; 649 655 } … … 651 657 // The root <statuses> node should hold the list of statuses <status> 652 658 // Walk over the nodes children. 653 for (i = 0; i < node->u.array.length; i++) {654 txs = twitter_xt_get_status( node->u.array.values[i]);659 for (i = 0; i < json_array_get_count(json_array(node)); i++) { 660 txs = twitter_xt_get_status(json_array_get_object(json_array(node), i)); 655 661 if (!txs) { 656 662 continue; … … 858 864 } 859 865 860 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter);866 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter); 861 867 862 868 static void twitter_http_stream(struct http_request *req) … … 864 870 struct im_connection *ic = req->data; 865 871 struct twitter_data *td; 866 json_value *parsed;872 JSON_Value *parsed; 867 873 int len = 0; 868 874 char c, *nl; … … 902 908 req->reply_body[len] = '\0'; 903 909 904 if ((parsed = json_parse (req->reply_body, req->body_size))) {910 if ((parsed = json_parse_string(req->reply_body))) { 905 911 from_filter = (req == td->filter_stream); 906 twitter_stream_handle_object(ic, parsed, from_filter);912 twitter_stream_handle_object(ic, json_object(parsed), from_filter); 907 913 } 908 914 json_value_free(parsed); … … 918 924 } 919 925 920 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value*o);926 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o); 921 927 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 922 928 923 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value*o, gboolean from_filter)929 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter) 924 930 { 925 931 struct twitter_data *td = ic->proto_data; 926 932 struct twitter_xml_status *txs; 927 json_value*c;933 JSON_Object *c; 928 934 929 935 if ((txs = twitter_xt_get_status(o))) { … … 932 938 txs_free(txs); 933 939 return ret; 934 } else if ((c = json_o _get(o, "direct_message")) &&940 } else if ((c = json_object_get_object(o, "direct_message")) && 935 941 (txs = twitter_xt_get_dm(c))) { 936 942 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { … … 940 946 txs_free(txs); 941 947 return TRUE; 942 } else if ( (c = json_o_get(o, "event")) && c->type == json_string) {948 } else if (json_object_get_string(o, "event")) { 943 949 twitter_stream_handle_event(ic, o); 944 950 return TRUE; 945 } else if ((c = json_o _get(o, "disconnect")) && c->type == json_object) {951 } else if ((c = json_object_get_object(o, "disconnect"))) { 946 952 /* HACK: Because we're inside an event handler, we can't just 947 953 disconnect here. Instead, just change the HTTP status string 948 954 into a Twitter status string. */ 949 char *reason = json_o_strdup(c, "reason");955 char *reason = g_strdup(json_object_get_string(c, "reason")); 950 956 if (reason) { 951 957 g_free(td->stream->status_string); … … 986 992 } 987 993 988 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o) 989 { 990 struct twitter_data *td = ic->proto_data; 991 json_value *source = json_o_get(o, "source"); 992 json_value *target = json_o_get(o, "target"); 993 const char *type = json_o_str(o, "event"); 994 995 if (!type || !source || source->type != json_object 996 || !target || target->type != json_object) { 994 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o) 995 { 996 struct twitter_data *td = ic->proto_data; 997 JSON_Object *source = json_object_get_object(o, "source"); 998 JSON_Object *target = json_object_get_object(o, "target"); 999 const char *type = json_object_get_string(o, "event"); 1000 1001 if (!type || !source || !target) { 997 1002 return FALSE; 998 1003 } … … 1091 1096 struct twitter_filter *tf; 1092 1097 GList *users = NULL; 1093 json_value *parsed; 1094 json_value *id; 1095 const char *name; 1098 JSON_Value *parsed; 1096 1099 GString *fstr; 1097 1100 GSList *l; … … 1118 1121 } 1119 1122 1120 if ( parsed->type != json_array) {1123 if (json_type(parsed) != JSONArray) { 1121 1124 goto finish; 1122 1125 } 1123 1126 1124 for (i = 0; i < parsed->u.array.length; i++) { 1125 id = json_o_get(parsed->u.array.values[i], "id"); 1126 name = json_o_str(parsed->u.array.values[i], "screen_name"); 1127 1128 if (!name || !id || id->type != json_integer) { 1127 for (i = 0; i < json_array_get_count(json_array(parsed)); i++) { 1128 JSON_Object *o = json_array_get_object(json_array(parsed), i); 1129 jint id = json_object_get_integer(o, "id"); 1130 const char *name = json_object_get_string(o, "screen_name"); 1131 1132 if (!name || !id) { 1129 1133 continue; 1130 1134 } … … 1134 1138 1135 1139 if (g_strcasecmp(tf->text, name) == 0) { 1136 tf->uid = id ->u.integer;1140 tf->uid = id; 1137 1141 users = g_list_delete_link(users, u); 1138 1142 break; … … 1375 1379 struct im_connection *ic = req->data; 1376 1380 struct twitter_data *td; 1377 json_value *parsed;1381 JSON_Value *parsed; 1378 1382 struct twitter_xml_list *txl; 1379 1383 … … 1414 1418 struct im_connection *ic = req->data; 1415 1419 struct twitter_data *td; 1416 json_value *parsed;1420 JSON_Value *parsed; 1417 1421 struct twitter_xml_list *txl; 1418 1422 … … 1454 1458 struct im_connection *ic = req->data; 1455 1459 struct twitter_data *td; 1456 json_value *parsed, *id; 1460 JSON_Value *parsed; 1461 jint id; 1457 1462 1458 1463 // Check if the connection is still active. … … 1468 1473 } 1469 1474 1470 if ((id = json_o _get(parsed, "id")) && id->type == json_integer) {1471 td->last_status_id = id ->u.integer;1475 if ((id = json_object_get_integer(json_object(parsed), "id"))) { 1476 td->last_status_id = id; 1472 1477 } 1473 1478 -
root_commands.c
r2f99f23 rb75671d 460 460 461 461 for (a = irc->b->accounts; a; a = a->next) { 462 char *con ;462 char *con = NULL, *protocol = NULL; 463 463 464 464 if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) { … … 471 471 con = ""; 472 472 } 473 474 irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con); 473 if (a->prpl == &protocol_missing) { 474 protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name")); 475 } else { 476 protocol = g_strdup(a->prpl->name); 477 } 478 479 irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, protocol, a->user, con); 480 g_free(protocol); 475 481 476 482 i++; … … 486 492 487 493 for (a = irc->b->accounts; a; a = a->next) { 488 if (!a->ic && a->auto_connect ) {494 if (!a->ic && a->auto_connect && a->prpl != &protocol_missing) { 489 495 if (strcmp(a->pass, PASSWORD_PENDING) == 0) { 490 496 irc_rootmsg(irc, "Enter password for account %s " … … 543 549 irc_rootmsg(irc, "Enter password for account %s " 544 550 "first (use /OPER)", a->tag); 551 } else if (a->prpl == &protocol_missing) { 552 irc_rootmsg(irc, "Protocol `%s' not recognised (plugin may be missing or not running?)", 553 set_getstr(&a->set, "_protocol_name")); 545 554 } else { 546 555 account_on(irc->b, a); … … 647 656 irc_rootmsg(irc, "That account is not on-line"); 648 657 return; 658 } else if (add_on_server && !a->prpl->add_buddy) { 659 irc_rootmsg(irc, "IM protocol does not support contact list modification"); 660 return; 649 661 } 650 662 … … 717 729 s = g_strdup(bu->handle); 718 730 719 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 731 if (bu->ic->acc->prpl->remove_buddy) { 732 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 733 } else { 734 irc_rootmsg(irc, "IM protocol does not support contact list modification, " 735 "removal will likely not be permanent"); 736 } 737 720 738 nick_del(bu); 721 739 if (g_slist_find(irc->users, iu)) { -
storage.c
r2f99f23 rb75671d 33 33 34 34 static GList *storage_backends = NULL; 35 36 const struct prpl protocol_missing = { 37 .name = "_unknown", 38 }; 35 39 36 40 void register_storage_backend(storage_t *backend) -
storage.h
r2f99f23 rb75671d 62 62 G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate); 63 63 64 extern const struct prpl protocol_missing; 65 64 66 #endif /* __STORAGE_H__ */ -
storage_xml.c
r2f99f23 rb75671d 83 83 } 84 84 85 /* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */ 86 static void handle_settings_raw(struct xt_node *node, set_t **head) 87 { 88 struct xt_node *c; 89 90 for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { 91 char *name = xt_find_attr(c, "name"); 92 93 if (!name) { 94 continue; 95 } 96 97 set_t *s = set_add(head, name, NULL, NULL, NULL); 98 set_setstr(head, name, c->text); 99 s->flags |= SET_HIDDEN | 100 ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; 101 } 102 } 103 85 104 static xt_status handle_account(struct xt_node *node, gpointer data) 86 105 { … … 89 108 char *pass_b64 = NULL; 90 109 unsigned char *pass_cr = NULL; 91 int pass_len , local = 0;110 int pass_len; 92 111 struct prpl *prpl = NULL; 93 112 account_t *acc; … … 104 123 prpl = find_protocol(protocol); 105 124 if (!prpl) { 106 irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol); 107 return XT_ABORT; 108 } 109 local = protocol_account_islocal(protocol); 125 irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol); 126 prpl = (struct prpl*) &protocol_missing; 127 } 110 128 } 111 129 … … 124 142 set_setstr(&acc->set, "tag", tag); 125 143 } 126 if (local) { 127 acc->flags |= ACC_FLAG_LOCAL; 144 if (prpl == &protocol_missing) { 145 set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL); 146 s->flags |= SET_HIDDEN | SET_NOSAVE | 147 ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; 128 148 } 129 149 } else { … … 136 156 g_free(password); 137 157 138 handle_settings(node, &acc->set); 158 if (prpl == &protocol_missing) { 159 handle_settings_raw(node, &acc->set); 160 } else { 161 handle_settings(node, &acc->set); 162 } 139 163 140 164 for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) { … … 312 336 313 337 cur = xt_new_node("account", NULL, NULL); 314 xt_add_attr(cur, "protocol", acc->prpl->name); 338 if (acc->prpl == &protocol_missing) { 339 xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name")); 340 } else { 341 xt_add_attr(cur, "protocol", acc->prpl->name); 342 } 315 343 xt_add_attr(cur, "handle", acc->user); 316 344 xt_add_attr(cur, "password", pass_b64);
Note: See TracChangeset
for help on using the changeset viewer.