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