aboutsummaryrefslogtreecommitdiffstats
path: root/libaxl_connect_without_handshake.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2020-06-11 20:14:09 +0200
committerMattias Andrée <maandree@kth.se>2020-06-11 20:14:09 +0200
commitb56c78b9251806c5e5cd3a5fa5d1f6e8e3de351b (patch)
treeaa502d70d9969c333ccf9e70d55fd6dea41623c2 /libaxl_connect_without_handshake.c
parentFix error checking (diff)
downloadlibaxl-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 'libaxl_connect_without_handshake.c')
-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;
+}