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