Changeset 6cdecc7 for protocols


Ignore:
Timestamp:
2015-02-26T09:57:31Z (10 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Children:
66aefeb
Parents:
3434a8c
Message:

Lots of changes. Implemented both to-plugin RPCs though not all complete yet.
Also, some connect and I/O code. It compiles but is very unlikely to actually
work still.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/rpc/rpc.c

    r3434a8c r6cdecc7  
     1#include "bitlbee.h"
     2#include "bee.h"
     3#include "nogaim.h"
     4#include "parson.h"
    15
    26static int next_rpc_id = 1;
    37
    4 struct rpc_protocol {
     8struct rpc_plugin {
    59        struct sockaddr *addr;
    610        socklen_t addrlen;
    7 }
     11};
    812
    913struct rpc_connection {
    1014        int fd;
    1115        char *buf;
    12 }
     16        int buflen;
     17};
    1318
    1419struct rpc_groupchat {
    1520        struct groupchat *bee_gc;
    1621        char *rpc_handle;
    17 }
     22};
    1823
    1924static JSON_Value *rpc_out_new(const char *method, JSON_Array **params_) {
    2025        JSON_Value *rpc = json_value_init_object();
    21         json_set_string(rpc, "method", "chat_msg");
    22         json_set_number(rpc, "id", next_rpc_id++);
    23 
    24         JSON_Array *params = json_value_init_array();
    25         json_object_set_value(rpc, "params", params);
     26        json_object_set_string(json_object(rpc), "method", method);
     27        json_object_set_number(json_object(rpc), "id", next_rpc_id++);
     28
     29        JSON_Value *params = json_value_init_array();
     30        json_object_set_value(json_object(rpc), "params", params);
    2631
    2732        if (params_)
    2833                *params_ = json_array(params);
     34
     35        return rpc;
    2936}
    3037
     
    4148}
    4249
    43 static JSON_Object *rpc_ser_account(const account_t *acc) {
     50static JSON_Value *rpc_ser_account(const account_t *acc) {
    4451        JSON_Value *v = json_value_init_object();
    4552        JSON_Object *o = json_object(v);
     
    5461}
    5562
     63static gboolean rpc_login_cb(gpointer data, gint fd, b_input_condition cond);
     64static gboolean rpc_in_event(gpointer data, gint fd, b_input_condition cond);
     65
    5666static void rpc_login(account_t *acc) {
    5767        struct im_connection *ic = imcb_new(acc);
     68        struct rpc_connection *rd = ic->proto_data = g_new0(struct rpc_connection, 1);
     69        struct rpc_plugin *pd = acc->prpl->data;
     70        rd->fd = socket(pd->addr->sa_family, SOCK_STREAM, 0);
     71        sock_make_nonblocking(rd->fd);
     72        if (connect(rd->fd, pd->addr, pd->addrlen) == -1) {
     73                closesocket(rd->fd);
     74                return;
     75        }
     76        ic->inpa = b_input_add(rd->fd, B_EV_IO_WRITE, rpc_login_cb, ic);
     77}
     78
     79static gboolean rpc_login_cb(gpointer data, gint fd, b_input_condition cond) {
     80        struct im_connection *ic = data;
     81        struct rpc_connection *rd = ic->proto_data;
    5882        RPC_OUT_INIT("login");
    59         json_array_append_value(params, rpc_ser_account(acc));
     83        json_array_append_value(params, rpc_ser_account(ic->acc));
     84        rpc_send(ic, rpc);
     85
     86        ic->inpa = b_input_add(rd->fd, B_EV_IO_READ, rpc_in_event, ic);
     87
     88        return FALSE;
     89}
     90
     91static void rpc_keepalive(struct im_connection *ic) {
     92        RPC_OUT_INIT("keepalive");
     93        rpc_send(ic, rpc);
     94}
     95
     96static void rpc_logout(struct im_connection *ic) {
     97        RPC_OUT_INIT("logout");
     98        rpc_send(ic, rpc);
     99}
     100
     101static int rpc_buddy_msg(struct im_connection *ic, char *to, char *message, int flags) {
     102        RPC_OUT_INIT("buddy_msg");
     103        json_array_append_string(params, to);
     104        json_array_append_string(params, message);
     105        json_array_append_number(params, flags);
     106        rpc_send(ic, rpc);
     107
     108        return 1; // BOGUS
     109}
     110
     111static void rpc_set_away(struct im_connection *ic, char *state, char *message) {
     112        RPC_OUT_INIT("set_away");
     113        json_array_append_string(params, state);
     114        json_array_append_string(params, message);
     115        rpc_send(ic, rpc);
     116}
     117
     118static int rpc_send_typing(struct im_connection *ic, char *who, int flags) {
     119        RPC_OUT_INIT("send_typing");
     120        json_array_append_string(params, who);
     121        json_array_append_number(params, flags);
     122        rpc_send(ic, rpc);
     123
     124        return 1; // BOGUS
     125}
     126
     127static void rpc_add_buddy(struct im_connection *ic, char *name, char *group) {
     128        RPC_OUT_INIT("add_buddy");
     129        json_array_append_string(params, name);
     130        json_array_append_string(params, group);
     131        rpc_send(ic, rpc);
     132}
     133
     134static void rpc_remove_buddy(struct im_connection *ic, char *name, char *group) {
     135        RPC_OUT_INIT("remove_buddy");
     136        json_array_append_string(params, name);
     137        json_array_append_string(params, group);
     138        rpc_send(ic, rpc);
     139}
     140
     141static void rpc_add_permit(struct im_connection *ic, char *who) {
     142        RPC_OUT_INIT("add_permit");
     143        json_array_append_string(params, who);
     144        rpc_send(ic, rpc);
     145}
     146
     147static void rpc_add_deny(struct im_connection *ic, char *who) {
     148        RPC_OUT_INIT("add_deny");
     149        json_array_append_string(params, who);
     150        rpc_send(ic, rpc);
     151}
     152
     153static void rpc_rem_permit(struct im_connection *ic, char *who) {
     154        RPC_OUT_INIT("rem_permit");
     155        json_array_append_string(params, who);
     156        rpc_send(ic, rpc);
     157}
     158
     159static void rpc_rem_deny(struct im_connection *ic, char *who) {
     160        RPC_OUT_INIT("rem_deny");
     161        json_array_append_string(params, who);
     162        rpc_send(ic, rpc);
     163}
     164
     165static void rpc_get_info(struct im_connection *ic, char *who) {
     166        RPC_OUT_INIT("get_info");
     167        json_array_append_string(params, who);
     168        rpc_send(ic, rpc);
     169}
     170
     171static void rpc_chat_invite(struct groupchat *gc, char *who, char *message) {
     172        RPC_OUT_INIT("chat_invite");
     173        json_array_append_string(params, who);
     174        json_array_append_string(params, message);
    60175        rpc_send(gc->ic, rpc);
    61         // Create im
     176}
     177
     178static void rpc_chat_kick(struct groupchat *gc, char *who, const char *message) {
     179        RPC_OUT_INIT("chat_kick");
     180        json_array_append_string(params, who);
     181        json_array_append_string(params, message);
     182        rpc_send(gc->ic, rpc);
     183}
     184
     185static void rpc_chat_leave(struct groupchat *gc) {
     186        RPC_OUT_INIT("chat_leave");
     187        rpc_send(gc->ic, rpc);
    62188}
    63189
    64190static void rpc_chat_msg(struct groupchat *gc, char *msg, int flags) {
    65191        RPC_OUT_INIT("chat_msg");       
    66         struct rpc_groupchat *data = gc->proto_data;
     192        struct rpc_groupchat *data = gc->data;
    67193        json_array_append_string(params, data->rpc_handle);
    68194        json_array_append_string(params, msg);
     
    71197}
    72198
    73 static void rpc_in(JSON_Object *rpc) {
     199static struct groupchat *rpc_chat_with(struct im_connection *ic, char *who) {
     200        RPC_OUT_INIT("chat_with");
     201        json_array_append_string(params, who);
     202        rpc_send(ic, rpc);
     203
     204        return NULL;
     205}
     206
     207static struct groupchat *rpc_chat_join(struct im_connection *ic, const char *room, const char *nick,
     208                                       const char *password, set_t **sets) {
     209        RPC_OUT_INIT("chat_join");
     210        json_array_append_string(params, room);
     211        json_array_append_string(params, nick);
     212        json_array_append_string(params, password);
     213        //json_array_append_value(params, rpc_ser_sets(sets));
     214        rpc_send(ic, rpc);
     215
     216        return NULL;
     217}
     218
     219static void rpc_chat_topic(struct groupchat *gc, char *topic) {
     220        RPC_OUT_INIT("chat_topic");
     221        json_array_append_string(params, topic);
     222        rpc_send(gc->ic, rpc);
     223}
     224
     225static void rpc_cmd_in(const char *cmd, JSON_Array *params) {
     226
     227}
     228
     229static void rpc_in(struct im_connection *ic, JSON_Object *rpc) {
    74230        JSON_Object *res = json_object_get_object(rpc, "result");
    75231        const char *cmd = json_object_get_string(rpc, "method");
    76         JSON_Value *Value *id = json_object_get_value(rpc, "id");
    77         JSON_Array *params *params = json_object_get_array(rpc, "params");
     232        JSON_Value *id = json_object_get_value(rpc, "id");
     233        JSON_Array *params = json_object_get_array(rpc, "params");
    78234
    79235        if ((!cmd && !res) || !id || (cmd && !params)) {
    80                 imcb_logout(ic, "Received invalid JSON-RPC object.");
     236                imcb_log(ic, "Received invalid JSON-RPC object.");
     237                imc_logout(ic, TRUE);
    81238                return;
    82239        }
     
    89246}
    90247
     248static gboolean rpc_in_event(gpointer data, gint fd, b_input_condition cond) {
     249        struct im_connection *ic = data;
     250        struct rpc_connection *rd = ic->proto_data;
     251        char buf[2048];
     252        int st;
     253
     254        while ((st = read(rd->fd, buf, sizeof(buf))) > 0) {
     255                rd->buf = g_realloc(rd->buf, rd->buflen + st + 1);
     256                memcpy(rd->buf + rd->buflen, buf, st);
     257        }
     258
     259        if (st == 0 || (st == -1 && !sockerr_again())) {
     260                imcb_log(ic, "Read error");
     261                imc_logout(ic, TRUE);
     262                return FALSE;
     263        }
     264        rd->buf[rd->buflen] = '\0';
     265
     266        JSON_Value *parsed;
     267        const char *end;
     268        while ((parsed = json_parse_first(rd->buf, &end))) {
     269                rpc_in(ic, json_object(parsed));
     270                json_value_free(parsed);
     271
     272                if (end == rd->buf + rd->buflen) {
     273                        g_free(rd->buf);
     274                        rd->buf = NULL;
     275                } else {
     276                        int newlen = rd->buf + rd->buflen - end;
     277                        char new[newlen];
     278                        memcpy(new, end, newlen);
     279                        rd->buf = g_realloc(rd->buf, newlen + 1);
     280                        memcpy(rd->buf, new, newlen);
     281                        rd->buf[rd->buflen] = '\0';
     282                }
     283        }
     284
     285        return TRUE;
     286}
     287
    91288static void rpc_imcb_buddy_typing(struct im_connection *ic, const char *cmd, JSON_Array *params) {
    92289        const char *handle = json_array_get_string(params, 0);
     
    99296        void (* func) (struct im_connection *ic, const char *cmd, JSON_Array *params);
    100297        char *args;
    101 }
    102 
    103 static void rpc_cmd_in(const char *cmd, JSON_Array *params) {
    104 
    105 }
     298};
    106299
    107300#define RPC_ADD_FUNC(func) \
    108301        if (g_hash_table_contains(methods, #func)) \
    109                 ret->func = rpc_ # func
    110 
    111 void rpc_initmodule_sock(struct sockaddr *address, socklen addrlen) {
     302                ret->func = rpc_ ## func
     303
     304void rpc_initmodule_sock(struct sockaddr *address, socklen_t addrlen) {
    112305        int st, fd, i;
    113306
    114         fd = socket(address->ss_family, SOCK_STREAM);
     307        fd = socket(address->sa_family, SOCK_STREAM, 0);
    115308        if (fd == -1 || connect(fd, address, addrlen) == -1)
    116309                return;
     
    120313        json_object_set_string(json_object(d), "version_str", BITLBEE_VERSION);
    121314        json_object_set_number(json_object(d), "version", BITLBEE_VERSION_CODE);
    122         json_array_append_value(d);
     315        json_array_append_value(params, d);
    123316        char *s = json_serialize_to_string(rpc);
    124317
     
    130323
    131324        char *resp = NULL;
    132         int bufsize = 4096, resplen = 0;
     325        int buflen = 4096, resplen = 0;
    133326        JSON_Value *parsed;
    134327        do {
     
    147340                }
    148341               
    149                 if (resplen >= bufsize)
    150                         bufsize *= 2;
    151                 resp = g_realloc(resp, bufsize + 1);
    152                 st = read(fd, resp + resplen, bufsize - resplen);
     342                if (resplen >= buflen)
     343                        buflen *= 2;
     344                resp = g_realloc(resp, buflen + 1);
     345                st = read(fd, resp + resplen, buflen - resplen);
    153346                if (st == -1) {
    154347                        if (sockerr_again())
     
    171364       
    172365        JSON_Array *methods_a = json_object_get_array(isup, "methods");
    173         GHashTable *methods = g_hash_table_new();
    174         int i;
     366        GHashTable *methods = g_hash_table_new(g_str_hash, g_str_equal);
    175367        for (i = 0; i < json_array_get_count(methods_a); i++)
    176                 g_hash_table_add(methods, json_array_get_string(methods_a, i));
    177 
     368                g_hash_table_add(methods, (void*) json_array_get_string(methods_a, i));
     369
     370        ret->init = rpc_init;
    178371        RPC_ADD_FUNC(login);
     372        RPC_ADD_FUNC(keepalive);
     373        RPC_ADD_FUNC(logout);
     374        RPC_ADD_FUNC(buddy_msg);
     375        RPC_ADD_FUNC(set_away);
     376        RPC_ADD_FUNC(send_typing);
     377        RPC_ADD_FUNC(add_buddy);
     378        RPC_ADD_FUNC(remove_buddy);
     379        RPC_ADD_FUNC(add_permit);
     380        RPC_ADD_FUNC(add_deny);
     381        RPC_ADD_FUNC(rem_permit);
     382        RPC_ADD_FUNC(rem_deny);
     383        RPC_ADD_FUNC(get_info);
     384        RPC_ADD_FUNC(chat_invite);
     385        RPC_ADD_FUNC(chat_kick);
     386        RPC_ADD_FUNC(chat_leave);
    179387        RPC_ADD_FUNC(chat_msg);
     388        RPC_ADD_FUNC(chat_with);
     389        RPC_ADD_FUNC(chat_join);
     390        RPC_ADD_FUNC(chat_topic);
    180391       
    181         g_hash_table_free(methods);
     392        g_hash_table_destroy(methods);
    182393
    183394        // TODO: Property for a few standard nickcmp implementations.
     
    185396        JSON_Array *settings = json_object_get_array(isup, "settings");
    186397        for (i = 0; i < json_array_get_count(settings); i++) {
    187                 JSON_Object *set = json_array_get_object(settings, i);
     398                //JSON_Object *set = json_array_get_object(settings, i);
    188399                // set..name, set..type, set..default, set..flags ?
    189400        }
     
    191402        ret->name = g_strdup(json_object_get_string(isup, "name"));
    192403
    193         struct rpc_protocol *proto_data = g_new0(struct rpc_protocol, 1);
     404        struct rpc_plugin *proto_data = g_new0(struct rpc_plugin, 1);
    194405        proto_data->addr = g_memdup(address, addrlen);
    195406        proto_data->addrlen = addrlen;
Note: See TracChangeset for help on using the changeset viewer.