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