Decouple socket path lookup logic

This commit is contained in:
Marc André Tanner 2014-12-22 11:11:03 +01:00
parent d4a74a23d7
commit 3cfa99a031
2 changed files with 34 additions and 32 deletions

View File

@ -119,7 +119,7 @@ static struct sockaddr_un sockaddr = {
.sun_family = AF_UNIX, .sun_family = AF_UNIX,
}; };
static int create_socket(const char *name); static bool set_socket_name(struct sockaddr_un *sockaddr, const char *name);
static void die(const char *s); static void die(const char *s);
static void info(const char *str, ...); static void info(const char *str, ...);
@ -214,8 +214,8 @@ static void usage(void) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static int create_socket_dir(void) { static int create_socket_dir(struct sockaddr_un *sockaddr) {
size_t maxlen = sizeof(sockaddr.sun_path); size_t maxlen = sizeof(sockaddr->sun_path);
char *dirs[] = { getenv("HOME"), getenv("TMPDIR"), "/tmp" }; char *dirs[] = { getenv("HOME"), getenv("TMPDIR"), "/tmp" };
int socketfd = socket(AF_UNIX, SOCK_STREAM, 0); int socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socketfd == -1) if (socketfd == -1)
@ -224,20 +224,20 @@ static int create_socket_dir(void) {
char *dir = dirs[i]; char *dir = dirs[i];
if (!dir) if (!dir)
continue; continue;
int len = snprintf(sockaddr.sun_path, maxlen, "%s/.%s/", dir, server.name); int len = snprintf(sockaddr->sun_path, maxlen, "%s/.%s/", dir, server.name);
if (len < 0 || (size_t)len >= maxlen) if (len < 0 || (size_t)len >= maxlen)
continue; continue;
if (mkdir(sockaddr.sun_path, 0750) == -1 && errno != EEXIST) if (mkdir(sockaddr->sun_path, 0750) == -1 && errno != EEXIST)
continue; continue;
int len2 = snprintf(sockaddr.sun_path, maxlen, "%s/.%s/.abduco-%d", dir, server.name, getpid()); int len2 = snprintf(sockaddr->sun_path, maxlen, "%s/.%s/.abduco-%d", dir, server.name, getpid());
if (len2 < 0 || (size_t)len2 >= maxlen) if (len2 < 0 || (size_t)len2 >= maxlen)
continue; continue;
socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1; socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr->sun_path) + 1;
if (bind(socketfd, (struct sockaddr*)&sockaddr, socklen) == -1) if (bind(socketfd, (struct sockaddr*)sockaddr, socklen) == -1)
continue; continue;
unlink(sockaddr.sun_path); unlink(sockaddr->sun_path);
close(socketfd); close(socketfd);
sockaddr.sun_path[len] = '\0'; sockaddr->sun_path[len] = '\0';
return len; return len;
} }
@ -245,27 +245,27 @@ static int create_socket_dir(void) {
return -1; return -1;
} }
static int create_socket(const char *name) { static bool set_socket_name(struct sockaddr_un *sockaddr, const char *name) {
size_t maxlen = sizeof(sockaddr.sun_path); size_t maxlen = sizeof(sockaddr->sun_path);
if (name[0] == '/') { if (name[0] == '/') {
strncpy(sockaddr.sun_path, name, maxlen); strncpy(sockaddr->sun_path, name, maxlen);
if (sockaddr.sun_path[maxlen-1]) if (sockaddr->sun_path[maxlen-1])
return -1; return false;
} else if (name[0] == '.' && (name[1] == '.' || name[1] == '/')) { } else if (name[0] == '.' && (name[1] == '.' || name[1] == '/')) {
char buf[maxlen], *cwd = getcwd(buf, sizeof buf); char buf[maxlen], *cwd = getcwd(buf, sizeof buf);
if (!cwd) if (!cwd)
return -1; return false;
int len = snprintf(sockaddr.sun_path, maxlen, "%s/%s", cwd, name); int len = snprintf(sockaddr->sun_path, maxlen, "%s/%s", cwd, name);
if (len < 0 || (size_t)len >= maxlen) if (len < 0 || (size_t)len >= maxlen)
return -1; return false;
} else { } else {
int dir_len = create_socket_dir(); int dir_len = create_socket_dir(sockaddr);
if (dir_len == -1 || dir_len + strlen(name) + strlen(server.host) >= maxlen) if (dir_len == -1 || dir_len + strlen(name) + strlen(server.host) >= maxlen)
return -1; return false;
strncat(sockaddr.sun_path, name, maxlen - strlen(sockaddr.sun_path) - 1); strncat(sockaddr->sun_path, name, maxlen - strlen(sockaddr->sun_path) - 1);
strncat(sockaddr.sun_path, server.host, maxlen - strlen(sockaddr.sun_path) - 1); strncat(sockaddr->sun_path, server.host, maxlen - strlen(sockaddr->sun_path) - 1);
} }
return socket(AF_UNIX, SOCK_STREAM, 0); return true;
} }
static bool create_session(const char *name, char * const argv[]) { static bool create_session(const char *name, char * const argv[]) {
@ -386,7 +386,7 @@ static bool create_session(const char *name, char * const argv[]) {
static bool attach_session(const char *name) { static bool attach_session(const char *name) {
if (server.socket > 0) if (server.socket > 0)
close(server.socket); close(server.socket);
if ((server.socket = create_socket(name)) == -1) if (!set_socket_name(&sockaddr, name) || (server.socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
return false; return false;
socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1; socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1;
if (connect(server.socket, (struct sockaddr*)&sockaddr, socklen) == -1) if (connect(server.socket, (struct sockaddr*)&sockaddr, socklen) == -1)
@ -442,7 +442,7 @@ static int session_comparator(const struct dirent **a, const struct dirent **b)
} }
static int list_session(void) { static int list_session(void) {
if (create_socket_dir() == -1) if (create_socket_dir(&sockaddr) == -1)
return 1; return 1;
chdir(sockaddr.sun_path); chdir(sockaddr.sun_path);
struct dirent **namelist; struct dirent **namelist;

View File

@ -32,19 +32,21 @@ static int server_mark_socket_exec(bool exec, bool usr) {
} }
static int server_create_socket(const char *name) { static int server_create_socket(const char *name) {
int socket = create_socket(name); if (!set_socket_name(&sockaddr, name))
if (socket == -1) return -1;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
return -1; return -1;
socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1; socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1;
mode_t mode = S_IRUSR|S_IWUSR; mode_t mode = S_IRUSR|S_IWUSR;
fchmod(socket, mode); fchmod(fd, mode);
if (bind(socket, (struct sockaddr*)&sockaddr, socklen) == -1) if (bind(fd, (struct sockaddr*)&sockaddr, socklen) == -1)
return -1; return -1;
if (fchmod(socket, mode) == -1 && chmod(sockaddr.sun_path, mode) == -1) if (fchmod(fd, mode) == -1 && chmod(sockaddr.sun_path, mode) == -1)
goto error; goto error;
if (listen(socket, 5) == -1) if (listen(fd, 5) == -1)
goto error; goto error;
return socket; return fd;
error: error:
unlink(sockaddr.sun_path); unlink(sockaddr.sun_path);
return -1; return -1;