64 lines
2.5 KiB
C
64 lines
2.5 KiB
C
/* Disposable PID1 fixture only: a real ELF manager, NOT an Archipelago build. */
|
|
#include <arpa/inet.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <stddef.h>
|
|
#include <unistd.h>
|
|
#ifndef VERSION
|
|
#define VERSION "2.0.3-alpha"
|
|
#endif
|
|
#ifndef HEALTH_VERSION
|
|
#define HEALTH_VERSION VERSION
|
|
#endif
|
|
int main(int argc, char **argv) {
|
|
if (argc == 2 && !strcmp(argv[1], "--version")) {
|
|
printf("archipelago %s\n", VERSION); return 0;
|
|
}
|
|
if (argc == 4 && !strcmp(argv[1], "ceremony") && !strcmp(argv[2], "verify")) {
|
|
execl("/usr/bin/python3", "python3", "-I", "/opt/public-fixture/verify.py", argv[3], NULL);
|
|
return 2;
|
|
}
|
|
#ifdef FAIL_START
|
|
return 3;
|
|
#endif
|
|
/* Reproduce the first-generation daemon waiting before READY/API startup. */
|
|
if (!access("/var/lib/archipelago/update-pending-verify.json", F_OK) &&
|
|
access("/etc/archipelago/public-update-runtime.json", F_OK)) {
|
|
for (;;) pause();
|
|
}
|
|
signal(SIGPIPE, SIG_IGN);
|
|
int server = socket(AF_INET, SOCK_STREAM, 0), yes = 1;
|
|
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
|
struct sockaddr_in addr = {.sin_family=AF_INET, .sin_port=htons(5678), .sin_addr.s_addr=htonl(INADDR_LOOPBACK)};
|
|
if (bind(server, (struct sockaddr *)&addr, sizeof(addr)) || listen(server, 8)) return 4;
|
|
const char *notify = getenv("NOTIFY_SOCKET");
|
|
if (notify) {
|
|
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
|
struct sockaddr_un endpoint = {.sun_family = AF_UNIX};
|
|
size_t length = strlen(notify);
|
|
if (length >= sizeof(endpoint.sun_path)) return 5;
|
|
memcpy(endpoint.sun_path, notify, length + 1);
|
|
if (endpoint.sun_path[0] == '@') endpoint.sun_path[0] = '\0';
|
|
if (sendto(fd, "READY=1", 7, 0, (struct sockaddr *)&endpoint,
|
|
offsetof(struct sockaddr_un, sun_path) + length + 1) < 0) return 6;
|
|
close(fd);
|
|
}
|
|
for (;;) {
|
|
int client = accept(server, NULL, NULL);
|
|
if (client < 0) continue;
|
|
char request[8192];
|
|
if (read(client, request, sizeof(request)) > 0) {
|
|
const char *body = "{\"status\":\"ok\",\"version\":\"" HEALTH_VERSION "\"}";
|
|
char response[1024];
|
|
int size = snprintf(response, sizeof(response),
|
|
"HTTP/1.1 200 OK\r\nContent-Length: %zu\r\nConnection: close\r\n\r\n%s", strlen(body), body);
|
|
if (write(client, response, size) < 0) { /* disconnected probe */ }
|
|
}
|
|
close(client);
|
|
}
|
|
}
|