summaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2022-08-08 04:39:20 +0200
committerPřemysl Eric Janouch <p@janouch.name>2022-09-05 14:26:00 +0200
commit1639235a48dbed75c2563c9a497b41c31a2a1bae (patch)
tree18193b72fa47e6bcac1358289ac9c36ed00c70ac /common.c
parent2160d037943ef0a3adbf4c6e30a91ee0f205c3f3 (diff)
downloadxK-1639235a48dbed75c2563c9a497b41c31a2a1bae.tar.gz
xK-1639235a48dbed75c2563c9a497b41c31a2a1bae.tar.xz
xK-1639235a48dbed75c2563c9a497b41c31a2a1bae.zip
Start X11 and web frontends for xC
For this, we needed a wire protocol. After surveying available options, it was decided to implement an XDR-like protocol code generator in portable AWK. It now has two backends, per each of: - xF, the X11 frontend, is in C, and is meant to be the primary user interface in the future. - xP, the web frontend, relies on a protocol proxy written in Go, and is meant for use on-the-go (no pun intended). They are very much work-in-progress proofs of concept right now, and the relay protocol is certain to change.
Diffstat (limited to 'common.c')
-rw-r--r--common.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/common.c b/common.c
index d9d2a61..6f99509 100644
--- a/common.c
+++ b/common.c
@@ -1,7 +1,7 @@
/*
* common.c: common functionality
*
- * Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name>
+ * Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
@@ -48,6 +48,66 @@ init_openssl (void)
#endif
}
+static char *
+gai_reconstruct_address (struct addrinfo *ai)
+{
+ char host[NI_MAXHOST] = {}, port[NI_MAXSERV] = {};
+ int err = getnameinfo (ai->ai_addr, ai->ai_addrlen,
+ host, sizeof host, port, sizeof port,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (err)
+ {
+ print_debug ("%s: %s", "getnameinfo", gai_strerror (err));
+ return xstrdup ("?");
+ }
+ return format_host_port_pair (host, port);
+}
+
+static bool
+accept_error_is_transient (int err)
+{
+ // OS kernels may return a wide range of unforeseeable errors.
+ // Assuming that they're either transient or caused by
+ // a connection that we've just extracted from the queue.
+ switch (err)
+ {
+ case EBADF:
+ case EINVAL:
+ case ENOTSOCK:
+ case EOPNOTSUPP:
+ return false;
+ default:
+ return true;
+ }
+}
+
+/// Destructively tokenize an address into a host part, and a port part.
+/// The port is only overwritten if that part is found, allowing for defaults.
+static const char *
+tokenize_host_port (char *address, const char **port)
+{
+ // Unwrap IPv6 addresses in format_host_port_pair() format.
+ char *rbracket = strchr (address, ']');
+ if (*address == '[' && rbracket)
+ {
+ if (rbracket[1] == ':')
+ {
+ *port = rbracket + 2;
+ return *rbracket = 0, address + 1;
+ }
+ if (!rbracket[1])
+ return *rbracket = 0, address + 1;
+ }
+
+ char *colon = strchr (address, ':');
+ if (colon)
+ {
+ *port = colon + 1;
+ return *colon = 0, address;
+ }
+ return address;
+}
+
// --- To be moved to liberty --------------------------------------------------
// FIXME: in xssl_get_error() we rely on error reasons never being NULL (i.e.,
@@ -74,6 +134,15 @@ xerr_describe_error (void)
return reason;
}
+static struct str
+str_from_cstr (const char *cstr)
+{
+ struct str self;
+ self.alloc = (self.len = strlen (cstr)) + 1;
+ self.str = memcpy (xmalloc (self.alloc), cstr, self.alloc);
+ return self;
+}
+
static ssize_t
strv_find (const struct strv *v, const char *s)
{