Changes in / [4a9c6b0:7a9d968]


Ignore:
Files:
7 added
4 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r4a9c6b0 r7a9d968  
    3232bitlbee.service
    3333bitlbee@.service
     34*.pyc
  • configure

    r4a9c6b0 r7a9d968  
    1717libdir='$prefix/lib/'
    1818plugindir='$prefix/lib/bitlbee/'
     19rpcplugindir='$plugindir/rpc/'
    1920includedir='$prefix/include/bitlbee/'
    2021systemdsystemunitdir=''
     
    3940twitter=1
    4041purple=0
     42rpc=1
    4143
    4244verbose=0
     
    124126--datadir=...                                           $datadir
    125127--plugindir=...                                         $plugindir
     128--rpcplugindir=...                                      $rpcplugindir
    126129--systemdsystemunitdir=...                              $systemdsystemunitdir
    127130--pidfile=...                                           $pidfile
     
    137140--purple=0/1    Disable/enable libpurple support        $purple
    138141                (automatically disables other protocol modules)
     142--rpc=0/1       Disable/enable RPC plugin interface     $rpc
    139143
    140144--pam=0/1       Disable/enable PAM authentication       $pam
     
    176180libdir=$(eval echo "$libdir/" | sed 's/\/\{1,\}/\//g')
    177181plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g')
     182rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g')
    178183includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g')
    179184libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g')
     
    197202DATADIR=$datadir
    198203PLUGINDIR=$plugindir
     204RPCPLUGINDIR=$rpcplugindir
    199205CONFIG=$config
    200206LIBDIR=$libdir
     
    247253#define VARDIR "$datadir"
    248254#define PLUGINDIR "$plugindir"
     255#define RPCPLUGINDIR "$rpcplugindir"
    249256#define DATADIR "$datadir"
    250257#define PIDFILE "$pidfile"
     
    288295        LDFLAGS="$LDFLAGS -fsanitize=address"
    289296        debug=1
     297fi
     298
     299if [ "$tsan" = "1" ]; then
     300        echo
     301        echo "Threaded BitlBee? Have a nice tall glass of http://imgur.com/gallery/tX4qxzS"
     302        echo "No need to sanitise threads in a single-threaded process!"
    290303fi
    291304
     
    730743fi
    731744
     745if [ "$rpc" = 0 ]; then
     746        # Somewhat pointless at this stage already but at least this keeps it
     747        # out of bitlbee.pc which is probably a good thing.
     748        rpcplugindir=""
     749fi
     750
    732751otrprefix=""
    733752if [ "$otr" = "auto" ]; then
     
    814833includedir=$includedir
    815834plugindir=$plugindir
     835rpcplugindir=$rpcplugindir
    816836libdir=$libdir
    817837datadir=$datadir
     
    899919        protocols=$protocols'twitter '
    900920        protoobjs=$protoobjs'twitter_mod.o '
     921fi
     922
     923if [ "$rpc" = 0 ]; then
     924        echo '#undef WITH_RPC' >> config.h
     925else
     926        echo '#define WITH_RPC' >> config.h
     927        protocols=$protocols'rpc '
     928        protoobjs=$protoobjs'rpc_mod.o '
    901929fi
    902930
     
    9901018echo '  Using event handler: '$events
    9911019echo '  Using SSL library: '$ssl
    992 #echo '  Building with these storage backends: '$STORAGES
    9931020
    9941021if [ -n "$protocols" ]; then
  • irc_channel.c

    r4a9c6b0 r7a9d968  
    757757        }
    758758
     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
    759764        bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle,
    760765                                     icc->group ? icc->group->name : NULL);
     
    774779        if (icc->type != IRC_CC_TYPE_GROUP) {
    775780                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);
    776786                return;
    777787        }
  • irc_commands.c

    r4a9c6b0 r7a9d968  
    330330                           showed an error message, or is doing some work
    331331                           before the join should be confirmed. (In the
    332                            latter case, the caller should take care of that
     332                           latter case, the callee should take care of that
    333333                           confirmation.) TRUE means all's good, let the
    334334                           user join the channel right away. */
  • lib/Makefile

    r4a9c6b0 r7a9d968  
    1313
    1414# [SH] Program variables
    15 objects = arc.o base64.o canohost.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o json.o json_util.o md5.o misc.o oauth.o oauth2.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ns_parse.o
     15objects = arc.o base64.o canohost.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o oauth2.o parson.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ns_parse.o
    1616
    1717LFLAGS += -r
  • lib/misc.c

    r4a9c6b0 r7a9d968  
    386386}
    387387
    388 int is_bool(char *value)
     388int is_bool(const char *value)
    389389{
    390390        if (*value == 0) {
     
    412412}
    413413
    414 int bool2int(char *value)
     414int bool2int(const char *value)
    415415{
    416416        int i;
  • lib/misc.h

    r4a9c6b0 r7a9d968  
    135135G_MODULE_EXPORT void random_bytes(unsigned char *buf, int count);
    136136
    137 G_MODULE_EXPORT int is_bool(char *value);
    138 G_MODULE_EXPORT int bool2int(char *value);
     137G_MODULE_EXPORT int is_bool(const char *value);
     138G_MODULE_EXPORT int bool2int(const char *value);
    139139
    140140G_MODULE_EXPORT struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain);
  • lib/oauth2.c

    r4a9c6b0 r7a9d968  
    4242#include "oauth2.h"
    4343#include "oauth.h"
    44 #include "json.h"
    45 #include "json_util.h"
     44#include "parson.h"
    4645#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++)
    4750
    4851char *oauth2_url(const struct oauth2_service *sp)
     
    113116}
    114117
    115 static char* oauth2_parse_error(json_value *e)
     118static char* oauth2_parse_error(const JSON_Value *e)
    116119{
    117120        /* This does a reasonable job with some of the flavours of error
    118121           responses I've seen. Because apparently it's not standardised. */
    119122
    120         if (e->type == json_object) {
     123        if (json_type(e) == JSONObject) {
    121124                /* 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);
    131129                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));
    134132        }
    135133        return NULL;
     
    156154        if (content_type && (strstr(content_type, "application/json") ||
    157155                             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){
    161159                                if (strcmp(k, "error") == 0) {
    162160                                        error = oauth2_parse_error(v);
    163161                                }
    164                                 if (v->type != json_string) {
     162                                if (json_type(v) != JSONString) {
    165163                                        continue;
    166164                                }
    167165                                if (strcmp(k, "access_token") == 0) {
    168                                         atoken = g_strdup(v->u.string.ptr);
     166                                        atoken = g_strdup(json_string(v));
    169167                                }
    170168                                if (strcmp(k, "refresh_token") == 0) {
    171                                         rtoken = g_strdup(v->u.string.ptr);
     169                                        rtoken = g_strdup(json_string(v));
    172170                                }
    173171                        }
  • protocols/account.c

    r4a9c6b0 r7a9d968  
    2727#include "bitlbee.h"
    2828#include "account.h"
    29 
    30 static const char* account_protocols_local[] = {
    31         "gg", "whatsapp", NULL
    32 };
    3329
    3430static char *set_eval_nick_source(set_t *set, char *value);
     
    469465        return a->auto_reconnect_delay;
    470466}
    471 
    472 int protocol_account_islocal(const char* protocol)
    473 {
    474         const char** p = account_protocols_local;
    475 
    476         do {
    477                 if (strcmp(*p, protocol) == 0) {
    478                         return 1;
    479                 }
    480         } while (*(++p));
    481         return 0;
    482 }
  • protocols/account.h

    r4a9c6b0 r7a9d968  
    5858int account_reconnect_delay(account_t *a);
    5959
    60 int protocol_account_islocal(const char* protocol);
    61 
    6260typedef enum {
    6361        ACC_SET_OFFLINE_ONLY = 0x02,    /* Allow changes only if the acct is offline. */
     
    7068        ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */
    7169        ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */
    72         ACC_FLAG_LOCAL = 0x08,          /* Contact list is local. */
     70        ACC_FLAG_LOCAL_CONTACTS = 0x08, /* Contact list is local. */
    7371        ACC_FLAG_LOCKED = 0x10,         /* Account is locked (cannot be deleted, certain settings can't changed) */
    7472} account_flag_t;
  • protocols/nogaim.c

    r4a9c6b0 r7a9d968  
    259259        extern void twitter_initmodule();
    260260        extern void purple_initmodule();
     261        extern void rpc_initmodule();
    261262
    262263#ifdef WITH_MSN
     
    278279#ifdef WITH_PURPLE
    279280        purple_initmodule();
     281#endif
     282
     283#ifdef WITH_RPC
     284        rpc_initmodule();
    280285#endif
    281286
     
    443448        }
    444449
    445         if (ic->acc->flags & ACC_FLAG_LOCAL) {
     450        if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) &&
     451            !(ic->flags & OPT_LOCAL_CONTACTS_SENT) &&
     452            ic->acc->prpl->add_buddy) {
    446453                GHashTableIter nicks;
    447                 gpointer k, v;
     454                gpointer handle;
    448455                g_hash_table_iter_init(&nicks, ic->acc->nicks);
    449                 while (g_hash_table_iter_next(&nicks, &k, &v)) {
    450                         ic->acc->prpl->add_buddy(ic, (char *) k, NULL);
     456                while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
     457                        ic->acc->prpl->add_buddy(ic, (char *) handle, NULL);
    451458                }
    452459        }
     
    543550        query_del_by_conn((irc_t *) ic->bee->ui_data, ic);
    544551
     552        /* Throw away groupchats owned by this account. Historically this was only
     553           ever done by IM modules which is a bug. But it gives them opportunity
     554           to clean up protocol-specific bits as well so keep it that way, just
     555           do another cleanup here as a fallback. Don't want to leave any dangling
     556           pointers! */
     557        while (ic->groupchats) {
     558                imcb_chat_free(ic->groupchats->data);
     559        }
     560
    545561        if (!a) {
    546562                /* Uhm... This is very sick. */
     
    641657}
    642658
     659/* Returns the local contacts for an IM account (based on assigned nicks).
     660   Linked list should be freed, the strings themselves not! So look at it
     661   like a GSList<const char*> I guess? Empty list means NULL retval (as
     662   always with GSList). */
     663GSList *imcb_get_local_contacts(struct im_connection *ic)
     664{
     665        GHashTableIter nicks;
     666        GSList *ret = NULL;
     667       
     668        if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) {
     669                /* Only allow protocols that indicate local contact list
     670                   support to use this function. */
     671                return ret;
     672        }
     673       
     674        g_hash_table_iter_init(&nicks, ic->acc->nicks);
     675        gpointer handle;
     676        while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
     677                ret = g_slist_prepend(ret, (char *) handle);
     678        }
     679       
     680        /* If the protocol asked for the list, assume we won't have to send it
     681           anymore in imcb_connected(). */
     682        ic->flags |= OPT_LOCAL_CONTACTS_SENT;
     683       
     684        return ret;
     685}
     686
     687
    643688struct imcb_ask_cb_data {
    644689        struct im_connection *ic;
     
    698743        struct imcb_ask_cb_data *cbd = data;
    699744
    700         cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
     745        if (cbd->ic->acc->prpl->add_buddy) {
     746                cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
     747        }
    701748
    702749        imcb_ask_cb_free(data);
  • protocols/nogaim.h

    r4a9c6b0 r7a9d968  
    5757
    5858/* 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... */
    6065#define OPT_LOGGED_IN   0x00000001
    6166#define OPT_LOGGING_OUT 0x00000002
     
    7075#define OPT_PONGS       0x00010000 /* Service sends us keep-alives */
    7176#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. */
    7278#define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */
    7379
     
    372378G_MODULE_EXPORT void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick);
    373379G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data);
     380G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic);
    374381
    375382G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags);
  • protocols/purple/purple.c

    r4a9c6b0 r7a9d968  
    327327        }
    328328        purple_accounts_remove(pa);
     329       
     330        /* Last, some protocols want their contact lists locally. */
     331        if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) {
     332                acc->flags |= ACC_FLAG_LOCAL_CONTACTS;
     333        }
    329334}
    330335
  • protocols/twitter/twitter_lib.c

    r4a9c6b0 r7a9d968  
    3636#include "base64.h"
    3737#include "twitter_lib.h"
    38 #include "json_util.h"
     38#include "parson.h"
    3939#include <ctype.h>
    4040#include <errno.h>
     
    6464        gboolean from_filter;
    6565};
     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++)
    6670
    6771/**
     
    166170{
    167171        static char *ret = NULL;
    168         json_value *root, *err;
     172        JSON_Value *root, *err;
    169173
    170174        g_free(ret);
     
    172176
    173177        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");
    179184                        if (msg) {
    180185                                ret = g_strdup_printf("%s (%s)", req->status_string, msg);
     
    189194/* WATCH OUT: This function might or might not destroy your connection.
    190195   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)
     196static JSON_Value *twitter_parse_response(struct im_connection *ic, struct http_request *req)
    192197{
    193198        gboolean logging_in = !(ic->flags & OPT_LOGGED_IN);
    194199        gboolean periodic;
    195200        struct twitter_data *td = ic->proto_data;
    196         json_value *ret;
     201        JSON_Value *ret;
    197202        char path[64] = "", *s;
    198203
     
    232237        }
    233238
    234         if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) {
     239        if ((ret = json_parse_string(req->reply_body)) == NULL) {
    235240                imcb_error(ic, "Could not retrieve %s: %s",
    236241                           path, "JSON parse error");
     
    289294 * Fill a list of ids.
    290295 */
    291 static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl)
    292 {
    293         json_value *c;
     296static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl)
     297{
     298        JSON_Array *c;
    294299        int i;
    295300
     
    297302        txl->type = TXL_ID;
    298303
    299         c = json_o_get(node, "ids");
    300         if (!c || c->type != json_array) {
     304        if (!(c = json_object_get_array(json_object(node), "ids"))) {
    301305                return FALSE;
    302306        }
    303307
    304         for (i = 0; i < c->u.array.length; i++) {
    305                 if (c->u.array.values[i]->type != json_integer) {
    306                         continue;
    307                 }
     308        for (i = 0; i < json_array_get_count(c); i++) {
     309                jint id = json_array_get_integer(c, i);
    308310
    309311                txl->list = g_slist_prepend(txl->list,
    310                                             g_strdup_printf("%" PRId64, c->u.array.values[i]->u.integer));
    311         }
    312 
    313         c = json_o_get(node, "next_cursor");
    314         if (c && c->type == json_integer) {
    315                 txl->next_cursor = c->u.integer;
     312                                            g_strdup_printf("%" PRIu64, id);
     313        }
     314
     315        JSON_Value *next = json_object_get_value(json_object(node), "next_cursor");
     316        if (next && json_type(next) == JSONInteger) {
     317                txl->next_cursor = json_integer(next);
    316318        } else {
    317319                txl->next_cursor = -1;
     
    329331{
    330332        struct im_connection *ic;
    331         json_value *parsed;
     333        JSON_Value *parsed;
    332334        struct twitter_xml_list *txl;
    333335        struct twitter_data *td;
     
    373375{
    374376        struct im_connection *ic = req->data;
    375         json_value *parsed;
     377        JSON_Value *parsed;
    376378        struct twitter_xml_list *txl;
    377379        struct twitter_data *td;
     
    418420{
    419421        struct im_connection *ic = req->data;
    420         json_value *parsed;
     422        JSON_Value *parsed;
    421423        struct twitter_xml_list *txl;
    422424        struct twitter_data *td;
     
    444446        // Process the retweet ids
    445447        txl->type = TXL_ID;
    446         if (parsed->type == json_array) {
     448        if (json_type(parsed) == JSONArray) {
     449                JSON_Array *arr = json_array(parsed);
    447450                unsigned int i;
    448                 for (i = 0; i < parsed->u.array.length; i++) {
    449                         json_value *c = parsed->u.array.values[i];
    450                         if (c->type != json_integer) {
    451                                 continue;
    452                         }
     451                for (i = 0; i < json_array_get_count(arr); i++) {
     452                        jint id = json_array_get_integer(arr, i);
    453453                        txl->list = g_slist_prepend(txl->list,
    454                                                     g_strdup_printf("%" PRId64, c->u.integer));
     454                                                    g_strdup_printf("%" PRId64, id));
    455455                }
    456456        }
     
    463463}
    464464
    465 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl);
     465static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl);
    466466static void twitter_http_get_users_lookup(struct http_request *req);
    467467
     
    504504{
    505505        struct im_connection *ic = req->data;
    506         json_value *parsed;
     506        JSON_Value *parsed;
    507507        struct twitter_xml_list *txl;
    508508        GSList *l = NULL;
     
    537537}
    538538
    539 struct twitter_xml_user *twitter_xt_get_user(const json_value *node)
     539struct twitter_xml_user *twitter_xt_get_user(const JSON_Object *node)
    540540{
    541541        struct twitter_xml_user *txu;
    542         json_value *jv;
     542       
     543        if (!node)
     544                return NULL;
    543545
    544546        txu = g_new0(struct twitter_xml_user, 1);
    545         txu->name = g_strdup(json_o_str(node, "name"));
    546         txu->screen_name = g_strdup(json_o_str(node, "screen_name"));
    547 
    548         jv = json_o_get(node, "id");
    549         txu->uid = jv->u.integer;
     547        txu->name = g_strdup(json_object_get_string(node, "name"));
     548        txu->screen_name = g_strdup(json_object_get_string(node, "screen_name"));
     549        txu->uid = json_object_get_integer(node, "id");
    550550
    551551        return txu;
     
    557557 *  - all <user>s from the <users> element.
    558558 */
    559 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl)
     559static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl)
    560560{
    561561        struct twitter_xml_user *txu;
     
    565565        txl->type = TXL_USER;
    566566
    567         if (!node || node->type != json_array) {
     567        if (json_type(node) != JSONArray) {
    568568                return FALSE;
    569569        }
    570 
     570       
    571571        // The root <users> node should hold the list of users <user>
    572572        // Walk over the nodes children.
    573         for (i = 0; i < node->u.array.length; i++) {
    574                 txu = twitter_xt_get_user(node->u.array.values[i]);
     573        JSON_Array *arr = json_array(node);
     574        for (i = 0; i < json_array_get_count(arr); i++) {
     575                JSON_Object *o = json_array_get_object(arr, i);
     576                if (!o)
     577                        continue;
     578                txu = twitter_xt_get_user(o);
    575579                if (txu) {
    576580                        txl->list = g_slist_prepend(txl->list, txu);
     
    587591#endif
    588592
    589 static void expand_entities(char **text, const json_value *node, const json_value *extended_node);
     593static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node);
    590594
    591595/**
     
    597601 *  - the user in a twitter_xml_user struct.
    598602 */
    599 static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
     603static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node)
    600604{
    601605        struct twitter_xml_status *txs = {0};
    602         const json_value *rt = NULL;
    603         const json_value *text_value = NULL;
    604         const json_value *extended_node = NULL;
    605 
    606         if (node->type != json_object) {
     606        const JSON_Object *rt = NULL;
     607        const JSON_Value *text_value = NULL;
     608        const JSON_Object *extended_node = NULL;
     609
     610        if (!node) {
    607611                return FALSE;
    608612        }
     
    610614
    611615        JSON_O_FOREACH(node, k, v) {
    612                 if (strcmp("text", k) == 0 && v->type == json_string && text_value == NULL) {
     616                if (strcmp("text", k) == 0 && json_type(v) == JSONString && text_value == NULL) {
    613617                        text_value = v;
    614                 } else if (strcmp("full_text", k) == 0 && v->type == json_string) {
     618                } else if (strcmp("full_text", k) == 0 && json_type(v) == JSONString) {
    615619                        text_value = v;
    616                 } else if (strcmp("extended_tweet", k) == 0 && v->type == json_object) {
    617                         text_value = json_o_get(v, "full_text");
    618                         extended_node = v;
    619                 } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {
    620                         rt = v;
    621                 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {
     620                } else if (strcmp("extended_tweet", k) == 0 && json_type(v) == JSONObject) {
     621                        text_value = json_object_get_value(json_object(v), "full_text");
     622                        extended_node = json_object(v);
     623                } else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) {
     624                        // Handling below.
     625                } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
    622626                        struct tm parsed;
    623627
     
    625629                           this field. :-( Also assumes the timezone used
    626630                           is UTC since C time handling functions suck. */
    627                         if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
     631                        if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
    628632                                txs->created_at = mktime_utc(&parsed);
    629633                        }
    630                 } else if (strcmp("user", k) == 0 && v->type == json_object) {
    631                         txs->user = twitter_xt_get_user(v);
    632                 } else if (strcmp("id", k) == 0 && v->type == json_integer) {
    633                         txs->rt_id = txs->id = v->u.integer;
    634                 } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {
    635                         txs->reply_to = v->u.integer;
     634                } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) {
     635                        txs->user = twitter_xt_get_user(json_object(v));
     636                } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
     637                        txs->rt_id = txs->id = json_integer(v);
     638                } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) {
     639                        txs->reply_to = json_integer(v);
    636640                }
    637641        }
     
    646650                        txs_free(rtxs);
    647651                }
    648         } else if (text_value && text_value->type == json_string) {
    649                 txs->text = g_memdup(text_value->u.string.ptr, text_value->u.string.length + 1);
     652        } else if (text_value && json_type(text_value) == JSONString) {
     653                txs->text = g_strdup(json_string(text_value));
    650654                strip_html(txs->text);
    651655                expand_entities(&txs->text, node, extended_node);
     
    663667 * Function to fill a twitter_xml_status struct (DM variant).
    664668 */
    665 static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node)
     669static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node)
    666670{
    667671        struct twitter_xml_status *txs;
    668672
    669         if (node->type != json_object) {
     673        if (!node) {
    670674                return FALSE;
    671675        }
     
    673677
    674678        JSON_O_FOREACH(node, k, v) {
    675                 if (strcmp("text", k) == 0 && v->type == json_string) {
    676                         txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
     679                if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {
    677680                        strip_html(txs->text);
    678                 } else if (strcmp("created_at", k) == 0 && v->type == json_string) {
     681                } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
    679682                        struct tm parsed;
    680683
     
    682685                           this field. :-( Also assumes the timezone used
    683686                           is UTC since C time handling functions suck. */
    684                         if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
     687                        if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
    685688                                txs->created_at = mktime_utc(&parsed);
    686689                        }
    687                 } else if (strcmp("sender", k) == 0 && v->type == json_object) {
    688                         txs->user = twitter_xt_get_user(v);
    689                 } else if (strcmp("id", k) == 0 && v->type == json_integer) {
    690                         txs->id = v->u.integer;
     690                } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) {
     691                        txs->user = twitter_xt_get_user(json_object(v));
     692                } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
     693                        txs->id = json_integer(v);
    691694                }
    692695        }
     
    702705}
    703706
    704 static void expand_entities(char **text, const json_value *node, const json_value *extended_node)
    705 {
    706         json_value *entities, *extended_entities, *quoted;
     707static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node)
     708{
     709        JSON_Object *entities, *extended_entities, *quoted;
    707710        char *quote_url = NULL, *quote_text = NULL;
    708711
    709         if (!((entities = json_o_get(node, "entities")) && entities->type == json_object))
    710                 return;
    711         if ((quoted = json_o_get(node, "quoted_status")) && quoted->type == json_object) {
     712        if (!(entities = json_object_get_object(node, "entities")))
     713                return;
     714        if ((quoted = json_object_get_object(node, "quoted_status"))) {
    712715                /* New "retweets with comments" feature. Grab the
    713716                 * full message and try to insert it when we run into the
     
    722725
    723726        if (extended_node) {
    724                 extended_entities = json_o_get(extended_node, "entities");
    725                 if (extended_entities && extended_entities->type == json_object) {
     727                extended_entities = json_object_get_object(extended_node, "entities");
     728                if (extended_entities) {
    726729                        entities = extended_entities;
    727730                }
     
    731734                int i;
    732735
    733                 if (v->type != json_array) {
     736                if (json_type(v) != JSONArray) {
    734737                        continue;
    735738                }
     
    738741                }
    739742
    740                 for (i = 0; i < v->u.array.length; i++) {
     743                for (i = 0; i < json_array_get_count(json_array(v)); i++) {
    741744                        const char *format = "%s%s <%s>%s";
    742 
    743                         if (v->u.array.values[i]->type != json_object) {
     745                        JSON_Object *r = json_array_get_object(json_array(v), i);
     746
     747                        if (!r) {
    744748                                continue;
    745749                        }
    746750
    747                         const char *kort = json_o_str(v->u.array.values[i], "url");
    748                         const char *disp = json_o_str(v->u.array.values[i], "display_url");
    749                         const char *full = json_o_str(v->u.array.values[i], "expanded_url");
     751                        const char *kort = json_object_get_string(r, "url");
     752                        const char *disp = json_object_get_string(r, "display_url");
     753                        const char *full = json_object_get_string(r, "expanded_url");
    750754                        char *pos, *new;
    751755
     
    779783 *  - the next_cursor.
    780784 */
    781 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,
     785static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,
    782786                                           struct twitter_xml_list *txl)
    783787{
     
    788792        txl->type = TXL_STATUS;
    789793
    790         if (node->type != json_array) {
     794        if (json_type(node) != JSONArray) {
    791795                return FALSE;
    792796        }
     
    794798        // The root <statuses> node should hold the list of statuses <status>
    795799        // Walk over the nodes children.
    796         for (i = 0; i < node->u.array.length; i++) {
    797                 txs = twitter_xt_get_status(node->u.array.values[i]);
     800        for (i = 0; i < json_array_get_count(json_array(node)); i++) {
     801                txs = twitter_xt_get_status(json_array_get_object(json_array(node), i));
    798802                if (!txs) {
    799803                        continue;
     
    10151019}
    10161020
    1017 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter);
     1021static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter);
    10181022
    10191023static void twitter_http_stream(struct http_request *req)
     
    10211025        struct im_connection *ic = req->data;
    10221026        struct twitter_data *td;
    1023         json_value *parsed;
     1027        JSON_Value *parsed;
    10241028        int len = 0;
    10251029        char c, *nl;
     
    10621066                req->reply_body[len] = '\0';
    10631067
    1064                 if ((parsed = json_parse(req->reply_body, req->body_size))) {
     1068                if ((parsed = json_parse_string(req->reply_body))) {
    10651069                        from_filter = (req == td->filter_stream);
    1066                         twitter_stream_handle_object(ic, parsed, from_filter);
     1070                        twitter_stream_handle_object(ic, json_object(parsed), from_filter);
    10671071                }
    10681072                json_value_free(parsed);
     
    10781082}
    10791083
    1080 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o);
     1084static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o);
    10811085static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs);
    10821086
    1083 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter)
     1087static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter)
    10841088{
    10851089        struct twitter_data *td = ic->proto_data;
    10861090        struct twitter_xml_status *txs;
    1087         json_value *c;
     1091        JSON_Object *c;
    10881092
    10891093        if ((txs = twitter_xt_get_status(o))) {
     
    10921096                txs_free(txs);
    10931097                return ret;
    1094         } else if ((c = json_o_get(o, "direct_message")) &&
     1098        } else if ((c = json_object_get_object(o, "direct_message")) &&
    10951099                   (txs = twitter_xt_get_dm(c))) {
    10961100                if (g_strcasecmp(txs->user->screen_name, td->user) != 0) {
     
    11001104                txs_free(txs);
    11011105                return TRUE;
    1102         } else if ((c = json_o_get(o, "event")) && c->type == json_string) {
     1106        } else if (json_object_get_string(o, "event")) {
    11031107                twitter_stream_handle_event(ic, o);
    11041108                return TRUE;
    1105         } else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) {
     1109        } else if ((c = json_object_get_object(o, "disconnect"))) {
    11061110                /* HACK: Because we're inside an event handler, we can't just
    11071111                   disconnect here. Instead, just change the HTTP status string
    11081112                   into a Twitter status string. */
    1109                 char *reason = json_o_strdup(c, "reason");
     1113                char *reason = g_strdup(json_object_get_string(c, "reason"));
    11101114                if (reason) {
    11111115                        g_free(td->stream->status_string);
     
    11461150}
    11471151
    1148 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o)
     1152static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o)
    11491153{
    11501154        struct twitter_data *td = ic->proto_data;
    1151         json_value *source = json_o_get(o, "source");
    1152         json_value *target = json_o_get(o, "target");
    1153         const char *type = json_o_str(o, "event");
     1155        JSON_Object *source = json_object_get_object(o, "source");
     1156        JSON_Object *target = json_object_get_object(o, "target");
     1157        const char *type = json_object_get_string(o, "event");
    11541158        struct twitter_xml_user *us = NULL;
    11551159        struct twitter_xml_user *ut = NULL;
    11561160
    1157         if (!type || !source || source->type != json_object
    1158             || !target || target->type != json_object) {
     1161        if (!type || !source || !target) {
    11591162                return FALSE;
    11601163        }
     
    12851288        struct twitter_filter *tf;
    12861289        GList *users = NULL;
    1287         json_value *parsed;
    1288         json_value *id;
    1289         const char *name;
     1290        JSON_Value *parsed;
    12901291        GString *fstr;
    12911292        GSList *l;
     
    13121313        }
    13131314
    1314         if (parsed->type != json_array) {
     1315        if (json_type(parsed) != JSONArray) {
    13151316                goto finish;
    13161317        }
    13171318
    1318         for (i = 0; i < parsed->u.array.length; i++) {
    1319                 id = json_o_get(parsed->u.array.values[i], "id");
    1320                 name = json_o_str(parsed->u.array.values[i], "screen_name");
    1321 
    1322                 if (!name || !id || id->type != json_integer) {
     1319        for (i = 0; i < json_array_get_count(json_array(parsed)); i++) {
     1320                JSON_Object *o = json_array_get_object(json_array(parsed), i);
     1321                jint id = json_object_get_integer(o, "id");
     1322                const char *name = json_object_get_string(o, "screen_name");
     1323
     1324                if (!name || !id) {
    13231325                        continue;
    13241326                }
     
    13281330
    13291331                        if (g_strcasecmp(tf->text, name) == 0) {
    1330                                 tf->uid = id->u.integer;
     1332                                tf->uid = id;
    13311333                                users = g_list_delete_link(users, u);
    13321334                                break;
     
    15731575        struct im_connection *ic = req->data;
    15741576        struct twitter_data *td;
    1575         json_value *parsed;
     1577        JSON_Value *parsed;
    15761578        struct twitter_xml_list *txl;
    15771579
     
    16131615        struct im_connection *ic = req->data;
    16141616        struct twitter_data *td;
    1615         json_value *parsed;
     1617        JSON_Value *parsed;
    16161618        struct twitter_xml_list *txl;
    16171619
     
    16541656        struct im_connection *ic = req->data;
    16551657        struct twitter_data *td;
    1656         json_value *parsed, *id;
     1658        JSON_Value *parsed;
     1659        jint id;
    16571660
    16581661        // Check if the connection is still active.
     
    16681671        }
    16691672
    1670         if ((id = json_o_get(parsed, "id")) && id->type == json_integer) {
    1671                 td->last_status_id = id->u.integer;
     1673        if ((id = json_object_get_integer(json_object(parsed), "id"))) {
     1674                td->last_status_id = id;
    16721675        }
    16731676
     
    17971800{
    17981801        struct im_connection *ic = req->data;
    1799         json_value *parsed, *id;
     1802        JSON_Value *parsed;
     1803        uint64_t id;
    18001804        const char *name;
    18011805
     
    18091813        }
    18101814
    1811         /* for the parson branch:
    18121815        name = json_object_dotget_string(json_object(parsed), "user.screen_name");
    18131816        id = json_object_get_integer(json_object(parsed), "id");
    1814         */
    1815 
    1816         name = json_o_str(json_o_get(parsed, "user"), "screen_name");
    1817         id = json_o_get(parsed, "id");
    1818 
    1819         if (name && id && id->type == json_integer) {
    1820                 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer);
     1817
     1818        if (name && id) {
     1819                twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id);
    18211820        } else {
    18221821                twitter_log(ic, "Error: could not fetch tweet url.");
  • root_commands.c

    r4a9c6b0 r7a9d968  
    509509                                con = "";
    510510                        }
    511 
    512511                        if (a->prpl == &protocol_missing) {
    513512                                protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name"));
     
    701700                irc_rootmsg(irc, "That account is not on-line");
    702701                return;
     702        } else if (add_on_server && !a->prpl->add_buddy) {
     703                irc_rootmsg(irc, "IM protocol does not support contact list modification");
     704                return;
     705        }
     706
     707        if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' &&
     708            (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) {
     709                /* If there's no @ or it's the last char, append the user's
     710                   domain name now. Exclude handles starting with a _ so
     711                   adding _xmlconsole will keep working. */
     712                if (s) {
     713                        *s = '\0';
     714                }
     715                if ((s = strchr(a->user, '@'))) {
     716                        cmd[2] = handle = g_strconcat(cmd[2], s, NULL);
     717                }
    703718        }
    704719
     
    715730        }
    716731
    717         if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' &&
    718             (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) {
    719                 /* If there's no @ or it's the last char, append the user's
    720                    domain name now. Exclude handles starting with a _ so
    721                    adding _xmlconsole will keep working. */
    722                 if (s) {
    723                         *s = '\0';
    724                 }
    725                 if ((s = strchr(a->user, '@'))) {
    726                         cmd[2] = handle = g_strconcat(cmd[2], s, NULL);
    727                 }
    728         }
    729 
    730732        if (add_on_server) {
    731733                irc_channel_t *ic;
     
    771773        s = g_strdup(bu->handle);
    772774
    773         bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
     775        if (bu->ic->acc->prpl->remove_buddy) {
     776                bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
     777        } else {
     778                irc_rootmsg(irc, "IM protocol does not support contact list modification, "
     779                                 "removal will likely not be permanent");
     780        }
     781
    774782        nick_del(bu);
    775783        if (g_slist_find(irc->users, iu)) {
  • storage_xml.c

    r4a9c6b0 r7a9d968  
    114114        char *pass_b64 = NULL;
    115115        unsigned char *pass_cr = NULL;
    116         int pass_len, local = 0;
     116        int pass_len;
    117117        struct prpl *prpl = NULL;
    118118        account_t *acc;
     
    133133                        prpl = (struct prpl*) &protocol_missing;
    134134                }
    135                 local = protocol_account_islocal(protocol);
    136135        }
    137136
     
    161160        if (tag) {
    162161                set_setstr(&acc->set, "tag", tag);
    163         }
    164         if (local) {
    165                 acc->flags |= ACC_FLAG_LOCAL;
    166162        }
    167163        if (locked && !g_strcasecmp(locked, "true")) {
Note: See TracChangeset for help on using the changeset viewer.