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.
This commit is contained in:
71
common.c
71
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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user