aboutsummaryrefslogtreecommitdiffstats
path: root/libaxl_connect_without_handshake.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libaxl_connect_without_handshake.c94
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;
+}