2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 #include "Ecore_Con.h"
11 #include "ecore_private.h"
12 #include "ecore_ipc_private.h"
13 #include "Ecore_Ipc.h"
15 #ifdef HAVE_NETINET_IN_H
16 # include <netinet/in.h>
19 #ifdef HAVE_WINSOCK2_H
20 # include <winsock2.h>
40 /* byte swappers - for dealing with big vs little endian machines */
42 _ecore_ipc_swap_16(unsigned short v)
46 s = (unsigned char *)(&v);
47 t = s[0]; s[0] = s[1]; s[1] = t;
52 _ecore_ipc_swap_32(unsigned int v)
56 s = (unsigned char *)(&v);
57 t = s[0]; s[0] = s[3]; s[3] = t;
58 t = s[1]; s[1] = s[2]; s[2] = t;
62 EAPI unsigned long long
63 _ecore_ipc_swap_64(unsigned long long v)
67 s = (unsigned char *)(&v);
68 t = s[0]; s[0] = s[7]; s[7] = t;
69 t = s[1]; s[1] = s[6]; s[6] = t;
70 t = s[2]; s[2] = s[5]; s[5] = t;
71 t = s[3]; s[3] = s[4]; s[4] = t;
75 static int _ecore_ipc_dlt_int(int out, int prev, int *mode);
76 static int _ecore_ipc_ddlt_int(int in, int prev, int mode);
79 _ecore_ipc_dlt_int(int out, int prev, int *mode)
89 if (out == (int)0xffffffff)
104 if (out == prev >> 1)
111 if (!(dlt & 0xffffff00))
117 if (!(dlt & 0xffffff00))
123 if (!(dlt & 0x00ffffff))
126 return (dlt >> 24) & 0xff;
129 if (!(dlt & 0x00ffffff))
132 return (dlt >> 24) & 0xff;
136 if (!(dlt & 0xffff0000))
142 if (!(dlt & 0xffff0000))
148 if (!(dlt & 0x0000ffff))
151 return (dlt >> 16) & 0xffff;
154 if (!(dlt & 0x0000ffff))
157 return (dlt >> 16) & 0xffff;
165 _ecore_ipc_ddlt_int(int in, int prev, int mode)
191 return prev + (in << 24);
194 return prev - (in << 24);
203 return prev + (in << 16);
206 return prev - (in << 16);
223 static int _ecore_ipc_event_client_add(void *data, int ev_type, void *ev);
224 static int _ecore_ipc_event_client_del(void *data, int ev_type, void *ev);
225 static int _ecore_ipc_event_server_add(void *data, int ev_type, void *ev);
226 static int _ecore_ipc_event_server_del(void *data, int ev_type, void *ev);
227 static int _ecore_ipc_event_client_data(void *data, int ev_type, void *ev);
228 static int _ecore_ipc_event_server_data(void *data, int ev_type, void *ev);
229 static void _ecore_ipc_event_client_add_free(void *data, void *ev);
230 static void _ecore_ipc_event_client_del_free(void *data, void *ev);
231 static void _ecore_ipc_event_client_data_free(void *data, void *ev);
232 static void _ecore_ipc_event_server_add_free(void *data, void *ev);
233 static void _ecore_ipc_event_server_del_free(void *data, void *ev);
234 static void _ecore_ipc_event_server_data_free(void *data, void *ev);
236 EAPI int ECORE_IPC_EVENT_CLIENT_ADD = 0;
237 EAPI int ECORE_IPC_EVENT_CLIENT_DEL = 0;
238 EAPI int ECORE_IPC_EVENT_SERVER_ADD = 0;
239 EAPI int ECORE_IPC_EVENT_SERVER_DEL = 0;
240 EAPI int ECORE_IPC_EVENT_CLIENT_DATA = 0;
241 EAPI int ECORE_IPC_EVENT_SERVER_DATA = 0;
243 static int init_count = 0;
244 static Ecore_Ipc_Server *servers = NULL;
245 static Ecore_Event_Handler *handler[6];
248 * @defgroup Ecore_IPC_Library_Group IPC Library Functions
250 * Functions that set up and shut down the Ecore IPC Library.
254 * Initialises the Ecore IPC library.
255 * @return Number of times the library has been initialised without
257 * @ingroup Ecore_IPC_Library_Group
264 if (++init_count != 1) return init_count;
268 ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new();
269 ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new();
270 ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new();
271 ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new();
272 ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new();
273 ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new();
275 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD,
276 _ecore_ipc_event_client_add, NULL);
277 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL,
278 _ecore_ipc_event_client_del, NULL);
279 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
280 _ecore_ipc_event_server_add, NULL);
281 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
282 _ecore_ipc_event_server_del, NULL);
283 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA,
284 _ecore_ipc_event_client_data, NULL);
285 handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
286 _ecore_ipc_event_server_data, NULL);
291 * Shuts down the Ecore IPC library.
292 * @return Number of times the library has been initialised without being
294 * @ingroup Ecore_IPC_Library_Group
297 ecore_ipc_shutdown(void)
301 if (--init_count != 0) return init_count;
303 while (servers) ecore_ipc_server_del(servers);
305 for (i = 0; i < 6; i++)
306 ecore_event_handler_del(handler[i]);
308 ecore_con_shutdown();
314 * @defgroup Ecore_IPC_Server_Group IPC Server Functions
316 * Functions the deal with IPC server objects.
320 * Creates an IPC server that listens for connections.
322 * For more details about the @p compl_type, @p name and @p port
323 * parameters, see the @ref ecore_con_server_add documentation.
325 * @param compl_type The connection type.
326 * @param name Name to associate with the socket used for connection.
327 * @param port Number to identify with socket used for connection.
328 * @param data Data to associate with the IPC server.
329 * @return New IPC server. If there is an error, @c NULL is returned.
330 * @ingroup Ecore_IPC_Server_Group
331 * @todo Need to add protocol type parameter to this function.
333 EAPI Ecore_Ipc_Server *
334 ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data)
336 Ecore_Ipc_Server *svr;
338 Ecore_Con_Type extra = 0;
340 svr = calloc(1, sizeof(Ecore_Ipc_Server));
341 if (!svr) return NULL;
343 type &= ~ECORE_IPC_USE_SSL;
344 if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
347 case ECORE_IPC_LOCAL_USER:
348 svr->server = ecore_con_server_add(ECORE_CON_LOCAL_USER | extra, name, port, svr);
350 case ECORE_IPC_LOCAL_SYSTEM:
351 svr->server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
353 case ECORE_IPC_REMOTE_SYSTEM:
354 svr->server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
365 svr->max_buf_size = 32 * 1024;
366 svr->data = (void *)data;
367 svr->client_list = ecore_list_new();
368 ecore_list_init(svr->client_list);
369 servers = _ecore_list2_append(servers, svr);
370 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
375 * Creates an IPC server object to represent the IPC server listening
378 * For more details about the @p compl_type, @p name and @p port
379 * parameters, see the @ref ecore_con_server_connect documentation.
381 * @param compl_type The IPC connection type.
382 * @param name Name used to determine which socket to use for the
384 * @param port Number used to identify the socket to use for the
386 * @param data Data to associate with the server.
387 * @return A new IPC server. @c NULL is returned on error.
388 * @ingroup Ecore_IPC_Server_Group
389 * @todo Need to add protocol type parameter.
391 EAPI Ecore_Ipc_Server *
392 ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data)
394 Ecore_Ipc_Server *svr;
396 Ecore_Con_Type extra = 0;
398 svr = calloc(1, sizeof(Ecore_Ipc_Server));
399 if (!svr) return NULL;
401 type &= ~ECORE_IPC_USE_SSL;
402 if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
405 case ECORE_IPC_LOCAL_USER:
406 svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr);
408 case ECORE_IPC_LOCAL_SYSTEM:
409 svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
411 case ECORE_IPC_REMOTE_SYSTEM:
412 svr->server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
423 svr->max_buf_size = -1;
424 svr->data = (void *)data;
425 servers = _ecore_list2_append(servers, svr);
426 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
431 * Closes the connection and frees the given IPC server.
432 * @param svr The given IPC server.
433 * @return The data associated with the server when it was created.
434 * @ingroup Ecore_IPC_Server_Group
437 ecore_ipc_server_del(Ecore_Ipc_Server *svr)
441 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
443 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
444 "ecore_ipc_server_del");
450 if (svr->event_count == 0)
453 ecore_ipc_client_del((Ecore_Ipc_Client *)svr->clients);
454 ecore_con_server_del(svr->server);
455 servers = _ecore_list2_remove(servers, svr);
456 if (svr->buf) free(svr->buf);
457 if (svr->client_list) ecore_list_destroy(svr->client_list);
458 ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
465 * Retrieves the data associated with the given IPC server.
466 * @param svr The given IPC server.
467 * @return The associated data.
468 * @ingroup Ecore_IPC_Server_Group
471 ecore_ipc_server_data_get(Ecore_Ipc_Server *svr)
473 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
475 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
476 "ecore_ipc_server_data_get");
483 * Retrieves whether the given IPC server is currently connected.
484 * @param svr The given IPC server.
485 * @return @c 1 if the server is connected. @c 0 otherwise.
486 * @ingroup Ecore_IPC_Server_Group
489 ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
491 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
493 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
494 "ecore_ipc_server_connected_get");
497 return ecore_con_server_connected_get(svr->server);
501 * Retrieves the list of clients for this server.
502 * @param svr The given IPC server.
503 * @return An Ecore_List with the clients.
504 * @ingroup Ecore_IPC_Server_Group
507 ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr)
509 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
511 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
512 "ecore_ipc_server_clients_get");
515 return svr->client_list;
518 #define SVENC(_member) \
519 d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \
524 dd = (unsigned char *)&v; \
527 *(dat + s + 0) = dd[0]; \
528 *(dat + s + 1) = dd[1]; \
529 *(dat + s + 2) = dd[2]; \
530 *(dat + s + 3) = dd[3]; \
533 else if (md >= DLT_ADD16) \
537 dd = (unsigned char *)&v; \
540 *(dat + s + 0) = dd[0]; \
541 *(dat + s + 1) = dd[1]; \
544 else if (md >= DLT_ADD8) \
546 *(dat + s + 0) = (unsigned char)d; \
551 * Sends a message to the given IPC server.
553 * The content of the parameters, excluding the @p svr paramter, is up to
556 * @param svr The given IPC server.
557 * @param major Major opcode of the message.
558 * @param minor Minor opcode of the message.
559 * @param ref Message reference number.
560 * @param ref_to Reference number of the message this message refers to.
561 * @param response Requires response.
562 * @param data The data to send as part of the message.
563 * @param size Length of the data, in bytes, to send.
564 * @return Number of bytes sent. @c 0 is returned if there is an error.
565 * @ingroup Ecore_IPC_Server_Group
566 * @todo This function needs to become an IPC message.
567 * @todo Fix up the documentation: Make sure what ref_to and response are.
570 ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
572 Ecore_Ipc_Msg_Head msg;
574 int *head, md = 0, d, s;
575 unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
577 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
579 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
580 "ecore_ipc_server_send");
583 if (size < 0) size = 0;
588 msg.response = response;
595 *head |= md << (4 * 1);
597 *head |= md << (4 * 2);
599 *head |= md << (4 * 3);
601 *head |= md << (4 * 4);
603 *head |= md << (4 * 5);
604 *head = htonl(*head);
606 ret = ecore_con_server_send(svr->server, dat, s);
607 if (size > 0) ret += ecore_con_server_send(svr->server, data, size);
612 * Sets a limit on the number of clients that can be handled concurrently
613 * by the given server, and a policy on what to do if excess clients try to
615 * Beware that if you set this once ecore is already running, you may
616 * already have pending CLIENT_ADD events in your event queue. Those
617 * clients have already connected and will not be affected by this call.
618 * Only clients subsequently trying to connect will be affected.
619 * @param svr The given server.
620 * @param client_limit The maximum number of clients to handle
621 * concurrently. -1 means unlimited (default). 0
622 * effectively disables the server.
623 * @param reject_excess_clients Set to 1 to automatically disconnect
624 * excess clients as soon as they connect if you are
625 * already handling client_limit clients. Set to 0
626 * (default) to just hold off on the "accept()"
627 * system call until the number of active clients
628 * drops. This causes the kernel to queue up to 4096
629 * connections (or your kernel's limit, whichever is
631 * @ingroup Ecore_Ipc_Server_Group
634 ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients)
636 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
638 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
639 "ecore_ipc_server_client_limit_set");
642 ecore_con_server_client_limit_set(svr->server, client_limit, reject_excess_clients);
646 * Sets the max data payload size for an Ipc message in bytes
648 * @param svr The given server.
649 * @param size The maximum data payload size in bytes.
650 * @ingroup Ecore_Ipc_Server_Group
653 ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *svr, int size)
655 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
657 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
658 "ecore_ipc_server_data_size_max_set");
661 svr->max_buf_size = size;
665 * Gets the max data payload size for an Ipc message in bytes
667 * @param svr The given server.
668 * @return The maximum data payload in bytes.
669 * @ingroup Ecore_Ipc_Server_Group
672 ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *svr)
674 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
676 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
677 "ecore_ipc_server_data_size_max_get");
680 return svr->max_buf_size;
684 * Gets the IP address of a server that has been connected to.
686 * @param svr The given server.
687 * @return A pointer to an internal string that contains the IP address of
688 * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
689 * This string should not be modified or trusted to stay valid after
690 * deletion for the @p svr object. If no IP is known NULL is returned.
691 * @ingroup Ecore_Ipc_Server_Group
694 ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr)
696 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
698 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
699 "ecore_ipc_server_ip_get");
702 return ecore_con_server_ip_get(svr->server);
706 * Flushes all pending data to the given server. Will return when done.
708 * @param svr The given server.
709 * @ingroup Ecore_Ipc_Server_Group
712 ecore_ipc_server_flush(Ecore_Ipc_Server *svr)
714 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
716 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
717 "ecore_ipc_server_server_flush");
720 ecore_con_server_flush(svr->server);
723 #define CLENC(_member) \
724 d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \
729 dd = (unsigned char *)&v; \
732 *(dat + s + 0) = dd[0]; \
733 *(dat + s + 1) = dd[1]; \
734 *(dat + s + 2) = dd[2]; \
735 *(dat + s + 3) = dd[3]; \
738 else if (md >= DLT_ADD16) \
742 dd = (unsigned char *)&v; \
745 *(dat + s + 0) = dd[0]; \
746 *(dat + s + 1) = dd[1]; \
749 else if (md >= DLT_ADD8) \
751 *(dat + s) = (unsigned char)d; \
756 * @defgroup Ecore_IPC_Client_Group IPC Client Functions
758 * Functions that deal with IPC client objects.
762 * Sends a message to the given IPC client.
763 * @param cl The given IPC client.
764 * @param major Major opcode of the message.
765 * @param minor Minor opcode of the message.
766 * @param ref Reference number of the message.
767 * @param ref_to Reference number of the message this message refers to.
768 * @param response Requires response.
769 * @param data The data to send as part of the message.
770 * @param size Length of the data, in bytes, to send.
771 * @return The number of bytes sent. @c 0 will be returned if there is
773 * @ingroup Ecore_IPC_Client_Group
774 * @todo This function needs to become an IPC message.
775 * @todo Make sure ref_to and response parameters are described correctly.
778 ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
780 Ecore_Ipc_Msg_Head msg;
782 int *head, md = 0, d, s;
783 unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
785 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
787 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
788 "ecore_ipc_client_send");
791 if (size < 0) size = 0;
796 msg.response = response;
803 *head |= md << (4 * 1);
805 *head |= md << (4 * 2);
807 *head |= md << (4 * 3);
809 *head |= md << (4 * 4);
811 *head |= md << (4 * 5);
812 *head = htonl(*head);
814 ret = ecore_con_client_send(cl->client, dat, s);
815 if (size > 0) ret += ecore_con_client_send(cl->client, data, size);
820 * Retrieves the IPC server that the given IPC client is connected to.
821 * @param cl The given IPC client.
822 * @return The IPC server the IPC client is connected to.
823 * @ingroup Ecore_IPC_Client_Group
825 EAPI Ecore_Ipc_Server *
826 ecore_ipc_client_server_get(Ecore_Ipc_Client *cl)
828 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
830 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
831 "ecore_ipc_client_server_get");
834 return (ecore_con_server_data_get(ecore_con_client_server_get(cl->client)));
838 * Closes the connection and frees memory allocated to the given IPC
840 * @param cl The given client.
841 * @return Data associated with the client.
842 * @ingroup Ecore_IPC_Client_Group
845 ecore_ipc_client_del(Ecore_Ipc_Client *cl)
848 Ecore_Ipc_Server *svr;
850 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
852 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
853 "ecore_ipc_client_del");
859 if (cl->event_count == 0)
861 svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
862 ecore_con_client_del(cl->client);
863 svr->clients = _ecore_list2_remove(svr->clients, cl);
864 if (cl->buf) free(cl->buf);
865 ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
872 * Sets the IPC data associated with the given IPC client to @p data.
873 * @param cl The given IPC client.
874 * @param data The data to associate with the IPC client.
875 * @ingroup Ecore_IPC_Client_Group
878 ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data)
880 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
882 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
883 "ecore_ipc_client_data_set");
886 cl->data = (void *)data;
890 * Retrieves the data that has been associated with the given IPC client.
891 * @param cl The given client.
892 * @return The data associated with the IPC client.
893 * @ingroup Ecore_IPC_Client_Group
896 ecore_ipc_client_data_get(Ecore_Ipc_Client *cl)
898 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
900 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
901 "ecore_ipc_client_data_get");
908 * Sets the max data payload size for an Ipc message in bytes
910 * @param client The given client.
911 * @param size The maximum data payload size in bytes.
912 * @ingroup Ecore_Ipc_Client_Group
915 ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client *cl, int size)
917 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
919 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
920 "ecore_ipc_client_data_size_max_set");
923 cl->max_buf_size = size;
927 * Sets the max data payload size for an Ipc message in bytes
929 * @param cl The given client.
930 * @param size The maximum data payload size in bytes.
931 * @ingroup Ecore_Ipc_Client_Group
934 ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client *cl)
936 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
938 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
939 "ecore_ipc_client_data_size_max_get");
942 return cl->max_buf_size;
946 * Gets the IP address of a client that has been connected to.
948 * @param cl The given client.
949 * @return A pointer to an internal string that contains the IP address of
950 * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
951 * This string should not be modified or trusted to stay valid after
952 * deletion for the @p cl object. If no IP is known NULL is returned.
953 * @ingroup Ecore_Ipc_Client_Group
956 ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl)
958 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
960 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
961 "ecore_ipc_client_ip_get");
964 return ecore_con_client_ip_get(cl->client);
968 * Flushes all pending data to the given client. Will return when done.
970 * @param cl The given client.
971 * @ingroup Ecore_Ipc_Client_Group
974 ecore_ipc_client_flush(Ecore_Ipc_Client *cl)
976 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
978 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
979 "ecore_ipc_client_flush");
982 ecore_con_client_flush(cl->client);
986 * Returns if SSL support is available
987 * @return 1 if SSL is available, 0 if it is not.
988 * @ingroup Ecore_Con_Client_Group
991 ecore_ipc_ssl_available_get(void)
993 return ecore_con_ssl_available_get();
998 _ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1000 Ecore_Con_Event_Client_Add *e;
1003 if (!_ecore_list2_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
1004 /* handling code here */
1006 Ecore_Ipc_Client *cl;
1007 Ecore_Ipc_Server *svr;
1009 cl = calloc(1, sizeof(Ecore_Ipc_Client));
1011 svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
1012 ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
1013 cl->client = e->client;
1014 cl->max_buf_size = 32 * 1024;
1015 ecore_con_client_data_set(cl->client, (void *)cl);
1016 svr->clients = _ecore_list2_append(svr->clients, cl);
1017 ecore_list_append(svr->client_list, cl);
1020 Ecore_Ipc_Event_Client_Add *e2;
1022 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add));
1027 ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, e2,
1028 _ecore_ipc_event_client_add_free, NULL);
1036 _ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1038 Ecore_Con_Event_Client_Del *e;
1041 if (!_ecore_list2_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
1042 /* handling code here */
1044 Ecore_Ipc_Client *cl;
1046 cl = ecore_con_client_data_get(e->client);
1048 Ecore_Ipc_Event_Client_Del *e2;
1049 Ecore_Ipc_Server *svr;
1051 svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
1052 ecore_list_goto(svr->client_list, cl);
1053 ecore_list_remove(svr->client_list);
1054 ecore_list_first_goto(svr->client_list);
1057 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del));
1062 ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, e2,
1063 _ecore_ipc_event_client_del_free, NULL);
1072 _ecore_ipc_event_server_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1074 Ecore_Con_Event_Server_Add *e;
1077 if (!_ecore_list2_find(servers, ecore_con_server_data_get(e->server))) return 1;
1078 /* handling code here */
1080 Ecore_Ipc_Server *svr;
1082 svr = ecore_con_server_data_get(e->server);
1083 if (!svr->delete_me)
1085 Ecore_Ipc_Event_Server_Add *e2;
1087 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add));
1092 ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, e2,
1093 _ecore_ipc_event_server_add_free, NULL);
1101 _ecore_ipc_event_server_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1103 Ecore_Con_Event_Server_Del *e;
1106 if (!_ecore_list2_find(servers, ecore_con_server_data_get(e->server))) return 1;
1107 /* handling code here */
1109 Ecore_Ipc_Server *svr;
1111 svr = ecore_con_server_data_get(e->server);
1112 if (!svr->delete_me)
1114 Ecore_Ipc_Event_Server_Del *e2;
1116 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del));
1121 ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, e2,
1122 _ecore_ipc_event_server_del_free, NULL);
1130 md = ((head >> (4 * _n)) & 0xf); \
1131 if (md >= DLT_SET) s += 4; \
1132 else if (md >= DLT_ADD16) s += 2; \
1133 else if (md >= DLT_ADD8) s += 1;
1135 #define CLDEC(_n, _member) \
1136 md = ((head >> (4 * _n)) & 0xf); \
1137 if (md >= DLT_SET) \
1140 unsigned char *dv; \
1141 dv = (unsigned char *)&v; \
1142 dv[0] = *(cl->buf + offset + s + 0); \
1143 dv[1] = *(cl->buf + offset + s + 1); \
1144 dv[2] = *(cl->buf + offset + s + 2); \
1145 dv[3] = *(cl->buf + offset + s + 3); \
1146 d = (int)ntohl(v); \
1149 else if (md >= DLT_ADD16) \
1152 unsigned char *dv; \
1153 dv = (unsigned char *)&v; \
1154 dv[0] = *(cl->buf + offset + s + 0); \
1155 dv[1] = *(cl->buf + offset + s + 1); \
1156 d = (int)ntohs(v); \
1159 else if (md >= DLT_ADD8) \
1162 unsigned char *dv; \
1163 dv = (unsigned char *)&v; \
1164 dv[0] = *(cl->buf + offset + s + 0); \
1168 msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md);
1171 _ecore_ipc_event_client_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1173 Ecore_Con_Event_Client_Data *e;
1176 if (!_ecore_list2_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
1177 /* handling code here */
1179 Ecore_Ipc_Client *cl;
1180 Ecore_Ipc_Msg_Head msg;
1184 cl = ecore_con_client_data_get(e->client);
1188 cl->buf_size = e->size;
1190 e->data = NULL; /* take it out of the old event */
1194 buf = realloc(cl->buf, cl->buf_size + e->size);
1203 memcpy(cl->buf + cl->buf_size, e->data, e->size);
1204 cl->buf_size += e->size;
1206 /* examine header */
1208 if ((cl->buf_size - offset) >= (int)sizeof(int))
1210 int s, md, d = 0, head;
1213 dd = (unsigned char *)&head;
1214 dd[0] = *(cl->buf + offset + 0);
1215 dd[1] = *(cl->buf + offset + 1);
1216 dd[2] = *(cl->buf + offset + 2);
1217 dd[3] = *(cl->buf + offset + 3);
1219 dd = (unsigned char *)&d;
1227 if ((cl->buf_size - offset) < s)
1229 if (offset > 0) goto scroll;
1240 if (msg.size < 0) msg.size = 0;
1241 /* there is enough data in the buffer for a full message */
1242 if ((cl->buf_size - offset) >= (s + msg.size))
1244 Ecore_Ipc_Event_Client_Data *e2;
1245 Ecore_Ipc_Server *svr;
1249 svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
1250 max = svr->max_buf_size;
1251 max2 = cl->max_buf_size;
1252 if ((max >= 0) && (max2 >= 0))
1254 if (max2 < max) max = max2;
1258 if (max < 0) max = max2;
1260 if ((max < 0) || (msg.size <= max))
1264 buf = malloc(msg.size);
1266 memcpy(buf, cl->buf + offset + s, msg.size);
1270 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data));
1275 e2->major = msg.major;
1276 e2->minor = msg.minor;
1278 e2->ref_to = msg.ref_to;
1279 e2->response = msg.response;
1280 e2->size = msg.size;
1282 ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2,
1283 _ecore_ipc_event_client_data_free,
1289 offset += (s + msg.size);
1290 if (cl->buf_size == offset)
1304 buf = malloc(cl->buf_size - offset);
1312 memcpy(buf, cl->buf + offset, cl->buf_size - offset);
1315 cl->buf_size -= offset;
1322 md = ((head >> (4 * _n)) & 0xf); \
1323 if (md >= DLT_SET) s += 4; \
1324 else if (md >= DLT_ADD16) s += 2; \
1325 else if (md >= DLT_ADD8) s += 1;
1327 #define SVDEC(_n, _member) \
1328 md = ((head >> (4 * _n)) & 0xf); \
1329 if (md >= DLT_SET) \
1332 unsigned char *dv; \
1333 dv = (unsigned char *)&v; \
1334 dv[0] = *(svr->buf + offset + s + 0); \
1335 dv[1] = *(svr->buf + offset + s + 1); \
1336 dv[2] = *(svr->buf + offset + s + 2); \
1337 dv[3] = *(svr->buf + offset + s + 3); \
1338 d = (int)ntohl(v); \
1341 else if (md >= DLT_ADD16) \
1344 unsigned char *dv; \
1345 dv = (unsigned char *)&v; \
1346 dv[0] = *(svr->buf + offset + s + 0); \
1347 dv[1] = *(svr->buf + offset + s + 1); \
1348 d = (int)ntohs(v); \
1351 else if (md >= DLT_ADD8) \
1354 unsigned char *dv; \
1355 dv = (unsigned char *)&v; \
1356 dv[0] = *(svr->buf + offset + s + 0); \
1360 msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md);
1363 _ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1365 Ecore_Con_Event_Server_Data *e;
1368 if (!_ecore_list2_find(servers, ecore_con_server_data_get(e->server))) return 1;
1369 /* handling code here */
1371 Ecore_Ipc_Server *svr;
1372 Ecore_Ipc_Msg_Head msg;
1376 svr = ecore_con_server_data_get(e->server);
1380 svr->buf_size = e->size;
1382 e->data = NULL; /* take it out of the old event */
1386 buf = realloc(svr->buf, svr->buf_size + e->size);
1395 memcpy(svr->buf + svr->buf_size, e->data, e->size);
1396 svr->buf_size += e->size;
1398 /* examine header */
1400 if ((svr->buf_size - offset) >= (int)sizeof(int))
1402 int s, md, d = 0, head;
1405 dd = (unsigned char *)&head;
1406 dd[0] = *(svr->buf + offset + 0);
1407 dd[1] = *(svr->buf + offset + 1);
1408 dd[2] = *(svr->buf + offset + 2);
1409 dd[3] = *(svr->buf + offset + 3);
1411 dd = (unsigned char *)&d;
1419 if ((svr->buf_size - offset) < s)
1421 if (offset > 0) goto scroll;
1432 if (msg.size < 0) msg.size = 0;
1433 /* there is enough data in the buffer for a full message */
1434 if ((svr->buf_size - offset) >= (s + msg.size))
1436 Ecore_Ipc_Event_Server_Data *e2;
1440 max = svr->max_buf_size;
1441 if ((max < 0) || (msg.size <= max))
1445 buf = malloc(msg.size);
1447 memcpy(buf, svr->buf + offset + s, msg.size);
1449 if (!svr->delete_me)
1451 e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data));
1456 e2->major = msg.major;
1457 e2->minor = msg.minor;
1459 e2->ref_to = msg.ref_to;
1460 e2->response = msg.response;
1461 e2->size = msg.size;
1463 ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2,
1464 _ecore_ipc_event_server_data_free,
1470 offset += (s + msg.size);
1471 if (svr->buf_size == offset)
1485 buf = malloc(svr->buf_size - offset);
1493 memcpy(buf, svr->buf + offset, svr->buf_size - offset);
1496 svr->buf_size -= offset;
1503 _ecore_ipc_event_client_add_free(void *data __UNUSED__, void *ev)
1505 Ecore_Ipc_Event_Client_Add *e;
1508 e->client->event_count--;
1509 if ((e->client->event_count == 0) && (e->client->delete_me))
1510 ecore_ipc_client_del(e->client);
1515 _ecore_ipc_event_client_del_free(void *data __UNUSED__, void *ev)
1517 Ecore_Ipc_Event_Client_Del *e;
1520 e->client->event_count--;
1521 if ((e->client->event_count == 0) && (e->client->delete_me))
1522 ecore_ipc_client_del(e->client);
1527 _ecore_ipc_event_client_data_free(void *data __UNUSED__, void *ev)
1529 Ecore_Ipc_Event_Client_Data *e;
1532 e->client->event_count--;
1533 if (e->data) free(e->data);
1534 if ((e->client->event_count == 0) && (e->client->delete_me))
1535 ecore_ipc_client_del(e->client);
1540 _ecore_ipc_event_server_add_free(void *data __UNUSED__, void *ev)
1542 Ecore_Ipc_Event_Server_Add *e;
1545 e->server->event_count--;
1546 if ((e->server->event_count == 0) && (e->server->delete_me))
1547 ecore_ipc_server_del(e->server);
1552 _ecore_ipc_event_server_del_free(void *data __UNUSED__, void *ev)
1554 Ecore_Ipc_Event_Server_Add *e;
1557 e->server->event_count--;
1558 if ((e->server->event_count == 0) && (e->server->delete_me))
1559 ecore_ipc_server_del(e->server);
1564 _ecore_ipc_event_server_data_free(void *data __UNUSED__, void *ev)
1566 Ecore_Ipc_Event_Server_Data *e;
1569 if (e->data) free(e->data);
1570 e->server->event_count--;
1571 if ((e->server->event_count == 0) && (e->server->delete_me))
1572 ecore_ipc_server_del(e->server);