Changes in / [3f44e43:5a8afc3]


Ignore:
Files:
4 added
7 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r3f44e43 r5a8afc3  
    3232bitlbee.service
    3333bitlbee@.service
    34 *.pyc
  • configure

    r3f44e43 r5a8afc3  
    1616config='/var/lib/bitlbee/'
    1717plugindir='$prefix/lib/bitlbee/'
    18 rpcplugindir='$plugindir/rpc/'
    1918includedir='$prefix/include/bitlbee/'
    2019systemdsystemunitdir=''
     
    3938twitter=1
    4039purple=0
    41 rpc=1
    4240
    4341doc=1
     
    124122--datadir=...                                           $datadir
    125123--plugindir=...                                         $plugindir
    126 --rpcplugindir=...                                      $rpcplugindir
    127124--systemdsystemunitdir=...                              $systemdsystemunitdir
    128125--pidfile=...                                           $pidfile
     
    136133--purple=0/1    Disable/enable libpurple support        $purple
    137134                (automatically disables other protocol modules)
    138 --rpc=0/1       Disable/enable RPC plugin interface     $rpc
    139135
    140136--pam=0/1       Disable/enable PAM authentication       $pam
     
    175171config=$(eval echo "$config/" | sed 's/\/\{1,\}/\//g')
    176172plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g')
    177 rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g')
    178173includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g')
    179174libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g')
     
    197192DATADIR=$datadir
    198193PLUGINDIR=$plugindir
    199 RPCPLUGINDIR=$rpcplugindir
    200194CONFIG=$config
    201195INCLUDEDIR=$includedir
     
    247241#define VARDIR "$datadir"
    248242#define PLUGINDIR "$plugindir"
    249 #define RPCPLUGINDIR "$rpcplugindir"
    250243#define PIDFILE "$pidfile"
    251244#define IPCSOCKET "$ipcsocket"
     
    288281        LDFLAGS="$LDFLAGS -fsanitize=address"
    289282        debug=1
    290 fi
    291 
    292 if [ "$tsan" = "1" ]; then
    293         echo
    294         echo "Threaded BitlBee? Have a nice tall glass of http://imgur.com/gallery/tX4qxzS"
    295         echo "No need to sanitise threads in a single-threaded process!"
    296283fi
    297284
     
    717704fi
    718705
    719 if [ "$rpc" = 0 ]; then
    720         # Somewhat pointless at this stage already but at least this keeps it
    721         # out of bitlbee.pc which is probably a good thing.
    722         rpcplugindir=""
    723 fi
    724 
    725706otrprefix=""
    726707if [ "$otr" = "auto" ]; then
     
    801782includedir=$includedir
    802783plugindir=$plugindir
    803 rpcplugindir=$rpcplugindir
    804784
    805785Name: bitlbee
     
    885865        protocols=$protocols'twitter '
    886866        protoobjs=$protoobjs'twitter_mod.o '
    887 fi
    888 
    889 if [ "$rpc" = 0 ]; then
    890         echo '#undef WITH_RPC' >> config.h
    891 else
    892         echo '#define WITH_RPC' >> config.h
    893         protocols=$protocols'rpc '
    894         protoobjs=$protoobjs'rpc_mod.o '
    895867fi
    896868
     
    982954echo '  Using event handler: '$events
    983955echo '  Using SSL library: '$ssl
     956#echo '  Building with these storage backends: '$STORAGES
    984957
    985958if [ -n "$protocols" ]; then
  • irc_channel.c

    r3f44e43 r5a8afc3  
    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 
    764759        bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle,
    765760                                     icc->group ? icc->group->name : NULL);
     
    779774        if (icc->type != IRC_CC_TYPE_GROUP) {
    780775                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);
    786776                return;
    787777        }
  • irc_commands.c

    r3f44e43 r5a8afc3  
    287287                           showed an error message, or is doing some work
    288288                           before the join should be confirmed. (In the
    289                            latter case, the callee should take care of that
     289                           latter case, the caller should take care of that
    290290                           confirmation.) TRUE means all's good, let the
    291291                           user join the channel right away. */
  • lib/Makefile

    r3f44e43 r5a8afc3  
    1313
    1414# [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.o
     15objects = 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
    1616
    1717LFLAGS += -r
  • lib/misc.c

    r3f44e43 r5a8afc3  
    431431}
    432432
    433 int is_bool(const char *value)
     433int is_bool(char *value)
    434434{
    435435        if (*value == 0) {
     
    457457}
    458458
    459 int bool2int(const char *value)
     459int bool2int(char *value)
    460460{
    461461        int i;
  • lib/misc.h

    r3f44e43 r5a8afc3  
    137137G_MODULE_EXPORT void random_bytes(unsigned char *buf, int count);
    138138
    139 G_MODULE_EXPORT int is_bool(const char *value);
    140 G_MODULE_EXPORT int bool2int(const char *value);
     139G_MODULE_EXPORT int is_bool(char *value);
     140G_MODULE_EXPORT int bool2int(char *value);
    141141
    142142G_MODULE_EXPORT struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain);
  • lib/oauth2.c

    r3f44e43 r5a8afc3  
    4242#include "oauth2.h"
    4343#include "oauth.h"
    44 #include "parson.h"
     44#include "json.h"
     45#include "json_util.h"
    4546#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++)
    5047
    5148char *oauth2_url(const struct oauth2_service *sp)
     
    116113}
    117114
    118 static char* oauth2_parse_error(const JSON_Value *e)
     115static char* oauth2_parse_error(json_value *e)
    119116{
    120117        /* This does a reasonable job with some of the flavours of error
    121118           responses I've seen. Because apparently it's not standardised. */
    122119
    123         if (json_type(e) == JSONObject) {
     120        if (e->type == json_object) {
    124121                /* 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
    129131                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);
    132134        }
    133135        return NULL;
     
    154156        if (content_type && (strstr(content_type, "application/json") ||
    155157                             strstr(content_type, "text/javascript"))) {
    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){
     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){
    159161                                if (strcmp(k, "error") == 0) {
    160162                                        error = oauth2_parse_error(v);
    161163                                }
    162                                 if (json_type(v) != JSONString) {
     164                                if (v->type != json_string) {
    163165                                        continue;
    164166                                }
    165167                                if (strcmp(k, "access_token") == 0) {
    166                                         atoken = g_strdup(json_string(v));
     168                                        atoken = g_strdup(v->u.string.ptr);
    167169                                }
    168170                                if (strcmp(k, "refresh_token") == 0) {
    169                                         rtoken = g_strdup(json_string(v));
     171                                        rtoken = g_strdup(v->u.string.ptr);
    170172                                }
    171173                        }
  • protocols/account.c

    r3f44e43 r5a8afc3  
    2727#include "bitlbee.h"
    2828#include "account.h"
     29
     30static const char* account_protocols_local[] = {
     31        "gg", "whatsapp", NULL
     32};
    2933
    3034static char *set_eval_nick_source(set_t *set, char *value);
     
    462466        return a->auto_reconnect_delay;
    463467}
     468
     469int protocol_account_islocal(const char* protocol)
     470{
     471        const char** p = account_protocols_local;
     472
     473        do {
     474                if (strcmp(*p, protocol) == 0) {
     475                        return 1;
     476                }
     477        } while (*(++p));
     478        return 0;
     479}
  • protocols/account.h

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

    r3f44e43 r5a8afc3  
    241241        extern void twitter_initmodule();
    242242        extern void purple_initmodule();
    243         extern void rpc_initmodule();
    244243
    245244#ifdef WITH_MSN
     
    261260#ifdef WITH_PURPLE
    262261        purple_initmodule();
    263 #endif
    264 
    265 #ifdef WITH_RPC
    266         rpc_initmodule();
    267262#endif
    268263
     
    430425        }
    431426
    432         if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) &&
    433             !(ic->flags & OPT_LOCAL_CONTACTS_SENT) &&
    434             ic->acc->prpl->add_buddy) {
     427        if (ic->acc->flags & ACC_FLAG_LOCAL) {
    435428                GHashTableIter nicks;
    436                 gpointer handle;
     429                gpointer k, v;
    437430                g_hash_table_iter_init(&nicks, ic->acc->nicks);
    438                 while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
    439                         ic->acc->prpl->add_buddy(ic, (char *) handle, NULL);
     431                while (g_hash_table_iter_next(&nicks, &k, &v)) {
     432                        ic->acc->prpl->add_buddy(ic, (char *) k, NULL);
    440433                }
    441434        }
     
    532525        query_del_by_conn((irc_t *) ic->bee->ui_data, ic);
    533526
    534         /* Throw away groupchats owned by this account. Historically this was only
    535            ever done by IM modules which is a bug. But it gives them opportunity
    536            to clean up protocol-specific bits as well so keep it that way, just
    537            do another cleanup here as a fallback. Don't want to leave any dangling
    538            pointers! */
    539         while (ic->groupchats) {
    540                 imcb_chat_free(ic->groupchats->data);
    541         }
    542 
    543527        if (!a) {
    544528                /* Uhm... This is very sick. */
     
    639623}
    640624
    641 /* Returns the local contacts for an IM account (based on assigned nicks).
    642    Linked list should be freed, the strings themselves not! So look at it
    643    like a GSList<const char*> I guess? Empty list means NULL retval (as
    644    always with GSList). */
    645 GSList *imcb_get_local_contacts(struct im_connection *ic)
    646 {
    647         GHashTableIter nicks;
    648         GSList *ret = NULL;
    649        
    650         if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) {
    651                 /* Only allow protocols that indicate local contact list
    652                    support to use this function. */
    653                 return ret;
    654         }
    655        
    656         g_hash_table_iter_init(&nicks, ic->acc->nicks);
    657         gpointer handle;
    658         while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
    659                 ret = g_slist_prepend(ret, (char *) handle);
    660         }
    661        
    662         /* If the protocol asked for the list, assume we won't have to send it
    663            anymore in imcb_connected(). */
    664         ic->flags |= OPT_LOCAL_CONTACTS_SENT;
    665        
    666         return ret;
    667 }
    668 
    669 
    670625struct imcb_ask_cb_data {
    671626        struct im_connection *ic;
     
    725680        struct imcb_ask_cb_data *cbd = data;
    726681
    727         if (cbd->ic->acc->prpl->add_buddy) {
    728                 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
    729         }
     682        cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
    730683
    731684        imcb_ask_cb_free(data);
  • protocols/nogaim.h

    r3f44e43 r5a8afc3  
    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. ;-)
    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. ;-) */
    6560#define OPT_LOGGED_IN   0x00000001
    6661#define OPT_LOGGING_OUT 0x00000002
     
    7570#define OPT_PONGS       0x00010000 /* Service sends us keep-alives */
    7671#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. */
    7872#define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */
    7973
     
    378372G_MODULE_EXPORT void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick);
    379373G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data);
    380 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic);
    381374
    382375G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags);
  • protocols/purple/purple.c

    r3f44e43 r5a8afc3  
    298298        }
    299299        purple_accounts_remove(pa);
    300        
    301         /* Last, some protocols want their contact lists locally. */
    302         if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) {
    303                 acc->flags |= ACC_FLAG_LOCAL_CONTACTS;
    304         }
    305300}
    306301
  • protocols/twitter/twitter_lib.c

    r3f44e43 r5a8afc3  
    3636#include "base64.h"
    3737#include "twitter_lib.h"
    38 #include "parson.h"
     38#include "json_util.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++)
    7066
    7167/**
     
    170166{
    171167        static char *ret = NULL;
    172         JSON_Value *root, *err;
     168        json_value *root, *err;
    173169
    174170        g_free(ret);
     
    176172
    177173        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");
    184179                        if (msg) {
    185180                                ret = g_strdup_printf("%s (%s)", req->status_string, msg);
     
    194189/* WATCH OUT: This function might or might not destroy your connection.
    195190   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)
     191static json_value *twitter_parse_response(struct im_connection *ic, struct http_request *req)
    197192{
    198193        gboolean logging_in = !(ic->flags & OPT_LOGGED_IN);
    199194        gboolean periodic;
    200195        struct twitter_data *td = ic->proto_data;
    201         JSON_Value *ret;
     196        json_value *ret;
    202197        char path[64] = "", *s;
    203198
     
    237232        }
    238233
    239         if ((ret = json_parse_string(req->reply_body)) == NULL) {
     234        if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) {
    240235                imcb_error(ic, "Could not retrieve %s: %s",
    241236                           path, "XML parse error");
     
    294289 * Fill a list of ids.
    295290 */
    296 static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl)
    297 {
    298         JSON_Array *c;
     291static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl)
     292{
     293        json_value *c;
    299294        int i;
    300295
     
    302297        txl->type = TXL_ID;
    303298
    304         if (!(c = json_object_get_array(json_object(node), "ids"))) {
     299        c = json_o_get(node, "ids");
     300        if (!c || c->type != json_array) {
    305301                return FALSE;
    306302        }
    307303
    308         for (i = 0; i < json_array_get_count(c); i++) {
    309                 jint id = json_array_get_integer(c, i);
     304        for (i = 0; i < c->u.array.length; i++) {
     305                if (c->u.array.values[i]->type != json_integer) {
     306                        continue;
     307                }
    310308
    311309                txl->list = g_slist_prepend(txl->list,
    312                                             g_strdup_printf("%lld", id));
    313         }
    314 
    315         JSON_Value *next = json_object_get_value(json_object(node), "next_cursor");
    316         if (next && json_type(next) == JSONInteger) {
    317                 txl->next_cursor = json_integer(next);
     310                                            g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer));
     311        }
     312
     313        c = json_o_get(node, "next_cursor");
     314        if (c && c->type == json_integer) {
     315                txl->next_cursor = c->u.integer;
    318316        } else {
    319317                txl->next_cursor = -1;
     
    331329{
    332330        struct im_connection *ic;
    333         JSON_Value *parsed;
     331        json_value *parsed;
    334332        struct twitter_xml_list *txl;
    335333        struct twitter_data *td;
     
    375373{
    376374        struct im_connection *ic = req->data;
    377         JSON_Value *parsed;
     375        json_value *parsed;
    378376        struct twitter_xml_list *txl;
    379377        struct twitter_data *td;
     
    420418{
    421419        struct im_connection *ic = req->data;
    422         JSON_Value *parsed;
     420        json_value *parsed;
    423421        struct twitter_xml_list *txl;
    424422        struct twitter_data *td;
     
    446444        // Process the retweet ids
    447445        txl->type = TXL_ID;
    448         if (json_type(parsed) == JSONArray) {
    449                 JSON_Array *arr = json_array(parsed);
     446        if (parsed->type == json_array) {
    450447                unsigned int i;
    451                 for (i = 0; i < json_array_get_count(arr); i++) {
    452                         jint id = json_array_get_integer(arr, i);
     448                for (i = 0; i < parsed->u.array.length; i++) {
     449                        json_value *c = parsed->u.array.values[i];
     450                        if (c->type != json_integer) {
     451                                continue;
     452                        }
    453453                        txl->list = g_slist_prepend(txl->list,
    454                                                     g_strdup_printf("%lld", id));
     454                                                    g_strdup_printf("%"PRIu64, c->u.integer));
    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_Object *node)
     539struct twitter_xml_user *twitter_xt_get_user(const json_value *node)
    540540{
    541541        struct twitter_xml_user *txu;
    542        
    543         if (!node)
    544                 return NULL;
     542        json_value *jv;
    545543
    546544        txu = g_new0(struct twitter_xml_user, 1);
    547         txu->name = g_strdup(json_object_get_string(node, "name"));
    548         txu->screen_name = g_strdup(json_object_get_string(node, "screen_name"));
    549         txu->uid = json_object_get_integer(node, "id");
     545        txu->name = g_strdup(json_o_str(node, "name"));
     546        txu->screen_name = g_strdup(json_o_str(node, "screen_name"));
     547
     548        jv = json_o_get(node, "id");
     549        txu->uid = jv->u.integer;
    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 (json_type(node) != JSONArray) {
     567        if (!node || node->type != json_array) {
    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         JSON_Array *arr = json_array(node);
    574         for (i = 0; i < json_array_get_count(arr); i++) {
    575                 JSON_Object *o = json_array_get_object(arr, i);
    576                 if (!o)
    577                         continue;
    578                 txu = twitter_xt_get_user(o);
     573        for (i = 0; i < node->u.array.length; i++) {
     574                txu = twitter_xt_get_user(node->u.array.values[i]);
    579575                if (txu) {
    580576                        txl->list = g_slist_prepend(txl->list, txu);
     
    591587#endif
    592588
    593 static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node);
     589static void expand_entities(char **text, const json_value *node, const json_value *extended_node);
    594590
    595591/**
     
    601597 *  - the user in a twitter_xml_user struct.
    602598 */
    603 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node)
     599static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
    604600{
    605601        struct twitter_xml_status *txs = {0};
    606         const JSON_Object *rt = NULL;
    607         const JSON_Value *text_value = NULL;
    608         const JSON_Object *extended_node = NULL;
    609 
    610         if (!node) {
     602        const json_value *rt = NULL;
     603        const json_value *text_value = NULL;
     604        const json_value *extended_node = NULL;
     605
     606        if (node->type != json_object) {
    611607                return FALSE;
    612608        }
     
    614610
    615611        JSON_O_FOREACH(node, k, v) {
    616                 if (strcmp("text", k) == 0 && json_type(v) == JSONString && text_value == NULL) {
     612                if (strcmp("text", k) == 0 && v->type == json_string && text_value == NULL) {
    617613                        text_value = v;
    618                 } else if (strcmp("full_text", k) == 0 && json_type(v) == JSONString) {
     614                } else if (strcmp("full_text", k) == 0 && v->type == json_string) {
    619615                        text_value = v;
    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) {
     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) {
    626622                        struct tm parsed;
    627623
     
    629625                           this field. :-( Also assumes the timezone used
    630626                           is UTC since C time handling functions suck. */
    631                         if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
     627                        if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
    632628                                txs->created_at = mktime_utc(&parsed);
    633629                        }
    634                 } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) {
    635                         txs->user = twitter_xt_get_user(json_object(v));
    636                 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
    637                         txs->rt_id = txs->id = json_integer(v);
    638                 } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) {
    639                         txs->reply_to = json_integer(v);
     630                } else if (strcmp("user", k) == 0 && v->type == json_object) {
     631                        txs->user = twitter_xt_get_user(v);
     632                } else if (strcmp("id", k) == 0 && v->type == json_integer) {
     633                        txs->rt_id = txs->id = v->u.integer;
     634                } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {
     635                        txs->reply_to = v->u.integer;
    640636                }
    641637        }
     
    650646                        txs_free(rtxs);
    651647                }
    652         } else if (text_value && json_type(text_value) == JSONString) {
    653                 txs->text = g_strdup(json_string(text_value));
     648        } else if (text_value && text_value->type == json_string) {
     649                txs->text = g_memdup(text_value->u.string.ptr, text_value->u.string.length + 1);
    654650                strip_html(txs->text);
    655651                expand_entities(&txs->text, node, extended_node);
     
    667663 * Function to fill a twitter_xml_status struct (DM variant).
    668664 */
    669 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node)
     665static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node)
    670666{
    671667        struct twitter_xml_status *txs;
    672668
    673         if (!node) {
     669        if (node->type != json_object) {
    674670                return FALSE;
    675671        }
     
    677673
    678674        JSON_O_FOREACH(node, k, v) {
    679                 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {
     675                if (strcmp("text", k) == 0 && v->type == json_string) {
     676                        txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
    680677                        strip_html(txs->text);
    681                 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
     678                } else if (strcmp("created_at", k) == 0 && v->type == json_string) {
    682679                        struct tm parsed;
    683680
     
    685682                           this field. :-( Also assumes the timezone used
    686683                           is UTC since C time handling functions suck. */
    687                         if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
     684                        if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
    688685                                txs->created_at = mktime_utc(&parsed);
    689686                        }
    690                 } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) {
    691                         txs->user = twitter_xt_get_user(json_object(v));
    692                 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
    693                         txs->id = json_integer(v);
     687                } else if (strcmp("sender", k) == 0 && v->type == json_object) {
     688                        txs->user = twitter_xt_get_user(v);
     689                } else if (strcmp("id", k) == 0 && v->type == json_integer) {
     690                        txs->id = v->u.integer;
    694691                }
    695692        }
     
    705702}
    706703
    707 static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node)
    708 {
    709         JSON_Object *entities, *extended_entities, *quoted;
     704static void expand_entities(char **text, const json_value *node, const json_value *extended_node)
     705{
     706        json_value *entities, *extended_entities, *quoted;
    710707        char *quote_url = NULL, *quote_text = NULL;
    711708
    712         if (!(entities = json_object_get_object(node, "entities")))
    713                 return;
    714         if ((quoted = json_object_get_object(node, "quoted_status"))) {
     709        if (!((entities = json_o_get(node, "entities")) && entities->type == json_object))
     710                return;
     711        if ((quoted = json_o_get(node, "quoted_status")) && quoted->type == json_object) {
    715712                /* New "retweets with comments" feature. Note that this info
    716713                 * seems to be included in the streaming API only! Grab the
     
    726723
    727724        if (extended_node) {
    728                 extended_entities = json_object_get_object(extended_node, "entities");
    729                 if (extended_entities) {
     725                extended_entities = json_o_get(extended_node, "entities");
     726                if (extended_entities && extended_entities->type == json_object) {
    730727                        entities = extended_entities;
    731728                }
     
    735732                int i;
    736733
    737                 if (json_type(v) != JSONArray) {
     734                if (v->type != json_array) {
    738735                        continue;
    739736                }
     
    742739                }
    743740
    744                 for (i = 0; i < json_array_get_count(json_array(v)); i++) {
     741                for (i = 0; i < v->u.array.length; i++) {
    745742                        const char *format = "%s%s <%s>%s";
    746                         JSON_Object *r = json_array_get_object(json_array(v), i);
    747 
    748                         if (!r) {
     743
     744                        if (v->u.array.values[i]->type != json_object) {
    749745                                continue;
    750746                        }
    751747
    752                         const char *kort = json_object_get_string(r, "url");
    753                         const char *disp = json_object_get_string(r, "display_url");
    754                         const char *full = json_object_get_string(r, "expanded_url");
     748                        const char *kort = json_o_str(v->u.array.values[i], "url");
     749                        const char *disp = json_o_str(v->u.array.values[i], "display_url");
     750                        const char *full = json_o_str(v->u.array.values[i], "expanded_url");
    755751                        char *pos, *new;
    756752
     
    781777 *  - the next_cursor.
    782778 */
    783 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,
     779static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,
    784780                                           struct twitter_xml_list *txl)
    785781{
     
    790786        txl->type = TXL_STATUS;
    791787
    792         if (json_type(node) != JSONArray) {
     788        if (node->type != json_array) {
    793789                return FALSE;
    794790        }
     
    796792        // The root <statuses> node should hold the list of statuses <status>
    797793        // Walk over the nodes children.
    798         for (i = 0; i < json_array_get_count(json_array(node)); i++) {
    799                 txs = twitter_xt_get_status(json_array_get_object(json_array(node), i));
     794        for (i = 0; i < node->u.array.length; i++) {
     795                txs = twitter_xt_get_status(node->u.array.values[i]);
    800796                if (!txs) {
    801797                        continue;
     
    982978       
    983979        /* Check this is not a tweet that should be muted */
    984         uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, status->user->uid);
     980        uid_str = g_strdup_printf("%" PRIu64, status->user->uid);
    985981
    986982        if (g_slist_find_custom(td->mutes_ids, uid_str, (GCompareFunc)strcmp)) {
     
    10171013}
    10181014
    1019 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter);
     1015static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter);
    10201016
    10211017static void twitter_http_stream(struct http_request *req)
     
    10231019        struct im_connection *ic = req->data;
    10241020        struct twitter_data *td;
    1025         JSON_Value *parsed;
     1021        json_value *parsed;
    10261022        int len = 0;
    10271023        char c, *nl;
     
    10641060                req->reply_body[len] = '\0';
    10651061
    1066                 if ((parsed = json_parse_string(req->reply_body))) {
     1062                if ((parsed = json_parse(req->reply_body, req->body_size))) {
    10671063                        from_filter = (req == td->filter_stream);
    1068                         twitter_stream_handle_object(ic, json_object(parsed), from_filter);
     1064                        twitter_stream_handle_object(ic, parsed, from_filter);
    10691065                }
    10701066                json_value_free(parsed);
     
    10801076}
    10811077
    1082 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o);
     1078static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o);
    10831079static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs);
    10841080
    1085 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter)
     1081static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter)
    10861082{
    10871083        struct twitter_data *td = ic->proto_data;
    10881084        struct twitter_xml_status *txs;
    1089         JSON_Object *c;
     1085        json_value *c;
    10901086
    10911087        if ((txs = twitter_xt_get_status(o))) {
     
    10941090                txs_free(txs);
    10951091                return ret;
    1096         } else if ((c = json_object_get_object(o, "direct_message")) &&
     1092        } else if ((c = json_o_get(o, "direct_message")) &&
    10971093                   (txs = twitter_xt_get_dm(c))) {
    10981094                if (g_strcasecmp(txs->user->screen_name, td->user) != 0) {
     
    11021098                txs_free(txs);
    11031099                return TRUE;
    1104         } else if (json_object_get_string(o, "event")) {
     1100        } else if ((c = json_o_get(o, "event")) && c->type == json_string) {
    11051101                twitter_stream_handle_event(ic, o);
    11061102                return TRUE;
    1107         } else if ((c = json_object_get_object(o, "disconnect"))) {
     1103        } else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) {
    11081104                /* HACK: Because we're inside an event handler, we can't just
    11091105                   disconnect here. Instead, just change the HTTP status string
    11101106                   into a Twitter status string. */
    1111                 char *reason = g_strdup(json_object_get_string(c, "reason"));
     1107                char *reason = json_o_strdup(c, "reason");
    11121108                if (reason) {
    11131109                        g_free(td->stream->status_string);
     
    11481144}
    11491145
    1150 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o)
     1146static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o)
    11511147{
    11521148        struct twitter_data *td = ic->proto_data;
    1153         JSON_Object *source = json_object_get_object(o, "source");
    1154         JSON_Object *target = json_object_get_object(o, "target");
    1155         const char *type = json_object_get_string(o, "event");
     1149        json_value *source = json_o_get(o, "source");
     1150        json_value *target = json_o_get(o, "target");
     1151        const char *type = json_o_str(o, "event");
    11561152        struct twitter_xml_user *us = NULL;
    11571153        struct twitter_xml_user *ut = NULL;
    11581154
    1159         if (!type || !source || !target) {
     1155        if (!type || !source || source->type != json_object
     1156            || !target || target->type != json_object) {
    11601157                return FALSE;
    11611158        }
     
    11711168                char *uid_str;
    11721169                ut = twitter_xt_get_user(target);
    1173                 uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid);
     1170                uid_str = g_strdup_printf("%" PRIu64, ut->uid);
    11741171                if (!(found = g_slist_find_custom(td->mutes_ids, uid_str,
    11751172                                                  (GCompareFunc)strcmp))) {
     
    11781175                twitter_log(ic, "Muted user %s", ut->screen_name);
    11791176                if (getenv("BITLBEE_DEBUG")) {
    1180                         fprintf(stderr, "New mute: %s %"G_GUINT64_FORMAT"\n",
     1177                        fprintf(stderr, "New mute: %s %"PRIu64"\n",
    11811178                                ut->screen_name, ut->uid);
    11821179                }
     
    11851182                char *uid_str;
    11861183                ut = twitter_xt_get_user(target);
    1187                 uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid);
     1184                uid_str = g_strdup_printf("%" PRIu64, ut->uid);
    11881185                if ((found = g_slist_find_custom(td->mutes_ids, uid_str,
    11891186                                                (GCompareFunc)strcmp))) {
     
    11951192                twitter_log(ic, "Unmuted user %s", ut->screen_name);
    11961193                if (getenv("BITLBEE_DEBUG")) {
    1197                         fprintf(stderr, "New unmute: %s %"G_GUINT64_FORMAT"\n",
     1194                        fprintf(stderr, "New unmute: %s %"PRIu64"\n",
    11981195                                ut->screen_name, ut->uid);
    11991196                }
     
    12861283        struct twitter_filter *tf;
    12871284        GList *users = NULL;
    1288         JSON_Value *parsed;
     1285        json_value *parsed;
     1286        json_value *id;
     1287        const char *name;
    12891288        GString *fstr;
    12901289        GSList *l;
     
    13111310        }
    13121311
    1313         if (json_type(parsed) != JSONArray) {
     1312        if (parsed->type != json_array) {
    13141313                goto finish;
    13151314        }
    13161315
    1317         for (i = 0; i < json_array_get_count(json_array(parsed)); i++) {
    1318                 JSON_Object *o = json_array_get_object(json_array(parsed), i);
    1319                 jint id = json_object_get_integer(o, "id");
    1320                 const char *name = json_object_get_string(o, "screen_name");
    1321 
    1322                 if (!name || !id) {
     1316        for (i = 0; i < parsed->u.array.length; i++) {
     1317                id = json_o_get(parsed->u.array.values[i], "id");
     1318                name = json_o_str(parsed->u.array.values[i], "screen_name");
     1319
     1320                if (!name || !id || id->type != json_integer) {
    13231321                        continue;
    13241322                }
     
    13281326
    13291327                        if (g_strcasecmp(tf->text, name) == 0) {
    1330                                 tf->uid = id;
     1328                                tf->uid = id->u.integer;
    13311329                                users = g_list_delete_link(users, u);
    13321330                                break;
     
    15731571        struct im_connection *ic = req->data;
    15741572        struct twitter_data *td;
    1575         JSON_Value *parsed;
     1573        json_value *parsed;
    15761574        struct twitter_xml_list *txl;
    15771575
     
    16131611        struct im_connection *ic = req->data;
    16141612        struct twitter_data *td;
    1615         JSON_Value *parsed;
     1613        json_value *parsed;
    16161614        struct twitter_xml_list *txl;
    16171615
     
    16541652        struct im_connection *ic = req->data;
    16551653        struct twitter_data *td;
    1656         JSON_Value *parsed;
    1657         jint id;
     1654        json_value *parsed, *id;
    16581655
    16591656        // Check if the connection is still active.
     
    16691666        }
    16701667
    1671         if ((id = json_object_get_integer(json_object(parsed), "id"))) {
    1672                 td->last_status_id = id;
     1668        if ((id = json_o_get(parsed, "id")) && id->type == json_integer) {
     1669                td->last_status_id = id->u.integer;
    16731670        }
    16741671
     
    17911788{
    17921789        struct im_connection *ic = req->data;
    1793         JSON_Value *parsed;
    1794         uint64_t id;
     1790        json_value *parsed, *id;
    17951791        const char *name;
    17961792
     
    18041800        }
    18051801
     1802        /* for the parson branch:
    18061803        name = json_object_dotget_string(json_object(parsed), "user.screen_name");
    18071804        id = json_object_get_integer(json_object(parsed), "id");
    1808 
    1809         if (name && id) {
    1810                 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id);
     1805        */
     1806
     1807        name = json_o_str(json_o_get(parsed, "user"), "screen_name");
     1808        id = json_o_get(parsed, "id");
     1809
     1810        if (name && id && id->type == json_integer) {
     1811                twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer);
    18111812        } else {
    18121813                twitter_log(ic, "Error: could not fetch tweet url.");
  • root_commands.c

    r3f44e43 r5a8afc3  
    509509                                con = "";
    510510                        }
     511
    511512                        if (a->prpl == &protocol_missing) {
    512513                                protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name"));
     
    700701                irc_rootmsg(irc, "That account is not on-line");
    701702                return;
    702         } else if (add_on_server && !a->prpl->add_buddy) {
    703                 irc_rootmsg(irc, "IM protocol does not support contact list modification");
    704                 return;
     703        }
     704
     705        if (cmd[3]) {
     706                if (!nick_ok(irc, cmd[3])) {
     707                        irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
     708                        return;
     709                } else if (irc_user_by_name(irc, cmd[3])) {
     710                        irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
     711                        return;
     712                } else {
     713                        nick_set_raw(a, cmd[2], cmd[3]);
     714                }
    705715        }
    706716
     
    718728        }
    719729
    720         if (cmd[3]) {
    721                 if (!nick_ok(irc, cmd[3])) {
    722                         irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
    723                         return;
    724                 } else if (irc_user_by_name(irc, cmd[3])) {
    725                         irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
    726                         return;
    727                 } else {
    728                         nick_set_raw(a, cmd[2], cmd[3]);
    729                 }
    730         }
    731 
    732730        if (add_on_server) {
    733731                irc_channel_t *ic;
     
    773771        s = g_strdup(bu->handle);
    774772
    775         if (bu->ic->acc->prpl->remove_buddy) {
    776                 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
    777         } else {
    778                 irc_rootmsg(irc, "IM protocol does not support contact list modification, "
    779                                  "removal will likely not be permanent");
    780         }
    781 
     773        bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
    782774        nick_del(bu);
    783775        if (g_slist_find(irc->users, iu)) {
  • storage_xml.c

    r3f44e43 r5a8afc3  
    114114        char *pass_b64 = NULL;
    115115        unsigned char *pass_cr = NULL;
    116         int pass_len;
     116        int pass_len, local = 0;
    117117        struct prpl *prpl = NULL;
    118118        account_t *acc;
     
    133133                        prpl = (struct prpl*) &protocol_missing;
    134134                }
     135                local = protocol_account_islocal(protocol);
    135136        }
    136137
     
    160161        if (tag) {
    161162                set_setstr(&acc->set, "tag", tag);
     163        }
     164        if (local) {
     165                acc->flags |= ACC_FLAG_LOCAL;
    162166        }
    163167        if (locked && !g_strcasecmp(locked, "true")) {
Note: See TracChangeset for help on using the changeset viewer.