Changes in / [3ddbd23c:73dd021]
- Files:
-
- 4 added
- 7 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r3ddbd23c r73dd021 32 32 bitlbee.service 33 33 bitlbee@.service 34 *.pyc -
configure
r3ddbd23c r73dd021 32 32 jabber="default-on" 33 33 oscar="default-on" 34 rpc="rpc-on"35 34 yahoo="default-on" 36 35 … … 131 130 --purple=0/1 Disable/enable libpurple support $purple 132 131 (automatically disables other protocol modules) 133 --rpc=0/1 Disable/enable RPC interface $rpc134 132 135 133 --doc=0/1 Disable/enable help.txt generation $doc … … 822 820 protocols=$protocols'twitter ' 823 821 protoobjs=$protoobjs'twitter_mod.o ' 824 fi825 826 if [ "$rpc" = 0 ]; then827 echo '#undef WITH_RPC' >> config.h828 else829 echo '#define WITH_RPC' >> config.h830 protocols=$protocols'rpc '831 protoobjs=$protoobjs'rpc_mod.o '832 822 fi 833 823 -
irc_channel.c
r3ddbd23c r73dd021 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 731 726 bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle, 732 727 icc->group ? icc->group->name : NULL); … … 746 741 if (icc->type != IRC_CC_TYPE_GROUP) { 747 742 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);753 743 return; 754 744 } -
irc_commands.c
r3ddbd23c r73dd021 166 166 showed an error message, or is doing some work 167 167 before the join should be confirmed. (In the 168 latter case, the calle eshould take care of that168 latter case, the caller should take care of that 169 169 confirmation.) TRUE means all's good, let the 170 170 user join the channel right away. */ -
lib/Makefile
r3ddbd23c r73dd021 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
r3ddbd23c r73dd021 427 427 } 428 428 429 int is_bool(c onst char *value)429 int is_bool(char *value) 430 430 { 431 431 if (*value == 0) { … … 453 453 } 454 454 455 int bool2int(c onst char *value)455 int bool2int(char *value) 456 456 { 457 457 int i; -
lib/misc.h
r3ddbd23c r73dd021 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
r3ddbd23c r73dd021 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
r3ddbd23c r73dd021 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); … … 459 463 return a->auto_reconnect_delay; 460 464 } 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
r3ddbd23c r73dd021 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. */ … … 67 69 ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */ 68 70 ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */ 69 ACC_FLAG_LOCAL _CONTACTS = 0x08,/* Contact list is local. */71 ACC_FLAG_LOCAL = 0x08, /* Contact list is local. */ 70 72 } account_flag_t; 71 73 -
protocols/nogaim.c
r3ddbd23c r73dd021 132 132 extern void twitter_initmodule(); 133 133 extern void purple_initmodule(); 134 extern void rpc_initmodule();135 134 136 135 #ifdef WITH_MSN … … 156 155 #ifdef WITH_PURPLE 157 156 purple_initmodule(); 158 #endif159 160 #ifdef WITH_RPC161 rpc_initmodule();162 157 #endif 163 158 … … 312 307 } 313 308 314 if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) && 315 !(ic->flags & OPT_LOCAL_CONTACTS_SENT) && 316 ic->acc->prpl->add_buddy) { 309 if (ic->acc->flags & ACC_FLAG_LOCAL) { 317 310 GHashTableIter nicks; 318 gpointer handle;311 gpointer k, v; 319 312 g_hash_table_iter_init(&nicks, ic->acc->nicks); 320 while (g_hash_table_iter_next(&nicks, & handle, NULL)) {321 ic->acc->prpl->add_buddy(ic, (char *) handle, NULL);313 while (g_hash_table_iter_next(&nicks, &k, &v)) { 314 ic->acc->prpl->add_buddy(ic, (char *) k, NULL); 322 315 } 323 316 } … … 414 407 query_del_by_conn((irc_t *) ic->bee->ui_data, ic); 415 408 416 /* Throw away groupchats owned by this account. Historically this was only417 ever done by IM modules which is a bug. But it gives them opportunity418 to clean up protocol-specific bits as well so keep it that way, just419 do another cleanup here as a fallback. Don't want to leave any dangling420 pointers! */421 while (ic->groupchats) {422 imcb_chat_free(ic->groupchats->data);423 }424 425 409 if (!a) { 426 410 /* Uhm... This is very sick. */ … … 508 492 } 509 493 510 /* Returns the local contacts for an IM account (based on assigned nicks).511 Linked list should be freed, the strings themselves not! So look at it512 like a GSList<const char*> I guess? Empty list means NULL retval (as513 always with GSList). */514 GSList *imcb_get_local_contacts(struct im_connection *ic)515 {516 GHashTableIter nicks;517 GSList *ret = NULL;518 519 if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) {520 /* Only allow protocols that indicate local contact list521 support to use this function. */522 return ret;523 }524 525 g_hash_table_iter_init(&nicks, ic->acc->nicks);526 gpointer handle;527 while (g_hash_table_iter_next(&nicks, &handle, NULL)) {528 ret = g_slist_prepend(ret, (char *) handle);529 }530 531 /* If the protocol asked for the list, assume we won't have to send it532 anymore in imcb_connected(). */533 ic->flags |= OPT_LOCAL_CONTACTS_SENT;534 535 return ret;536 }537 538 494 539 495 struct imcb_ask_cb_data { … … 594 550 struct imcb_ask_cb_data *cbd = data; 595 551 596 if (cbd->ic->acc->prpl->add_buddy) { 597 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 598 } 552 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 599 553 600 554 imcb_ask_cb_free(data); -
protocols/nogaim.h
r3ddbd23c r73dd021 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 79 73 /* ok. now the fun begins. first we create a connection structure */ … … 330 324 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); 331 325 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);333 326 334 327 G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags); -
protocols/purple/purple.c
r3ddbd23c r73dd021 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 }271 266 } 272 267 -
protocols/twitter/twitter_lib.c
r3ddbd23c r73dd021 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"); … … 264 259 * Fill a list of ids. 265 260 */ 266 static gboolean twitter_xt_get_friends_id_list( JSON_Value *node, struct twitter_xml_list *txl)267 { 268 JSON_Array*c;261 static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl) 262 { 263 json_value *c; 269 264 int i; 270 265 … … 272 267 txl->type = TXL_ID; 273 268 274 if (!(c = json_object_get_array(json_object(node), "ids"))) { 269 c = json_o_get(node, "ids"); 270 if (!c || c->type != json_array) { 275 271 return FALSE; 276 272 } 277 273 278 for (i = 0; i < json_array_get_count(c); i++) { 279 jint id = json_array_get_integer(c, i); 274 for (i = 0; i < c->u.array.length; i++) { 275 if (c->u.array.values[i]->type != json_integer) { 276 continue; 277 } 280 278 281 279 txl->list = g_slist_prepend(txl->list, 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);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; 288 286 } else { 289 287 txl->next_cursor = -1; … … 301 299 { 302 300 struct im_connection *ic; 303 JSON_Value *parsed;301 json_value *parsed; 304 302 struct twitter_xml_list *txl; 305 303 struct twitter_data *td; … … 339 337 } 340 338 341 static gboolean twitter_xt_get_users( JSON_Value *node, struct twitter_xml_list *txl);339 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl); 342 340 static void twitter_http_get_users_lookup(struct http_request *req); 343 341 … … 380 378 { 381 379 struct im_connection *ic = req->data; 382 JSON_Value *parsed;380 json_value *parsed; 383 381 struct twitter_xml_list *txl; 384 382 GSList *l = NULL; … … 412 410 } 413 411 414 struct twitter_xml_user *twitter_xt_get_user(const JSON_Object*node)412 struct twitter_xml_user *twitter_xt_get_user(const json_value *node) 415 413 { 416 414 struct twitter_xml_user *txu; 417 418 if (!node) 419 return NULL; 415 json_value *jv; 420 416 421 417 txu = g_new0(struct twitter_xml_user, 1); 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"); 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; 425 423 426 424 return txu; … … 432 430 * - all <user>s from the <users> element. 433 431 */ 434 static gboolean twitter_xt_get_users( JSON_Value *node, struct twitter_xml_list *txl)432 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl) 435 433 { 436 434 struct twitter_xml_user *txu; … … 440 438 txl->type = TXL_USER; 441 439 442 if ( json_type(node) != JSONArray) {440 if (!node || node->type != json_array) { 443 441 return FALSE; 444 442 } 445 443 446 444 // The root <users> node should hold the list of users <user> 447 445 // Walk over the nodes children. 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); 446 for (i = 0; i < node->u.array.length; i++) { 447 txu = twitter_xt_get_user(node->u.array.values[i]); 454 448 if (txu) { 455 449 txl->list = g_slist_prepend(txl->list, txu); … … 466 460 #endif 467 461 468 static void expand_entities(char **text, const JSON_Object*node);462 static void expand_entities(char **text, const json_value *node); 469 463 470 464 /** … … 476 470 * - the user in a twitter_xml_user struct. 477 471 */ 478 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object*node)472 static struct twitter_xml_status *twitter_xt_get_status(const json_value *node) 479 473 { 480 474 struct twitter_xml_status *txs; 481 const JSON_Object*rt = NULL;482 483 if ( !node) {475 const json_value *rt = NULL; 476 477 if (node->type != json_object) { 484 478 return FALSE; 485 479 } … … 487 481 488 482 JSON_O_FOREACH(node, k, v) { 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..483 if (strcmp("text", k) == 0 && v->type == json_string) { 484 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); 491 485 strip_html(txs->text); 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) {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) { 495 489 struct tm parsed; 496 490 … … 498 492 this field. :-( Also assumes the timezone used 499 493 is UTC since C time handling functions suck. */ 500 if (strptime( json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {494 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 501 495 txs->created_at = mktime_utc(&parsed); 502 496 } 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);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; 509 503 } 510 504 } … … 535 529 * Function to fill a twitter_xml_status struct (DM variant). 536 530 */ 537 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object*node)531 static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node) 538 532 { 539 533 struct twitter_xml_status *txs; 540 534 541 if ( !node) {535 if (node->type != json_object) { 542 536 return FALSE; 543 537 } … … 545 539 546 540 JSON_O_FOREACH(node, k, v) { 547 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(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); 548 543 strip_html(txs->text); 549 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {544 } else if (strcmp("created_at", k) == 0 && v->type == json_string) { 550 545 struct tm parsed; 551 546 … … 553 548 this field. :-( Also assumes the timezone used 554 549 is UTC since C time handling functions suck. */ 555 if (strptime( json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {550 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 556 551 txs->created_at = mktime_utc(&parsed); 557 552 } 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);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; 562 557 } 563 558 } … … 573 568 } 574 569 575 static void expand_entities(char **text, const JSON_Object*node)576 { 577 JSON_Object*entities, *quoted;570 static void expand_entities(char **text, const json_value *node) 571 { 572 json_value *entities, *quoted; 578 573 char *quote_url = NULL, *quote_text = NULL; 579 574 580 if (!( entities = json_object_get_object(node, "entities")))581 return; 582 if ((quoted = json_o bject_get_object(node, "quoted_status"))) {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) { 583 578 /* New "retweets with comments" feature. Note that this info 584 579 * seems to be included in the streaming API only! Grab the … … 596 591 int i; 597 592 598 if ( json_type(v) != JSONArray) {593 if (v->type != json_array) { 599 594 continue; 600 595 } … … 603 598 } 604 599 605 for (i = 0; i < json_array_get_count(json_array(v)); i++) {600 for (i = 0; i < v->u.array.length; i++) { 606 601 const char *format = "%s%s <%s>%s"; 607 JSON_Object *r = json_array_get_object(json_array(v), i); 608 609 if (!r) { 602 603 if (v->u.array.values[i]->type != json_object) { 610 604 continue; 611 605 } 612 606 613 const char *kort = json_o bject_get_string(r, "url");614 const char *disp = json_o bject_get_string(r, "display_url");615 const char *full = json_o bject_get_string(r, "expanded_url");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"); 616 610 char *pos, *new; 617 611 … … 642 636 * - the next_cursor. 643 637 */ 644 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,638 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node, 645 639 struct twitter_xml_list *txl) 646 640 { … … 651 645 txl->type = TXL_STATUS; 652 646 653 if ( json_type(node) != JSONArray) {647 if (node->type != json_array) { 654 648 return FALSE; 655 649 } … … 657 651 // The root <statuses> node should hold the list of statuses <status> 658 652 // Walk over the nodes children. 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));653 for (i = 0; i < node->u.array.length; i++) { 654 txs = twitter_xt_get_status(node->u.array.values[i]); 661 655 if (!txs) { 662 656 continue; … … 864 858 } 865 859 866 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object*o, gboolean from_filter);860 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter); 867 861 868 862 static void twitter_http_stream(struct http_request *req) … … 870 864 struct im_connection *ic = req->data; 871 865 struct twitter_data *td; 872 JSON_Value *parsed;866 json_value *parsed; 873 867 int len = 0; 874 868 char c, *nl; … … 908 902 req->reply_body[len] = '\0'; 909 903 910 if ((parsed = json_parse _string(req->reply_body))) {904 if ((parsed = json_parse(req->reply_body, req->body_size))) { 911 905 from_filter = (req == td->filter_stream); 912 twitter_stream_handle_object(ic, json_object(parsed), from_filter);906 twitter_stream_handle_object(ic, parsed, from_filter); 913 907 } 914 908 json_value_free(parsed); … … 924 918 } 925 919 926 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object*o);920 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o); 927 921 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 928 922 929 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object*o, gboolean from_filter)923 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter) 930 924 { 931 925 struct twitter_data *td = ic->proto_data; 932 926 struct twitter_xml_status *txs; 933 JSON_Object*c;927 json_value *c; 934 928 935 929 if ((txs = twitter_xt_get_status(o))) { … … 938 932 txs_free(txs); 939 933 return ret; 940 } else if ((c = json_o bject_get_object(o, "direct_message")) &&934 } else if ((c = json_o_get(o, "direct_message")) && 941 935 (txs = twitter_xt_get_dm(c))) { 942 936 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { … … 946 940 txs_free(txs); 947 941 return TRUE; 948 } else if ( json_object_get_string(o, "event")) {942 } else if ((c = json_o_get(o, "event")) && c->type == json_string) { 949 943 twitter_stream_handle_event(ic, o); 950 944 return TRUE; 951 } else if ((c = json_o bject_get_object(o, "disconnect"))) {945 } else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) { 952 946 /* HACK: Because we're inside an event handler, we can't just 953 947 disconnect here. Instead, just change the HTTP status string 954 948 into a Twitter status string. */ 955 char *reason = g_strdup(json_object_get_string(c, "reason"));949 char *reason = json_o_strdup(c, "reason"); 956 950 if (reason) { 957 951 g_free(td->stream->status_string); … … 992 986 } 993 987 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) { 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) { 1002 997 return FALSE; 1003 998 } … … 1096 1091 struct twitter_filter *tf; 1097 1092 GList *users = NULL; 1098 JSON_Value *parsed; 1093 json_value *parsed; 1094 json_value *id; 1095 const char *name; 1099 1096 GString *fstr; 1100 1097 GSList *l; … … 1121 1118 } 1122 1119 1123 if ( json_type(parsed) != JSONArray) {1120 if (parsed->type != json_array) { 1124 1121 goto finish; 1125 1122 } 1126 1123 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) { 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) { 1133 1129 continue; 1134 1130 } … … 1138 1134 1139 1135 if (g_strcasecmp(tf->text, name) == 0) { 1140 tf->uid = id ;1136 tf->uid = id->u.integer; 1141 1137 users = g_list_delete_link(users, u); 1142 1138 break; … … 1379 1375 struct im_connection *ic = req->data; 1380 1376 struct twitter_data *td; 1381 JSON_Value *parsed;1377 json_value *parsed; 1382 1378 struct twitter_xml_list *txl; 1383 1379 … … 1418 1414 struct im_connection *ic = req->data; 1419 1415 struct twitter_data *td; 1420 JSON_Value *parsed;1416 json_value *parsed; 1421 1417 struct twitter_xml_list *txl; 1422 1418 … … 1458 1454 struct im_connection *ic = req->data; 1459 1455 struct twitter_data *td; 1460 JSON_Value *parsed; 1461 jint id; 1456 json_value *parsed, *id; 1462 1457 1463 1458 // Check if the connection is still active. … … 1473 1468 } 1474 1469 1475 if ((id = json_o bject_get_integer(json_object(parsed), "id"))) {1476 td->last_status_id = id ;1470 if ((id = json_o_get(parsed, "id")) && id->type == json_integer) { 1471 td->last_status_id = id->u.integer; 1477 1472 } 1478 1473 … … 1582 1577 { 1583 1578 struct im_connection *ic = req->data; 1584 JSON_Value *parsed; 1585 uint64_t id; 1579 json_value *parsed, *id; 1586 1580 const char *name; 1587 1581 … … 1595 1589 } 1596 1590 1591 /* for the parson branch: 1597 1592 name = json_object_dotget_string(json_object(parsed), "user.screen_name"); 1598 1593 id = json_object_get_integer(json_object(parsed), "id"); 1599 1600 if (name && id) { 1601 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id); 1594 */ 1595 1596 name = json_o_str(json_o_get(parsed, "user"), "screen_name"); 1597 id = json_o_get(parsed, "id"); 1598 1599 if (name && id && id->type == json_integer) { 1600 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer); 1602 1601 } else { 1603 1602 twitter_log(ic, "Error: could not fetch tweet url."); -
root_commands.c
r3ddbd23c r73dd021 460 460 461 461 for (a = irc->b->accounts; a; a = a->next) { 462 char *con = NULL, *protocol = NULL;462 char *con; 463 463 464 464 if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) { … … 471 471 con = ""; 472 472 } 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); 473 474 irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con); 481 475 482 476 i++; … … 492 486 493 487 for (a = irc->b->accounts; a; a = a->next) { 494 if (!a->ic && a->auto_connect && a->prpl != &protocol_missing) {488 if (!a->ic && a->auto_connect) { 495 489 if (strcmp(a->pass, PASSWORD_PENDING) == 0) { 496 490 irc_rootmsg(irc, "Enter password for account %s " … … 549 543 irc_rootmsg(irc, "Enter password for account %s " 550 544 "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"));554 545 } else { 555 546 account_on(irc->b, a); … … 656 647 irc_rootmsg(irc, "That account is not on-line"); 657 648 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 } 650 651 if (cmd[3]) { 652 if (!nick_ok(irc, cmd[3])) { 653 irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]); 654 return; 655 } else if (irc_user_by_name(irc, cmd[3])) { 656 irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]); 657 return; 658 } else { 659 nick_set_raw(a, cmd[2], cmd[3]); 660 } 661 661 } 662 662 … … 674 674 } 675 675 676 if (cmd[3]) {677 if (!nick_ok(irc, cmd[3])) {678 irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);679 return;680 } else if (irc_user_by_name(irc, cmd[3])) {681 irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);682 return;683 } else {684 nick_set_raw(a, cmd[2], cmd[3]);685 }686 }687 688 676 if (add_on_server) { 689 677 irc_channel_t *ic; … … 729 717 s = g_strdup(bu->handle); 730 718 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 719 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 738 720 nick_del(bu); 739 721 if (g_slist_find(irc->users, iu)) { -
storage.c
r3ddbd23c r73dd021 33 33 34 34 static GList *storage_backends = NULL; 35 36 const struct prpl protocol_missing = {37 .name = "_unknown",38 };39 35 40 36 void register_storage_backend(storage_t *backend) -
storage.h
r3ddbd23c r73dd021 62 62 G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate); 63 63 64 extern const struct prpl protocol_missing;65 66 64 #endif /* __STORAGE_H__ */ -
storage_xml.c
r3ddbd23c r73dd021 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 104 85 static xt_status handle_account(struct xt_node *node, gpointer data) 105 86 { … … 108 89 char *pass_b64 = NULL; 109 90 unsigned char *pass_cr = NULL; 110 int pass_len ;91 int pass_len, local = 0; 111 92 struct prpl *prpl = NULL; 112 93 account_t *acc; … … 123 104 prpl = find_protocol(protocol); 124 105 if (!prpl) { 125 irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol); 126 prpl = (struct prpl*) &protocol_missing; 127 } 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); 128 110 } 129 111 … … 142 124 set_setstr(&acc->set, "tag", tag); 143 125 } 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; 126 if (local) { 127 acc->flags |= ACC_FLAG_LOCAL; 148 128 } 149 129 } else { … … 156 136 g_free(password); 157 137 158 if (prpl == &protocol_missing) { 159 handle_settings_raw(node, &acc->set); 160 } else { 161 handle_settings(node, &acc->set); 162 } 138 handle_settings(node, &acc->set); 163 139 164 140 for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) { … … 336 312 337 313 cur = xt_new_node("account", NULL, NULL); 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 } 314 xt_add_attr(cur, "protocol", acc->prpl->name); 343 315 xt_add_attr(cur, "handle", acc->user); 344 316 xt_add_attr(cur, "password", pass_b64);
Note: See TracChangeset
for help on using the changeset viewer.