- Timestamp:
- 2015-02-26T09:57:31Z (10 years ago)
- Children:
- 66aefeb
- Parents:
- 3434a8c
- 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" 1 5 2 6 static int next_rpc_id = 1; 3 7 4 struct rpc_p rotocol{8 struct rpc_plugin { 5 9 struct sockaddr *addr; 6 10 socklen_t addrlen; 7 } 11 }; 8 12 9 13 struct rpc_connection { 10 14 int fd; 11 15 char *buf; 12 } 16 int buflen; 17 }; 13 18 14 19 struct rpc_groupchat { 15 20 struct groupchat *bee_gc; 16 21 char *rpc_handle; 17 } 22 }; 18 23 19 24 static JSON_Value *rpc_out_new(const char *method, JSON_Array **params_) { 20 25 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); 26 31 27 32 if (params_) 28 33 *params_ = json_array(params); 34 35 return rpc; 29 36 } 30 37 … … 41 48 } 42 49 43 static JSON_ Object*rpc_ser_account(const account_t *acc) {50 static JSON_Value *rpc_ser_account(const account_t *acc) { 44 51 JSON_Value *v = json_value_init_object(); 45 52 JSON_Object *o = json_object(v); … … 54 61 } 55 62 63 static gboolean rpc_login_cb(gpointer data, gint fd, b_input_condition cond); 64 static gboolean rpc_in_event(gpointer data, gint fd, b_input_condition cond); 65 56 66 static void rpc_login(account_t *acc) { 57 67 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 79 static 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; 58 82 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 91 static void rpc_keepalive(struct im_connection *ic) { 92 RPC_OUT_INIT("keepalive"); 93 rpc_send(ic, rpc); 94 } 95 96 static void rpc_logout(struct im_connection *ic) { 97 RPC_OUT_INIT("logout"); 98 rpc_send(ic, rpc); 99 } 100 101 static 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 111 static 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 118 static 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 127 static 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 134 static 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 141 static 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 147 static 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 153 static 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 159 static 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 165 static 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 171 static 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); 60 175 rpc_send(gc->ic, rpc); 61 // Create im 176 } 177 178 static 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 185 static void rpc_chat_leave(struct groupchat *gc) { 186 RPC_OUT_INIT("chat_leave"); 187 rpc_send(gc->ic, rpc); 62 188 } 63 189 64 190 static void rpc_chat_msg(struct groupchat *gc, char *msg, int flags) { 65 191 RPC_OUT_INIT("chat_msg"); 66 struct rpc_groupchat *data = gc-> proto_data;192 struct rpc_groupchat *data = gc->data; 67 193 json_array_append_string(params, data->rpc_handle); 68 194 json_array_append_string(params, msg); … … 71 197 } 72 198 73 static void rpc_in(JSON_Object *rpc) { 199 static 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 207 static 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 219 static 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 225 static void rpc_cmd_in(const char *cmd, JSON_Array *params) { 226 227 } 228 229 static void rpc_in(struct im_connection *ic, JSON_Object *rpc) { 74 230 JSON_Object *res = json_object_get_object(rpc, "result"); 75 231 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"); 78 234 79 235 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); 81 238 return; 82 239 } … … 89 246 } 90 247 248 static 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 91 288 static void rpc_imcb_buddy_typing(struct im_connection *ic, const char *cmd, JSON_Array *params) { 92 289 const char *handle = json_array_get_string(params, 0); … … 99 296 void (* func) (struct im_connection *ic, const char *cmd, JSON_Array *params); 100 297 char *args; 101 } 102 103 static void rpc_cmd_in(const char *cmd, JSON_Array *params) { 104 105 } 298 }; 106 299 107 300 #define RPC_ADD_FUNC(func) \ 108 301 if (g_hash_table_contains(methods, #func)) \ 109 ret->func = rpc_ # func110 111 void rpc_initmodule_sock(struct sockaddr *address, socklen addrlen) {302 ret->func = rpc_ ## func 303 304 void rpc_initmodule_sock(struct sockaddr *address, socklen_t addrlen) { 112 305 int st, fd, i; 113 306 114 fd = socket(address->s s_family, SOCK_STREAM);307 fd = socket(address->sa_family, SOCK_STREAM, 0); 115 308 if (fd == -1 || connect(fd, address, addrlen) == -1) 116 309 return; … … 120 313 json_object_set_string(json_object(d), "version_str", BITLBEE_VERSION); 121 314 json_object_set_number(json_object(d), "version", BITLBEE_VERSION_CODE); 122 json_array_append_value( d);315 json_array_append_value(params, d); 123 316 char *s = json_serialize_to_string(rpc); 124 317 … … 130 323 131 324 char *resp = NULL; 132 int buf size= 4096, resplen = 0;325 int buflen = 4096, resplen = 0; 133 326 JSON_Value *parsed; 134 327 do { … … 147 340 } 148 341 149 if (resplen >= buf size)150 buf size*= 2;151 resp = g_realloc(resp, buf size+ 1);152 st = read(fd, resp + resplen, buf size- resplen);342 if (resplen >= buflen) 343 buflen *= 2; 344 resp = g_realloc(resp, buflen + 1); 345 st = read(fd, resp + resplen, buflen - resplen); 153 346 if (st == -1) { 154 347 if (sockerr_again()) … … 171 364 172 365 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); 175 367 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; 178 371 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); 179 387 RPC_ADD_FUNC(chat_msg); 388 RPC_ADD_FUNC(chat_with); 389 RPC_ADD_FUNC(chat_join); 390 RPC_ADD_FUNC(chat_topic); 180 391 181 g_hash_table_ free(methods);392 g_hash_table_destroy(methods); 182 393 183 394 // TODO: Property for a few standard nickcmp implementations. … … 185 396 JSON_Array *settings = json_object_get_array(isup, "settings"); 186 397 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); 188 399 // set..name, set..type, set..default, set..flags ? 189 400 } … … 191 402 ret->name = g_strdup(json_object_get_string(isup, "name")); 192 403 193 struct rpc_p rotocol *proto_data = g_new0(struct rpc_protocol, 1);404 struct rpc_plugin *proto_data = g_new0(struct rpc_plugin, 1); 194 405 proto_data->addr = g_memdup(address, addrlen); 195 406 proto_data->addrlen = addrlen;
Note: See TracChangeset
for help on using the changeset viewer.