aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 17:29:19 +1000
committerDavid Walter Seikel2013-01-13 17:29:19 +1000
commit07274513e984f0b5544586c74508ccd16e7dcafa (patch)
treeb32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c
parentAdded Irrlicht 1.8, but without all the Windows binaries. (diff)
downloadSledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz
Remove EFL, since it's been released now.
Diffstat (limited to 'libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c')
-rw-r--r--libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c1593
1 files changed, 0 insertions, 1593 deletions
diff --git a/libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c b/libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c
deleted file mode 100644
index 0210f1d..0000000
--- a/libraries/ecore/src/lib/ecore_ipc/ecore_ipc.c
+++ /dev/null
@@ -1,1593 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <string.h>
6
7#ifdef HAVE_NETINET_IN_H
8# include <sys/types.h>
9# include <netinet/in.h>
10#endif
11
12#ifdef HAVE_WINSOCK2_H
13# include <winsock2.h>
14#endif
15
16#if USE_GNUTLS_OPENSSL
17# include <gnutls/openssl.h>
18#elif USE_OPENSSL
19# include <openssl/ssl.h>
20#endif
21
22#include <Ecore.h>
23#include <ecore_private.h>
24#include <Ecore_Con.h>
25
26#include "Ecore_Ipc.h"
27#include "ecore_ipc_private.h"
28
29#define DLT_ZERO 0
30#define DLT_ONE 1
31#define DLT_SAME 2
32#define DLT_SHL 3
33#define DLT_SHR 4
34#define DLT_ADD8 5
35#define DLT_DEL8 6
36#define DLT_ADDU8 7
37#define DLT_DELU8 8
38#define DLT_ADD16 9
39#define DLT_DEL16 10
40#define DLT_ADDU16 11
41#define DLT_DELU16 12
42#define DLT_SET 13
43#define DLT_R1 14
44#define DLT_R2 15
45
46int _ecore_ipc_log_dom = -1;
47
48EAPI unsigned short
49_ecore_ipc_swap_16(unsigned short v)
50{
51 unsigned char *s, t;
52
53 s = (unsigned char *)(&v);
54 t = s[0]; s[0] = s[1]; s[1] = t;
55 return v;
56}
57
58EAPI unsigned int
59_ecore_ipc_swap_32(unsigned int v)
60{
61 unsigned char *s, t;
62
63 s = (unsigned char *)(&v);
64 t = s[0]; s[0] = s[3]; s[3] = t;
65 t = s[1]; s[1] = s[2]; s[2] = t;
66 return v;
67}
68
69EAPI unsigned long long
70_ecore_ipc_swap_64(unsigned long long v)
71{
72 unsigned char *s, t;
73
74 s = (unsigned char *)(&v);
75 t = s[0]; s[0] = s[7]; s[7] = t;
76 t = s[1]; s[1] = s[6]; s[6] = t;
77 t = s[2]; s[2] = s[5]; s[5] = t;
78 t = s[3]; s[3] = s[4]; s[4] = t;
79 return v;
80}
81
82static int _ecore_ipc_dlt_int(int out, int prev, int *mode);
83static int _ecore_ipc_ddlt_int(int in, int prev, int mode);
84
85static int
86_ecore_ipc_dlt_int(int out, int prev, int *mode)
87{
88 int dlt;
89
90 /* 0 byte */
91 if (out == 0)
92 {
93 *mode = DLT_ZERO;
94 return 0;
95 }
96 if (out == (int)0xffffffff)
97 {
98 *mode = DLT_ONE;
99 return 0;
100 }
101 if (out == prev)
102 {
103 *mode = DLT_SAME;
104 return 0;
105 }
106 if (out == prev << 1)
107 {
108 *mode = DLT_SHL;
109 return 0;
110 }
111 if (out == prev >> 1)
112 {
113 *mode = DLT_SHR;
114 return 0;
115 }
116 /* 1 byte */
117 dlt = out - prev;
118 if (!(dlt & 0xffffff00))
119 {
120 *mode = DLT_ADD8;
121 return dlt & 0xff;
122 }
123 dlt = prev - out;
124 if (!(dlt & 0xffffff00))
125 {
126 *mode = DLT_DEL8;
127 return dlt & 0xff;
128 }
129 dlt = out - prev;
130 if (!(dlt & 0x00ffffff))
131 {
132 *mode = DLT_ADDU8;
133 return (dlt >> 24) & 0xff;
134 }
135 dlt = prev - out;
136 if (!(dlt & 0x00ffffff))
137 {
138 *mode = DLT_DELU8;
139 return (dlt >> 24) & 0xff;
140 }
141 /* 2 byte */
142 dlt = out - prev;
143 if (!(dlt & 0xffff0000))
144 {
145 *mode = DLT_ADD16;
146 return dlt & 0xffff;
147 }
148 dlt = prev - out;
149 if (!(dlt & 0xffff0000))
150 {
151 *mode = DLT_DEL16;
152 return dlt & 0xffff;
153 }
154 dlt = out - prev;
155 if (!(dlt & 0x0000ffff))
156 {
157 *mode = DLT_ADDU16;
158 return (dlt >> 16) & 0xffff;
159 }
160 dlt = prev - out;
161 if (!(dlt & 0x0000ffff))
162 {
163 *mode = DLT_DELU16;
164 return (dlt >> 16) & 0xffff;
165 }
166 /* 4 byte */
167 *mode = DLT_SET;
168 return out;
169}
170
171static int
172_ecore_ipc_ddlt_int(int in, int prev, int mode)
173{
174 switch (mode)
175 {
176 case DLT_ZERO:
177 return 0;
178 break;
179 case DLT_ONE:
180 return 0xffffffff;
181 break;
182 case DLT_SAME:
183 return prev;
184 break;
185 case DLT_SHL:
186 return prev << 1;
187 break;
188 case DLT_SHR:
189 return prev >> 1;
190 break;
191 case DLT_ADD8:
192 return prev + in;
193 break;
194 case DLT_DEL8:
195 return prev - in;
196 break;
197 case DLT_ADDU8:
198 return prev + (in << 24);
199 break;
200 case DLT_DELU8:
201 return prev - (in << 24);
202 break;
203 case DLT_ADD16:
204 return prev + in;
205 break;
206 case DLT_DEL16:
207 return prev - in;
208 break;
209 case DLT_ADDU16:
210 return prev + (in << 16);
211 break;
212 case DLT_DELU16:
213 return prev - (in << 16);
214 break;
215 case DLT_SET:
216 return in;
217 break;
218 case DLT_R1:
219 return 0;
220 break;
221 case DLT_R2:
222 return 0;
223 break;
224 default:
225 break;
226 }
227 return 0;
228}
229
230static Eina_Bool _ecore_ipc_event_client_add(void *data, int ev_type, void *ev);
231static Eina_Bool _ecore_ipc_event_client_del(void *data, int ev_type, void *ev);
232static Eina_Bool _ecore_ipc_event_server_add(void *data, int ev_type, void *ev);
233static Eina_Bool _ecore_ipc_event_server_del(void *data, int ev_type, void *ev);
234static Eina_Bool _ecore_ipc_event_client_data(void *data, int ev_type, void *ev);
235static Eina_Bool _ecore_ipc_event_server_data(void *data, int ev_type, void *ev);
236static void _ecore_ipc_event_client_add_free(void *data, void *ev);
237static void _ecore_ipc_event_client_del_free(void *data, void *ev);
238static void _ecore_ipc_event_client_data_free(void *data, void *ev);
239static void _ecore_ipc_event_server_add_free(void *data, void *ev);
240static void _ecore_ipc_event_server_del_free(void *data, void *ev);
241static void _ecore_ipc_event_server_data_free(void *data, void *ev);
242
243EAPI int ECORE_IPC_EVENT_CLIENT_ADD = 0;
244EAPI int ECORE_IPC_EVENT_CLIENT_DEL = 0;
245EAPI int ECORE_IPC_EVENT_SERVER_ADD = 0;
246EAPI int ECORE_IPC_EVENT_SERVER_DEL = 0;
247EAPI int ECORE_IPC_EVENT_CLIENT_DATA = 0;
248EAPI int ECORE_IPC_EVENT_SERVER_DATA = 0;
249
250static int _ecore_ipc_init_count = 0;
251static Eina_List *servers = NULL;
252static Ecore_Event_Handler *handler[6];
253
254/**
255 * @defgroup Ecore_IPC_Library_Group IPC Library Functions
256 *
257 * Functions that set up and shut down the Ecore IPC Library.
258 */
259
260/**
261 * Initialises the Ecore IPC library.
262 * @return Number of times the library has been initialised without
263 * being shut down.
264 * @ingroup Ecore_IPC_Library_Group
265 */
266EAPI int
267ecore_ipc_init(void)
268{
269 int i = 0;
270
271 if (++_ecore_ipc_init_count != 1)
272 return _ecore_ipc_init_count;
273 _ecore_ipc_log_dom = eina_log_domain_register
274 ("ecore_ipc", ECORE_IPC_DEFAULT_LOG_COLOR);
275 if(_ecore_ipc_log_dom < 0)
276 {
277 EINA_LOG_ERR("Impossible to create a log domain for the Ecore IPC module.");
278 return --_ecore_ipc_init_count;
279 }
280 if (!ecore_con_init())
281 return --_ecore_ipc_init_count;
282
283 ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new();
284 ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new();
285 ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new();
286 ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new();
287 ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new();
288 ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new();
289
290 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD,
291 _ecore_ipc_event_client_add, NULL);
292 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL,
293 _ecore_ipc_event_client_del, NULL);
294 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
295 _ecore_ipc_event_server_add, NULL);
296 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
297 _ecore_ipc_event_server_del, NULL);
298 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA,
299 _ecore_ipc_event_client_data, NULL);
300 handler[i] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
301 _ecore_ipc_event_server_data, NULL);
302 return _ecore_ipc_init_count;
303}
304
305/**
306 * Shuts down the Ecore IPC library.
307 * @return Number of times the library has been initialised without being
308 * shut down.
309 * @ingroup Ecore_IPC_Library_Group
310 */
311EAPI int
312ecore_ipc_shutdown(void)
313{
314 int i;
315
316 if (--_ecore_ipc_init_count != 0)
317 return _ecore_ipc_init_count;
318
319 Eina_List *l, *l2;
320 Ecore_Ipc_Server *svr;
321 EINA_LIST_FOREACH_SAFE(servers, l, l2, svr)
322 ecore_ipc_server_del(svr);
323
324 for (i = 0; i < 6; i++)
325 ecore_event_handler_del(handler[i]);
326
327 ecore_con_shutdown();
328 eina_log_domain_unregister(_ecore_ipc_log_dom);
329 _ecore_ipc_log_dom = -1;
330 return _ecore_ipc_init_count;
331}
332
333/**
334 * @defgroup Ecore_IPC_Server_Group IPC Server Functions
335 *
336 * Functions the deal with IPC server objects.
337 */
338
339/**
340 * Creates an IPC server that listens for connections.
341 *
342 * For more details about the @p compl_type, @p name and @p port
343 * parameters, see the @ref ecore_con_server_add documentation.
344 *
345 * @param compl_type The connection type.
346 * @param name Name to associate with the socket used for connection.
347 * @param port Number to identify with socket used for connection.
348 * @param data Data to associate with the IPC server.
349 * @return New IPC server. If there is an error, @c NULL is returned.
350 * @ingroup Ecore_IPC_Server_Group
351 * @todo Need to add protocol type parameter to this function.
352 */
353EAPI Ecore_Ipc_Server *
354ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data)
355{
356 Ecore_Ipc_Server *svr;
357 Ecore_Ipc_Type type;
358 Ecore_Con_Type extra = 0;
359
360 svr = calloc(1, sizeof(Ecore_Ipc_Server));
361 if (!svr) return NULL;
362 type = compl_type;
363 type &= ~ECORE_IPC_USE_SSL;
364 if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
365 switch (type)
366 {
367 case ECORE_IPC_LOCAL_USER:
368 svr->server = ecore_con_server_add(ECORE_CON_LOCAL_USER | extra, name, port, svr);
369 break;
370 case ECORE_IPC_LOCAL_SYSTEM:
371 svr->server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
372 break;
373 case ECORE_IPC_REMOTE_SYSTEM:
374 svr->server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
375 break;
376 default:
377 free(svr);
378 return NULL;
379 }
380 if (!svr->server)
381 {
382 free(svr);
383 return NULL;
384 }
385 svr->max_buf_size = 32 * 1024;
386 svr->data = (void *)data;
387 servers = eina_list_append(servers, svr);
388 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
389 return svr;
390}
391
392/**
393 * Creates an IPC server object to represent the IPC server listening
394 * on the given port.
395 *
396 * For more details about the @p compl_type, @p name and @p port
397 * parameters, see the @ref ecore_con_server_connect documentation.
398 *
399 * @param compl_type The IPC connection type.
400 * @param name Name used to determine which socket to use for the
401 * IPC connection.
402 * @param port Number used to identify the socket to use for the
403 * IPC connection.
404 * @param data Data to associate with the server.
405 * @return A new IPC server. @c NULL is returned on error.
406 * @ingroup Ecore_IPC_Server_Group
407 * @todo Need to add protocol type parameter.
408 */
409EAPI Ecore_Ipc_Server *
410ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data)
411{
412 Ecore_Ipc_Server *svr;
413 Ecore_Ipc_Type type;
414 Ecore_Con_Type extra = 0;
415
416 svr = calloc(1, sizeof(Ecore_Ipc_Server));
417 if (!svr) return NULL;
418 type = compl_type;
419 type &= ~ECORE_IPC_USE_SSL;
420 if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
421 switch (type)
422 {
423 case ECORE_IPC_LOCAL_USER:
424 svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr);
425 break;
426 case ECORE_IPC_LOCAL_SYSTEM:
427 svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
428 break;
429 case ECORE_IPC_REMOTE_SYSTEM:
430 svr->server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
431 break;
432 default:
433 free(svr);
434 return NULL;
435 }
436 if (!svr->server)
437 {
438 free(svr);
439 return NULL;
440 }
441 svr->max_buf_size = -1;
442 svr->data = (void *)data;
443 servers = eina_list_append(servers, svr);
444 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
445 return svr;
446}
447
448/**
449 * Closes the connection and frees the given IPC server.
450 * @param svr The given IPC server.
451 * @return The data associated with the server when it was created.
452 * @ingroup Ecore_IPC_Server_Group
453 */
454EAPI void *
455ecore_ipc_server_del(Ecore_Ipc_Server *svr)
456{
457 void *data;
458
459 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
460 {
461 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
462 "ecore_ipc_server_del");
463 return NULL;
464 }
465 if (svr->delete_me) return NULL;
466
467 data = svr->data;
468 svr->data = NULL;
469 svr->delete_me = 1;
470 if (svr->event_count == 0)
471 {
472 Ecore_Ipc_Client *cl;
473
474 EINA_LIST_FREE(svr->clients, cl)
475 ecore_ipc_client_del(cl);
476 ecore_con_server_del(svr->server);
477 servers = eina_list_remove(servers, svr);
478
479 if (svr->buf) free(svr->buf);
480 ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
481 free(svr);
482 }
483 return data;
484}
485
486/**
487 * Retrieves the data associated with the given IPC server.
488 * @param svr The given IPC server.
489 * @return The associated data.
490 * @ingroup Ecore_IPC_Server_Group
491 */
492EAPI void *
493ecore_ipc_server_data_get(Ecore_Ipc_Server *svr)
494{
495 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
496 {
497 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
498 "ecore_ipc_server_data_get");
499 return NULL;
500 }
501 return svr->data;
502}
503
504/**
505 * Retrieves whether the given IPC server is currently connected.
506 * @param svr The given IPC server.
507 * @return #EINA_TRUE if the server is connected. #EINA_FALSE otherwise.
508 * @ingroup Ecore_IPC_Server_Group
509 */
510EAPI Eina_Bool
511ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
512{
513 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
514 {
515 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
516 "ecore_ipc_server_connected_get");
517 return EINA_FALSE;
518 }
519 return ecore_con_server_connected_get(svr->server);
520}
521
522/**
523 * Retrieves the list of clients for this server.
524 * @param svr The given IPC server.
525 * @return An Eina_List with the clients.
526 * @ingroup Ecore_IPC_Server_Group
527 */
528EAPI Eina_List *
529ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr)
530{
531 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
532 {
533 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
534 "ecore_ipc_server_clients_get");
535 return NULL;
536 }
537 return svr->client_list;
538}
539
540#define SVENC(_member) \
541 d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \
542 if (md >= DLT_SET) \
543 { \
544 unsigned int v; \
545 unsigned char *dd; \
546 dd = (unsigned char *)&v; \
547 v = d; \
548 v = htonl(v); \
549 *(dat + s + 0) = dd[0]; \
550 *(dat + s + 1) = dd[1]; \
551 *(dat + s + 2) = dd[2]; \
552 *(dat + s + 3) = dd[3]; \
553 s += 4; \
554 } \
555 else if (md >= DLT_ADD16) \
556 { \
557 unsigned short v; \
558 unsigned char *dd; \
559 dd = (unsigned char *)&v; \
560 v = d; \
561 v = htons(v); \
562 *(dat + s + 0) = dd[0]; \
563 *(dat + s + 1) = dd[1]; \
564 s += 2; \
565 } \
566 else if (md >= DLT_ADD8) \
567 { \
568 *(dat + s + 0) = (unsigned char)d; \
569 s += 1; \
570 }
571
572/**
573 * Sends a message to the given IPC server.
574 *
575 * The content of the parameters, excluding the @p svr paramter, is up to
576 * the client.
577 *
578 * @param svr The given IPC server.
579 * @param major Major opcode of the message.
580 * @param minor Minor opcode of the message.
581 * @param ref Message reference number.
582 * @param ref_to Reference number of the message this message refers to.
583 * @param response Requires response.
584 * @param data The data to send as part of the message.
585 * @param size Length of the data, in bytes, to send.
586 * @return Number of bytes sent. @c 0 is returned if there is an error.
587 * @ingroup Ecore_IPC_Server_Group
588 * @todo This function needs to become an IPC message.
589 * @todo Fix up the documentation: Make sure what ref_to and response are.
590 */
591EAPI int
592ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
593{
594 Ecore_Ipc_Msg_Head msg;
595 int ret;
596 int *head, md = 0, d, s;
597 unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
598
599 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
600 {
601 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
602 "ecore_ipc_server_send");
603 return 0;
604 }
605 if (size < 0) size = 0;
606 msg.major = major;
607 msg.minor = minor;
608 msg.ref = ref;
609 msg.ref_to = ref_to;
610 msg.response = response;
611 msg.size = size;
612 head = (int *)dat;
613 s = 4;
614 SVENC(major);
615 *head = md;
616 SVENC(minor);
617 *head |= md << (4 * 1);
618 SVENC(ref);
619 *head |= md << (4 * 2);
620 SVENC(ref_to);
621 *head |= md << (4 * 3);
622 SVENC(response);
623 *head |= md << (4 * 4);
624 SVENC(size);
625 *head |= md << (4 * 5);
626 *head = htonl(*head);
627 svr->prev.o = msg;
628 ret = ecore_con_server_send(svr->server, dat, s);
629 if (size > 0) ret += ecore_con_server_send(svr->server, data, size);
630 return ret;
631}
632
633/**
634 * Sets a limit on the number of clients that can be handled concurrently
635 * by the given server, and a policy on what to do if excess clients try to
636 * connect.
637 * Beware that if you set this once ecore is already running, you may
638 * already have pending CLIENT_ADD events in your event queue. Those
639 * clients have already connected and will not be affected by this call.
640 * Only clients subsequently trying to connect will be affected.
641 * @param svr The given server.
642 * @param client_limit The maximum number of clients to handle
643 * concurrently. -1 means unlimited (default). 0
644 * effectively disables the server.
645 * @param reject_excess_clients Set to 1 to automatically disconnect
646 * excess clients as soon as they connect if you are
647 * already handling client_limit clients. Set to 0
648 * (default) to just hold off on the "accept()"
649 * system call until the number of active clients
650 * drops. This causes the kernel to queue up to 4096
651 * connections (or your kernel's limit, whichever is
652 * lower).
653 * @ingroup Ecore_Ipc_Server_Group
654 */
655EAPI void
656ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients)
657{
658 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
659 {
660 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
661 "ecore_ipc_server_client_limit_set");
662 return;
663 }
664 ecore_con_server_client_limit_set(svr->server, client_limit, reject_excess_clients);
665}
666
667/**
668 * Sets the max data payload size for an Ipc message in bytes
669 *
670 * @param svr The given server.
671 * @param size The maximum data payload size in bytes.
672 * @ingroup Ecore_Ipc_Server_Group
673 */
674EAPI void
675ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *svr, int size)
676{
677 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
678 {
679 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
680 "ecore_ipc_server_data_size_max_set");
681 return;
682 }
683 svr->max_buf_size = size;
684}
685
686/**
687 * Gets the max data payload size for an Ipc message in bytes
688 *
689 * @param svr The given server.
690 * @return The maximum data payload in bytes.
691 * @ingroup Ecore_Ipc_Server_Group
692 */
693EAPI int
694ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *svr)
695{
696 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
697 {
698 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
699 "ecore_ipc_server_data_size_max_get");
700 return -1;
701 }
702 return svr->max_buf_size;
703}
704
705/**
706 * Gets the IP address of a server that has been connected to.
707 *
708 * @param svr The given server.
709 * @return A pointer to an internal string that contains the IP address of
710 * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
711 * This string should not be modified or trusted to stay valid after
712 * deletion for the @p svr object. If no IP is known NULL is returned.
713 * @ingroup Ecore_Ipc_Server_Group
714 */
715EAPI const char *
716ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr)
717{
718 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
719 {
720 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
721 "ecore_ipc_server_ip_get");
722 return NULL;
723 }
724 return ecore_con_server_ip_get(svr->server);
725}
726
727/**
728 * Flushes all pending data to the given server. Will return when done.
729 *
730 * @param svr The given server.
731 * @ingroup Ecore_Ipc_Server_Group
732 */
733EAPI void
734ecore_ipc_server_flush(Ecore_Ipc_Server *svr)
735{
736 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
737 {
738 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
739 "ecore_ipc_server_server_flush");
740 return;
741 }
742 ecore_con_server_flush(svr->server);
743}
744
745#define CLENC(_member) \
746 d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \
747 if (md >= DLT_SET) \
748 { \
749 unsigned int v; \
750 unsigned char *dd; \
751 dd = (unsigned char *)&v; \
752 v = d; \
753 v = htonl(v); \
754 *(dat + s + 0) = dd[0]; \
755 *(dat + s + 1) = dd[1]; \
756 *(dat + s + 2) = dd[2]; \
757 *(dat + s + 3) = dd[3]; \
758 s += 4; \
759 } \
760 else if (md >= DLT_ADD16) \
761 { \
762 unsigned short v; \
763 unsigned char *dd; \
764 dd = (unsigned char *)&v; \
765 v = d; \
766 v = htons(v); \
767 *(dat + s + 0) = dd[0]; \
768 *(dat + s + 1) = dd[1]; \
769 s += 2; \
770 } \
771 else if (md >= DLT_ADD8) \
772 { \
773 *(dat + s) = (unsigned char)d; \
774 s += 1; \
775 }
776
777/**
778 * @defgroup Ecore_IPC_Client_Group IPC Client Functions
779 *
780 * Functions that deal with IPC client objects.
781 */
782
783/**
784 * Sends a message to the given IPC client.
785 * @param cl The given IPC client.
786 * @param major Major opcode of the message.
787 * @param minor Minor opcode of the message.
788 * @param ref Reference number of the message.
789 * @param ref_to Reference number of the message this message refers to.
790 * @param response Requires response.
791 * @param data The data to send as part of the message.
792 * @param size Length of the data, in bytes, to send.
793 * @return The number of bytes sent. @c 0 will be returned if there is
794 * an error.
795 * @ingroup Ecore_IPC_Client_Group
796 * @todo This function needs to become an IPC message.
797 * @todo Make sure ref_to and response parameters are described correctly.
798 */
799EAPI int
800ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
801{
802 Ecore_Ipc_Msg_Head msg;
803 int ret;
804 int *head, md = 0, d, s;
805 unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
806
807 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
808 {
809 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
810 "ecore_ipc_client_send");
811 return 0;
812 }
813 if (size < 0) size = 0;
814 msg.major = major;
815 msg.minor = minor;
816 msg.ref = ref;
817 msg.ref_to = ref_to;
818 msg.response = response;
819 msg.size = size;
820 head = (int *)dat;
821 s = 4;
822 CLENC(major);
823 *head = md;
824 CLENC(minor);
825 *head |= md << (4 * 1);
826 CLENC(ref);
827 *head |= md << (4 * 2);
828 CLENC(ref_to);
829 *head |= md << (4 * 3);
830 CLENC(response);
831 *head |= md << (4 * 4);
832 CLENC(size);
833 *head |= md << (4 * 5);
834 *head = htonl(*head);
835 cl->prev.o = msg;
836 ret = ecore_con_client_send(cl->client, dat, s);
837 if (size > 0) ret += ecore_con_client_send(cl->client, data, size);
838 return ret;
839}
840
841/**
842 * Retrieves the IPC server that the given IPC client is connected to.
843 * @param cl The given IPC client.
844 * @return The IPC server the IPC client is connected to.
845 * @ingroup Ecore_IPC_Client_Group
846 */
847EAPI Ecore_Ipc_Server *
848ecore_ipc_client_server_get(Ecore_Ipc_Client *cl)
849{
850 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
851 {
852 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
853 "ecore_ipc_client_server_get");
854 return NULL;
855 }
856 return (ecore_con_server_data_get(ecore_con_client_server_get(cl->client)));
857}
858
859/**
860 * Closes the connection and frees memory allocated to the given IPC
861 * client.
862 * @param cl The given client.
863 * @return Data associated with the client.
864 * @ingroup Ecore_IPC_Client_Group
865 */
866EAPI void *
867ecore_ipc_client_del(Ecore_Ipc_Client *cl)
868{
869 void *data;
870 Ecore_Ipc_Server *svr;
871
872 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
873 {
874 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
875 "ecore_ipc_client_del");
876 return NULL;
877 }
878 data = cl->data;
879 cl->data = NULL;
880 cl->delete_me = 1;
881 if (cl->event_count == 0)
882 {
883 svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
884 ecore_con_client_del(cl->client);
885 svr->clients = eina_list_remove(svr->clients, cl);
886 if (cl->buf) free(cl->buf);
887 ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
888 free(cl);
889 }
890 return data;
891}
892
893/**
894 * Sets the IPC data associated with the given IPC client to @p data.
895 * @param cl The given IPC client.
896 * @param data The data to associate with the IPC client.
897 * @ingroup Ecore_IPC_Client_Group
898 */
899EAPI void
900ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data)
901{
902 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
903 {
904 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
905 "ecore_ipc_client_data_set");
906 return;
907 }
908 cl->data = (void *)data;
909}
910
911/**
912 * Retrieves the data that has been associated with the given IPC client.
913 * @param cl The given client.
914 * @return The data associated with the IPC client.
915 * @ingroup Ecore_IPC_Client_Group
916 */
917EAPI void *
918ecore_ipc_client_data_get(Ecore_Ipc_Client *cl)
919{
920 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
921 {
922 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
923 "ecore_ipc_client_data_get");
924 return NULL;
925 }
926 return cl->data;
927}
928
929/**
930 * Sets the max data payload size for an Ipc message in bytes
931 *
932 * @param cl The given client.
933 * @param size The maximum data payload size in bytes.
934 * @ingroup Ecore_Ipc_Client_Group
935 */
936EAPI void
937ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client *cl, int size)
938{
939 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
940 {
941 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
942 "ecore_ipc_client_data_size_max_set");
943 return;
944 }
945 cl->max_buf_size = size;
946}
947
948/**
949 * Sets the max data payload size for an Ipc message in bytes
950 *
951 * @param cl The given client.
952 * @ingroup Ecore_Ipc_Client_Group
953 */
954EAPI int
955ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client *cl)
956{
957 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
958 {
959 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
960 "ecore_ipc_client_data_size_max_get");
961 return -1;
962 }
963 return cl->max_buf_size;
964}
965
966/**
967 * Gets the IP address of a client that has been connected to.
968 *
969 * @param cl The given client.
970 * @return A pointer to an internal string that contains the IP address of
971 * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
972 * This string should not be modified or trusted to stay valid after
973 * deletion for the @p cl object. If no IP is known NULL is returned.
974 * @ingroup Ecore_Ipc_Client_Group
975 */
976EAPI const char *
977ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl)
978{
979 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
980 {
981 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
982 "ecore_ipc_client_ip_get");
983 return NULL;
984 }
985 return ecore_con_client_ip_get(cl->client);
986}
987
988/**
989 * Flushes all pending data to the given client. Will return when done.
990 *
991 * @param cl The given client.
992 * @ingroup Ecore_Ipc_Client_Group
993 */
994EAPI void
995ecore_ipc_client_flush(Ecore_Ipc_Client *cl)
996{
997 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
998 {
999 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1000 "ecore_ipc_client_flush");
1001 return;
1002 }
1003 ecore_con_client_flush(cl->client);
1004}
1005
1006/**
1007 * Returns if SSL support is available
1008 * @return 1 if SSL is available, 0 if it is not.
1009 * @ingroup Ecore_Con_Client_Group
1010 */
1011EAPI int
1012ecore_ipc_ssl_available_get(void)
1013{
1014 return ecore_con_ssl_available_get();
1015}
1016
1017
1018static Eina_Bool
1019_ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1020{
1021 Ecore_Con_Event_Client_Add *e;
1022
1023 e = ev;
1024 if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return ECORE_CALLBACK_RENEW;
1025 /* handling code here */
1026 {
1027 Ecore_Ipc_Client *cl;
1028 Ecore_Ipc_Server *svr;
1029
1030 cl = calloc(1, sizeof(Ecore_Ipc_Client));
1031 if (!cl) return ECORE_CALLBACK_CANCEL;
1032 svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
1033 ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
1034 cl->client = e->client;
1035 cl->max_buf_size = 32 * 1024;
1036 ecore_con_client_data_set(cl->client, (void *)cl);
1037 svr->clients = eina_list_append(svr->clients, cl);
1038 svr->client_list = eina_list_append(svr->client_list, cl);
1039 if (!cl->delete_me)
1040 {
1041 Ecore_Ipc_Event_Client_Add *e2;
1042
1043 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add));
1044 if (e2)
1045 {
1046 cl->event_count++;
1047 e2->client = cl;
1048 ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, e2,
1049 _ecore_ipc_event_client_add_free, NULL);
1050 }
1051 }
1052 }
1053 return ECORE_CALLBACK_CANCEL;
1054}
1055
1056static Eina_Bool
1057_ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1058{
1059 Ecore_Con_Event_Client_Del *e;
1060
1061 e = ev;
1062 if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return ECORE_CALLBACK_RENEW;
1063 /* handling code here */
1064 {
1065 Ecore_Ipc_Client *cl;
1066
1067 cl = ecore_con_client_data_get(e->client);
1068 {
1069 Ecore_Ipc_Event_Client_Del *e2;
1070 Ecore_Ipc_Server *svr;
1071
1072 svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
1073 svr->client_list = eina_list_remove(svr->client_list, cl);
1074 if (!cl->delete_me)
1075 {
1076 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del));
1077 if (e2)
1078 {
1079 cl->event_count++;
1080 e2->client = cl;
1081 ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, e2,
1082 _ecore_ipc_event_client_del_free, NULL);
1083 }
1084 }
1085 }
1086 }
1087 return ECORE_CALLBACK_CANCEL;
1088}
1089
1090static Eina_Bool
1091_ecore_ipc_event_server_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1092{
1093 Ecore_Con_Event_Server_Add *e;
1094
1095 e = ev;
1096 if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return ECORE_CALLBACK_RENEW;
1097 /* handling code here */
1098 {
1099 Ecore_Ipc_Server *svr;
1100
1101 svr = ecore_con_server_data_get(e->server);
1102 if (!svr->delete_me)
1103 {
1104 Ecore_Ipc_Event_Server_Add *e2;
1105
1106 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add));
1107 if (e2)
1108 {
1109 svr->event_count++;
1110 e2->server = svr;
1111 ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, e2,
1112 _ecore_ipc_event_server_add_free, NULL);
1113 }
1114 }
1115 }
1116 return ECORE_CALLBACK_CANCEL;
1117}
1118
1119static Eina_Bool
1120_ecore_ipc_event_server_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1121{
1122 Ecore_Con_Event_Server_Del *e;
1123
1124 e = ev;
1125 if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return ECORE_CALLBACK_RENEW;
1126 /* handling code here */
1127 {
1128 Ecore_Ipc_Server *svr;
1129
1130 svr = ecore_con_server_data_get(e->server);
1131 if (!svr->delete_me)
1132 {
1133 Ecore_Ipc_Event_Server_Del *e2;
1134
1135 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del));
1136 if (e2)
1137 {
1138 svr->event_count++;
1139 e2->server = svr;
1140 ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, e2,
1141 _ecore_ipc_event_server_del_free, NULL);
1142 }
1143 }
1144 }
1145 return ECORE_CALLBACK_CANCEL;
1146}
1147
1148#define CLSZ(_n) \
1149 md = ((head >> (4 * _n)) & 0xf); \
1150 if (md >= DLT_SET) s += 4; \
1151 else if (md >= DLT_ADD16) s += 2; \
1152 else if (md >= DLT_ADD8) s += 1;
1153
1154#define CLDEC(_n, _member) \
1155 md = ((head >> (4 * _n)) & 0xf); \
1156 if (md >= DLT_SET) \
1157 { \
1158 unsigned int v; \
1159 unsigned char *dv; \
1160 dv = (unsigned char *)&v; \
1161 dv[0] = *(cl->buf + offset + s + 0); \
1162 dv[1] = *(cl->buf + offset + s + 1); \
1163 dv[2] = *(cl->buf + offset + s + 2); \
1164 dv[3] = *(cl->buf + offset + s + 3); \
1165 d = (int)ntohl(v); \
1166 s += 4; \
1167 } \
1168 else if (md >= DLT_ADD16) \
1169 { \
1170 unsigned short v; \
1171 unsigned char *dv; \
1172 dv = (unsigned char *)&v; \
1173 dv[0] = *(cl->buf + offset + s + 0); \
1174 dv[1] = *(cl->buf + offset + s + 1); \
1175 d = (int)ntohs(v); \
1176 s += 2; \
1177 } \
1178 else if (md >= DLT_ADD8) \
1179 { \
1180 unsigned char v; \
1181 unsigned char *dv; \
1182 dv = (unsigned char *)&v; \
1183 dv[0] = *(cl->buf + offset + s + 0); \
1184 d = (int)v; \
1185 s += 1; \
1186 } \
1187 msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md);
1188
1189static Eina_Bool
1190_ecore_ipc_event_client_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1191{
1192 Ecore_Con_Event_Client_Data *e;
1193
1194 e = ev;
1195 if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return ECORE_CALLBACK_RENEW;
1196 /* handling code here */
1197 {
1198 Ecore_Ipc_Client *cl;
1199 Ecore_Ipc_Msg_Head msg;
1200 int offset = 0;
1201 unsigned char *buf;
1202
1203 cl = ecore_con_client_data_get(e->client);
1204
1205 if (!cl->buf)
1206 {
1207 cl->buf_size = e->size;
1208 cl->buf = e->data;
1209 e->data = NULL; /* take it out of the old event */
1210 }
1211 else
1212 {
1213 buf = realloc(cl->buf, cl->buf_size + e->size);
1214 if (!buf)
1215 {
1216 free(cl->buf);
1217 cl->buf = 0;
1218 cl->buf_size = 0;
1219 return ECORE_CALLBACK_CANCEL;
1220 }
1221 cl->buf = buf;
1222 memcpy(cl->buf + cl->buf_size, e->data, e->size);
1223 cl->buf_size += e->size;
1224 }
1225 /* examine header */
1226 redo:
1227 if ((cl->buf_size - offset) >= (int)sizeof(int))
1228 {
1229 int s, md, d = 0, head;
1230 unsigned char *dd;
1231
1232 dd = (unsigned char *)&head;
1233 dd[0] = *(cl->buf + offset + 0);
1234 dd[1] = *(cl->buf + offset + 1);
1235 dd[2] = *(cl->buf + offset + 2);
1236 dd[3] = *(cl->buf + offset + 3);
1237 head = ntohl(head);
1238 dd = (unsigned char *)&d;
1239 s = 4;
1240 CLSZ(0);
1241 CLSZ(1);
1242 CLSZ(2);
1243 CLSZ(3);
1244 CLSZ(4);
1245 CLSZ(5);
1246 if ((cl->buf_size - offset) < s)
1247 {
1248 if (offset > 0) goto scroll;
1249 return ECORE_CALLBACK_CANCEL;
1250 }
1251
1252 s = 4;
1253 CLDEC(0, major);
1254 CLDEC(1, minor);
1255 CLDEC(2, ref);
1256 CLDEC(3, ref_to);
1257 CLDEC(4, response);
1258 CLDEC(5, size);
1259 if (msg.size < 0) msg.size = 0;
1260 /* there is enough data in the buffer for a full message */
1261 if ((cl->buf_size - offset) >= (s + msg.size))
1262 {
1263 Ecore_Ipc_Event_Client_Data *e2;
1264 Ecore_Ipc_Server *svr;
1265 int max, max2;
1266
1267 buf = NULL;
1268 svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
1269 max = svr->max_buf_size;
1270 max2 = cl->max_buf_size;
1271 if ((max >= 0) && (max2 >= 0))
1272 {
1273 if (max2 < max) max = max2;
1274 }
1275 else
1276 {
1277 if (max < 0) max = max2;
1278 }
1279 if ((max < 0) || (msg.size <= max))
1280 {
1281 if (msg.size > 0)
1282 {
1283 buf = malloc(msg.size);
1284 if (!buf) return ECORE_CALLBACK_CANCEL;
1285 memcpy(buf, cl->buf + offset + s, msg.size);
1286 }
1287 if (!cl->delete_me)
1288 {
1289 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data));
1290 if (e2)
1291 {
1292 cl->event_count++;
1293 e2->client = cl;
1294 e2->major = msg.major;
1295 e2->minor = msg.minor;
1296 e2->ref = msg.ref;
1297 e2->ref_to = msg.ref_to;
1298 e2->response = msg.response;
1299 e2->size = msg.size;
1300 e2->data = buf;
1301 ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2,
1302 _ecore_ipc_event_client_data_free,
1303 NULL);
1304 }
1305 }
1306 }
1307 cl->prev.i = msg;
1308 offset += (s + msg.size);
1309 if (cl->buf_size == offset)
1310 {
1311 free(cl->buf);
1312 cl->buf = NULL;
1313 cl->buf_size = 0;
1314 return ECORE_CALLBACK_CANCEL;
1315 }
1316 goto redo;
1317 }
1318 else goto scroll;
1319 }
1320 else
1321 {
1322 scroll:
1323 buf = malloc(cl->buf_size - offset);
1324 if (!buf)
1325 {
1326 free(cl->buf);
1327 cl->buf = NULL;
1328 cl->buf_size = 0;
1329 return ECORE_CALLBACK_CANCEL;
1330 }
1331 memcpy(buf, cl->buf + offset, cl->buf_size - offset);
1332 free(cl->buf);
1333 cl->buf = buf;
1334 cl->buf_size -= offset;
1335 }
1336 }
1337 return ECORE_CALLBACK_CANCEL;
1338}
1339
1340#define SVSZ(_n) \
1341 md = ((head >> (4 * _n)) & 0xf); \
1342 if (md >= DLT_SET) s += 4; \
1343 else if (md >= DLT_ADD16) s += 2; \
1344 else if (md >= DLT_ADD8) s += 1;
1345
1346#define SVDEC(_n, _member) \
1347 md = ((head >> (4 * _n)) & 0xf); \
1348 if (md >= DLT_SET) \
1349 { \
1350 unsigned int v; \
1351 unsigned char *dv; \
1352 dv = (unsigned char *)&v; \
1353 dv[0] = *(svr->buf + offset + s + 0); \
1354 dv[1] = *(svr->buf + offset + s + 1); \
1355 dv[2] = *(svr->buf + offset + s + 2); \
1356 dv[3] = *(svr->buf + offset + s + 3); \
1357 d = (int)ntohl(v); \
1358 s += 4; \
1359 } \
1360 else if (md >= DLT_ADD16) \
1361 { \
1362 unsigned short v; \
1363 unsigned char *dv; \
1364 dv = (unsigned char *)&v; \
1365 dv[0] = *(svr->buf + offset + s + 0); \
1366 dv[1] = *(svr->buf + offset + s + 1); \
1367 d = (int)ntohs(v); \
1368 s += 2; \
1369 } \
1370 else if (md >= DLT_ADD8) \
1371 { \
1372 unsigned char v; \
1373 unsigned char *dv; \
1374 dv = (unsigned char *)&v; \
1375 dv[0] = *(svr->buf + offset + s + 0); \
1376 d = (int)v; \
1377 s += 1; \
1378 } \
1379 msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md);
1380
1381static Eina_Bool
1382_ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1383{
1384 Ecore_Con_Event_Server_Data *e;
1385
1386 e = ev;
1387 if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return ECORE_CALLBACK_RENEW;
1388 /* handling code here */
1389 {
1390 Ecore_Ipc_Server *svr;
1391 Ecore_Ipc_Msg_Head msg;
1392 int offset = 0;
1393 unsigned char *buf;
1394
1395 svr = ecore_con_server_data_get(e->server);
1396
1397 if (!svr->buf)
1398 {
1399 svr->buf_size = e->size;
1400 svr->buf = e->data;
1401 e->data = NULL; /* take it out of the old event */
1402 }
1403 else
1404 {
1405 buf = realloc(svr->buf, svr->buf_size + e->size);
1406 if (!buf)
1407 {
1408 free(svr->buf);
1409 svr->buf = 0;
1410 svr->buf_size = 0;
1411 return ECORE_CALLBACK_CANCEL;
1412 }
1413 svr->buf = buf;
1414 memcpy(svr->buf + svr->buf_size, e->data, e->size);
1415 svr->buf_size += e->size;
1416 }
1417 /* examine header */
1418 redo:
1419 if ((svr->buf_size - offset) >= (int)sizeof(int))
1420 {
1421 int s, md, d = 0, head;
1422 unsigned char *dd;
1423
1424 dd = (unsigned char *)&head;
1425 dd[0] = *(svr->buf + offset + 0);
1426 dd[1] = *(svr->buf + offset + 1);
1427 dd[2] = *(svr->buf + offset + 2);
1428 dd[3] = *(svr->buf + offset + 3);
1429 head = ntohl(head);
1430 dd = (unsigned char *)&d;
1431 s = 4;
1432 SVSZ(0);
1433 SVSZ(1);
1434 SVSZ(2);
1435 SVSZ(3);
1436 SVSZ(4);
1437 SVSZ(5);
1438 if ((svr->buf_size - offset) < s)
1439 {
1440 if (offset > 0) goto scroll;
1441 return ECORE_CALLBACK_CANCEL;
1442 }
1443
1444 s = 4;
1445 SVDEC(0, major);
1446 SVDEC(1, minor);
1447 SVDEC(2, ref);
1448 SVDEC(3, ref_to);
1449 SVDEC(4, response);
1450 SVDEC(5, size);
1451 if (msg.size < 0) msg.size = 0;
1452 /* there is enough data in the buffer for a full message */
1453 if ((svr->buf_size - offset) >= (s + msg.size))
1454 {
1455 Ecore_Ipc_Event_Server_Data *e2;
1456 int max;
1457
1458 buf = NULL;
1459 max = svr->max_buf_size;
1460 if ((max < 0) || (msg.size <= max))
1461 {
1462 if (msg.size > 0)
1463 {
1464 buf = malloc(msg.size);
1465 if (!buf) return ECORE_CALLBACK_CANCEL;
1466 memcpy(buf, svr->buf + offset + s, msg.size);
1467 }
1468 if (!svr->delete_me)
1469 {
1470 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data));
1471 if (e2)
1472 {
1473 svr->event_count++;
1474 e2->server = svr;
1475 e2->major = msg.major;
1476 e2->minor = msg.minor;
1477 e2->ref = msg.ref;
1478 e2->ref_to = msg.ref_to;
1479 e2->response = msg.response;
1480 e2->size = msg.size;
1481 e2->data = buf;
1482 ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2,
1483 _ecore_ipc_event_server_data_free,
1484 NULL);
1485 }
1486 }
1487 }
1488 svr->prev.i = msg;
1489 offset += (s + msg.size);
1490 if (svr->buf_size == offset)
1491 {
1492 free(svr->buf);
1493 svr->buf = NULL;
1494 svr->buf_size = 0;
1495 return ECORE_CALLBACK_CANCEL;
1496 }
1497 goto redo;
1498 }
1499 else goto scroll;
1500 }
1501 else
1502 {
1503 scroll:
1504 buf = malloc(svr->buf_size - offset);
1505 if (!buf)
1506 {
1507 free(svr->buf);
1508 svr->buf = NULL;
1509 svr->buf_size = 0;
1510 return ECORE_CALLBACK_CANCEL;
1511 }
1512 memcpy(buf, svr->buf + offset, svr->buf_size - offset);
1513 free(svr->buf);
1514 svr->buf = buf;
1515 svr->buf_size -= offset;
1516 }
1517 }
1518 return ECORE_CALLBACK_CANCEL;
1519}
1520
1521static void
1522_ecore_ipc_event_client_add_free(void *data __UNUSED__, void *ev)
1523{
1524 Ecore_Ipc_Event_Client_Add *e;
1525
1526 e = ev;
1527 e->client->event_count--;
1528 if ((e->client->event_count == 0) && (e->client->delete_me))
1529 ecore_ipc_client_del(e->client);
1530 free(e);
1531}
1532
1533static void
1534_ecore_ipc_event_client_del_free(void *data __UNUSED__, void *ev)
1535{
1536 Ecore_Ipc_Event_Client_Del *e;
1537
1538 e = ev;
1539 e->client->event_count--;
1540 if ((e->client->event_count == 0) && (e->client->delete_me))
1541 ecore_ipc_client_del(e->client);
1542 free(e);
1543}
1544
1545static void
1546_ecore_ipc_event_client_data_free(void *data __UNUSED__, void *ev)
1547{
1548 Ecore_Ipc_Event_Client_Data *e;
1549
1550 e = ev;
1551 e->client->event_count--;
1552 if (e->data) free(e->data);
1553 if ((e->client->event_count == 0) && (e->client->delete_me))
1554 ecore_ipc_client_del(e->client);
1555 free(e);
1556}
1557
1558static void
1559_ecore_ipc_event_server_add_free(void *data __UNUSED__, void *ev)
1560{
1561 Ecore_Ipc_Event_Server_Add *e;
1562
1563 e = ev;
1564 e->server->event_count--;
1565 if ((e->server->event_count == 0) && (e->server->delete_me))
1566 ecore_ipc_server_del(e->server);
1567 free(e);
1568}
1569
1570static void
1571_ecore_ipc_event_server_del_free(void *data __UNUSED__, void *ev)
1572{
1573 Ecore_Ipc_Event_Server_Add *e;
1574
1575 e = ev;
1576 e->server->event_count--;
1577 if ((e->server->event_count == 0) && (e->server->delete_me))
1578 ecore_ipc_server_del(e->server);
1579 free(e);
1580}
1581
1582static void
1583_ecore_ipc_event_server_data_free(void *data __UNUSED__, void *ev)
1584{
1585 Ecore_Ipc_Event_Server_Data *e;
1586
1587 e = ev;
1588 if (e->data) free(e->data);
1589 e->server->event_count--;
1590 if ((e->server->event_count == 0) && (e->server->delete_me))
1591 ecore_ipc_server_del(e->server);
1592 free(e);
1593}