forked from enlightenment/efl
ecore_con: export function to create local path string.
The new efl_net code won't compose any path own its own, allowing the user to connect to non-EFL systems. However we need a way to use the same path Ecore_Con_Server does, so we can reach it. Then export and use ecore_con_local_path_new() to do exactly that.
This commit is contained in:
parent
44d95dd408
commit
2f91934502
|
@ -1097,6 +1097,42 @@ EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs);
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Create a local path to connect the socket.
|
||||
*
|
||||
* In the old API, ecore_con_server_add() and
|
||||
* ecore_con_server_connect() calculated a local path for connections
|
||||
* using @c ECORE_CON_LOCAL_USER and @c ECORE_CON_LOCAL_SYSTEM, this
|
||||
* function returns that path allocated so it can be used in
|
||||
* applications that want to connect to that path without replicating
|
||||
* its logic.
|
||||
*
|
||||
* @li If @a type is @c ECORE_CON_LOCAL_USER, the server will conect to
|
||||
* the Unix socket. The path to the socket is taken from XDG_RUNTIME_DIR,
|
||||
* if that is not set, then from HOME, even if this is not set, then from
|
||||
* TMPDIR. If none is set, then path would be /tmp. From this path the
|
||||
* function would connect to socket at "[path]/.ecore/[name]/[port]". If
|
||||
* port is negetive, then to socket at "[path]/.ecore/[name]".
|
||||
* @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will connect to
|
||||
* Unix socket at "/tmp/.ecore_service|[name]|[port]". If port is negetive,
|
||||
* then to Unix socket at "/tmp/.ecore_service|[name]".
|
||||
*
|
||||
* @param is_system If #EINA_TRUE, will be a system wide socket
|
||||
* similar to @c ECORE_CON_LOCAL_SYSTEM. If #EINA_FALSE,
|
||||
* then it's similar to @c ECORE_CON_LOCAL_USER.
|
||||
* @param name Name to associate with the socket. It is used when
|
||||
* generating the socket name of a Unix socket,
|
||||
* @c NULL will not be accepted.
|
||||
* @param port Number to identify socket. When a Unix socket is used,
|
||||
* it becomes part of the socket name.
|
||||
*
|
||||
* @return NULL on failure or newly allocated path string on success,
|
||||
* remember to free() it after usage.
|
||||
*
|
||||
* @since 1.19
|
||||
*/
|
||||
EAPI char *ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port) EINA_WARN_UNUSED_RESULT EINA_MALLOC EINA_ARG_NONNULL(2);
|
||||
|
||||
/**
|
||||
* @brief Create a server to listen for connections.
|
||||
*
|
||||
|
@ -1132,6 +1168,8 @@ EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs);
|
|||
*
|
||||
* The @p data parameter can be fetched later using ecore_con_server_data_get()
|
||||
* or changed with ecore_con_server_data_set().
|
||||
*
|
||||
* @see ecore_con_local_path_new()
|
||||
*/
|
||||
EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
|
||||
const char *name, int port,
|
||||
|
@ -1182,6 +1220,8 @@ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
|
|||
*
|
||||
* The @p data parameter can be fetched later using ecore_con_server_data_get()
|
||||
* or changed with ecore_con_server_data_set().
|
||||
*
|
||||
* @see ecore_con_local_path_new()
|
||||
*/
|
||||
EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
|
||||
const char *name, int port,
|
||||
|
|
|
@ -64,24 +64,15 @@ ecore_con_local_shutdown(void)
|
|||
return _ecore_con_local_init_count;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_local_connect(Ecore_Con_Server *obj,
|
||||
Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
|
||||
void *data EINA_UNUSED)
|
||||
EAPI char *
|
||||
ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port)
|
||||
{
|
||||
#ifndef HAVE_LOCAL_SOCKETS
|
||||
return 0;
|
||||
#else
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char buf[4096];
|
||||
struct sockaddr_un socket_unix;
|
||||
int curstate = 0;
|
||||
const char *homedir;
|
||||
int socket_unix_len;
|
||||
|
||||
buf[0] = '\0';
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
if (!is_system)
|
||||
{
|
||||
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
||||
if (getuid() == geteuid())
|
||||
|
@ -97,50 +88,78 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (svr->port < 0)
|
||||
if (port < 0)
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore/%s",
|
||||
homedir, svr->name);
|
||||
homedir, name);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i",
|
||||
homedir, svr->name, svr->port);
|
||||
homedir, name, port);
|
||||
return strdup(buf);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
else
|
||||
{
|
||||
if (svr->port < 0)
|
||||
if (port < 0)
|
||||
{
|
||||
if (svr->name[0] == '/')
|
||||
{
|
||||
strncpy(buf, svr->name, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
}
|
||||
if (name[0] == '/')
|
||||
return strdup(name);
|
||||
else
|
||||
{
|
||||
homedir = eina_environment_tmp_get();
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore_service|%s",
|
||||
homedir, svr->name);
|
||||
homedir, name);
|
||||
return strdup(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (svr->name[0] == '/')
|
||||
snprintf(buf, sizeof(buf), "%s|%i", svr->name, svr->port);
|
||||
if (name[0] == '/')
|
||||
snprintf(buf, sizeof(buf), "%s|%i", name, port);
|
||||
else
|
||||
{
|
||||
homedir = eina_environment_tmp_get();
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore_service|%s|%i",
|
||||
homedir, svr->name, svr->port);
|
||||
homedir, name, port);
|
||||
}
|
||||
return strdup(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_local_connect(Ecore_Con_Server *obj,
|
||||
Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
|
||||
void *data EINA_UNUSED)
|
||||
{
|
||||
#ifndef HAVE_LOCAL_SOCKETS
|
||||
return 0;
|
||||
#else
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char *buf = NULL;
|
||||
struct sockaddr_un socket_unix;
|
||||
int curstate = 0;
|
||||
int socket_unix_len;
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
{
|
||||
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
strncpy(buf, svr->name, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
buf = strdup(svr->name);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (svr->fd < 0)
|
||||
return 0;
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
||||
goto error;
|
||||
|
@ -182,9 +201,8 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
goto error;
|
||||
}
|
||||
|
||||
svr->path = strdup(buf);
|
||||
if (!svr->path)
|
||||
goto error;
|
||||
svr->path = buf;
|
||||
buf = NULL;
|
||||
|
||||
if (svr->type & ECORE_CON_SSL)
|
||||
{
|
||||
|
@ -199,14 +217,65 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
|
||||
if (!svr->delete_me) ecore_con_event_server_add(obj);
|
||||
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
error:
|
||||
if (svr->fd) close(svr->fd);
|
||||
svr->fd = -1;
|
||||
free(buf);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOCAL_SOCKETS
|
||||
static void
|
||||
_ecore_con_local_mkpath(const char *path, mode_t mode)
|
||||
{
|
||||
char *s, *d, *itr;
|
||||
|
||||
if (!path) return;
|
||||
EINA_SAFETY_ON_TRUE_RETURN(path[0] != '/');
|
||||
|
||||
s = strdup(path);
|
||||
EINA_SAFETY_ON_NULL_RETURN(s);
|
||||
d = dirname(s);
|
||||
EINA_SAFETY_ON_NULL_RETURN(d);
|
||||
|
||||
for (itr = d + 1; *itr != '\0'; itr++)
|
||||
{
|
||||
if (*itr == '/')
|
||||
{
|
||||
*itr = '\0';
|
||||
if (mkdir(d, mode) != 0)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
ERR("could not create parent directory '%s' of path '%s': %s", d, path, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
*itr = '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (mkdir(d, mode) != 0)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
ERR("could not create parent directory '%s' of path '%s': %s", d, path, strerror(errno));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if ((stat(d, &st) != 0) || (!S_ISDIR(st.st_mode)))
|
||||
ERR("could not create parent directory '%s' of path '%s': exists but is not a directory", d, path);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
free(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ecore_con_local_listen(
|
||||
Ecore_Con_Server *obj,
|
||||
|
@ -219,11 +288,10 @@ ecore_con_local_listen(
|
|||
{
|
||||
#ifdef HAVE_LOCAL_SOCKETS
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char buf[4096];
|
||||
char *buf = NULL;
|
||||
struct sockaddr_un socket_unix;
|
||||
struct linger lin;
|
||||
mode_t pmode;
|
||||
const char *homedir;
|
||||
mode_t mask;
|
||||
int socket_unix_len;
|
||||
Eina_Bool abstract_socket;
|
||||
|
@ -232,87 +300,25 @@ ecore_con_local_listen(
|
|||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
{
|
||||
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
||||
if (getuid() == geteuid())
|
||||
#endif
|
||||
homedir = _ecore_con_local_path_get();
|
||||
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
|
||||
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
||||
else
|
||||
{
|
||||
struct passwd *pw = getpwent();
|
||||
|
||||
if ((!pw) || (!pw->pw_dir)) homedir = "/tmp";
|
||||
else homedir = pw->pw_dir;
|
||||
}
|
||||
#endif
|
||||
mask = S_IRUSR | S_IWUSR | S_IXUSR;
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
|
||||
if (mkdir(buf, mask) < 0)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
ERR("mkdir '%s' failed", buf);
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
|
||||
if (mkdir(buf, mask) < 0)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
ERR("mkdir '%s' failed", buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (svr->port < 0)
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore/%s",
|
||||
homedir, svr->name);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i",
|
||||
homedir, svr->name, svr->port);
|
||||
_ecore_con_local_mkpath(buf, mask);
|
||||
|
||||
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
mask = 0;
|
||||
if (svr->port < 0)
|
||||
{
|
||||
if (svr->name[0] == '/')
|
||||
{
|
||||
strncpy(buf, svr->name, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
homedir = eina_environment_tmp_get();
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore_service|%s",
|
||||
homedir, svr->name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (svr->name[0] == '/')
|
||||
snprintf(buf, sizeof(buf), "%s|%i", svr->name, svr->port);
|
||||
else
|
||||
{
|
||||
homedir = eina_environment_tmp_get();
|
||||
snprintf(buf, sizeof(buf), "%s/.ecore_service|%s|%i",
|
||||
homedir, svr->name, svr->port);
|
||||
}
|
||||
}
|
||||
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
strncpy(buf, svr->name, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[0] = '\0';
|
||||
buf = strdup(svr->name);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
pmode = umask(mask);
|
||||
start:
|
||||
socket_unix.sun_family = AF_UNIX;
|
||||
|
@ -408,9 +414,8 @@ start:
|
|||
#ifdef HAVE_SYSTEMD
|
||||
fd_ready:
|
||||
#endif
|
||||
svr->path = strdup(buf);
|
||||
if (!svr->path)
|
||||
goto error_umask;
|
||||
svr->path = buf;
|
||||
buf = NULL;
|
||||
|
||||
svr->fd_handler =
|
||||
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
||||
|
@ -419,6 +424,8 @@ fd_ready:
|
|||
if (!svr->fd_handler)
|
||||
goto error;
|
||||
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
|
||||
error_fd:
|
||||
|
@ -427,6 +434,7 @@ error_fd:
|
|||
error_umask:
|
||||
umask(pmode);
|
||||
error:
|
||||
free(buf);
|
||||
#endif /* HAVE_LOCAL_SOCKETS */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -386,11 +386,29 @@ _ecore_con_local_win32_listening(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
if (!is_system)
|
||||
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s%ld", name, GetProcessId(GetCurrentProcess()));
|
||||
else
|
||||
{
|
||||
const char *computername;
|
||||
|
||||
computername = getenv("COMPUTERNAME");
|
||||
snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s%ld", computername, name, GetProcessId(GetCurrentProcess()));
|
||||
}
|
||||
|
||||
return strdup(buf);
|
||||
(void)port; // CHECK-ME: shouldn't we use port to be similar to UNIX?
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
ecore_con_local_listen(Ecore_Con_Server *obj)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char buf[256];
|
||||
HANDLE thread_listening;
|
||||
Ecore_Win32_Handler *handler;
|
||||
|
||||
|
@ -401,16 +419,10 @@ ecore_con_local_listen(Ecore_Con_Server *obj)
|
|||
}
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s%ld", svr->name, GetProcessId(GetCurrentProcess()));
|
||||
svr->path = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
const char *computername;
|
||||
svr->path = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
|
||||
computername = getenv("COMPUTERNAME");
|
||||
snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s%ld", computername, svr->name, GetProcessId(GetCurrentProcess()));
|
||||
}
|
||||
|
||||
svr->path = strdup(buf);
|
||||
if (!svr->path)
|
||||
{
|
||||
ERR("Allocation failed");
|
||||
|
@ -540,7 +552,7 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
{
|
||||
#warning "I am pretty sure cb_done should be used."
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char buf[256];
|
||||
char buf = NULL;
|
||||
Ecore_Win32_Handler *handler_read;
|
||||
Ecore_Win32_Handler *handler_peek;
|
||||
|
||||
|
@ -551,14 +563,11 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
}
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name);
|
||||
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
const char *computername;
|
||||
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
|
||||
computername = getenv("COMPUTERNAME");
|
||||
snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name);
|
||||
}
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -576,6 +585,7 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
if (GetLastError() != ERROR_PIPE_BUSY)
|
||||
{
|
||||
DBG("Connection to a server failed");
|
||||
free(buf);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
@ -587,12 +597,8 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
}
|
||||
}
|
||||
|
||||
svr->path = strdup(buf);
|
||||
if (!svr->path)
|
||||
{
|
||||
ERR("Allocation failed");
|
||||
goto close_pipe;
|
||||
}
|
||||
svr->path = buf;
|
||||
buf = NULL;
|
||||
|
||||
svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!svr->event_read)
|
||||
|
@ -636,6 +642,7 @@ ecore_con_local_connect(Ecore_Con_Server *obj,
|
|||
if (!svr->delete_me) ecore_con_event_server_add(obj);
|
||||
|
||||
ResumeThread(svr->thread_read);
|
||||
free(buf);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
|
@ -652,6 +659,7 @@ free_path:
|
|||
svr->path = NULL;
|
||||
close_pipe:
|
||||
CloseHandle(svr->pipe);
|
||||
free(buf);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue