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