2010-01-04 11:35:21 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2010-01-04 15:43:16 -08:00
|
|
|
#include <stdio.h>
|
2010-01-04 11:35:21 -08:00
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <fcntl.h>
|
2010-02-20 10:01:50 -08:00
|
|
|
#include <sys/stat.h>
|
|
|
|
|
2010-02-20 11:12:52 -08:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
# include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_UN_H
|
|
|
|
# include <sys/un.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_WS2TCPIP_H
|
2010-02-20 10:01:50 -08:00
|
|
|
# include <ws2tcpip.h>
|
|
|
|
#endif
|
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
#include <Ecore.h>
|
|
|
|
#include <ecore_private.h>
|
|
|
|
|
|
|
|
#include "Ecore_Con.h"
|
|
|
|
#include "ecore_con_private.h"
|
|
|
|
|
2010-11-03 10:58:37 -07:00
|
|
|
#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
|
|
|
|
(size_t)(((struct sockaddr_un *)NULL)-> \
|
|
|
|
sun_path))
|
|
|
|
#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
|
2010-07-26 23:30:27 -07:00
|
|
|
(size_t)(((struct sockaddr_un \
|
|
|
|
*)NULL)->sun_path))
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
static int _ecore_con_local_init_count = 0;
|
|
|
|
|
|
|
|
int
|
|
|
|
ecore_con_local_init(void)
|
|
|
|
{
|
|
|
|
if (++_ecore_con_local_init_count != 1)
|
2010-11-03 10:58:37 -07:00
|
|
|
return _ecore_con_local_init_count;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
return _ecore_con_local_init_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ecore_con_local_shutdown(void)
|
|
|
|
{
|
|
|
|
if (--_ecore_con_local_init_count != 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return _ecore_con_local_init_count;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
return _ecore_con_local_init_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2011-07-04 17:06:27 -07:00
|
|
|
ecore_con_local_connect(Ecore_Con_Server *svr,
|
|
|
|
Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
|
|
|
|
void *data __UNUSED__)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
char buf[4096];
|
2010-01-04 11:35:21 -08:00
|
|
|
struct sockaddr_un socket_unix;
|
2010-07-26 23:30:27 -07:00
|
|
|
int curstate = 0;
|
|
|
|
const char *homedir;
|
|
|
|
int socket_unix_len;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
2010-07-30 10:03:34 -07:00
|
|
|
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
homedir = getenv("HOME");
|
|
|
|
if (!homedir)
|
2010-11-03 10:58:37 -07:00
|
|
|
homedir = getenv("TMP");
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (!homedir)
|
2010-11-03 10:58:37 -07:00
|
|
|
homedir = "/tmp";
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name,
|
|
|
|
svr->port);
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-30 10:03:34 -07:00
|
|
|
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
if (svr->port < 0)
|
|
|
|
{
|
|
|
|
if (svr->name[0] == '/')
|
2010-11-03 10:58:37 -07:00
|
|
|
strncpy(buf, svr->name, sizeof(buf));
|
2010-07-26 23:30:27 -07:00
|
|
|
else
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
|
2010-07-26 23:30:27 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (svr->name[0] ==
|
|
|
|
'/')
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s|%i", svr->name,
|
|
|
|
svr->port);
|
2010-07-26 23:30:27 -07:00
|
|
|
else
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i",
|
|
|
|
svr->name,
|
|
|
|
svr->port);
|
2010-07-26 23:30:27 -07:00
|
|
|
}
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-30 10:03:34 -07:00
|
|
|
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
2010-11-03 10:58:37 -07:00
|
|
|
strncpy(buf, svr->name,
|
|
|
|
sizeof(buf));
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (svr->fd < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
|
|
|
|
sizeof(curstate)) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
socket_unix.sun_family = AF_UNIX;
|
|
|
|
|
2010-07-30 10:03:34 -07:00
|
|
|
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
|
|
|
#ifdef HAVE_ABSTRACT_SOCKETS
|
2010-07-26 23:30:27 -07:00
|
|
|
/* copy name insto sun_path, prefixed by null to indicate abstract namespace */
|
|
|
|
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
|
|
|
|
svr->name);
|
|
|
|
socket_unix.sun_path[0] = '\0';
|
|
|
|
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
|
|
|
|
svr->name);
|
2010-01-04 11:35:21 -08:00
|
|
|
#else
|
2010-07-26 23:30:27 -07:00
|
|
|
WRN("Your system does not support abstract sockets!");
|
|
|
|
return 0;
|
2010-01-04 11:35:21 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
|
|
|
|
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
|
|
|
|
2010-07-26 23:30:27 -07:00
|
|
|
if (connect(svr->fd, (struct sockaddr *)&socket_unix,
|
|
|
|
socket_unix_len) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
svr->path = strdup(buf);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (!svr->path)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
if (svr->type & ECORE_CON_SSL)
|
2010-11-03 10:58:37 -07:00
|
|
|
ecore_con_ssl_server_init(svr);
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
svr->fd_handler =
|
2010-11-03 10:58:37 -07:00
|
|
|
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
|
|
|
cb_done, svr, NULL, NULL);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (!svr->fd_handler)
|
2010-11-03 10:58:37 -07:00
|
|
|
return 0;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
2011-07-04 17:06:27 -07:00
|
|
|
if (!svr->delete_me) ecore_con_event_server_add(svr);
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2010-07-26 23:30:27 -07:00
|
|
|
ecore_con_local_listen(
|
2010-11-03 10:58:37 -07:00
|
|
|
Ecore_Con_Server *svr,
|
|
|
|
Eina_Bool (*
|
|
|
|
cb_listen)(void *data,
|
|
|
|
Ecore_Fd_Handler *
|
|
|
|
fd_handler),
|
|
|
|
void *data
|
|
|
|
__UNUSED__)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
char buf[4096];
|
2010-01-04 11:35:21 -08:00
|
|
|
struct sockaddr_un socket_unix;
|
2010-07-26 23:30:27 -07:00
|
|
|
struct linger lin;
|
|
|
|
mode_t pmode;
|
|
|
|
const char *homedir;
|
|
|
|
struct stat st;
|
|
|
|
mode_t mask;
|
|
|
|
int socket_unix_len;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
|
|
|
|
2010-07-30 10:03:34 -07:00
|
|
|
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
homedir = getenv("HOME");
|
|
|
|
if (!homedir)
|
2010-11-03 10:58:37 -07:00
|
|
|
homedir = getenv("TMP");
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (!homedir)
|
2010-11-03 10:58:37 -07:00
|
|
|
homedir = "/tmp";
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
mask = S_IRUSR | S_IWUSR | S_IXUSR;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
|
|
|
|
if (stat(buf, &st) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
mkdir(buf, mask);
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
|
|
|
|
if (stat(buf, &st) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
mkdir(buf, mask);
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf,
|
2010-07-26 23:30:27 -07:00
|
|
|
sizeof(buf),
|
|
|
|
"%s/.ecore/%s/%i",
|
|
|
|
homedir,
|
|
|
|
svr->name,
|
|
|
|
svr->port);
|
|
|
|
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-30 10:03:34 -07:00
|
|
|
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
mask = 0;
|
|
|
|
if (svr->name[0] == '/')
|
|
|
|
{
|
|
|
|
if (svr->port >= 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf,
|
|
|
|
sizeof(buf),
|
|
|
|
"%s|%i",
|
|
|
|
svr->name,
|
|
|
|
svr->port);
|
2010-07-26 23:30:27 -07:00
|
|
|
else
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf,
|
|
|
|
sizeof(buf),
|
|
|
|
"%s",
|
|
|
|
svr->name);
|
2010-07-26 23:30:27 -07:00
|
|
|
}
|
|
|
|
else
|
2010-11-03 10:58:37 -07:00
|
|
|
snprintf(buf,
|
|
|
|
sizeof(buf),
|
|
|
|
"/tmp/.ecore_service|%s|%i",
|
|
|
|
svr->name,
|
|
|
|
svr->port);
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-30 10:03:34 -07:00
|
|
|
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
2010-11-03 10:58:37 -07:00
|
|
|
strncpy(buf, svr->name,
|
|
|
|
sizeof(buf));
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
pmode = umask(mask);
|
2010-07-26 23:30:27 -07:00
|
|
|
start:
|
2010-01-04 11:35:21 -08:00
|
|
|
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (svr->fd < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
lin.l_onoff = 1;
|
|
|
|
lin.l_linger = 0;
|
2010-07-26 23:30:27 -07:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
|
|
|
|
sizeof(struct linger)) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
socket_unix.sun_family = AF_UNIX;
|
2010-07-30 10:03:34 -07:00
|
|
|
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
2010-01-04 11:35:21 -08:00
|
|
|
{
|
|
|
|
#ifdef HAVE_ABSTRACT_SOCKETS
|
2010-07-26 23:30:27 -07:00
|
|
|
/* . is a placeholder */
|
|
|
|
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
|
|
|
|
svr->name);
|
|
|
|
/* first char null indicates abstract namespace */
|
|
|
|
socket_unix.sun_path[0] = '\0';
|
|
|
|
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
|
|
|
|
svr->name);
|
2010-01-04 11:35:21 -08:00
|
|
|
#else
|
2010-07-26 23:30:27 -07:00
|
|
|
ERR("Your system does not support abstract sockets!");
|
|
|
|
goto error_umask;
|
2010-01-04 11:35:21 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-26 23:30:27 -07:00
|
|
|
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
|
|
|
|
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
|
|
|
|
{
|
2010-07-30 10:03:34 -07:00
|
|
|
if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
|
|
|
|
((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
|
2010-07-26 23:30:27 -07:00
|
|
|
(connect(svr->fd, (struct sockaddr *)&socket_unix,
|
|
|
|
socket_unix_len) < 0) &&
|
|
|
|
(unlink(buf) >= 0))
|
2010-11-03 10:58:37 -07:00
|
|
|
goto start;
|
2010-07-26 23:30:27 -07:00
|
|
|
else
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-01-04 11:35:21 -08:00
|
|
|
}
|
2010-07-26 23:30:27 -07:00
|
|
|
|
|
|
|
if (listen(svr->fd, 4096) < 0)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
svr->path = strdup(buf);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (!svr->path)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error_umask;
|
2010-07-26 23:30:27 -07:00
|
|
|
|
2010-01-04 11:35:21 -08:00
|
|
|
svr->fd_handler =
|
2010-11-03 10:58:37 -07:00
|
|
|
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
|
|
|
cb_listen, svr, NULL, NULL);
|
2010-01-04 11:35:21 -08:00
|
|
|
umask(pmode);
|
2010-07-26 23:30:27 -07:00
|
|
|
if (!svr->fd_handler)
|
2010-11-03 10:58:37 -07:00
|
|
|
goto error;
|
2010-01-04 11:35:21 -08:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2010-07-26 23:30:27 -07:00
|
|
|
error_umask:
|
2010-01-04 11:35:21 -08:00
|
|
|
umask(pmode);
|
2010-07-26 23:30:27 -07:00
|
|
|
error:
|
2010-01-04 11:35:21 -08:00
|
|
|
return 0;
|
|
|
|
}
|
2010-11-03 10:58:37 -07:00
|
|
|
|