Changes in / [3fbce97:82cb190]


Ignore:
Files:
4 added
7 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r3fbce97 r82cb190  
    3232bitlbee.service
    3333bitlbee@.service
    34 *.pyc
  • configure

    r3fbce97 r82cb190  
    1616config='/var/lib/bitlbee/'
    1717plugindir='$prefix/lib/bitlbee/'
    18 rpcplugindir='$plugindir/rpc/'
    1918includedir='$prefix/include/bitlbee/'
    2019systemdsystemunitdir=''
     
    4039twitter=1
    4140purple=0
    42 rpc=1
    4341
    4442doc=1
     
    123121--datadir=...                                           $datadir
    124122--plugindir=...                                         $plugindir
    125 --rpcplugindir=...                                      $rpcplugindir
    126123--systemdsystemunitdir=...                              $systemdsystemunitdir
    127124--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--doc=0/1       Disable/enable help.txt generation      $doc
     
    172168config=$(eval echo "$config/" | sed 's/\/\{1,\}/\//g')
    173169plugindir=$(eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g')
    174 rpcplugindir=$(eval echo "$rpcplugindir/" | sed 's/\/\{1,\}/\//g')
    175170includedir=$(eval echo "$includedir"/ | sed 's/\/\{1,\}/\//g')
    176171libevent=$(eval echo "$libevent"/ | sed 's/\/\{1,\}/\//g')
     
    194189DATADIR=$datadir
    195190PLUGINDIR=$plugindir
    196 RPCPLUGINDIR=$rpcplugindir
    197191CONFIG=$config
    198192INCLUDEDIR=$includedir
     
    246240#define VARDIR "$datadir"
    247241#define PLUGINDIR "$plugindir"
    248 #define RPCPLUGINDIR "$rpcplugindir"
    249242#define PIDFILE "$pidfile"
    250243#define IPCSOCKET "$ipcsocket"
     
    289282        LDFLAGS="$LDFLAGS -fsanitize=address"
    290283        debug=1
    291 fi
    292 
    293 if [ "$tsan" = "1" ]; then
    294         echo
    295         echo "Threaded BitlBee? Have a nice tall glass of http://imgur.com/gallery/tX4qxzS"
    296         echo "No need to sanitise threads in a single-threaded process!"
    297284fi
    298285
     
    685672fi
    686673
    687 if [ "$rpc" = 0 ]; then
    688         # Somewhat pointless at this stage already but at least this keeps it
    689         # out of bitlbee.pc which is probably a good thing.
    690         rpcplugindir=""
    691 fi
    692 
    693674otrprefix=""
    694675if [ "$otr" = "auto" ]; then
     
    769750includedir=$includedir
    770751plugindir=$plugindir
    771 rpcplugindir=$rpcplugindir
    772752
    773753Name: bitlbee
     
    862842        protocols=$protocols'twitter '
    863843        protoobjs=$protoobjs'twitter_mod.o '
    864 fi
    865 
    866 if [ "$rpc" = 0 ]; then
    867         echo '#undef WITH_RPC' >> config.h
    868 else
    869         echo '#define WITH_RPC' >> config.h
    870         protocols=$protocols'rpc '
    871         protoobjs=$protoobjs'rpc_mod.o '
    872844fi
    873845
     
    959931echo '  Using event handler: '$events
    960932echo '  Using SSL library: '$ssl
     933#echo '  Building with these storage backends: '$STORAGES
    961934
    962935if [ -n "$protocols" ]; then
  • irc_channel.c

    r3fbce97 r82cb190  
    755755        }
    756756
    757         if (!bu->ic->acc->prpl->add_buddy) {
    758                 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name);
    759                 return FALSE;
    760         }
    761 
    762757        bu->ic->acc->prpl->add_buddy(bu->ic, bu->handle,
    763758                                     icc->group ? icc->group->name : NULL);
     
    777772        if (icc->type != IRC_CC_TYPE_GROUP) {
    778773                irc_send_num(ic->irc, 482, "%s :Kicks are only possible to fill_by=group channels", ic->name);
    779                 return;
    780         }
    781 
    782         if (!bu->ic->acc->prpl->remove_buddy) {
    783                 irc_send_num(ic->irc, 482, "%s :IM protocol does not support contact list modification", ic->name);
    784774                return;
    785775        }
  • irc_commands.c

    r3fbce97 r82cb190  
    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

    r3fbce97 r82cb190  
    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

    r3fbce97 r82cb190  
    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

    r3fbce97 r82cb190  
    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

    r3fbce97 r82cb190  
    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

    r3fbce97 r82cb190  
    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);
     
    457461        return a->auto_reconnect_delay;
    458462}
     463
     464int protocol_account_islocal(const char* protocol)
     465{
     466        const char** p = account_protocols_local;
     467
     468        do {
     469                if (strcmp(*p, protocol) == 0) {
     470                        return 1;
     471                }
     472        } while (*(++p));
     473        return 0;
     474}
  • protocols/account.h

    r3fbce97 r82cb190  
    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. */
     
    6769        ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */
    6870        ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */
    69         ACC_FLAG_LOCAL_CONTACTS = 0x08, /* Contact list is local. */
     71        ACC_FLAG_LOCAL = 0x08,          /* Contact list is local. */
    7072} account_flag_t;
    7173
  • protocols/nogaim.c

    r3fbce97 r82cb190  
    135135        extern void twitter_initmodule();
    136136        extern void purple_initmodule();
    137         extern void rpc_initmodule();
    138137
    139138#ifdef WITH_MSN
     
    159158#ifdef WITH_PURPLE
    160159        purple_initmodule();
    161 #endif
    162 
    163 #ifdef WITH_RPC
    164         rpc_initmodule();
    165160#endif
    166161
     
    318313        }
    319314
    320         if ((ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS) &&
    321             !(ic->flags & OPT_LOCAL_CONTACTS_SENT) &&
    322             ic->acc->prpl->add_buddy) {
     315        if (ic->acc->flags & ACC_FLAG_LOCAL) {
    323316                GHashTableIter nicks;
    324                 gpointer handle;
     317                gpointer k, v;
    325318                g_hash_table_iter_init(&nicks, ic->acc->nicks);
    326                 while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
    327                         ic->acc->prpl->add_buddy(ic, (char *) handle, NULL);
     319                while (g_hash_table_iter_next(&nicks, &k, &v)) {
     320                        ic->acc->prpl->add_buddy(ic, (char *) k, NULL);
    328321                }
    329322        }
     
    420413        query_del_by_conn((irc_t *) ic->bee->ui_data, ic);
    421414
    422         /* Throw away groupchats owned by this account. Historically this was only
    423            ever done by IM modules which is a bug. But it gives them opportunity
    424            to clean up protocol-specific bits as well so keep it that way, just
    425            do another cleanup here as a fallback. Don't want to leave any dangling
    426            pointers! */
    427         while (ic->groupchats) {
    428                 imcb_chat_free(ic->groupchats->data);
    429         }
    430 
    431415        if (!a) {
    432416                /* Uhm... This is very sick. */
     
    514498}
    515499
    516 /* Returns the local contacts for an IM account (based on assigned nicks).
    517    Linked list should be freed, the strings themselves not! So look at it
    518    like a GSList<const char*> I guess? Empty list means NULL retval (as
    519    always with GSList). */
    520 GSList *imcb_get_local_contacts(struct im_connection *ic)
    521 {
    522         GHashTableIter nicks;
    523         GSList *ret = NULL;
    524        
    525         if (!(ic->acc->flags & ACC_FLAG_LOCAL_CONTACTS)) {
    526                 /* Only allow protocols that indicate local contact list
    527                    support to use this function. */
    528                 return ret;
    529         }
    530        
    531         g_hash_table_iter_init(&nicks, ic->acc->nicks);
    532         gpointer handle;
    533         while (g_hash_table_iter_next(&nicks, &handle, NULL)) {
    534                 ret = g_slist_prepend(ret, (char *) handle);
    535         }
    536        
    537         /* If the protocol asked for the list, assume we won't have to send it
    538            anymore in imcb_connected(). */
    539         ic->flags |= OPT_LOCAL_CONTACTS_SENT;
    540        
    541         return ret;
    542 }
    543 
    544500
    545501struct imcb_ask_cb_data {
     
    600556        struct imcb_ask_cb_data *cbd = data;
    601557
    602         if (cbd->ic->acc->prpl->add_buddy) {
    603                 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
    604         }
     558        cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
    605559
    606560        imcb_ask_cb_free(data);
  • protocols/nogaim.h

    r3fbce97 r82cb190  
    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
     
    331325G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick);
    332326G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data);
    333 G_MODULE_EXPORT GSList *imcb_get_local_contacts(struct im_connection *ic);
    334327
    335328G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags);
  • protocols/purple/purple.c

    r3fbce97 r82cb190  
    277277        }
    278278        purple_accounts_remove(pa);
    279        
    280         /* Last, some protocols want their contact lists locally. */
    281         if (strcmp(acc->prpl->name, "whatsapp") == 0 || strcmp(acc->prpl->name, "gg") == 0) {
    282                 acc->flags |= ACC_FLAG_LOCAL_CONTACTS;
    283         }
    284279}
    285280
  • protocols/twitter/twitter_lib.c

    r3fbce97 r82cb190  
    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");
     
    264259 * Fill a list of ids.
    265260 */
    266 static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl)
    267 {
    268         JSON_Array *c;
     261static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl)
     262{
     263        json_value *c;
    269264        int i;
    270265
     
    272267        txl->type = TXL_ID;
    273268
    274         if (!(c = json_object_get_array(json_object(node), "ids"))) {
     269        c = json_o_get(node, "ids");
     270        if (!c || c->type != json_array) {
    275271                return FALSE;
    276272        }
    277273
    278         for (i = 0; i < json_array_get_count(c); i++) {
    279                 jint id = json_array_get_integer(c, i);
     274        for (i = 0; i < c->u.array.length; i++) {
     275                if (c->u.array.values[i]->type != json_integer) {
     276                        continue;
     277                }
    280278
    281279                txl->list = g_slist_prepend(txl->list,
    282                                             g_strdup_printf("%lld", id));
    283         }
    284 
    285         JSON_Value *next = json_object_get_value(json_object(node), "next_cursor");
    286         if (next && json_type(next) == JSONInteger) {
    287                 txl->next_cursor = json_integer(next);
     280                                            g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer));
     281        }
     282
     283        c = json_o_get(node, "next_cursor");
     284        if (c && c->type == json_integer) {
     285                txl->next_cursor = c->u.integer;
    288286        } else {
    289287                txl->next_cursor = -1;
     
    301299{
    302300        struct im_connection *ic;
    303         JSON_Value *parsed;
     301        json_value *parsed;
    304302        struct twitter_xml_list *txl;
    305303        struct twitter_data *td;
     
    339337}
    340338
    341 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl);
     339static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl);
    342340static void twitter_http_get_users_lookup(struct http_request *req);
    343341
     
    380378{
    381379        struct im_connection *ic = req->data;
    382         JSON_Value *parsed;
     380        json_value *parsed;
    383381        struct twitter_xml_list *txl;
    384382        GSList *l = NULL;
     
    413411}
    414412
    415 struct twitter_xml_user *twitter_xt_get_user(const JSON_Object *node)
     413struct twitter_xml_user *twitter_xt_get_user(const json_value *node)
    416414{
    417415        struct twitter_xml_user *txu;
    418        
    419         if (!node)
    420                 return NULL;
     416        json_value *jv;
    421417
    422418        txu = g_new0(struct twitter_xml_user, 1);
    423         txu->name = g_strdup(json_object_get_string(node, "name"));
    424         txu->screen_name = g_strdup(json_object_get_string(node, "screen_name"));
    425         txu->uid = json_object_get_integer(node, "id");
     419        txu->name = g_strdup(json_o_str(node, "name"));
     420        txu->screen_name = g_strdup(json_o_str(node, "screen_name"));
     421
     422        jv = json_o_get(node, "id");
     423        txu->uid = jv->u.integer;
    426424
    427425        return txu;
     
    433431 *  - all <user>s from the <users> element.
    434432 */
    435 static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl)
     433static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl)
    436434{
    437435        struct twitter_xml_user *txu;
     
    441439        txl->type = TXL_USER;
    442440
    443         if (json_type(node) != JSONArray) {
     441        if (!node || node->type != json_array) {
    444442                return FALSE;
    445443        }
    446        
     444
    447445        // The root <users> node should hold the list of users <user>
    448446        // Walk over the nodes children.
    449         JSON_Array *arr = json_array(node);
    450         for (i = 0; i < json_array_get_count(arr); i++) {
    451                 JSON_Object *o = json_array_get_object(arr, i);
    452                 if (!o)
    453                         continue;
    454                 txu = twitter_xt_get_user(o);
     447        for (i = 0; i < node->u.array.length; i++) {
     448                txu = twitter_xt_get_user(node->u.array.values[i]);
    455449                if (txu) {
    456450                        txl->list = g_slist_prepend(txl->list, txu);
     
    467461#endif
    468462
    469 static void expand_entities(char **text, const JSON_Object *node);
     463static void expand_entities(char **text, const json_value *node);
    470464
    471465/**
     
    477471 *  - the user in a twitter_xml_user struct.
    478472 */
    479 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node)
     473static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
    480474{
    481475        struct twitter_xml_status *txs;
    482         const JSON_Object *rt = NULL;
    483 
    484         if (!node) {
     476        const json_value *rt = NULL;
     477
     478        if (node->type != json_object) {
    485479                return FALSE;
    486480        }
     
    488482
    489483        JSON_O_FOREACH(node, k, v) {
    490                 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {
    491                         // TODO: Huh strip html? In json? Not sure whether I have to..
     484                if (strcmp("text", k) == 0 && v->type == json_string) {
     485                        txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
    492486                        strip_html(txs->text);
    493                 } else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) {
    494                         // Handling below.
    495                 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
     487                } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {
     488                        rt = v;
     489                } else if (strcmp("created_at", k) == 0 && v->type == json_string) {
    496490                        struct tm parsed;
    497491
     
    499493                           this field. :-( Also assumes the timezone used
    500494                           is UTC since C time handling functions suck. */
    501                         if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
     495                        if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
    502496                                txs->created_at = mktime_utc(&parsed);
    503497                        }
    504                 } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) {
    505                         txs->user = twitter_xt_get_user(json_object(v));
    506                 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
    507                         txs->rt_id = txs->id = json_integer(v);
    508                 } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) {
    509                         txs->reply_to = json_integer(v);
     498                } else if (strcmp("user", k) == 0 && v->type == json_object) {
     499                        txs->user = twitter_xt_get_user(v);
     500                } else if (strcmp("id", k) == 0 && v->type == json_integer) {
     501                        txs->rt_id = txs->id = v->u.integer;
     502                } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {
     503                        txs->reply_to = v->u.integer;
    510504                }
    511505        }
     
    536530 * Function to fill a twitter_xml_status struct (DM variant).
    537531 */
    538 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node)
     532static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node)
    539533{
    540534        struct twitter_xml_status *txs;
    541535
    542         if (!node) {
     536        if (node->type != json_object) {
    543537                return FALSE;
    544538        }
     
    546540
    547541        JSON_O_FOREACH(node, k, v) {
    548                 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {
     542                if (strcmp("text", k) == 0 && v->type == json_string) {
     543                        txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
    549544                        strip_html(txs->text);
    550                 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
     545                } else if (strcmp("created_at", k) == 0 && v->type == json_string) {
    551546                        struct tm parsed;
    552547
     
    554549                           this field. :-( Also assumes the timezone used
    555550                           is UTC since C time handling functions suck. */
    556                         if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
     551                        if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
    557552                                txs->created_at = mktime_utc(&parsed);
    558553                        }
    559                 } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) {
    560                         txs->user = twitter_xt_get_user(json_object(v));
    561                 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
    562                         txs->id = json_integer(v);
     554                } else if (strcmp("sender", k) == 0 && v->type == json_object) {
     555                        txs->user = twitter_xt_get_user(v);
     556                } else if (strcmp("id", k) == 0 && v->type == json_integer) {
     557                        txs->id = v->u.integer;
    563558                }
    564559        }
     
    574569}
    575570
    576 static void expand_entities(char **text, const JSON_Object *node)
    577 {
    578         JSON_Object *entities, *quoted;
     571static void expand_entities(char **text, const json_value *node)
     572{
     573        json_value *entities, *quoted;
    579574        char *quote_url = NULL, *quote_text = NULL;
    580575
    581         if (!(entities = json_object_get_object(node, "entities")))
    582                 return;
    583         if ((quoted = json_object_get_object(node, "quoted_status"))) {
     576        if (!((entities = json_o_get(node, "entities")) && entities->type == json_object))
     577                return;
     578        if ((quoted = json_o_get(node, "quoted_status")) && quoted->type == json_object) {
    584579                /* New "retweets with comments" feature. Note that this info
    585580                 * seems to be included in the streaming API only! Grab the
     
    597592                int i;
    598593
    599                 if (json_type(v) != JSONArray) {
     594                if (v->type != json_array) {
    600595                        continue;
    601596                }
     
    604599                }
    605600
    606                 for (i = 0; i < json_array_get_count(json_array(v)); i++) {
     601                for (i = 0; i < v->u.array.length; i++) {
    607602                        const char *format = "%s%s <%s>%s";
    608                         JSON_Object *r = json_array_get_object(json_array(v), i);
    609 
    610                         if (!r) {
     603
     604                        if (v->u.array.values[i]->type != json_object) {
    611605                                continue;
    612606                        }
    613607
    614                         const char *kort = json_object_get_string(r, "url");
    615                         const char *disp = json_object_get_string(r, "display_url");
    616                         const char *full = json_object_get_string(r, "expanded_url");
     608                        const char *kort = json_o_str(v->u.array.values[i], "url");
     609                        const char *disp = json_o_str(v->u.array.values[i], "display_url");
     610                        const char *full = json_o_str(v->u.array.values[i], "expanded_url");
    617611                        char *pos, *new;
    618612
     
    643637 *  - the next_cursor.
    644638 */
    645 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,
     639static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,
    646640                                           struct twitter_xml_list *txl)
    647641{
     
    652646        txl->type = TXL_STATUS;
    653647
    654         if (json_type(node) != JSONArray) {
     648        if (node->type != json_array) {
    655649                return FALSE;
    656650        }
     
    658652        // The root <statuses> node should hold the list of statuses <status>
    659653        // Walk over the nodes children.
    660         for (i = 0; i < json_array_get_count(json_array(node)); i++) {
    661                 txs = twitter_xt_get_status(json_array_get_object(json_array(node), i));
     654        for (i = 0; i < node->u.array.length; i++) {
     655                txs = twitter_xt_get_status(node->u.array.values[i]);
    662656                if (!txs) {
    663657                        continue;
     
    865859}
    866860
    867 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter);
     861static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter);
    868862
    869863static void twitter_http_stream(struct http_request *req)
     
    871865        struct im_connection *ic = req->data;
    872866        struct twitter_data *td;
    873         JSON_Value *parsed;
     867        json_value *parsed;
    874868        int len = 0;
    875869        char c, *nl;
     
    909903                req->reply_body[len] = '\0';
    910904
    911                 if ((parsed = json_parse_string(req->reply_body))) {
     905                if ((parsed = json_parse(req->reply_body, req->body_size))) {
    912906                        from_filter = (req == td->filter_stream);
    913                         twitter_stream_handle_object(ic, json_object(parsed), from_filter);
     907                        twitter_stream_handle_object(ic, parsed, from_filter);
    914908                }
    915909                json_value_free(parsed);
     
    925919}
    926920
    927 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o);
     921static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o);
    928922static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs);
    929923
    930 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter)
     924static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter)
    931925{
    932926        struct twitter_data *td = ic->proto_data;
    933927        struct twitter_xml_status *txs;
    934         JSON_Object *c;
     928        json_value *c;
    935929
    936930        if ((txs = twitter_xt_get_status(o))) {
     
    939933                txs_free(txs);
    940934                return ret;
    941         } else if ((c = json_object_get_object(o, "direct_message")) &&
     935        } else if ((c = json_o_get(o, "direct_message")) &&
    942936                   (txs = twitter_xt_get_dm(c))) {
    943937                if (g_strcasecmp(txs->user->screen_name, td->user) != 0) {
     
    947941                txs_free(txs);
    948942                return TRUE;
    949         } else if (json_object_get_string(o, "event")) {
     943        } else if ((c = json_o_get(o, "event")) && c->type == json_string) {
    950944                twitter_stream_handle_event(ic, o);
    951945                return TRUE;
    952         } else if ((c = json_object_get_object(o, "disconnect"))) {
     946        } else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) {
    953947                /* HACK: Because we're inside an event handler, we can't just
    954948                   disconnect here. Instead, just change the HTTP status string
    955949                   into a Twitter status string. */
    956                 char *reason = g_strdup(json_object_get_string(c, "reason"));
     950                char *reason = json_o_strdup(c, "reason");
    957951                if (reason) {
    958952                        g_free(td->stream->status_string);
     
    993987}
    994988
    995 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o)
    996 {
    997         struct twitter_data *td = ic->proto_data;
    998         JSON_Object *source = json_object_get_object(o, "source");
    999         JSON_Object *target = json_object_get_object(o, "target");
    1000         const char *type = json_object_get_string(o, "event");
    1001 
    1002         if (!type || !source || !target) {
     989static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o)
     990{
     991        struct twitter_data *td = ic->proto_data;
     992        json_value *source = json_o_get(o, "source");
     993        json_value *target = json_o_get(o, "target");
     994        const char *type = json_o_str(o, "event");
     995
     996        if (!type || !source || source->type != json_object
     997            || !target || target->type != json_object) {
    1003998                return FALSE;
    1004999        }
     
    10971092        struct twitter_filter *tf;
    10981093        GList *users = NULL;
    1099         JSON_Value *parsed;
     1094        json_value *parsed;
     1095        json_value *id;
     1096        const char *name;
    11001097        GString *fstr;
    11011098        GSList *l;
     
    11221119        }
    11231120
    1124         if (json_type(parsed) != JSONArray) {
     1121        if (parsed->type != json_array) {
    11251122                goto finish;
    11261123        }
    11271124
    1128         for (i = 0; i < json_array_get_count(json_array(parsed)); i++) {
    1129                 JSON_Object *o = json_array_get_object(json_array(parsed), i);
    1130                 jint id = json_object_get_integer(o, "id");
    1131                 const char *name = json_object_get_string(o, "screen_name");
    1132 
    1133                 if (!name || !id) {
     1125        for (i = 0; i < parsed->u.array.length; i++) {
     1126                id = json_o_get(parsed->u.array.values[i], "id");
     1127                name = json_o_str(parsed->u.array.values[i], "screen_name");
     1128
     1129                if (!name || !id || id->type != json_integer) {
    11341130                        continue;
    11351131                }
     
    11391135
    11401136                        if (g_strcasecmp(tf->text, name) == 0) {
    1141                                 tf->uid = id;
     1137                                tf->uid = id->u.integer;
    11421138                                users = g_list_delete_link(users, u);
    11431139                                break;
     
    13801376        struct im_connection *ic = req->data;
    13811377        struct twitter_data *td;
    1382         JSON_Value *parsed;
     1378        json_value *parsed;
    13831379        struct twitter_xml_list *txl;
    13841380
     
    14201416        struct im_connection *ic = req->data;
    14211417        struct twitter_data *td;
    1422         JSON_Value *parsed;
     1418        json_value *parsed;
    14231419        struct twitter_xml_list *txl;
    14241420
     
    14611457        struct im_connection *ic = req->data;
    14621458        struct twitter_data *td;
    1463         JSON_Value *parsed;
    1464         jint id;
     1459        json_value *parsed, *id;
    14651460
    14661461        // Check if the connection is still active.
     
    14761471        }
    14771472
    1478         if ((id = json_object_get_integer(json_object(parsed), "id"))) {
    1479                 td->last_status_id = id;
     1473        if ((id = json_o_get(parsed, "id")) && id->type == json_integer) {
     1474                td->last_status_id = id->u.integer;
    14801475        }
    14811476
     
    15851580{
    15861581        struct im_connection *ic = req->data;
    1587         JSON_Value *parsed;
    1588         uint64_t id;
     1582        json_value *parsed, *id;
    15891583        const char *name;
    15901584
     
    15981592        }
    15991593
     1594        /* for the parson branch:
    16001595        name = json_object_dotget_string(json_object(parsed), "user.screen_name");
    16011596        id = json_object_get_integer(json_object(parsed), "id");
    1602 
    1603         if (name && id) {
    1604                 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id);
     1597        */
     1598
     1599        name = json_o_str(json_o_get(parsed, "user"), "screen_name");
     1600        id = json_o_get(parsed, "id");
     1601
     1602        if (name && id && id->type == json_integer) {
     1603                twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer);
    16051604        } else {
    16061605                twitter_log(ic, "Error: could not fetch tweet url.");
  • root_commands.c

    r3fbce97 r82cb190  
    476476
    477477                for (a = irc->b->accounts; a; a = a->next) {
    478                         char *con = NULL, *protocol = NULL;
     478                        char *con;
    479479
    480480                        if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) {
     
    487487                                con = "";
    488488                        }
    489                         if (a->prpl == &protocol_missing) {
    490                                 protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name"));
    491                         } else {
    492                                 protocol = g_strdup(a->prpl->name);
    493                         }
    494 
    495                         irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, protocol, a->user, con);
    496                         g_free(protocol);
     489
     490                        irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con);
    497491
    498492                        i++;
     
    508502
    509503                        for (a = irc->b->accounts; a; a = a->next) {
    510                                 if (!a->ic && a->auto_connect && a->prpl != &protocol_missing) {
     504                                if (!a->ic && a->auto_connect) {
    511505                                        if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
    512506                                                irc_rootmsg(irc, "Enter password for account %s "
     
    565559                        irc_rootmsg(irc, "Enter password for account %s "
    566560                                    "first (use /OPER)", a->tag);
    567                 } else if (a->prpl == &protocol_missing) {
    568                         irc_rootmsg(irc, "Protocol `%s' not recognised (plugin may be missing or not running?)",
    569                                     set_getstr(&a->set, "_protocol_name"));
    570561                } else {
    571562                        account_on(irc->b, a);
     
    672663                irc_rootmsg(irc, "That account is not on-line");
    673664                return;
    674         } else if (add_on_server && !a->prpl->add_buddy) {
    675                 irc_rootmsg(irc, "IM protocol does not support contact list modification");
    676                 return;
     665        }
     666
     667        if (cmd[3]) {
     668                if (!nick_ok(irc, cmd[3])) {
     669                        irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
     670                        return;
     671                } else if (irc_user_by_name(irc, cmd[3])) {
     672                        irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
     673                        return;
     674                } else {
     675                        nick_set_raw(a, cmd[2], cmd[3]);
     676                }
    677677        }
    678678
     
    690690        }
    691691
    692         if (cmd[3]) {
    693                 if (!nick_ok(irc, cmd[3])) {
    694                         irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
    695                         return;
    696                 } else if (irc_user_by_name(irc, cmd[3])) {
    697                         irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
    698                         return;
    699                 } else {
    700                         nick_set_raw(a, cmd[2], cmd[3]);
    701                 }
    702         }
    703 
    704692        if (add_on_server) {
    705693                irc_channel_t *ic;
     
    745733        s = g_strdup(bu->handle);
    746734
    747         if (bu->ic->acc->prpl->remove_buddy) {
    748                 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
    749         } else {
    750                 irc_rootmsg(irc, "IM protocol does not support contact list modification, "
    751                                  "removal will likely not be permanent");
    752         }
    753 
     735        bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
    754736        nick_del(bu);
    755737        if (g_slist_find(irc->users, iu)) {
  • storage.c

    r3fbce97 r82cb190  
    3333
    3434static GList *storage_backends = NULL;
    35 
    36 const struct prpl protocol_missing = {
    37         .name = "_unknown",
    38 };
    3935
    4036void register_storage_backend(storage_t *backend)
  • storage.h

    r3fbce97 r82cb190  
    6262G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate);
    6363
    64 extern const struct prpl protocol_missing;
    65 
    6664#endif /* __STORAGE_H__ */
  • storage_xml.c

    r3fbce97 r82cb190  
    8383}
    8484
    85 /* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */
    86 static void handle_settings_raw(struct xt_node *node, set_t **head)
    87 {
    88         struct xt_node *c;
    89 
    90         for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) {
    91                 char *name = xt_find_attr(c, "name");
    92 
    93                 if (!name) {
    94                         continue;
    95                 }
    96 
    97                 set_t *s = set_add(head, name, NULL, NULL, NULL);
    98                 set_setstr(head, name, c->text);
    99                 s->flags |= SET_HIDDEN |
    100                             ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY;
    101         }
    102 }
    103 
    10485static xt_status handle_account(struct xt_node *node, gpointer data)
    10586{
     
    10889        char *pass_b64 = NULL;
    10990        unsigned char *pass_cr = NULL;
    110         int pass_len;
     91        int pass_len, local = 0;
    11192        struct prpl *prpl = NULL;
    11293        account_t *acc;
     
    123104                prpl = find_protocol(protocol);
    124105                if (!prpl) {
    125                         irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol);
    126                         prpl = (struct prpl*) &protocol_missing;
    127                 }
     106                        irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol);
     107                        return XT_ABORT;
     108                }
     109                local = protocol_account_islocal(protocol);
    128110        }
    129111
     
    142124                        set_setstr(&acc->set, "tag", tag);
    143125                }
    144                 if (prpl == &protocol_missing) {
    145                         set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL);
    146                         s->flags |= SET_HIDDEN | SET_NOSAVE |
    147                                     ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY;
     126                if (local) {
     127                        acc->flags |= ACC_FLAG_LOCAL;
    148128                }
    149129        } else {
     
    156136        g_free(password);
    157137
    158         if (prpl == &protocol_missing) {
    159                 handle_settings_raw(node, &acc->set);
    160         } else {
    161                 handle_settings(node, &acc->set);
    162         }
     138        handle_settings(node, &acc->set);
    163139
    164140        for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
     
    336312
    337313                cur = xt_new_node("account", NULL, NULL);
    338                 if (acc->prpl == &protocol_missing) {
    339                         xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name"));
    340                 } else {
    341                         xt_add_attr(cur, "protocol", acc->prpl->name);
    342                 }
     314                xt_add_attr(cur, "protocol", acc->prpl->name);
    343315                xt_add_attr(cur, "handle", acc->user);
    344316                xt_add_attr(cur, "password", pass_b64);
Note: See TracChangeset for help on using the changeset viewer.