diff options
author | Mattias Andrée <maandree@kth.se> | 2020-06-11 20:14:09 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2020-06-11 20:14:09 +0200 |
commit | b56c78b9251806c5e5cd3a5fa5d1f6e8e3de351b (patch) | |
tree | aa502d70d9969c333ccf9e70d55fd6dea41623c2 /libaxl_connect_without_handshake.c | |
parent | Fix error checking (diff) | |
download | libaxl-b56c78b9251806c5e5cd3a5fa5d1f6e8e3de351b.tar.gz libaxl-b56c78b9251806c5e5cd3a5fa5d1f6e8e3de351b.tar.bz2 libaxl-b56c78b9251806c5e5cd3a5fa5d1f6e8e3de351b.tar.xz |
Misc, mainly connect stuff
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | libaxl_connect_without_handshake.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/libaxl_connect_without_handshake.c b/libaxl_connect_without_handshake.c new file mode 100644 index 0000000..181cdb2 --- /dev/null +++ b/libaxl_connect_without_handshake.c @@ -0,0 +1,94 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +static int +connect_tcp_ip(const char *host, int display) +{ + uint16_t port = libaxl_get_tcp_port(display); + int fd; + + abort(); /* TODO */ + + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &(int){1}, sizeof(int)); + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &(int){1}, sizeof(int)); + + return -1; +} + +static int +connect_unix(const char *path) +{ + struct sockaddr_un addr; + int fd; + + fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + liberror_save_backtrace(NULL); + liberror_set_error_errno(strerror(errno), "socket", errno); + return -1; + } + + if (strlen(path) >= sizeof(addr.sun_path)) { + liberror_save_backtrace(NULL); + /* We could fix this with an O_PATH fd to the file, + * but we will not as other libraries probably do + * not do that, and there is something very wrong + * with your setup if the name is too long for + * `struct sockaddr_un`. */ + close(fd); + errno = ENAMETOOLONG; + liberror_set_error_errno("Path to X display socket is too long", "libaxl_connect_without_handshake", ENAMETOOLONG); + return -1; + } + + addr.sun_family = AF_LOCAL; + stpcpy(addr.sun_path, path); + if (connect(fd, (void *)&addr, (socklen_t)sizeof(addr))) { + liberror_save_backtrace(NULL); + liberror_set_error_errno(strerror(errno), "connect", errno); + return -1; + } + + return fd; +} + +LIBAXL_CONNECTION * +libaxl_connect_without_handshake(const char *host, const char *protocol, int display, int screen) +{ + LIBAXL_CONNECTION *conn; + char path[sizeof("/tmp/.X11-unix/X-") + 3 * sizeof(int)]; + int fd; + + if ((!protocol || !*protocol) && (!host || !*host)) { + sprintf(path, "/tmp/.X11-unix/X%i", display); + fd = connect_unix(path); + if (fd < 0) { + fd = connect_tcp_ip("localhost", display); + if (fd >= 0) + liberror_pop_error(); + } + + } else if (!protocol || !*protocol || + !strcasecmp(protocol, "tcp") || !strcasecmp(protocol, "inet") || + !strcasecmp(protocol, "tcp6") || !strcasecmp(protocol, "inet6")) { + fd = connect_tcp_ip(host, display); + + } else if (!strcmp(protocol, "unix")) { + fd = connect_unix(host); + + } else { + liberror_save_backtrace(NULL); + liberror_set_error("Display server uses unsupported underlaying protocol", + "libaxl_connect_without_handshake", "libaxl", LIBAXL_ERROR_PROTOCOL_NOT_SUPPORTED); + return NULL; + } + + if (fd < 0) + return NULL; + + conn = libaxl_create(fd); + if (conn) + conn->info.default_screen_number = screen; + + return conn; +} |