mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
Finit had no way to answer the question every service manager gets asked: what is running, and change it. D-Bus is how the rest of userspace asks, but linking libdbus, sd-bus or GIO into PID 1 buys a dependency, an allocator and a main loop we do not control. So libink: the wire format, an object tree, and a bus of Finit's own at /run/finit/bus, gated like INIT_SOCKET. It speaks the standard org.freedesktop.DBus, .Peer, .Introspectable interfaces, and Finit's own Manager1, Service1 and Cond1 on top. Methods that change something are marked privileged and answered only for a caller the kernel vouched for, via SO_PEERCRED. Server and client both, since initctl is the first thing that needs to talk to it, and its Start/Stop/Restart/Reload now go over the bus rather than the legacy socket. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
44 lines
841 B
C
44 lines
841 B
C
/* libink — D-Bus object-path encoding for arbitrary identifiers.
|
|
*
|
|
* Copyright (c) 2026 Joachim Wiberg <troglobit@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "path.h"
|
|
|
|
static int is_safe(unsigned char c)
|
|
{
|
|
return (c >= 'A' && c <= 'Z')
|
|
|| (c >= 'a' && c <= 'z')
|
|
|| (c >= '0' && c <= '9');
|
|
}
|
|
|
|
int link_path_encode(const char *in, char *out, size_t outsz)
|
|
{
|
|
static const char hex[] = "0123456789abcdef";
|
|
size_t off = 0;
|
|
|
|
if (!in || !out || outsz == 0)
|
|
return -1;
|
|
|
|
for (; *in; in++) {
|
|
unsigned char c = (unsigned char)*in;
|
|
|
|
if (is_safe(c)) {
|
|
if (off + 1 >= outsz)
|
|
return -1;
|
|
out[off++] = (char)c;
|
|
} else {
|
|
if (off + 3 >= outsz)
|
|
return -1;
|
|
out[off++] = '_';
|
|
out[off++] = hex[c >> 4];
|
|
out[off++] = hex[c & 0xf];
|
|
}
|
|
}
|
|
out[off] = '\0';
|
|
return (int)off;
|
|
}
|