Files
archy/scripts/tests/public_update_fixture.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);
}
}