10 #include <sys/types.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
25 #ifdef HAVE_WS2TCPIP_H
26 # include <ws2tcpip.h>
30 #include <ecore_private.h>
32 #include "Ecore_Con.h"
33 #include "ecore_con_private.h"
35 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
36 (size_t)(((struct sockaddr_un *)NULL)-> \
38 #define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
39 (size_t)(((struct sockaddr_un \
42 static int _ecore_con_local_init_count = 0;
45 ecore_con_local_init(void)
47 if (++_ecore_con_local_init_count != 1)
48 return _ecore_con_local_init_count;
50 return _ecore_con_local_init_count;
54 ecore_con_local_shutdown(void)
56 if (--_ecore_con_local_init_count != 0)
57 return _ecore_con_local_init_count;
59 return _ecore_con_local_init_count;
63 ecore_con_local_connect(Ecore_Con_Server *svr,
64 Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
65 void *data __UNUSED__)
67 #ifndef HAVE_LOCAL_SOCKETS
71 struct sockaddr_un socket_unix;
76 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
78 homedir = getenv("HOME");
80 homedir = getenv("TMP");
85 snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name,
88 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
92 if (svr->name[0] == '/')
93 strncpy(buf, svr->name, sizeof(buf));
95 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
101 snprintf(buf, sizeof(buf), "%s|%i", svr->name,
104 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i",
109 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
110 strncpy(buf, svr->name,
113 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
117 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
120 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
123 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
124 sizeof(curstate)) < 0)
127 socket_unix.sun_family = AF_UNIX;
129 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
131 #ifdef HAVE_ABSTRACT_SOCKETS
132 /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
133 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
135 socket_unix.sun_path[0] = '\0';
136 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
139 WRN("Your system does not support abstract sockets!");
145 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
146 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
149 if (connect(svr->fd, (struct sockaddr *)&socket_unix,
150 socket_unix_len) < 0)
152 ERR("local connection failed: %s", strerror(errno));
156 svr->path = strdup(buf);
160 if (svr->type & ECORE_CON_SSL)
161 ecore_con_ssl_server_init(svr);
164 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
165 cb_done, svr, NULL, NULL);
166 if (!svr->fd_handler)
169 if (!svr->delete_me) ecore_con_event_server_add(svr);
176 ecore_con_local_listen(
177 Ecore_Con_Server *svr,
179 cb_listen)(void *data,
185 #ifdef HAVE_LOCAL_SOCKETS
187 struct sockaddr_un socket_unix;
195 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
197 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
199 homedir = getenv("HOME");
201 homedir = getenv("TMP");
206 mask = S_IRUSR | S_IWUSR | S_IXUSR;
207 snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
208 if (stat(buf, &st) < 0)
211 snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
212 if (stat(buf, &st) < 0)
221 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
223 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
226 if (svr->name[0] == '/')
243 "/tmp/.ecore_service|%s|%i",
247 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
248 strncpy(buf, svr->name,
253 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
257 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
260 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
265 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
266 sizeof(struct linger)) < 0)
269 socket_unix.sun_family = AF_UNIX;
270 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
272 #ifdef HAVE_ABSTRACT_SOCKETS
273 /* . is a placeholder */
274 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
276 /* first char null indicates abstract namespace */
277 socket_unix.sun_path[0] = '\0';
278 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
281 ERR("Your system does not support abstract sockets!");
287 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
288 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
291 if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
293 if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
294 ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
295 (connect(svr->fd, (struct sockaddr *)&socket_unix,
296 socket_unix_len) < 0) &&
303 if (listen(svr->fd, 4096) < 0)
306 svr->path = strdup(buf);
311 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
312 cb_listen, svr, NULL, NULL);
314 if (!svr->fd_handler)
322 #endif /* HAVE_LOCAL_SOCKETS */