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