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