diff options
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; +} |