12 #ifdef HAVE_SYS_SOCKET_H
13 # include <sys/socket.h>
20 #ifdef HAVE_WS2TCPIP_H
21 # include <ws2tcpip.h>
25 #include <ecore_private.h>
27 #include "Ecore_Con.h"
28 #include "ecore_con_private.h"
30 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
31 (size_t)(((struct sockaddr_un *)NULL)-> \
33 #define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
34 (size_t)(((struct sockaddr_un \
37 static int _ecore_con_local_init_count = 0;
40 ecore_con_local_init(void)
42 if (++_ecore_con_local_init_count != 1)
43 return _ecore_con_local_init_count;
45 return _ecore_con_local_init_count;
49 ecore_con_local_shutdown(void)
51 if (--_ecore_con_local_init_count != 0)
52 return _ecore_con_local_init_count;
54 return _ecore_con_local_init_count;
58 ecore_con_local_connect(Ecore_Con_Server *svr,
59 Eina_Bool (*cb_done)(void *data,
60 Ecore_Fd_Handler *fd_handler),
61 void *data __UNUSED__,
62 void (*cb_free)(void *data,
66 struct sockaddr_un socket_unix;
71 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
73 homedir = getenv("HOME");
75 homedir = getenv("TMP");
80 snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name,
83 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
87 if (svr->name[0] == '/')
88 strncpy(buf, svr->name, sizeof(buf));
90 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
96 snprintf(buf, sizeof(buf), "%s|%i", svr->name,
99 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i",
104 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
105 strncpy(buf, svr->name,
108 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
112 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
115 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
118 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
119 sizeof(curstate)) < 0)
122 socket_unix.sun_family = AF_UNIX;
124 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
126 #ifdef HAVE_ABSTRACT_SOCKETS
127 /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
128 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
130 socket_unix.sun_path[0] = '\0';
131 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
134 WRN("Your system does not support abstract sockets!");
140 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
141 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
144 if (connect(svr->fd, (struct sockaddr *)&socket_unix,
145 socket_unix_len) < 0)
148 svr->path = strdup(buf);
152 if (svr->type & ECORE_CON_SSL)
153 ecore_con_ssl_server_init(svr);
156 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
157 cb_done, svr, NULL, NULL);
158 if (!svr->fd_handler)
163 /* we got our server! */
164 Ecore_Con_Event_Server_Add *e;
166 e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
171 ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
180 ecore_con_local_listen(
181 Ecore_Con_Server *svr,
183 cb_listen)(void *data,
190 struct sockaddr_un socket_unix;
198 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
200 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
202 homedir = getenv("HOME");
204 homedir = getenv("TMP");
209 mask = S_IRUSR | S_IWUSR | S_IXUSR;
210 snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
211 if (stat(buf, &st) < 0)
214 snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
215 if (stat(buf, &st) < 0)
224 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
226 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
229 if (svr->name[0] == '/')
246 "/tmp/.ecore_service|%s|%i",
250 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
251 strncpy(buf, svr->name,
256 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
260 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
263 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
268 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
269 sizeof(struct linger)) < 0)
272 socket_unix.sun_family = AF_UNIX;
273 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
275 #ifdef HAVE_ABSTRACT_SOCKETS
276 /* . is a placeholder */
277 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
279 /* first char null indicates abstract namespace */
280 socket_unix.sun_path[0] = '\0';
281 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
284 ERR("Your system does not support abstract sockets!");
290 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
291 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
294 if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
296 if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
297 ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
298 (connect(svr->fd, (struct sockaddr *)&socket_unix,
299 socket_unix_len) < 0) &&
306 if (listen(svr->fd, 4096) < 0)
309 svr->path = strdup(buf);
314 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
315 cb_listen, svr, NULL, NULL);
317 if (!svr->fd_handler)