1 /* EINA - EFL data type library
2 * Copyright (C) 2015 Carsten Haitzler
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #define EFL_BETA_API_SUPPORT 1
24
25 #include <fcntl.h>
26 #include "eina_debug_private.h"
27
28 #ifdef _WIN32
29 # include <evil_private.h> /* mkdir */
30 #endif
31 #include <Eina.h>
32 #include <Ecore.h>
33 #include <Ecore_Con.h>
34
35 static int _log_dom = -1;
36 #ifdef ERR
37 # undef ERR
38 #endif
39 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
40
41 #ifdef DBG
42 # undef DBG
43 #endif
44 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
45
46 #ifdef INF
47 # undef INF
48 #endif
49 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
50
51 #ifdef WRN
52 # undef WRN
53 #endif
54 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
55
56 #ifdef CRI
57 # undef CRI
58 #endif
59 #define CRI(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
60 #if __BYTE_ORDER == __LITTLE_ENDIAN
61 #define SWAP_64(x) x
62 #define SWAP_32(x) x
63 #define SWAP_16(x) x
64 #else
65 #define SWAP_64(x) eina_swap64(x)
66 #define SWAP_32(x) eina_swap32(x)
67 #define SWAP_16(x) eina_swap16(x)
68 #endif
69
70 #define STORE(_buf, pval, sz) \
71 { \
72 memcpy(_buf, pval, sz); \
73 _buf += sz; \
74 }
75
76 #define EXTRACT(_buf, pval, sz) \
77 { \
78 memcpy(pval, _buf, sz); \
79 _buf += sz; \
80 }
81
82 typedef struct _Client Client;
83
84 struct _Client
85 {
86 Eo * client;
87 Eina_Stringshare *app_name;
88
89 int version;
90 int cid;
91 pid_t pid;
92
93 Eina_Bool cl_stat_obs : 1;
94 Eina_Bool is_master : 1;
95 };
96
97 static Eina_List *_clients = NULL;
98 static int _retval;
99
100 static Eo *_local_server = NULL, *_remote_server = NULL;
101
102 typedef Eina_Bool (*Opcode_Cb)(Client *client, void *buffer, int size);
103
104 static Eina_Hash *_string_to_opcode_hash = NULL;
105
106 static int _free_cid = 1;
107
108 static int _clients_stat_register_opcode = EINA_DEBUG_OPCODE_INVALID;
109 static int _slave_added_opcode = EINA_DEBUG_OPCODE_INVALID;
110 static int _slave_deleted_opcode = EINA_DEBUG_OPCODE_INVALID;
111 static int _cid_from_pid_opcode = EINA_DEBUG_OPCODE_INVALID;
112 static int _test_loop_opcode = EINA_DEBUG_OPCODE_INVALID;
113
114 typedef struct
115 {
116 int opcode;
117 Eina_Stringshare *opcode_string;
118 Opcode_Cb cb;
119 } Opcode_Information;
120
121 #define MAX_OPCODES 1000
122 Opcode_Information *_opcodes[MAX_OPCODES];
123
124 static Client *
_client_find_by_cid(int cid)125 _client_find_by_cid(int cid)
126 {
127 Client *c;
128 Eina_List *l;
129 EINA_LIST_FOREACH(_clients, l, c)
130 if (c->cid == cid) return c;
131 return NULL;
132 }
133
134 static Client *
_client_find_by_pid(int pid)135 _client_find_by_pid(int pid)
136 {
137 Client *c;
138 Eina_List *l;
139 EINA_LIST_FOREACH(_clients, l, c)
140 if (c->pid == pid) return c;
141 return NULL;
142 }
143
144 static void
_send(Client * dest,int opcode,void * payload,int payload_size)145 _send(Client *dest, int opcode, void *payload, int payload_size)
146 {
147 Eina_Error err;
148 Eina_Slice s, r;
149 Eina_Debug_Packet_Header hdr;
150 int size = sizeof(Eina_Debug_Packet_Header) + payload_size;
151
152 hdr.size = SWAP_32(size);
153 hdr.cid = 0;
154 hdr.opcode = SWAP_32(opcode);
155
156 s.mem = &hdr;
157 s.len = sizeof(hdr);
158
159 err = efl_io_writer_write(dest->client, &s, &r);
160 if (err || r.len) goto end;
161
162 if (!payload_size) goto end;
163
164 s.mem = payload;
165 s.len = payload_size;
166 err = efl_io_writer_write(dest->client, &s, &r);
167
168 INF("Send packet (size = %d, opcode %s) to %s", size,
169 _opcodes[opcode]->opcode_string,
170 dest->app_name);
171
172 end:
173 if (err)
174 {
175 fprintf(stderr, "ERROR: could not queue message '%d': %s\n", opcode, eina_error_msg_get(err));
176 }
177
178 if (r.len)
179 {
180 fprintf(stderr, "ERROR: could not queue message '%d': out of memory\n", opcode);
181 }
182 }
183
184 static Eina_Bool
_dispatch(Client * src,void * buffer)185 _dispatch(Client *src, void *buffer)
186 {
187 Eina_Debug_Packet_Header *hdr = (Eina_Debug_Packet_Header *)buffer;
188 if (hdr->cid)
189 {
190 /* If the client id is given, we forward */
191 Client *dest = _client_find_by_cid(hdr->cid);
192 if (dest)
193 {
194 if (dest->is_master != src->is_master)
195 {
196 Eina_Slice s;
197 s.mem = buffer;
198 s.len = hdr->size;
199 hdr->cid = SWAP_32(src->cid);
200 hdr->size = SWAP_32(hdr->size);
201 hdr->opcode = SWAP_32(hdr->opcode);
202 if (efl_io_writer_write(dest->client, &s, NULL) !=
203 EINA_ERROR_NO_ERROR)
204 ERR("Cannot write to client [%s:%i]", dest->app_name, (int)dest->pid);
205 INF("Transfer of %d bytes from %s(%d) to %s(%d): operation %s\n",
206 hdr->size,
207 src->app_name, src->pid,
208 dest->app_name, dest->pid,
209 _opcodes[hdr->opcode]->opcode_string);
210 }
211 else
212 {
213 /*
214 * Packets Master -> Master or Slave -> Slave are forbidden
215 * Only Master <-> Slave packets are allowed.
216 */
217 ERR("Packet from %d to %d: denied (same type)\n", hdr->cid, dest->cid);
218 }
219 }
220 }
221 else
222 {
223 INF("Invoke %s\n", _opcodes[hdr->opcode]->opcode_string);
224 if (_opcodes[hdr->opcode]->cb)
225 return _opcodes[hdr->opcode]->cb(src,
226 (char *)buffer + sizeof(Eina_Debug_Packet_Header),
227 hdr->size - sizeof(Eina_Debug_Packet_Header));
228 }
229 return EINA_TRUE;
230 }
231
232 static int
_opcode_register(const char * op_name,int op_id,Opcode_Cb cb)233 _opcode_register(const char *op_name, int op_id, Opcode_Cb cb)
234 {
235 static int free_opcode = 0;
236 Opcode_Information *op_info = eina_hash_find(_string_to_opcode_hash, op_name);
237 if (!op_info)
238 {
239 op_info = calloc(1, sizeof(*op_info));
240 if (op_id == EINA_DEBUG_OPCODE_INVALID)
241 {
242 do
243 {
244 free_opcode = (free_opcode + 1) % MAX_OPCODES;
245 op_id = free_opcode;
246 }
247 while(_opcodes[op_id]);
248 }
249 op_info->opcode = op_id;
250 op_info->opcode_string = eina_stringshare_add(op_name);
251 op_info->cb = cb;
252 eina_hash_add(_string_to_opcode_hash, op_name, op_info);
253 _opcodes[op_id] = op_info;
254 }
255 INF("Register %s -> opcode %d\n", op_name, op_info->opcode);
256 return op_info->opcode;
257 }
258
259 static Eina_Bool
_hello_cb(Client * c,void * buffer,int size)260 _hello_cb(Client *c, void *buffer, int size)
261 {
262 Eina_List *itr;
263 char *buf = (char *)buffer, *tmp;
264 int version, pid, cid;
265
266 EXTRACT(buf, &version, 4);
267 EXTRACT(buf, &pid, 4);
268 c->version = SWAP_32(version);
269 c->pid = SWAP_32(pid);
270 size -= 8;
271
272 c->cid = _free_cid++;
273 cid = SWAP_32(c->cid);
274 if (size > 1)
275 {
276 c->app_name = eina_stringshare_add_length(buf, size);
277 }
278 INF("Connection of %s: pid %d - name %s -> cid %d\n",
279 c->is_master ? "Master" : "Slave",
280 c->pid, c->app_name, c->cid);
281
282 if (c->is_master) return EINA_TRUE;
283
284 /* Update the observers */
285 size = 2 * sizeof(int) + (c->app_name ? strlen(c->app_name) : 0) + 1; /* cid + pid + name + \0 */
286 buf = alloca(size);
287 tmp = buf;
288 STORE(tmp, &cid, sizeof(int));
289 STORE(tmp, &pid, sizeof(int));
290 if (c->app_name)
291 {
292 STORE(tmp, c->app_name, strlen(c->app_name) + 1);
293 }
294 else
295 {
296 char end = '\0';
297 STORE(tmp, &end, 1);
298 }
299 EINA_LIST_FOREACH(_clients, itr, c)
300 {
301 if (c->cl_stat_obs) _send(c, _slave_added_opcode, buf, size);
302 }
303 return EINA_TRUE;
304 }
305
306 static Eina_Bool
_cid_get_cb(Client * src,void * buffer,int size EINA_UNUSED)307 _cid_get_cb(Client *src, void *buffer, int size EINA_UNUSED)
308 {
309 int pid = SWAP_32(*(int *)buffer);
310 Client *c = _client_find_by_pid(pid);
311 int cid = c ? SWAP_32(c->cid) : 0;
312 _send(src, _cid_from_pid_opcode, &cid, sizeof(int));
313 return EINA_TRUE;
314 }
315
316 static Eina_Bool
_data_test_cb(Client * src,void * buffer,int size)317 _data_test_cb(Client *src, void *buffer, int size)
318 {
319 DBG("Data test: loop packet of %d bytes\n", size);
320 _send(src, _test_loop_opcode, buffer, size);
321 return EINA_TRUE;
322 }
323
324 static Eina_Bool
_cl_stat_obs_register_cb(Client * src,void * buffer,int size)325 _cl_stat_obs_register_cb(Client *src, void *buffer, int size)
326 {
327 Client *c;
328 if (!src) return EINA_FALSE;
329 if (!src->is_master) return EINA_FALSE;
330 if (!src->cl_stat_obs)
331 {
332 Eina_List *itr;
333 src->cl_stat_obs = EINA_TRUE;
334 size = 0;
335 EINA_LIST_FOREACH(_clients, itr, c)
336 {
337 char *tmp;
338 int cid, pid;
339 if (c->is_master) continue;
340 size = 2 * sizeof(int) + (c->app_name ? strlen(c->app_name) : 0) + 1;
341 buffer = alloca(size);
342 tmp = buffer;
343 cid = SWAP_32(c->cid);
344 pid = SWAP_32(c->pid);
345 STORE(tmp, &cid, sizeof(int));
346 STORE(tmp, &pid, sizeof(int));
347 if (c->app_name)
348 {
349 STORE(tmp, c->app_name, strlen(c->app_name) + 1);
350 }
351 else
352 {
353 char end = '\0';
354 STORE(tmp, &end, 1);
355 }
356 _send(src, _slave_added_opcode, buffer, size);
357 }
358 }
359 return EINA_TRUE;
360 }
361
362 static Eina_Bool
_opcode_register_cb(Client * src,void * buffer,int size)363 _opcode_register_cb(Client *src, void *buffer, int size)
364 {
365 char *buf = (char *)buffer;
366 char *ops_buf = buf;
367 int ops_size = size;
368
369 ops_buf += sizeof(uint64_t);
370 ops_size -= sizeof(uint64_t);
371 int *opcodes = (int *)ops_buf;
372
373 while (ops_size > 0)
374 {
375 int len = strlen(ops_buf) + 1;
376 *opcodes++ = SWAP_32(_opcode_register(ops_buf, EINA_DEBUG_OPCODE_INVALID, NULL));
377 ops_buf += len;
378 ops_size -= len;
379 }
380
381 _send(src, EINA_DEBUG_OPCODE_REGISTER, buf, (char *)opcodes - (char *)buf);
382
383 return EINA_TRUE;
384 }
385
386 static void
_client_data(void * data,const Efl_Event * event)387 _client_data(void *data, const Efl_Event *event)
388 {
389 static unsigned char *buffer = NULL;
390 unsigned int size = 0;
391 Eina_Debug_Packet_Header *hdr;
392 Client *c = data;
393 Eina_Slice slice;
394
395 if (!c) return;
396
397 if (!buffer) buffer = malloc(EINA_DEBUG_MAX_PACKET_SIZE);
398
399 slice = efl_io_buffered_stream_slice_get(c->client);
400
401 if (slice.len < sizeof(*hdr)) return;
402
403 hdr = (Eina_Debug_Packet_Header *)slice.mem;
404 size = SWAP_32(hdr->size);
405 if (size < sizeof(*hdr)) /* must contain at least the header */
406 {
407 fprintf(stderr, "ERROR: invalid message header, size=%u\n", hdr->size);
408 goto err;
409 }
410
411 if (size > EINA_DEBUG_MAX_PACKET_SIZE)
412 {
413 fprintf(stderr, "ERROR: packet too big (max: %d), size=%u\n",
414 EINA_DEBUG_MAX_PACKET_SIZE, hdr->size);
415 goto err;
416 }
417
418 /* Incomplete packet: need to wait */
419 if (size > slice.len) return;
420
421 memcpy(buffer, slice.mem, size);
422 hdr = (Eina_Debug_Packet_Header *)buffer;
423 hdr->size = SWAP_32(hdr->size);
424 hdr->opcode = SWAP_32(hdr->opcode);
425 hdr->cid = SWAP_32(hdr->cid);
426
427 if(!_dispatch(c, buffer))
428 {
429 // something we don't understand
430 fprintf(stderr, "Dispatch: unknown command: %d\n", hdr->opcode);
431 }
432 efl_io_buffered_stream_discard(c->client, size);
433 return;
434 err:
435 if (!efl_io_closer_closed_get(event->object))
436 efl_io_closer_close(event->object);
437 fprintf(stderr, "INFO: client %p [pid: %d] sent invalid data\n", c, (int)c->pid);
438 }
439
440 static void
_client_error(void * data,const Efl_Event * event)441 _client_error(void *data, const Efl_Event *event)
442 {
443 Client *c = data;
444 Eina_Error *perr = event->info;
445 WRN("client %p [pid: %d] error: %s",
446 c, (int)c->pid, eina_error_msg_get(*perr));
447 fprintf(stderr, "INFO: client %p [pid: %d] error: %s\n",
448 c, (int)c->pid, eina_error_msg_get(*perr));
449 }
450
451 static void
_client_eos(void * data,const Efl_Event * event EINA_UNUSED)452 _client_eos(void *data, const Efl_Event *event EINA_UNUSED)
453 {
454 Client *c = data;
455 DBG("client %p (%p) [pid: %d] closed, pending read %zu, write %zu",
456 c, c->client, (int)c->pid,
457 efl_io_buffered_stream_pending_read_get(c->client),
458 efl_io_buffered_stream_pending_write_get(c->client));
459 efl_io_closer_close(c->client);
460 }
461
462 static void
_client_write_finished(void * data,const Efl_Event * event EINA_UNUSED)463 _client_write_finished(void *data, const Efl_Event *event EINA_UNUSED)
464 {
465 Client *c = data;
466 DBG("client %p (%p) [pid: %d] finished writing, pending read %zu",
467 c, c->client, (int)c->pid, efl_io_buffered_stream_pending_read_get(c->client));
468 }
469
470 static void
_client_read_finished(void * data,const Efl_Event * event EINA_UNUSED)471 _client_read_finished(void *data, const Efl_Event *event EINA_UNUSED)
472 {
473 Client *c = data;
474 DBG("client %p (%p) [pid: %d] finished reading, pending write %zu",
475 c, c->client, (int)c->pid, efl_io_buffered_stream_pending_write_get(c->client));
476 }
477
478 static Efl_Callback_Array_Item *_client_cbs(void);
479
480 static void
_client_finished(void * data,const Efl_Event * event EINA_UNUSED)481 _client_finished(void *data, const Efl_Event *event EINA_UNUSED)
482 {
483 Eina_List *itr;
484 Client *c = data, *c2;
485 int cid = SWAP_32(c->cid);
486 efl_event_callback_array_del(c->client, _client_cbs(), c);
487 INF("finished client %p (%p) [pid:%d]", c, c->client, c->pid);
488 _clients = eina_list_remove(_clients, c);
489 efl_unref(c->client);
490
491 /* Don't update the observers if the client is a master */
492 if (c->is_master) return;
493
494 EINA_LIST_FOREACH(_clients, itr, c2)
495 {
496 if (c2->cl_stat_obs) _send(c2, _slave_deleted_opcode, &cid, sizeof(int));
497 }
498 free(c);
499 }
500
501 EFL_CALLBACKS_ARRAY_DEFINE(_client_cbs,
502 { EFL_IO_READER_EVENT_EOS, _client_eos },
503 { EFL_IO_BUFFERED_STREAM_EVENT_ERROR, _client_error },
504 { EFL_IO_BUFFERED_STREAM_EVENT_READ_FINISHED, _client_read_finished },
505 { EFL_IO_BUFFERED_STREAM_EVENT_WRITE_FINISHED, _client_write_finished },
506 { EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, _client_finished },
507 { EFL_IO_BUFFERED_STREAM_EVENT_SLICE_CHANGED, _client_data });
508
509 static void
_client_add(void * data EINA_UNUSED,const Efl_Event * event)510 _client_add(void *data EINA_UNUSED, const Efl_Event *event)
511 {
512 Client *c = calloc(1, sizeof(Client));
513
514 EINA_SAFETY_ON_NULL_RETURN(c);
515 c->client = efl_ref(event->info);
516 c->is_master = (event->object == _remote_server);
517 _clients = eina_list_append(_clients, c);
518 efl_event_callback_array_add(c->client, _client_cbs(), c);
519 INF("server %p new client %p (%p)", event->object, c, c->client);
520 }
521
522 static void
_error(void * data EINA_UNUSED,const Efl_Event * event)523 _error(void *data EINA_UNUSED, const Efl_Event *event)
524 {
525 Eina_Error *perr = event->info;
526 ERR("server %p error: %s", event->object, eina_error_msg_get(*perr));
527 fprintf(stderr, "ERROR: %s\n", eina_error_msg_get(*perr));
528 ecore_main_loop_quit();
529 _retval = EXIT_FAILURE;
530 }
531
532 static Eina_Bool
_local_server_create(void)533 _local_server_create(void)
534 {
535 Eo *loop;
536 Eina_Error err;
537 mode_t mask = 0;
538 char path[512];
539 Eina_Bool ret = EINA_FALSE;
540
541 eina_vpath_resolve_snprintf(path, sizeof(path), "(:usr.run:)/%s", LOCAL_SERVER_PATH);
542 if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST)
543 {
544 perror("mkdir SERVER_PATH");
545 goto end;
546 }
547 eina_vpath_resolve_snprintf(path, sizeof(path), "(:usr.run:)/%s/%s", LOCAL_SERVER_PATH, LOCAL_SERVER_NAME);
548 if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST)
549 {
550 perror("mkdir SERVER_NAME");
551 goto end;
552 }
553 mask = umask(S_IRWXG | S_IRWXO);
554 eina_vpath_resolve_snprintf(path, sizeof(path) - 1, "(:usr.run:)/%s/%s/%i",
555 LOCAL_SERVER_PATH, LOCAL_SERVER_NAME, LOCAL_SERVER_PORT);
556
557 loop = efl_main_loop_get();
558
559 #ifdef EFL_NET_SERVER_UNIX_CLASS
560 _local_server = efl_add(EFL_NET_SERVER_SIMPLE_CLASS, loop,
561 efl_net_server_simple_inner_class_set(efl_added, EFL_NET_SERVER_UNIX_CLASS));
562 #else
563 /* TODO: maybe start a TCP using locahost:12345?
564 * Right now eina_debug_monitor is only for AF_UNIX, so not an issue.
565 */
566 fprintf(stderr, "ERROR: your platform doesn't support Efl.Net.Server.Unix\n");
567 #endif
568 if (!_local_server)
569 {
570 fprintf(stderr, "ERROR: could not create communication server\n");
571 goto end;
572 }
573
574 efl_event_callback_add(_local_server, EFL_NET_SERVER_EVENT_CLIENT_ADD, _client_add, NULL);
575 efl_event_callback_add(_local_server, EFL_NET_SERVER_EVENT_SERVER_ERROR, _error, NULL);
576
577 #ifdef EFL_NET_SERVER_UNIX_CLASS
578 {
579 Eo *inner_server = efl_net_server_simple_inner_server_get(_local_server);
580 efl_net_server_unix_leading_directories_create_set(inner_server, EINA_TRUE, 0700);
581 }
582 #endif
583
584 err = efl_net_server_serve(_local_server, path);
585 if (err)
586 {
587 fprintf(stderr, "ERROR: could not serve '%s': %s\n", path, eina_error_msg_get(err));
588 goto end;
589 }
590 ret = EINA_TRUE;
591 end:
592 umask(mask);
593 if (!ret)
594 {
595 efl_del(_local_server);
596 _local_server = NULL;
597 }
598 return ret;
599 }
600
601 static Eina_Bool
_remote_server_create(void)602 _remote_server_create(void)
603 {
604 Eo *loop;
605 Eina_Error err;
606 mode_t mask = 0;
607 Eina_Bool ret = EINA_FALSE;
608 char address[256];
609
610 loop = efl_main_loop_get();
611
612 _remote_server = efl_add(EFL_NET_SERVER_SIMPLE_CLASS, loop,
613 efl_net_server_simple_inner_class_set(efl_added, EFL_NET_SERVER_TCP_CLASS));
614 if (!_remote_server)
615 {
616 fprintf(stderr, "ERROR: could not create communication server\n");
617 goto end;
618 }
619
620 {
621 Eo *inner_server = efl_net_server_simple_inner_server_get(_remote_server);
622 efl_net_server_fd_reuse_address_set(inner_server, EINA_TRUE);
623 }
624 efl_event_callback_add(_remote_server, EFL_NET_SERVER_EVENT_CLIENT_ADD, _client_add, NULL);
625 efl_event_callback_add(_remote_server, EFL_NET_SERVER_EVENT_SERVER_ERROR, _error, NULL);
626
627 sprintf(address, "127.0.0.1:%d", REMOTE_SERVER_PORT);
628 err = efl_net_server_serve(_remote_server, address);
629 if (err)
630 {
631 fprintf(stderr, "ERROR: could not serve port '%d': %s\n",
632 REMOTE_SERVER_PORT, eina_error_msg_get(err));
633 goto end;
634 }
635 ret = EINA_TRUE;
636 end:
637 umask(mask);
638 if (!ret)
639 {
640 efl_del(_remote_server);
641 _remote_server = NULL;
642 }
643 return ret;
644 }
645
646 static Eina_Bool
_server_launch(void)647 _server_launch(void)
648 {
649 if (_local_server_create() <= 0) goto err;
650 if (_remote_server_create() <= 0) goto err;
651
652 return EINA_TRUE;
653 err:
654 efl_del(_local_server);
655 efl_del(_remote_server);
656 return EINA_FALSE;
657 }
658
659 int
main(int argc EINA_UNUSED,char ** argv EINA_UNUSED)660 main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
661 {
662 eina_debug_disable();
663 ecore_app_no_system_modules();
664
665 eina_init();
666 ecore_init();
667 ecore_con_init();
668
669 _retval = EXIT_SUCCESS;
670 _log_dom = eina_log_domain_register("efl_debugd", EINA_COLOR_CYAN);
671
672 _string_to_opcode_hash = eina_hash_string_superfast_new(NULL);
673 _opcode_register("Daemon/opcode_register", EINA_DEBUG_OPCODE_REGISTER, _opcode_register_cb);
674 _opcode_register("Daemon/greet", EINA_DEBUG_OPCODE_HELLO, _hello_cb);
675 _clients_stat_register_opcode = _opcode_register("Daemon/Client/register_observer", EINA_DEBUG_OPCODE_INVALID, _cl_stat_obs_register_cb);
676 _slave_added_opcode = _opcode_register("Daemon/Client/added", EINA_DEBUG_OPCODE_INVALID, NULL);
677 _slave_deleted_opcode = _opcode_register("Daemon/Client/deleted", EINA_DEBUG_OPCODE_INVALID, NULL);
678 _cid_from_pid_opcode = _opcode_register("Daemon/Client/cid_from_pid", EINA_DEBUG_OPCODE_INVALID, _cid_get_cb);
679 _test_loop_opcode = _opcode_register("Test/data_loop", EINA_DEBUG_OPCODE_INVALID, _data_test_cb);
680
681 if (_server_launch()) ecore_main_loop_begin();
682 else _retval = EXIT_FAILURE;
683
684 ecore_con_shutdown();
685 ecore_shutdown();
686 eina_shutdown();
687
688 return _retval;
689 }
690