Files
finit/libink/path.c
T
Joachim Wiberg 0a269f3298 libink: a brokerless D-Bus implementation for Finit
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>
2026-08-13 09:28:14 +02:00

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;
}