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