Changeset 9ae7332


Ignore:
Timestamp:
2015-02-27T23:58:11Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Children:
578790e
Parents:
66aefeb
Message:

Some support for calls *from* the plugin.

This gets uglier, also very poor const hygiene in BitlBee is not helping.
:-(

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/rpc/rpc.c

    r66aefeb r9ae7332  
    118118static void rpc_logout(struct im_connection *ic) {
    119119        RPC_OUT_INIT("logout");
    120         rpc_send(ic, rpc);
     120        if (!rpc_send(ic, rpc))
     121                return;
    121122
    122123        struct rpc_connection *rd = ic->proto_data;
     
    133134        json_array_append_string(params, message);
    134135        json_array_append_number(params, flags);
    135         rpc_send(ic, rpc);
    136 
    137         return 1; // BOGUS
     136        return rpc_send(ic, rpc);
    138137}
    139138
     
    149148        json_array_append_string(params, who);
    150149        json_array_append_number(params, flags);
    151         rpc_send(ic, rpc);
    152 
    153         return 1; // BOGUS
     150        return rpc_send(ic, rpc);
    154151}
    155152
     
    237234        rc->id = next_rpc_id;
    238235        rc->gc = gc;
    239         return gc;
     236        return gc;  // TODO: RETVAL HERE AND BELOW
    240237}
    241238
     
    248245        rpc_send(ic, rpc);
    249246
    250         return NULL;
     247        return gc;
    251248}
    252249
     
    263260        rpc_send(ic, rpc);
    264261
    265         return NULL;
     262        return gc;
    266263}
    267264
     
    274271}
    275272
    276 static void rpc_cmd_in(const char *cmd, JSON_Array *params) {
    277 
    278 }
    279 
    280 static void rpc_in(struct im_connection *ic, JSON_Object *rpc) {
     273static gboolean rpc_cmd_in(struct im_connection *ic, const char *cmd, JSON_Array *params);
     274
     275static gboolean rpc_in(struct im_connection *ic, JSON_Object *rpc) {
    281276        JSON_Object *res = json_object_get_object(rpc, "result");
    282277        const char *cmd = json_object_get_string(rpc, "method");
     
    287282                imcb_log(ic, "Received invalid JSON-RPC object.");
    288283                imc_logout(ic, TRUE);
    289                 return;
     284                return FALSE;
    290285        }
    291286
    292287        if (res) {
    293288                // handle response. I think I mostly won't.
     289                return TRUE;
    294290        } else {
    295                 rpc_cmd_in(cmd, params);
     291                gboolean st = rpc_cmd_in(ic, cmd, params);
     292                JSON_Value *resp = json_value_init_object();
     293                json_object_set_value(json_object(resp), "id", json_value_deep_copy(id));
     294                if (st)
     295                        json_object_set_value(json_object(resp), "result", json_value_init_object());
     296                else
     297                        json_object_set_value(json_object(resp), "error", json_value_init_object());
     298                return rpc_send(ic, resp);
    296299        }
    297300}
     
    306309                rd->buf = g_realloc(rd->buf, rd->buflen + st + 1);
    307310                memcpy(rd->buf + rd->buflen, buf, st);
    308         }
    309 
    310         if (st == 0 || (st == -1 && !sockerr_again())) {
     311                rd->buflen += st;
     312        }
     313
     314        if (st == 0 || (st == -1 && !(sockerr_again() || errno == EAGAIN))) {
    311315                imcb_log(ic, "Read error");
    312316                imc_logout(ic, TRUE);
     
    318322        const char *end;
    319323        while ((parsed = json_parse_first(rd->buf, &end))) {
    320                 rpc_in(ic, json_object(parsed));
     324                st = rpc_in(ic, json_object(parsed));
    321325                json_value_free(parsed);
     326
     327                if (!st)
     328                        return FALSE;
    322329
    323330                if (end == rd->buf + rd->buflen) {
     
    330337                        rd->buf = g_realloc(rd->buf, newlen + 1);
    331338                        memcpy(rd->buf, new, newlen);
     339                        rd->buflen = newlen;
    332340                        rd->buf[rd->buflen] = '\0';
    333341                }
     
    337345}
    338346
    339 static void rpc_imcb_buddy_typing(struct im_connection *ic, const char *cmd, JSON_Array *params) {
    340         const char *handle = json_array_get_string(params, 0);
    341         int flags = json_array_get_number(params, 1);
    342         imcb_buddy_typing(ic, handle, flags);
     347static void rpc_imcb_log(struct im_connection *ic, void *func_, JSON_Array *params) {
     348        void (*func)(struct im_connection*, char*, ...) = func_;
     349        func(ic, "%s", json_array_get_string(params, 0));
     350}
     351
     352static void rpc_imcb_connected(struct im_connection *ic, void *func_, JSON_Array *params) {
     353        void (*func)(struct im_connection*) = func_;
     354        func(ic);
     355}
     356
     357static void rpc_imc_logout(struct im_connection *ic, void *func_, JSON_Array *params) {
     358        void (*func)(struct im_connection*, gboolean) = func_;
     359        func(ic, json_array_get_boolean(params, 0));
     360}
     361
     362static void rpc_imcb_add_buddy(struct im_connection *ic, void *func_, JSON_Array *params) {
     363        void (*func)(struct im_connection*, const char*, const char*) = func_;
     364        func(ic, json_array_get_string(params, 0), json_array_get_string(params, 1));
     365}
     366
     367static void rpc_imcb_buddy_status(struct im_connection *ic, void *func_, JSON_Array *params) {
     368        void (*func)(struct im_connection*, const char*, int, const char*, const char*) = func_;
     369        func(ic, json_array_get_string(params, 0), json_array_get_number(params, 1),
     370                 json_array_get_string(params, 2), json_array_get_string(params, 3));
     371}
     372
     373static void rpc_imcb_buddy_times(struct im_connection *ic, void *func_, JSON_Array *params) {
     374        void (*func)(struct im_connection*, const char*, int, int) = func_;
     375        func(ic, json_array_get_string(params, 0), json_array_get_number(params, 1),
     376                 json_array_get_number(params, 2));
     377}
     378
     379static void rpc_imcb_buddy_msg(struct im_connection *ic, void *func_, JSON_Array *params) {
     380        void (*func)(struct im_connection*, const char*, const char*, int, int) = func_;
     381        func(ic, json_array_get_string(params, 0), json_array_get_string(params, 1),
     382                 json_array_get_number(params, 2), json_array_get_number(params, 3));
     383}
     384
     385static void rpc_imcb_buddy_typing(struct im_connection *ic, void *func_, JSON_Array *params) {
     386        void (*func)(struct im_connection*, char*, int) = func_;
     387        func(ic, (char*) json_array_get_string(params, 0), json_array_get_number(params, 1));
    343388}
    344389
    345390struct rpc_in_method {
    346391        char *name;
    347         void (* func) (struct im_connection *ic, const char *cmd, JSON_Array *params);
    348         char *args;
     392        void *func;
     393        void (* wfunc) (struct im_connection *ic, void *cmd, JSON_Array *params);
     394        char args[8];
    349395};
     396
     397static const struct rpc_in_method methods[] = {
     398        { "imcb_log", imcb_log, rpc_imcb_log, "s" },
     399        { "imcb_error", imcb_error, rpc_imcb_log, "s" },
     400        { "imcb_connected", imcb_connected, rpc_imcb_connected, "" },
     401        { "imc_logout", imc_logout, rpc_imc_logout, "b" },
     402        { "imcb_add_buddy", imcb_add_buddy, rpc_imcb_add_buddy, "ss" },
     403        { "imcb_remove_buddy", imcb_remove_buddy, rpc_imcb_add_buddy, "ss" },
     404        { "imcb_rename_buddy", imcb_rename_buddy, rpc_imcb_add_buddy, "ss" },
     405        { "imcb_buddy_nick_hint", imcb_buddy_nick_hint, rpc_imcb_add_buddy, "ss" },
     406        { "imcb_buddy_status", imcb_buddy_status, rpc_imcb_buddy_status, "snss" },
     407        { "imcb_buddy_status_msg", imcb_buddy_status_msg, rpc_imcb_add_buddy, "ss" },
     408        { "imcb_buddy_times", imcb_buddy_times, rpc_imcb_buddy_times, "snn" },
     409        { "imcb_buddy_msg", imcb_buddy_msg, rpc_imcb_buddy_msg, "ssnn" },
     410        { "imcb_buddy_typing", imcb_buddy_typing, rpc_imcb_buddy_typing, "sn" },
     411        { NULL },
     412};
     413
     414static gboolean rpc_cmd_in(struct im_connection *ic, const char *cmd, JSON_Array *params) {
     415        int i;
     416
     417        for (i = 0; methods[i].name; i++) {
     418                if (strcmp(cmd, methods[i].name) == 0) {
     419                        if (json_array_get_count(params) != strlen(methods[i].args)) {
     420                                imcb_error(ic, "Invalid argument count to method %s: %d, wanted %zd", cmd, (int) json_array_get_count(params), strlen(methods[i].args));
     421                                return FALSE;
     422                        }
     423                        int j;
     424                        for (j = 0; methods[i].args[j]; j++) {
     425                                JSON_Value_Type type = json_value_get_type(json_array_get_value(params, j));
     426                                gboolean ok = FALSE;
     427                                switch (methods[i].args[j]) {
     428                                case 's':
     429                                        ok = type == JSONString;
     430                                        break;
     431                                case 'n':
     432                                        ok = type == JSONNumber;
     433                                        break;
     434                                case 'o':
     435                                        ok = type == JSONObject;
     436                                        break;
     437                                case 'a':
     438                                        ok = type == JSONArray;
     439                                        break;
     440                                case 'b':
     441                                        ok = type == JSONBoolean;
     442                                        break;
     443                                }
     444                                if (!ok) {
     445                                        // This error sucks, but just get your types right!
     446                                        imcb_error(ic, "Invalid argument type, %s parameter %d: %d not %c", cmd, j, type, methods[i].args[j]);
     447                                        return FALSE;
     448                                }
     449                        }
     450                        methods[i].wfunc(ic, methods[i].func, params);
     451                        return TRUE;
     452                }
     453        }
     454        return FALSE;
     455}
    350456
    351457#define RPC_ADD_FUNC(func) \
Note: See TracChangeset for help on using the changeset viewer.