1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 
9 #ifdef HAVE_ARPA_INET_H
10 # include <arpa/inet.h>
11 #endif
12 
13 #include <Ecore.h>
14 #include <ecore_private.h>
15 #include <Ecore_Con.h>
16 
17 #include "Ecore_Ipc.h"
18 #include "ecore_ipc_private.h"
19 
20 #define DLT_ZERO   0
21 #define DLT_ONE    1
22 #define DLT_SAME   2
23 #define DLT_SHL    3
24 #define DLT_SHR    4
25 #define DLT_ADD8   5
26 #define DLT_DEL8   6
27 #define DLT_ADDU8  7
28 #define DLT_DELU8  8
29 #define DLT_ADD16  9
30 #define DLT_DEL16  10
31 #define DLT_ADDU16 11
32 #define DLT_DELU16 12
33 #define DLT_SET    13
34 #define DLT_R1     14
35 #define DLT_R2     15
36 
37 static int _ecore_ipc_log_dom = -1;
38 
39 /****** This swap function are around just for backward compatibility do not remove *******/
40 EAPI unsigned short
_ecore_ipc_swap_16(unsigned short v)41 _ecore_ipc_swap_16(unsigned short v)
42 {
43    return eina_swap16(v);
44 }
45 
46 EAPI unsigned int
_ecore_ipc_swap_32(unsigned int v)47 _ecore_ipc_swap_32(unsigned int v)
48 {
49    return eina_swap32(v);
50 }
51 
52 EAPI unsigned long long
_ecore_ipc_swap_64(unsigned long long v)53 _ecore_ipc_swap_64(unsigned long long v)
54 {
55    return eina_swap64(v);
56 }
57 /***********************/
58 
59 static int _ecore_ipc_dlt_int(int out, int prev, int *mode);
60 static int _ecore_ipc_ddlt_int(int in, int prev, int mode);
61 
62 static int
_ecore_ipc_dlt_int(int out,int prev,int * mode)63 _ecore_ipc_dlt_int(int out, int prev, int *mode)
64 {
65    int dlt;
66 
67    /* 0 byte */
68    if (out == 0)
69      {
70         *mode = DLT_ZERO;
71         return 0;
72      }
73    if (out == (int)0xffffffff)
74      {
75         *mode = DLT_ONE;
76         return 0;
77      }
78    if (out == prev)
79      {
80         *mode = DLT_SAME;
81         return 0;
82      }
83    if (out == prev << 1)
84      {
85         *mode = DLT_SHL;
86         return 0;
87      }
88    if (out == prev >> 1)
89      {
90         *mode = DLT_SHR;
91         return 0;
92      }
93    /* 1 byte */
94    dlt = out - prev;
95    if (!(dlt & 0xffffff00))
96      {
97         *mode = DLT_ADD8;
98         return dlt & 0xff;
99      }
100    dlt = prev - out;
101    if (!(dlt & 0xffffff00))
102      {
103         *mode = DLT_DEL8;
104         return dlt & 0xff;
105      }
106    dlt = out - prev;
107    if (!(dlt & 0x00ffffff))
108      {
109         *mode = DLT_ADDU8;
110         return (dlt >> 24) & 0xff;
111      }
112    dlt = prev - out;
113    if (!(dlt & 0x00ffffff))
114      {
115         *mode = DLT_DELU8;
116         return (dlt >> 24) & 0xff;
117      }
118    /* 2 byte */
119    dlt = out - prev;
120    if (!(dlt & 0xffff0000))
121      {
122         *mode = DLT_ADD16;
123         return dlt & 0xffff;
124      }
125    dlt = prev - out;
126    if (!(dlt & 0xffff0000))
127      {
128         *mode = DLT_DEL16;
129         return dlt & 0xffff;
130      }
131    dlt = out - prev;
132    if (!(dlt & 0x0000ffff))
133      {
134         *mode = DLT_ADDU16;
135         return (dlt >> 16) & 0xffff;
136      }
137    dlt = prev - out;
138    if (!(dlt & 0x0000ffff))
139      {
140         *mode = DLT_DELU16;
141         return (dlt >> 16) & 0xffff;
142      }
143    /* 4 byte */
144    *mode = DLT_SET;
145    return out;
146 }
147 
148 static int
_ecore_ipc_ddlt_int(int in,int prev,int mode)149 _ecore_ipc_ddlt_int(int in, int prev, int mode)
150 {
151    switch (mode)
152      {
153       case DLT_ZERO:
154         return 0;
155         break;
156       case DLT_ONE:
157         return 0xffffffff;
158         break;
159       case DLT_SAME:
160         return prev;
161         break;
162       case DLT_SHL:
163         return prev << 1;
164         break;
165       case DLT_SHR:
166         return prev >> 1;
167         break;
168       case DLT_ADD8:
169         return prev + in;
170         break;
171       case DLT_DEL8:
172         return prev - in;
173         break;
174       case DLT_ADDU8:
175         return prev + (in << 24);
176         break;
177       case DLT_DELU8:
178         return prev - (in << 24);
179         break;
180       case DLT_ADD16:
181         return prev + in;
182         break;
183       case DLT_DEL16:
184         return prev - in;
185         break;
186       case DLT_ADDU16:
187         return prev + (in << 16);
188         break;
189       case DLT_DELU16:
190         return prev - (in << 16);
191         break;
192       case DLT_SET:
193         return in;
194         break;
195       case DLT_R1:
196         return 0;
197         break;
198       case DLT_R2:
199         return 0;
200         break;
201       default:
202         break;
203      }
204    return 0;
205 }
206 
207 /* EFL_NET_SERVER_UNIX_CLASS and EFL_NET_DIALER_UNIX_CLASS should be defined at the same time, we're only checking for EFL_NET_SERVER_UNIX_CLASS in shared blocks */
208 
209 static void _ecore_ipc_event_client_add_free(void *data, void *ev);
210 static void _ecore_ipc_event_client_del_free(void *data, void *ev);
211 static void _ecore_ipc_event_client_data_free(void *data, void *ev);
212 static void _ecore_ipc_event_server_add_free(void *data, void *ev);
213 static void _ecore_ipc_event_server_del_free(void *data, void *ev);
214 static void _ecore_ipc_event_server_data_free(void *data, void *ev);
215 
216 EAPI int ECORE_IPC_EVENT_CLIENT_ADD = 0;
217 EAPI int ECORE_IPC_EVENT_CLIENT_DEL = 0;
218 EAPI int ECORE_IPC_EVENT_SERVER_ADD = 0;
219 EAPI int ECORE_IPC_EVENT_SERVER_DEL = 0;
220 EAPI int ECORE_IPC_EVENT_CLIENT_DATA = 0;
221 EAPI int ECORE_IPC_EVENT_SERVER_DATA = 0;
222 
223 static int                  _ecore_ipc_init_count = 0;
224 static Eina_List           *servers = NULL;
225 
226 static void
ecore_ipc_post_event_server_add(Ecore_Ipc_Server * svr)227 ecore_ipc_post_event_server_add(Ecore_Ipc_Server *svr)
228 {
229    Ecore_Ipc_Event_Server_Add *ev;
230 
231    if (svr->delete_me) return;
232 
233    ev = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add));
234    EINA_SAFETY_ON_NULL_RETURN(ev);
235 
236    svr->event_count++;
237    ev->server = svr;
238    ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, ev,
239                    _ecore_ipc_event_server_add_free, NULL);
240 }
241 
242 static void
ecore_ipc_post_event_server_del(Ecore_Ipc_Server * svr)243 ecore_ipc_post_event_server_del(Ecore_Ipc_Server *svr)
244 {
245    Ecore_Ipc_Event_Server_Del *ev;
246 
247    if (svr->delete_me) return;
248 
249    ev = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del));
250    EINA_SAFETY_ON_NULL_RETURN(ev);
251 
252    svr->event_count++;
253    ev->server = svr;
254    ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, ev,
255                    _ecore_ipc_event_server_del_free, NULL);
256 }
257 
258 static void
ecore_ipc_post_event_client_add(Ecore_Ipc_Client * cl)259 ecore_ipc_post_event_client_add(Ecore_Ipc_Client *cl)
260 {
261    Ecore_Ipc_Event_Client_Add *ev;
262 
263    if (cl->delete_me) return;
264 
265    ev = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add));
266    EINA_SAFETY_ON_NULL_RETURN(ev);
267 
268    cl->event_count++;
269    ev->client = cl;
270    ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, ev,
271                    _ecore_ipc_event_client_add_free, NULL);
272 }
273 
274 static void
ecore_ipc_post_event_client_del(Ecore_Ipc_Client * cl)275 ecore_ipc_post_event_client_del(Ecore_Ipc_Client *cl)
276 {
277    Ecore_Ipc_Event_Client_Del *ev;
278 
279    if (cl->delete_me) return;
280 
281    cl->delete_me = EINA_TRUE;
282 
283    ev = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del));
284    EINA_SAFETY_ON_NULL_RETURN(ev);
285 
286    cl->event_count++;
287    ev->client = cl;
288    ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, ev,
289                    _ecore_ipc_event_client_del_free, NULL);
290 }
291 
292 static Ecore_Ipc_Client *
ecore_ipc_client_add(Ecore_Ipc_Server * svr)293 ecore_ipc_client_add(Ecore_Ipc_Server *svr)
294 {
295    Ecore_Ipc_Client *cl;
296 
297    cl = calloc(1, sizeof(Ecore_Ipc_Client));
298    EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
299    cl->svr = svr;
300    cl->max_buf_size = 32 * 1024;
301 
302    ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
303    svr->clients = eina_list_append(svr->clients, cl);
304 
305    return cl;
306 }
307 
308 EAPI int
ecore_ipc_init(void)309 ecore_ipc_init(void)
310 {
311    if (++_ecore_ipc_init_count != 1)
312      return _ecore_ipc_init_count;
313 
314    _ecore_ipc_log_dom = eina_log_domain_register
315          ("ecore_ipc", ECORE_IPC_DEFAULT_LOG_COLOR);
316    if(_ecore_ipc_log_dom < 0)
317      {
318         EINA_LOG_ERR("Impossible to create a log domain for the Ecore IPC module.");
319         return --_ecore_ipc_init_count;
320      }
321 
322    if (!ecore_con_init())
323      {
324         eina_log_domain_unregister(_ecore_ipc_log_dom);
325         _ecore_ipc_log_dom = -1;
326         return --_ecore_ipc_init_count;
327      }
328 
329    ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new();
330    ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new();
331    ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new();
332    ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new();
333    ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new();
334    ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new();
335 
336    return _ecore_ipc_init_count;
337 }
338 
339 EAPI int
ecore_ipc_shutdown(void)340 ecore_ipc_shutdown(void)
341 {
342    if (--_ecore_ipc_init_count != 0)
343      return _ecore_ipc_init_count;
344 
345    Eina_List *l, *l2;
346    Ecore_Ipc_Server *svr;
347    EINA_LIST_FOREACH_SAFE(servers, l, l2, svr)
348      ecore_ipc_server_del(svr);
349 
350    ecore_event_type_flush(ECORE_IPC_EVENT_CLIENT_ADD,
351                           ECORE_IPC_EVENT_CLIENT_DEL,
352                           ECORE_IPC_EVENT_SERVER_ADD,
353                           ECORE_IPC_EVENT_SERVER_DEL,
354                           ECORE_IPC_EVENT_CLIENT_DATA,
355                           ECORE_IPC_EVENT_SERVER_DATA);
356 
357    ecore_con_shutdown();
358 
359    eina_log_domain_unregister(_ecore_ipc_log_dom);
360    _ecore_ipc_log_dom = -1;
361 
362    return _ecore_ipc_init_count;
363 }
364 
365 static void
_ecore_ipc_server_del(Ecore_Ipc_Server * svr)366 _ecore_ipc_server_del(Ecore_Ipc_Server *svr)
367 {
368    DBG("server %p del", svr);
369 
370    if (svr->server)
371      {
372         efl_del(svr->server);
373         svr->server = NULL;
374      }
375 }
376 
377 static void _ecore_ipc_server_client_add(void *data, const Efl_Event *event);
378 
379 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_server_cbs,
380                            { EFL_NET_SERVER_EVENT_CLIENT_ADD, _ecore_ipc_server_client_add });
381 
382 /* FIXME: need to add protocol type parameter */
383 EAPI Ecore_Ipc_Server *
ecore_ipc_server_add(Ecore_Ipc_Type type,const char * name,int port,const void * data)384 ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data)
385 {
386    Ecore_Ipc_Server *svr;
387    Eo *loop = efl_main_loop_get();
388    char *address = NULL;
389    Eina_Error err;
390 #ifdef EFL_NET_SERVER_UNIX_CLASS
391    Eina_Bool local_system = EINA_FALSE;
392    mode_t old_mask = 0, new_mask = 0;
393 #endif
394 
395    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
396 
397    svr = calloc(1, sizeof(Ecore_Ipc_Server));
398    EINA_SAFETY_ON_NULL_RETURN_VAL(svr, NULL);
399 
400    if (0) { }
401 #ifdef EFL_NET_SERVER_UNIX_CLASS
402    if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER)
403      {
404         address = ecore_con_local_path_new(EINA_FALSE, name, port);
405         EINA_SAFETY_ON_NULL_GOTO(address, error_server);
406 
407         new_mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
408 
409         svr->server = efl_add(EFL_NET_SERVER_UNIX_CLASS, efl_main_loop_get(),
410                               efl_net_server_unix_leading_directories_create_set(efl_added, EINA_TRUE, S_IRUSR | S_IWUSR | S_IXUSR));
411         EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
412      }
413    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)
414      {
415         address = ecore_con_local_path_new(EINA_TRUE, name, port);
416         EINA_SAFETY_ON_NULL_GOTO(address, error_server);
417 
418         /* ecore_con didn't create leading directories for LOCAL_SYSTEM */
419 
420         new_mask = 0;
421         local_system = EINA_TRUE;
422 
423         svr->server = efl_add(EFL_NET_SERVER_UNIX_CLASS, efl_main_loop_get());
424         EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
425      }
426 #endif /* EFL_NET_SERVER_UNIX_CLASS */
427 #ifdef EFL_NET_SERVER_WINDOWS_CLASS
428    if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER)
429      {
430         address = ecore_con_local_path_new(EINA_FALSE, name, port);
431         EINA_SAFETY_ON_NULL_GOTO(address, error_server);
432 
433         // TODO: specify SECURITY_ATTRIBUTES to use or some
434         // Efl_Net_Server_Windows API to limit access
435 
436         svr->server = efl_add(EFL_NET_SERVER_WINDOWS_CLASS, efl_main_loop_get());
437         EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
438      }
439    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)
440      {
441         address = ecore_con_local_path_new(EINA_TRUE, name, port);
442         EINA_SAFETY_ON_NULL_GOTO(address, error_server);
443 
444         // TODO: specify SECURITY_ATTRIBUTES to use or some
445         // Efl_Net_Server_Windows API to limit access
446 
447         svr->server = efl_add(EFL_NET_SERVER_WINDOWS_CLASS, efl_main_loop_get());
448         EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
449      }
450 #endif /* EFL_NET_SERVER_WINDOWS_CLASS */
451    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_REMOTE_SYSTEM)
452      {
453         char buf[4096];
454 
455         if (port <= 0)
456           {
457              ERR("remote system requires port>=0, got %d", port);
458              goto error_server;
459           }
460 
461         snprintf(buf, sizeof(buf), "%s:%d", name, port);
462         address = strdup(buf);
463         EINA_SAFETY_ON_NULL_GOTO(address, error_server);
464 
465         if ((type & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL)
466           {
467              svr->server = efl_add(EFL_NET_SERVER_SSL_CLASS, loop);
468              EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
469           }
470         else
471           {
472              svr->server = efl_add(EFL_NET_SERVER_TCP_CLASS, loop);
473              EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server);
474           }
475      }
476    else
477      {
478         ERR("IPC Type must be one of: local_user, local_system or remote_system");
479         goto error_server;
480      }
481 
482    efl_event_callback_array_add(svr->server, _ecore_ipc_server_cbs(), svr);
483 
484    if (efl_isa(svr->server, EFL_NET_SERVER_FD_CLASS))
485      {
486         efl_net_server_fd_reuse_address_set(svr->server, EINA_TRUE);
487         efl_net_server_fd_reuse_port_set(svr->server, EINA_TRUE);
488      }
489 
490    if (efl_isa(svr->server, EFL_NET_SERVER_TCP_CLASS))
491      {
492         /* old ecore_con did not map ipv4 to ipv6... */
493         efl_net_server_ip_ipv6_only_set(svr->server, EINA_TRUE);
494      }
495 
496 #ifdef EFL_NET_SERVER_UNIX_CLASS
497    if (efl_isa(svr->server, EFL_NET_SERVER_UNIX_CLASS))
498      {
499         old_mask = umask(new_mask);
500         efl_net_server_unix_leading_directories_create_set(svr->server,
501                                                            EINA_TRUE,
502                                                            local_system ? 0755 : 0700);
503      }
504 #endif
505 
506    err = efl_net_server_serve(svr->server, address);
507 
508 #ifdef EFL_NET_SERVER_UNIX_CLASS
509    if (efl_isa(svr->server, EFL_NET_SERVER_UNIX_CLASS))
510      umask(old_mask);
511 #endif
512 
513    if (err)
514      {
515         WRN("Could not serve %s %s: %s",
516             efl_class_name_get(efl_class_get(svr->server)),
517             address, eina_error_msg_get(err));
518         goto error;
519      }
520    DBG("will serve %p %s address='%s'",
521        svr->server,
522        efl_class_name_get(efl_class_get(svr->server)),
523        address);
524 
525    svr->max_buf_size = 32 * 1024;
526    svr->data = (void *)data;
527    servers = eina_list_append(servers, svr);
528    ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
529    free(address);
530    return svr;
531 
532  error:
533    free(address);
534    _ecore_ipc_server_del(svr);
535    free(svr);
536    return NULL; /* server will trigger all cleanup on its own callbacks */
537 
538  error_server:
539    free(address);
540    free(svr);
541    return NULL;
542 }
543 
544 static Efl_Callback_Array_Item *_ecore_ipc_dialer_cbs(void);
545 
546 static void
_ecore_ipc_dialer_del(Ecore_Ipc_Server * svr)547 _ecore_ipc_dialer_del(Ecore_Ipc_Server *svr)
548 {
549    DBG("dialer %p del", svr);
550 
551    if (svr->dialer.recv_copier)
552      {
553         efl_del(svr->dialer.recv_copier);
554         svr->dialer.recv_copier = NULL;
555      }
556 
557    if (svr->dialer.send_copier)
558      {
559         efl_del(svr->dialer.send_copier);
560         svr->dialer.send_copier = NULL;
561      }
562 
563    if (svr->dialer.input)
564      {
565         efl_del(svr->dialer.input);
566         svr->dialer.input = NULL;
567      }
568 
569    if (svr->dialer.dialer)
570      {
571         efl_event_callback_array_del(svr->dialer.dialer, _ecore_ipc_dialer_cbs(), svr);
572         if (!efl_io_closer_closed_get(svr->dialer.dialer))
573           efl_io_closer_close(svr->dialer.dialer);
574 
575         efl_del(svr->dialer.dialer);
576         svr->dialer.dialer = NULL;
577      }
578 }
579 
580 static void
_ecore_ipc_dialer_eos(void * data,const Efl_Event * event EINA_UNUSED)581 _ecore_ipc_dialer_eos(void *data, const Efl_Event *event EINA_UNUSED)
582 {
583    Ecore_Ipc_Server *svr = data;
584 
585    DBG("dialer %p %p eos", svr, svr->dialer.dialer);
586 
587    _ecore_ipc_dialer_del(svr);
588 
589    ecore_ipc_post_event_server_del(svr);
590 }
591 
592 static void
_ecore_ipc_dialer_error(void * data,const Efl_Event * event)593 _ecore_ipc_dialer_error(void *data, const Efl_Event *event)
594 {
595    Ecore_Ipc_Server *svr = data;
596    Eina_Error *perr = event->info;
597 
598    WRN("dialer %p %p error %s", svr, svr->dialer.dialer, eina_error_msg_get(*perr));
599 
600    if (!efl_io_closer_closed_get(svr->dialer.dialer))
601      efl_io_closer_close(svr->dialer.dialer); /* triggers EOS */
602 }
603 
604 static void
_ecore_ipc_dialer_connected(void * data,const Efl_Event * event EINA_UNUSED)605 _ecore_ipc_dialer_connected(void *data, const Efl_Event *event EINA_UNUSED)
606 {
607    Ecore_Ipc_Server *svr = data;
608 
609    DBG("connected to %s %s",
610        efl_class_name_get(efl_class_get(svr->dialer.dialer)),
611        efl_net_dialer_address_dial_get(svr->dialer.dialer));
612 
613    ecore_ipc_post_event_server_add(svr);
614 }
615 
616 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_dialer_cbs,
617                            { EFL_IO_READER_EVENT_EOS, _ecore_ipc_dialer_eos },
618                            { EFL_NET_DIALER_EVENT_DIALER_ERROR, _ecore_ipc_dialer_error },
619                            { EFL_NET_DIALER_EVENT_DIALER_CONNECTED, _ecore_ipc_dialer_connected });
620 
621 static Eina_Bool ecore_ipc_server_data_process(Ecore_Ipc_Server *svr, void *data, int size, Eina_Bool *stolen);
622 
623 static void
_ecore_ipc_dialer_copier_data(void * data,const Efl_Event * event EINA_UNUSED)624 _ecore_ipc_dialer_copier_data(void *data, const Efl_Event *event EINA_UNUSED)
625 {
626    Ecore_Ipc_Server *svr = data;
627    Eina_Binbuf *binbuf;
628    uint8_t *mem;
629    int size;
630    Eina_Bool stolen;
631 
632    DBG("dialer %p recv_copier %p data", svr, svr->dialer.recv_copier);
633 
634    binbuf = efl_io_copier_binbuf_steal(svr->dialer.recv_copier);
635    EINA_SAFETY_ON_NULL_RETURN(binbuf);
636    size = eina_binbuf_length_get(binbuf);
637    mem = eina_binbuf_string_steal(binbuf);
638    eina_binbuf_free(binbuf);
639 
640    ecore_ipc_server_data_process(svr, mem, size, &stolen);
641    if (!stolen) free(mem);
642 }
643 
644 static void
_ecore_ipc_dialer_copier_error(void * data,const Efl_Event * event)645 _ecore_ipc_dialer_copier_error(void *data, const Efl_Event *event)
646 {
647    Ecore_Ipc_Server *svr = data;
648    Eina_Error *perr = event->info;
649 
650    WRN("dialer %p %p copier %p error %s", svr, svr->dialer.dialer, event->object, eina_error_msg_get(*perr));
651 
652    if (!efl_io_closer_closed_get(svr->dialer.dialer))
653      efl_io_closer_close(svr->dialer.dialer);
654 }
655 
656 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_dialer_copier_cbs,
657                            { EFL_IO_COPIER_EVENT_ERROR, _ecore_ipc_dialer_copier_error });
658 
659 /* FIXME: need to add protocol type parameter */
660 EAPI Ecore_Ipc_Server *
ecore_ipc_server_connect(Ecore_Ipc_Type type,char * name,int port,const void * data)661 ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data)
662 {
663    Ecore_Ipc_Server *svr;
664    Eo *loop = efl_main_loop_get();
665    char *address = NULL;
666    Eina_Error err;
667 
668    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
669 
670    svr = calloc(1, sizeof(Ecore_Ipc_Server));
671    EINA_SAFETY_ON_NULL_RETURN_VAL(svr, NULL);
672 
673    if (0) { }
674 #ifdef EFL_NET_DIALER_UNIX_CLASS
675    if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER)
676      {
677         struct stat st;
678 
679         address = ecore_con_local_path_new(EINA_FALSE, name, port);
680         EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
681 
682         if ((stat(address, &st) != 0)
683 #ifdef S_ISSOCK
684             || (!S_ISSOCK(st.st_mode))
685 #endif
686             )
687           {
688              DBG("%s is not a socket", address);
689              goto error_dialer;
690           }
691 
692         svr->dialer.dialer = efl_add(EFL_NET_DIALER_UNIX_CLASS, efl_main_loop_get());
693         EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
694      }
695    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)
696      {
697         address = ecore_con_local_path_new(EINA_TRUE, name, port);
698         EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
699 
700         svr->dialer.dialer = efl_add(EFL_NET_DIALER_UNIX_CLASS, efl_main_loop_get());
701         EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
702      }
703 #endif /* EFL_NET_DIALER_UNIX_CLASS */
704 #ifdef EFL_NET_DIALER_WINDOWS_CLASS
705    if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER)
706      {
707         address = ecore_con_local_path_new(EINA_FALSE, name, port);
708         EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
709 
710         svr->dialer.dialer = efl_add(EFL_NET_DIALER_WINDOWS_CLASS, efl_main_loop_get());
711         EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
712      }
713    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)
714      {
715         address = ecore_con_local_path_new(EINA_TRUE, name, port);
716         EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
717 
718         svr->dialer.dialer = efl_add(EFL_NET_DIALER_WINDOWS_CLASS, efl_main_loop_get());
719         EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
720      }
721 #endif /* EFL_NET_DIALER_WINDOWS_CLASS */
722    else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_REMOTE_SYSTEM)
723      {
724         char buf[4096];
725 
726         if (port <= 0)
727           {
728              ERR("remote system requires port>=0, got %d", port);
729              goto error_dialer;
730           }
731 
732         snprintf(buf, sizeof(buf), "%s:%d", name, port);
733         address = strdup(buf);
734         EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
735 
736         if ((type & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL)
737           {
738              svr->dialer.dialer = efl_add(EFL_NET_DIALER_SSL_CLASS, loop);
739              EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
740           }
741         else
742           {
743              svr->dialer.dialer = efl_add(EFL_NET_DIALER_TCP_CLASS, loop);
744              EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
745           }
746 
747         if ((type & ECORE_IPC_NO_PROXY) == ECORE_IPC_NO_PROXY)
748           efl_net_dialer_proxy_set(svr->dialer.dialer, "");
749      }
750    else
751      {
752         ERR("IPC Type must be one of: local_user, local_system or remote_system");
753         goto error_dialer;
754      }
755 
756    efl_io_closer_close_on_invalidate_set(svr->dialer.dialer, EINA_TRUE);
757    efl_event_callback_array_add(svr->dialer.dialer, _ecore_ipc_dialer_cbs(), svr);
758 
759    svr->dialer.input = efl_add(EFL_IO_QUEUE_CLASS, loop);
760    EINA_SAFETY_ON_NULL_GOTO(svr->dialer.input, error);
761 
762    svr->dialer.send_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
763                                      efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE),
764                                      efl_io_copier_source_set(efl_added, svr->dialer.input),
765                                      efl_io_copier_destination_set(efl_added, svr->dialer.dialer),
766                                      efl_event_callback_array_add(efl_added, _ecore_ipc_dialer_copier_cbs(), svr));
767    EINA_SAFETY_ON_NULL_GOTO(svr->dialer.send_copier, error);
768 
769    svr->dialer.recv_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
770                                      efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE),
771                                      efl_io_copier_source_set(efl_added, svr->dialer.dialer),
772                                      efl_event_callback_array_add(efl_added, _ecore_ipc_dialer_copier_cbs(), svr),
773                                      efl_event_callback_add(efl_added, EFL_IO_COPIER_EVENT_DATA, _ecore_ipc_dialer_copier_data, svr));
774    EINA_SAFETY_ON_NULL_GOTO(svr->dialer.recv_copier, error);
775 
776    err = efl_net_dialer_dial(svr->dialer.dialer, address);
777    if (err)
778      {
779         WRN("Could not reach %s %s: %s",
780             efl_class_name_get(efl_class_get(svr->dialer.dialer)),
781             address, eina_error_msg_get(err));
782         goto error;
783      }
784    DBG("connecting %p %s address='%s'",
785        svr->dialer.dialer,
786        efl_class_name_get(efl_class_get(svr->dialer.dialer)),
787        address);
788 
789    svr->max_buf_size = -1;
790    svr->data = (void *)data;
791    servers = eina_list_append(servers, svr);
792    ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
793    free(address);
794    return svr;
795 
796  error:
797    free(address);
798    _ecore_ipc_dialer_del(svr);
799    free(svr);
800    return NULL; /* dialer will trigger all cleanup on its own callbacks */
801 
802  error_dialer:
803    free(address);
804    free(svr);
805    return NULL;
806 }
807 
808 EAPI void *
ecore_ipc_server_del(Ecore_Ipc_Server * svr)809 ecore_ipc_server_del(Ecore_Ipc_Server *svr)
810 {
811    void *data;
812 
813    if (!svr) return NULL;
814    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
815      {
816         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
817                          "ecore_ipc_server_del");
818         return NULL;
819      }
820 
821    data = svr->data;
822    svr->data = NULL;
823    svr->delete_me = 1;
824    if (svr->event_count == 0)
825      {
826         Ecore_Ipc_Client *cl;
827 
828         EINA_LIST_FREE(svr->clients, cl)
829           {
830              cl->svr = NULL;
831              ecore_ipc_client_del(cl);
832           }
833 
834         if (svr->dialer.dialer) _ecore_ipc_dialer_del(svr);
835         if (svr->server) _ecore_ipc_server_del(svr);
836         servers = eina_list_remove(servers, svr);
837 
838         if (svr->buf) free(svr->buf);
839         eina_list_free(svr->dead_clients);
840         eina_list_free(svr->clients);
841         ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
842         DBG("server %p freed", svr);
843         free(svr);
844      }
845    else DBG("server %p has %d events pending, postpone deletion", svr, svr->event_count);
846    return data;
847 }
848 
849 EAPI void *
ecore_ipc_server_data_get(Ecore_Ipc_Server * svr)850 ecore_ipc_server_data_get(Ecore_Ipc_Server *svr)
851 {
852    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
853      {
854         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
855                          "ecore_ipc_server_data_get");
856         return NULL;
857      }
858    return svr->data;
859 }
860 
861 EAPI Eina_Bool
ecore_ipc_server_connected_get(Ecore_Ipc_Server * svr)862 ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
863 {
864    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
865      {
866         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
867                          "ecore_ipc_server_connected_get");
868         return EINA_FALSE;
869      }
870 
871    if (svr->dialer.dialer)
872      return efl_net_dialer_connected_get(svr->dialer.dialer);
873    else if (svr->server) return EINA_TRUE;
874    return EINA_FALSE;
875 }
876 
877 EAPI Eina_List *
ecore_ipc_server_clients_get(Ecore_Ipc_Server * svr)878 ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr)
879 {
880    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
881      {
882         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
883                          "ecore_ipc_server_clients_get");
884         return NULL;
885      }
886    return svr->clients;
887 }
888 
889 #define SVENC(_member) \
890    d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \
891    if (md >= DLT_SET) \
892      { \
893         unsigned int v; \
894         unsigned char *dd; \
895         dd = (unsigned char *)&v; \
896         v = d; \
897         v = eina_htonl(v); \
898         *(dat + s + 0) = dd[0]; \
899         *(dat + s + 1) = dd[1]; \
900         *(dat + s + 2) = dd[2]; \
901         *(dat + s + 3) = dd[3]; \
902         s += 4; \
903      } \
904    else if (md >= DLT_ADD16) \
905      { \
906         unsigned short v; \
907         unsigned char *dd; \
908         dd = (unsigned char *)&v; \
909         v = d; \
910         v = eina_htons(v); \
911         *(dat + s + 0) = dd[0]; \
912         *(dat + s + 1) = dd[1]; \
913         s += 2; \
914      } \
915    else if (md >= DLT_ADD8) \
916      { \
917         *(dat + s + 0) = (unsigned char)d; \
918         s += 1; \
919      }
920 
921 /* FIXME: this needs to become an ipc message */
922 EAPI int
ecore_ipc_server_send(Ecore_Ipc_Server * svr,int major,int minor,int ref,int ref_to,int response,const void * data,int size)923 ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
924 {
925    Ecore_Ipc_Msg_Head msg;
926    int *head, md = 0, d, s;
927    unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
928 
929    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
930      {
931         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
932                          "ecore_ipc_server_send");
933         return 0;
934      }
935    if (size < 0) size = 0;
936    msg.major    = major;
937    msg.minor    = minor;
938    msg.ref      = ref;
939    msg.ref_to   = ref_to;
940    msg.response = response;
941    msg.size     = size;
942    head = (int *)dat;
943    s = 4;
944    SVENC(major);
945    *head = md;
946    SVENC(minor);
947    *head |= md << (4 * 1);
948    SVENC(ref);
949    *head |= md << (4 * 2);
950    SVENC(ref_to);
951    *head |= md << (4 * 3);
952    SVENC(response);
953    *head |= md << (4 * 4);
954    SVENC(size);
955    *head |= md << (4 * 5);
956    *head = eina_htonl(*head);
957    svr->prev.o = msg;
958 
959    if (svr->dialer.input)
960      {
961         Eina_Slice slice;
962         Eina_Error err;
963 
964         slice.mem = dat;
965         slice.len = s;
966         err = efl_io_writer_write(svr->dialer.input, &slice, NULL);
967         if (err)
968           {
969              ERR("could not write queue=%p %zd bytes: %s",
970                  svr->dialer.input, slice.len, eina_error_msg_get(err));
971              return 0;
972           }
973         if (slice.len < (size_t)s)
974           {
975              ERR("only wrote %zd of %d bytes to queue %p",
976                  slice.len, s, svr->dialer.input);
977              return 0;
978           }
979 
980         if ((data) && (size > 0))
981           {
982              slice.mem = data;
983              slice.len = size;
984              err = efl_io_writer_write(svr->dialer.input, &slice, NULL);
985              if (err)
986                {
987                   ERR("could not write queue=%p %zd bytes: %s",
988                       svr->dialer.input, slice.len, eina_error_msg_get(err));
989                   return 0;
990                }
991              if (slice.len < (size_t)size)
992                {
993                   ERR("only wrote %zd of %d bytes to queue %p",
994                       slice.len, size, svr->dialer.input);
995                   return 0;
996                }
997           }
998 
999         return s + size;
1000      }
1001    else if (svr->server)
1002      {
1003         ERR("Send data to clients, not the server handle");
1004         return 0;
1005      }
1006    return 0;
1007 }
1008 
1009 EAPI void
ecore_ipc_server_client_limit_set(Ecore_Ipc_Server * svr,int client_limit,char reject_excess_clients)1010 ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients)
1011 {
1012    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1013      {
1014         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
1015                          "ecore_ipc_server_client_limit_set");
1016         return;
1017      }
1018    if (svr->server)
1019      {
1020         efl_net_server_clients_limit_set(svr->server, client_limit, reject_excess_clients);
1021         return;
1022      }
1023 }
1024 
1025 EAPI void
ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server * svr,int size)1026 ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *svr, int size)
1027 {
1028    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1029      {
1030         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
1031                          "ecore_ipc_server_data_size_max_set");
1032         return;
1033      }
1034    svr->max_buf_size = size;
1035 }
1036 
1037 EAPI int
ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server * svr)1038 ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *svr)
1039 {
1040    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1041      {
1042         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
1043                          "ecore_ipc_server_data_size_max_get");
1044         return -1;
1045      }
1046    return svr->max_buf_size;
1047 }
1048 
1049 EAPI const char *
ecore_ipc_server_ip_get(Ecore_Ipc_Server * svr)1050 ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr)
1051 {
1052    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1053      {
1054         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
1055                          "ecore_ipc_server_ip_get");
1056         return NULL;
1057      }
1058 
1059    if (svr->dialer.dialer)
1060      {
1061         if (efl_isa(svr->dialer.dialer, EFL_NET_DIALER_TCP_CLASS) ||
1062             efl_isa(svr->dialer.dialer, EFL_NET_DIALER_SSL_CLASS))
1063           return efl_net_dialer_address_dial_get(svr->dialer.dialer);
1064         /* original IPC just returned IP for remote connections */
1065         return NULL;
1066      }
1067    else if (svr->server)
1068      {
1069         if (efl_isa(svr->server, EFL_NET_SERVER_TCP_CLASS) ||
1070             efl_isa(svr->server, EFL_NET_SERVER_SSL_CLASS))
1071           return efl_net_server_address_get(svr->server);
1072         /* original IPC just returned IP for remote connections */
1073         return NULL;
1074      }
1075    return NULL;
1076 }
1077 
1078 EAPI void
ecore_ipc_server_flush(Ecore_Ipc_Server * svr)1079 ecore_ipc_server_flush(Ecore_Ipc_Server *svr)
1080 {
1081    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1082      {
1083         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
1084                          "ecore_ipc_server_server_flush");
1085         return;
1086      }
1087    if (svr->dialer.input)
1088      {
1089         while (!efl_io_closer_closed_get(svr->dialer.dialer) &&
1090                !efl_net_dialer_connected_get(svr->dialer.dialer))
1091           ecore_main_loop_iterate();
1092         while ((efl_io_queue_usage_get(svr->dialer.input) > 0) ||
1093                (efl_io_copier_pending_size_get(svr->dialer.send_copier) > 0))
1094           efl_io_copier_flush(svr->dialer.send_copier, EINA_TRUE, EINA_TRUE);
1095         return;
1096      }
1097    else if (svr->server)
1098      {
1099         ERR("Flush clients, not the server handle");
1100         return;
1101      }
1102 }
1103 
1104 #define CLENC(_member) \
1105    d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \
1106    if (md >= DLT_SET) \
1107      { \
1108         unsigned int v; \
1109         unsigned char *dd; \
1110         dd = (unsigned char *)&v; \
1111         v = d; \
1112         v = eina_htonl(v); \
1113         *(dat + s + 0) = dd[0]; \
1114         *(dat + s + 1) = dd[1]; \
1115         *(dat + s + 2) = dd[2]; \
1116         *(dat + s + 3) = dd[3]; \
1117         s += 4; \
1118      } \
1119    else if (md >= DLT_ADD16) \
1120      { \
1121         unsigned short v; \
1122         unsigned char *dd; \
1123         dd = (unsigned char *)&v; \
1124         v = d; \
1125         v = eina_htons(v); \
1126         *(dat + s + 0) = dd[0]; \
1127         *(dat + s + 1) = dd[1]; \
1128         s += 2; \
1129      } \
1130    else if (md >= DLT_ADD8) \
1131      { \
1132         *(dat + s) = (unsigned char)d; \
1133         s += 1; \
1134      }
1135 
1136 /* FIXME: this needs to become an ipc message */
1137 EAPI int
ecore_ipc_client_send(Ecore_Ipc_Client * cl,int major,int minor,int ref,int ref_to,int response,const void * data,int size)1138 ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
1139 {
1140    Ecore_Ipc_Msg_Head msg;
1141    int *head, md = 0, d, s;
1142    unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
1143 
1144    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1145      {
1146         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1147                          "ecore_ipc_client_send");
1148         return 0;
1149      }
1150    if (cl->socket.socket)
1151      EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(cl->socket.socket), 0);
1152    else
1153      {
1154         ERR("client %p is not connected", cl);
1155         return 0;
1156      }
1157 
1158    if (size < 0) size = 0;
1159    msg.major    = major;
1160    msg.minor    = minor;
1161    msg.ref      = ref;
1162    msg.ref_to   = ref_to;
1163    msg.response = response;
1164    msg.size     = size;
1165    head = (int *)dat;
1166    s = 4;
1167    CLENC(major);
1168    *head = md;
1169    CLENC(minor);
1170    *head |= md << (4 * 1);
1171    CLENC(ref);
1172    *head |= md << (4 * 2);
1173    CLENC(ref_to);
1174    *head |= md << (4 * 3);
1175    CLENC(response);
1176    *head |= md << (4 * 4);
1177    CLENC(size);
1178    *head |= md << (4 * 5);
1179    *head = eina_htonl(*head);
1180    cl->prev.o = msg;
1181 
1182    if (cl->socket.input)
1183      {
1184         Eina_Slice slice;
1185         Eina_Error err;
1186 
1187         slice.mem = dat;
1188         slice.len = s;
1189         err = efl_io_writer_write(cl->socket.input, &slice, NULL);
1190         if (err)
1191           {
1192              ERR("could not write queue=%p %zd bytes: %s",
1193                  cl->socket.input, slice.len, eina_error_msg_get(err));
1194              return 0;
1195           }
1196         if (slice.len < (size_t)s)
1197           {
1198              ERR("only wrote %zd of %d bytes to queue %p",
1199                  slice.len, s, cl->socket.input);
1200              return 0;
1201           }
1202         if ((data) && (size > 0))
1203           {
1204              slice.mem = data;
1205              slice.len = size;
1206              err = efl_io_writer_write(cl->socket.input, &slice, NULL);
1207              if (err)
1208                {
1209                   ERR("could not write queue=%p %zd bytes: %s",
1210                       cl->socket.input, slice.len, eina_error_msg_get(err));
1211                   return 0;
1212                }
1213              if (slice.len < (size_t)size)
1214                {
1215                   ERR("only wrote %zd of %d bytes to queue %p",
1216                       slice.len, size, cl->socket.input);
1217                   return 0;
1218                }
1219           }
1220 
1221         return s + size;
1222      }
1223    return 0;
1224 }
1225 
1226 EAPI Ecore_Ipc_Server *
ecore_ipc_client_server_get(Ecore_Ipc_Client * cl)1227 ecore_ipc_client_server_get(Ecore_Ipc_Client *cl)
1228 {
1229    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1230      {
1231         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1232                          "ecore_ipc_client_server_get");
1233         return NULL;
1234      }
1235    return cl->svr;
1236 }
1237 
1238 static Efl_Callback_Array_Item *_ecore_ipc_socket_cbs(void);
1239 
1240 static void
_ecore_ipc_client_socket_del(Ecore_Ipc_Client * cl)1241 _ecore_ipc_client_socket_del(Ecore_Ipc_Client *cl)
1242 {
1243    DBG("client %p socket del", cl);
1244 
1245    if (cl->socket.recv_copier)
1246      {
1247         efl_del(cl->socket.recv_copier);
1248         cl->socket.recv_copier = NULL;
1249      }
1250 
1251    if (cl->socket.send_copier)
1252      {
1253         efl_del(cl->socket.send_copier);
1254         cl->socket.send_copier = NULL;
1255      }
1256 
1257    if (cl->socket.input)
1258      {
1259         efl_del(cl->socket.input);
1260         cl->socket.input = NULL;
1261      }
1262 
1263    if (cl->socket.socket)
1264      {
1265         efl_event_callback_array_del(cl->socket.socket, _ecore_ipc_socket_cbs(), cl);
1266         /* do not del() as it's owned by srv->server */
1267         if (!efl_io_closer_closed_get(cl->socket.socket))
1268           efl_io_closer_close(cl->socket.socket);
1269         efl_unref(cl->socket.socket);
1270         cl->socket.socket = NULL;
1271         if (!cl->svr) return;
1272         cl->svr->clients = eina_list_remove(cl->svr->clients, cl);
1273         cl->svr->dead_clients = eina_list_append(cl->svr->dead_clients, cl);
1274      }
1275 }
1276 
1277 static void
_ecore_ipc_client_socket_eos(void * data,const Efl_Event * event EINA_UNUSED)1278 _ecore_ipc_client_socket_eos(void *data, const Efl_Event *event EINA_UNUSED)
1279 {
1280    Ecore_Ipc_Client *cl = data;
1281 
1282    DBG("client %p socket %p eos", cl, cl->socket.socket);
1283 
1284    _ecore_ipc_client_socket_del(cl);
1285 
1286    ecore_ipc_post_event_client_del(cl);
1287 }
1288 
1289 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_socket_cbs,
1290                            { EFL_IO_READER_EVENT_EOS, _ecore_ipc_client_socket_eos });
1291 
1292 static Eina_Bool ecore_ipc_client_data_process(Ecore_Ipc_Client *cl, void *data, int size, Eina_Bool *stolen);
1293 
1294 static void
_ecore_ipc_client_socket_copier_data(void * data,const Efl_Event * event EINA_UNUSED)1295 _ecore_ipc_client_socket_copier_data(void *data, const Efl_Event *event EINA_UNUSED)
1296 {
1297    Ecore_Ipc_Client *cl = data;
1298    Eina_Binbuf *binbuf;
1299    uint8_t *mem;
1300    int size;
1301    Eina_Bool stolen;
1302 
1303    DBG("client %p recv_copier %p data", cl, cl->socket.recv_copier);
1304 
1305    binbuf = efl_io_copier_binbuf_steal(cl->socket.recv_copier);
1306    EINA_SAFETY_ON_NULL_RETURN(binbuf);
1307    size = eina_binbuf_length_get(binbuf);
1308    mem = eina_binbuf_string_steal(binbuf);
1309    eina_binbuf_free(binbuf);
1310 
1311    ecore_ipc_client_data_process(cl, mem, size, &stolen);
1312    if (!stolen) free(mem);
1313 }
1314 
1315 static void
_ecore_ipc_client_socket_copier_error(void * data,const Efl_Event * event)1316 _ecore_ipc_client_socket_copier_error(void *data, const Efl_Event *event)
1317 {
1318    Ecore_Ipc_Client *cl = data;
1319    Eina_Error *perr = event->info;
1320 
1321    WRN("client %p socket %p copier %p error %s", cl, cl->socket.socket, event->object, eina_error_msg_get(*perr));
1322 
1323    if (!efl_io_closer_closed_get(cl->socket.socket))
1324      efl_io_closer_close(cl->socket.socket);
1325 }
1326 
1327 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_client_socket_copier_cbs,
1328                            { EFL_IO_COPIER_EVENT_ERROR, _ecore_ipc_client_socket_copier_error });
1329 
1330 static void
_ecore_ipc_server_client_add(void * data,const Efl_Event * event)1331 _ecore_ipc_server_client_add(void *data, const Efl_Event *event)
1332 {
1333    Ecore_Ipc_Server *svr = data;
1334    Eo *socket = event->info;
1335    Ecore_Ipc_Client *cl;
1336    Eo *loop;
1337 
1338    DBG("server %p %p got new client %p (%s)",
1339        svr, svr->server,
1340        event->object, efl_net_socket_address_remote_get(socket));
1341 
1342    cl = ecore_ipc_client_add(svr);
1343    EINA_SAFETY_ON_NULL_RETURN(cl);
1344 
1345    cl->socket.socket = efl_ref(socket);
1346    efl_event_callback_array_add(cl->socket.socket, _ecore_ipc_socket_cbs(), cl);
1347 
1348    loop = efl_loop_get(socket);
1349 
1350    cl->socket.input = efl_add(EFL_IO_QUEUE_CLASS, loop);
1351    EINA_SAFETY_ON_NULL_GOTO(cl->socket.input, error);
1352 
1353    cl->socket.send_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
1354                                      efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE),
1355                                      efl_io_copier_source_set(efl_added, cl->socket.input),
1356                                      efl_io_copier_destination_set(efl_added, cl->socket.socket),
1357                                      efl_event_callback_array_add(efl_added, _ecore_ipc_client_socket_copier_cbs(), cl));
1358    EINA_SAFETY_ON_NULL_GOTO(cl->socket.send_copier, error);
1359 
1360    cl->socket.recv_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
1361                                      efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE),
1362                                      efl_io_copier_source_set(efl_added, cl->socket.socket),
1363                                      efl_event_callback_array_add(efl_added, _ecore_ipc_client_socket_copier_cbs(), cl),
1364                                      efl_event_callback_add(efl_added, EFL_IO_COPIER_EVENT_DATA, _ecore_ipc_client_socket_copier_data, cl));
1365    EINA_SAFETY_ON_NULL_GOTO(cl->socket.recv_copier, error);
1366 
1367    ecore_ipc_post_event_client_add(cl);
1368    return;
1369 
1370  error:
1371    _ecore_ipc_client_socket_del(cl);
1372    free(cl);
1373 }
1374 
1375 EAPI void *
ecore_ipc_client_del(Ecore_Ipc_Client * cl)1376 ecore_ipc_client_del(Ecore_Ipc_Client *cl)
1377 {
1378    void *data;
1379    Ecore_Ipc_Server *svr;
1380 
1381    if (!cl) return NULL;
1382    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1383      {
1384         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1385                          "ecore_ipc_client_del");
1386         return NULL;
1387      }
1388    data = cl->data;
1389    cl->data = NULL;
1390    cl->delete_me = 1;
1391    if (cl->event_count == 0)
1392      {
1393         svr = cl->svr;
1394         if (cl->socket.socket) _ecore_ipc_client_socket_del(cl);
1395         if (ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
1396           svr->dead_clients = eina_list_remove(svr->dead_clients, cl);
1397         if (cl->buf) free(cl->buf);
1398         ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
1399         free(cl);
1400      }
1401    return data;
1402 }
1403 
1404 EAPI void
ecore_ipc_client_data_set(Ecore_Ipc_Client * cl,const void * data)1405 ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data)
1406 {
1407    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1408      {
1409         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1410                          "ecore_ipc_client_data_set");
1411         return;
1412      }
1413    cl->data = (void *)data;
1414 }
1415 
1416 EAPI void *
ecore_ipc_client_data_get(Ecore_Ipc_Client * cl)1417 ecore_ipc_client_data_get(Ecore_Ipc_Client *cl)
1418 {
1419    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1420      {
1421         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1422                          "ecore_ipc_client_data_get");
1423         return NULL;
1424      }
1425    return cl->data;
1426 }
1427 
1428 EAPI void
ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client * cl,int size)1429 ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client *cl, int size)
1430 {
1431    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1432      {
1433         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1434                          "ecore_ipc_client_data_size_max_set");
1435         return;
1436      }
1437    cl->max_buf_size = size;
1438 }
1439 
1440 EAPI int
ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client * cl)1441 ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client *cl)
1442 {
1443    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1444      {
1445         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1446                          "ecore_ipc_client_data_size_max_get");
1447         return -1;
1448      }
1449    return cl->max_buf_size;
1450 }
1451 
1452 EAPI const char *
ecore_ipc_client_ip_get(Ecore_Ipc_Client * cl)1453 ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl)
1454 {
1455    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1456      {
1457         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1458                          "ecore_ipc_client_ip_get");
1459         return NULL;
1460      }
1461    if (cl->socket.socket)
1462      {
1463         if (efl_isa(cl->socket.socket, EFL_NET_SOCKET_TCP_CLASS) ||
1464             efl_isa(cl->socket.socket, EFL_NET_SOCKET_SSL_CLASS))
1465           return efl_net_socket_address_remote_get(cl->socket.socket);
1466         /* original IPC just returned IP for remote connections,
1467          * for unix socket it returned 0.0.0.0
1468          */
1469         return "0.0.0.0";
1470      }
1471    return NULL;
1472 }
1473 
1474 EAPI void
ecore_ipc_client_flush(Ecore_Ipc_Client * cl)1475 ecore_ipc_client_flush(Ecore_Ipc_Client *cl)
1476 {
1477    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
1478      {
1479         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
1480                          "ecore_ipc_client_flush");
1481         return;
1482      }
1483    if (cl->socket.input)
1484      {
1485         while (efl_io_queue_usage_get(cl->socket.input) > 0)
1486           efl_io_copier_flush(cl->socket.send_copier, EINA_TRUE, EINA_TRUE);
1487         return;
1488      }
1489 }
1490 
1491 EAPI int
ecore_ipc_ssl_available_get(void)1492 ecore_ipc_ssl_available_get(void)
1493 {
1494    return ecore_con_ssl_available_get();
1495 }
1496 
1497 #define CLSZ(_n) \
1498    md = ((head >> (4 * _n)) & 0xf); \
1499    if (md >= DLT_SET) s += 4; \
1500    else if (md >= DLT_ADD16) s += 2; \
1501    else if (md >= DLT_ADD8) s += 1;
1502 
1503 #define CLDEC(_n, _member) \
1504    md = ((head >> (4 * _n)) & 0xf); \
1505    if (md >= DLT_SET) \
1506      { \
1507         unsigned int v; \
1508         unsigned char *dv; \
1509         dv = (unsigned char *)&v; \
1510         dv[0] = *(cl->buf + offset + s + 0); \
1511         dv[1] = *(cl->buf + offset + s + 1); \
1512         dv[2] = *(cl->buf + offset + s + 2); \
1513         dv[3] = *(cl->buf + offset + s + 3); \
1514         d = (int)eina_ntohl(v); \
1515         s += 4; \
1516      } \
1517    else if (md >= DLT_ADD16) \
1518      { \
1519         unsigned short v; \
1520         unsigned char *dv; \
1521         dv = (unsigned char *)&v; \
1522         dv[0] = *(cl->buf + offset + s + 0); \
1523         dv[1] = *(cl->buf + offset + s + 1); \
1524         d = (int)eina_ntohs(v); \
1525         s += 2; \
1526      } \
1527    else if (md >= DLT_ADD8) \
1528      { \
1529         unsigned char v; \
1530         unsigned char *dv; \
1531         dv = (unsigned char *)&v; \
1532         dv[0] = *(cl->buf + offset + s + 0); \
1533         d = (int)v; \
1534         s += 1; \
1535      } \
1536    msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md);
1537 
1538 static Eina_Bool
ecore_ipc_client_data_process(Ecore_Ipc_Client * cl,void * data,int size,Eina_Bool * stolen)1539 ecore_ipc_client_data_process(Ecore_Ipc_Client *cl, void *data, int size, Eina_Bool *stolen)
1540 {
1541    /* use e->data and e->size to reduce diff to original code */
1542    struct { void *data; int size; } _e = { data, size }, *e = &_e;
1543    Ecore_Ipc_Server *svr = ecore_ipc_client_server_get(cl);
1544    *stolen = EINA_FALSE;
1545    if (1)
1546      { /* keep same identation as original code to help verification */
1547         Ecore_Ipc_Msg_Head msg;
1548         int offset = 0;
1549         unsigned char *buf;
1550 
1551         if (!cl->buf)
1552           {
1553              cl->buf_size = e->size;
1554              cl->buf = e->data;
1555              *stolen = EINA_TRUE;
1556           }
1557         else
1558           {
1559              buf = realloc(cl->buf, cl->buf_size + e->size);
1560              if (!buf)
1561                {
1562                   free(cl->buf);
1563                   cl->buf = 0;
1564                   cl->buf_size  = 0;
1565                   return ECORE_CALLBACK_CANCEL;
1566                }
1567              cl->buf = buf;
1568              memcpy(cl->buf + cl->buf_size, e->data, e->size);
1569              cl->buf_size += e->size;
1570           }
1571         /* examine header */
1572         redo:
1573         if ((cl->buf_size - offset) >= (int)sizeof(int))
1574           {
1575              int s, md, d = 0, head;
1576              unsigned char *dd;
1577 
1578              dd = (unsigned char *)&head;
1579              dd[0] = *(cl->buf + offset + 0);
1580              dd[1] = *(cl->buf + offset + 1);
1581              dd[2] = *(cl->buf + offset + 2);
1582              dd[3] = *(cl->buf + offset + 3);
1583              head = eina_ntohl(head);
1584              dd = (unsigned char *)&d;
1585              s = 4;
1586              CLSZ(0);
1587              CLSZ(1);
1588              CLSZ(2);
1589              CLSZ(3);
1590              CLSZ(4);
1591              CLSZ(5);
1592              if ((cl->buf_size - offset) < s)
1593                {
1594                   if (offset > 0) goto scroll;
1595                   return ECORE_CALLBACK_CANCEL;
1596                }
1597 
1598              s = 4;
1599              CLDEC(0, major);
1600              CLDEC(1, minor);
1601              CLDEC(2, ref);
1602              CLDEC(3, ref_to);
1603              CLDEC(4, response);
1604              CLDEC(5, size);
1605              if (msg.size < 0) msg.size = 0;
1606              /* there is enough data in the buffer for a full message */
1607              if ((cl->buf_size - offset) >= (s + msg.size))
1608                {
1609                   Ecore_Ipc_Event_Client_Data *e2;
1610                   int max, max2;
1611 
1612                   buf = NULL;
1613                   max = svr->max_buf_size;
1614                   max2 = cl->max_buf_size;
1615                   if ((max >= 0) && (max2 >= 0))
1616                     {
1617                        if (max2 < max) max = max2;
1618                     }
1619                   else
1620                     {
1621                        if (max < 0) max = max2;
1622                     }
1623                   if ((max < 0) || (msg.size <= max))
1624                     {
1625                        Eina_Bool need_free = EINA_FALSE;
1626                        if (msg.size > 0)
1627                          {
1628                             buf = malloc(msg.size);
1629                             if (!buf) return ECORE_CALLBACK_CANCEL;
1630                             memcpy(buf, cl->buf + offset + s, msg.size);
1631                             need_free = EINA_TRUE;
1632                          }
1633                        if (!cl->delete_me)
1634                          {
1635                             e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data));
1636                             if (e2)
1637                               {
1638                                  cl->event_count++;
1639                                  e2->client   = cl;
1640                                  e2->major    = msg.major;
1641                                  e2->minor    = msg.minor;
1642                                  e2->ref      = msg.ref;
1643                                  e2->ref_to   = msg.ref_to;
1644                                  e2->response = msg.response;
1645                                  e2->size     = msg.size;
1646                                  e2->data     = buf;
1647                                  ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2,
1648                                                  _ecore_ipc_event_client_data_free,
1649                                                  NULL);
1650                                  need_free = EINA_FALSE;
1651                               }
1652                          }
1653                        if (need_free) free(buf);
1654                     }
1655                   cl->prev.i = msg;
1656                   offset += (s + msg.size);
1657                   if (cl->buf_size == offset)
1658                     {
1659                        free(cl->buf);
1660                        cl->buf = NULL;
1661                        cl->buf_size = 0;
1662                        return ECORE_CALLBACK_CANCEL;
1663                     }
1664                   goto redo;
1665                }
1666              else goto scroll;
1667           }
1668         else
1669           {
1670              scroll:
1671              buf = malloc(cl->buf_size - offset);
1672              if (!buf)
1673                {
1674                   free(cl->buf);
1675                   cl->buf = NULL;
1676                   cl->buf_size = 0;
1677                   return ECORE_CALLBACK_CANCEL;
1678                }
1679              memcpy(buf, cl->buf + offset, cl->buf_size - offset);
1680              free(cl->buf);
1681              cl->buf = buf;
1682              cl->buf_size -= offset;
1683           }
1684      }
1685 
1686    return ECORE_CALLBACK_CANCEL;
1687 }
1688 
1689 #define SVSZ(_n) \
1690    md = ((head >> (4 * _n)) & 0xf); \
1691    if (md >= DLT_SET) s += 4; \
1692    else if (md >= DLT_ADD16) s += 2; \
1693    else if (md >= DLT_ADD8) s += 1;
1694 
1695 #define SVDEC(_n, _member) \
1696    md = ((head >> (4 * _n)) & 0xf); \
1697    if (md >= DLT_SET) \
1698      { \
1699         unsigned int v; \
1700         unsigned char *dv; \
1701         dv = (unsigned char *)&v; \
1702         dv[0] = *(svr->buf + offset + s + 0); \
1703         dv[1] = *(svr->buf + offset + s + 1); \
1704         dv[2] = *(svr->buf + offset + s + 2); \
1705         dv[3] = *(svr->buf + offset + s + 3); \
1706         d = (int)eina_ntohl(v); \
1707         s += 4; \
1708      } \
1709    else if (md >= DLT_ADD16) \
1710      { \
1711         unsigned short v; \
1712         unsigned char *dv; \
1713         dv = (unsigned char *)&v; \
1714         dv[0] = *(svr->buf + offset + s + 0); \
1715         dv[1] = *(svr->buf + offset + s + 1); \
1716         d = (int)eina_ntohs(v); \
1717         s += 2; \
1718      } \
1719    else if (md >= DLT_ADD8) \
1720      { \
1721         unsigned char v; \
1722         unsigned char *dv; \
1723         dv = (unsigned char *)&v; \
1724         dv[0] = *(svr->buf + offset + s + 0); \
1725         d = (int)v; \
1726         s += 1; \
1727      } \
1728    msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md);
1729 
1730 static Eina_Bool
ecore_ipc_server_data_process(Ecore_Ipc_Server * svr,void * data,int size,Eina_Bool * stolen)1731 ecore_ipc_server_data_process(Ecore_Ipc_Server *svr, void *data, int size, Eina_Bool *stolen)
1732 {
1733    /* use e->data and e->size to reduce diff to original code */
1734    struct { void *data; int size; } _e = { data, size }, *e = &_e;
1735    *stolen = EINA_FALSE;
1736    if (1)
1737      { /* keep same identation as original code to help verification */
1738         Ecore_Ipc_Msg_Head msg;
1739         int offset = 0;
1740         unsigned char *buf = NULL;
1741 
1742         if (!svr->buf)
1743           {
1744              svr->buf_size = e->size;
1745              svr->buf = e->data;
1746              *stolen = EINA_TRUE;
1747           }
1748         else
1749           {
1750              buf = realloc(svr->buf, svr->buf_size + e->size);
1751              if (!buf)
1752                {
1753                   free(svr->buf);
1754                   svr->buf = 0;
1755                   svr->buf_size  = 0;
1756                   return ECORE_CALLBACK_CANCEL;
1757                }
1758              svr->buf = buf;
1759              memcpy(svr->buf + svr->buf_size, e->data, e->size);
1760              svr->buf_size += e->size;
1761           }
1762         /* examine header */
1763         redo:
1764         if ((svr->buf_size - offset) >= (int)sizeof(int))
1765           {
1766              int s, md, d = 0, head;
1767              unsigned char *dd;
1768 
1769              dd = (unsigned char *)&head;
1770              dd[0] = *(svr->buf + offset + 0);
1771              dd[1] = *(svr->buf + offset + 1);
1772              dd[2] = *(svr->buf + offset + 2);
1773              dd[3] = *(svr->buf + offset + 3);
1774              head = eina_ntohl(head);
1775              dd = (unsigned char *)&d;
1776              s = 4;
1777              SVSZ(0);
1778              SVSZ(1);
1779              SVSZ(2);
1780              SVSZ(3);
1781              SVSZ(4);
1782              SVSZ(5);
1783              if ((svr->buf_size - offset) < s)
1784                {
1785                   if (offset > 0) goto scroll;
1786                   return ECORE_CALLBACK_CANCEL;
1787                }
1788 
1789              s = 4;
1790              SVDEC(0, major);
1791              SVDEC(1, minor);
1792              SVDEC(2, ref);
1793              SVDEC(3, ref_to);
1794              SVDEC(4, response);
1795              SVDEC(5, size);
1796              if (msg.size < 0) msg.size = 0;
1797              /* there is enough data in the buffer for a full message */
1798              if ((svr->buf_size - offset) >= (s + msg.size))
1799                {
1800                   Ecore_Ipc_Event_Server_Data *e2;
1801                   int max;
1802 
1803                   if (buf != svr->buf) free(buf);
1804                   buf = NULL;
1805                   max = svr->max_buf_size;
1806                   if ((max < 0) || (msg.size <= max))
1807                     {
1808                        if (msg.size > 0)
1809                          {
1810                             buf = malloc(msg.size);
1811                             if (!buf) return ECORE_CALLBACK_CANCEL;
1812                             memcpy(buf, svr->buf + offset + s, msg.size);
1813                          }
1814                        if (!svr->delete_me)
1815                          {
1816                             e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data));
1817                             if (e2)
1818                               {
1819                                  svr->event_count++;
1820                                  e2->server   = svr;
1821                                  e2->major    = msg.major;
1822                                  e2->minor    = msg.minor;
1823                                  e2->ref      = msg.ref;
1824                                  e2->ref_to   = msg.ref_to;
1825                                  e2->response = msg.response;
1826                                  e2->size     = msg.size;
1827                                  e2->data     = buf;
1828                                  if (buf == svr->buf)
1829                                    {
1830                                       svr->buf = NULL;
1831                                       svr->buf_size = 0;
1832                                    }
1833                                  buf = NULL;
1834                                  ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2,
1835                                                  _ecore_ipc_event_server_data_free,
1836                                                  NULL);
1837                               }
1838                             else
1839                               {
1840                                  free(buf);
1841                                  buf = NULL;
1842                               }
1843                          }
1844                        else
1845                          {
1846                             free(buf);
1847                             buf = NULL;
1848                          }
1849                     }
1850                   svr->prev.i = msg;
1851                   offset += (s + msg.size);
1852                   if ((svr->buf_size == offset) && (svr->buf))
1853                     {
1854                        free(svr->buf);
1855                        svr->buf = NULL;
1856                        svr->buf_size = 0;
1857                        return ECORE_CALLBACK_CANCEL;
1858                     }
1859                   goto redo;
1860                }
1861              else goto scroll;
1862           }
1863         else
1864           {
1865              scroll:
1866              if (buf != svr->buf) free(buf);
1867              buf = malloc(svr->buf_size - offset);
1868              if (!buf)
1869                {
1870                   free(svr->buf);
1871                   svr->buf = NULL;
1872                   svr->buf_size = 0;
1873                   return ECORE_CALLBACK_CANCEL;
1874                }
1875              memcpy(buf, svr->buf + offset, svr->buf_size - offset);
1876              free(svr->buf);
1877              svr->buf = buf;
1878              svr->buf_size -= offset;
1879           }
1880      }
1881 
1882    return ECORE_CALLBACK_CANCEL;
1883 }
1884 
1885 static void
_ecore_ipc_event_client_add_free(void * data EINA_UNUSED,void * ev)1886 _ecore_ipc_event_client_add_free(void *data EINA_UNUSED, void *ev)
1887 {
1888    Ecore_Ipc_Event_Client_Add *e;
1889 
1890    e = ev;
1891    e->client->event_count--;
1892    if ((e->client->event_count == 0) && (e->client->delete_me))
1893      ecore_ipc_client_del(e->client);
1894    free(e);
1895 }
1896 
1897 static void
_ecore_ipc_event_client_del_free(void * data EINA_UNUSED,void * ev)1898 _ecore_ipc_event_client_del_free(void *data EINA_UNUSED, void *ev)
1899 {
1900    Ecore_Ipc_Event_Client_Del *e;
1901 
1902    e = ev;
1903    e->client->event_count--;
1904    if ((e->client->event_count == 0) && (e->client->delete_me))
1905      ecore_ipc_client_del(e->client);
1906    free(e);
1907 }
1908 
1909 static void
_ecore_ipc_event_client_data_free(void * data EINA_UNUSED,void * ev)1910 _ecore_ipc_event_client_data_free(void *data EINA_UNUSED, void *ev)
1911 {
1912    Ecore_Ipc_Event_Client_Data *e;
1913 
1914    e = ev;
1915    e->client->event_count--;
1916    if (e->data) free(e->data);
1917    if ((e->client->event_count == 0) && (e->client->delete_me))
1918      ecore_ipc_client_del(e->client);
1919    free(e);
1920 }
1921 
1922 static void
_ecore_ipc_event_server_add_free(void * data EINA_UNUSED,void * ev)1923 _ecore_ipc_event_server_add_free(void *data EINA_UNUSED, void *ev)
1924 {
1925    Ecore_Ipc_Event_Server_Add *e;
1926 
1927    e = ev;
1928    e->server->event_count--;
1929    if ((e->server->event_count == 0) && (e->server->delete_me))
1930      ecore_ipc_server_del(e->server);
1931    free(e);
1932 }
1933 
1934 static void
_ecore_ipc_event_server_del_free(void * data EINA_UNUSED,void * ev)1935 _ecore_ipc_event_server_del_free(void *data EINA_UNUSED, void *ev)
1936 {
1937    Ecore_Ipc_Event_Server_Del *e;
1938 
1939    e = ev;
1940    e->server->event_count--;
1941    if ((e->server->event_count == 0) && (e->server->delete_me))
1942      ecore_ipc_server_del(e->server);
1943    free(e);
1944 }
1945 
1946 static void
_ecore_ipc_event_server_data_free(void * data EINA_UNUSED,void * ev)1947 _ecore_ipc_event_server_data_free(void *data EINA_UNUSED, void *ev)
1948 {
1949    Ecore_Ipc_Event_Server_Data *e;
1950 
1951    e = ev;
1952    if (e->data) free(e->data);
1953    e->server->event_count--;
1954    if ((e->server->event_count == 0) && (e->server->delete_me))
1955      ecore_ipc_server_del(e->server);
1956    free(e);
1957 }
1958