From 77dc79afe5fd909fb1fe0a3cc668db2763b82fb8 Mon Sep 17 00:00:00 2001 From: rubin Date: Fri, 22 May 2026 13:42:51 +0200 Subject: import repository Signed-off-by: rubinowy blask --- build.sh | 17 ++++++++ child.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ child.h | 2 + fdwatcher.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fdwatcher.h | 18 +++++++++ logging.h | 29 ++++++++++++++ main.c | 40 +++++++++++++++++++ network.c | 55 ++++++++++++++++++++++++++ network.h | 4 ++ parent.c | 86 ++++++++++++++++++++++++++++++++++++++++ parent.h | 2 + 11 files changed, 487 insertions(+) create mode 100755 build.sh create mode 100644 child.c create mode 100644 child.h create mode 100644 fdwatcher.c create mode 100644 fdwatcher.h create mode 100644 logging.h create mode 100644 main.c create mode 100644 network.c create mode 100644 network.h create mode 100644 parent.c create mode 100644 parent.h diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..6f1ddad --- /dev/null +++ b/build.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e; # exit on error + +#CC="x86_64-unknown-linux-musl-gcc" +CC="gcc" + +roll_print() { printf "\t\t%s\t%s\n" "$1" "$2"; } + +for i in fdwatcher network parent child main; do + roll_print "CC" "$i.o" + "$CC" -I. -c -o "$i.o" "$i.c" +done + +"$CC" -static -o aura fdwatcher.o network.o parent.o child.o main.o +strip aura + diff --git a/child.c b/child.c new file mode 100644 index 0000000..58ee999 --- /dev/null +++ b/child.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include + +#include "fdwatcher.h" +#include "logging.h" + +struct ConnectionDataBuffer { + size_t capacity; + size_t length; + char buf[]; +}; + +struct ConnectionData { + struct ConnectionDataBuffer *buffer; +}; + +static int +aura_addbufferdata(struct ConnectionDataBuffer *buffer, char *data, size_t length) +{ + if (buffer->length + length > buffer->capacity) { + aura_printf("FUCK!\n"); + aura_printf("buffer->length: %ld\n", buffer->length); + aura_printf("buffer->capacity: %ld\n", buffer->capacity); + aura_printf("length: %ld\n", length); + + abort(); + } + + memcpy(buffer->buf, data, length); + buffer->length = buffer->length + length; + + return 0; +} + +static int +meowiero(struct FDWatchHandle *handle, enum FDWatch_EventType type, int fd, void *data) +{ + struct ConnectionData *connectiondata = (struct ConnectionData *)data; + char c = 0; + + switch (type) { + case FDWATCH_EVENT_INP: + aura_printf("INPUT event in fd:%d\n", fd); + + read(fd, &c, 2); + aura_addbufferdata(connectiondata->buffer, &c, 2); + + aura_printf("%c\n", c); + break; + case FDWATCH_EVENT_HUP: + aura_printf("HANGUP event in fd:%d, exiting\n", fd); + fdwatcher_remove(handle, fd); + close(fd); + return 0; + } + + return 1; +} + +/* init */ +int childProcessMain(int argc, char **argv) +{ + struct ConnectionData *connectiondata = { 0 }; + struct FDWatchHandle fdhandle = { 0 }; + int sockie = 0; + int ret = 0; + + connectiondata = (struct ConnectionData *)malloc(sizeof(struct ConnectionData)); + if (errno != 0) { + perror("malloc(3)"); + return 1; + } + + connectiondata->buffer = malloc(sizeof(struct ConnectionDataBuffer) + 65536); + if (errno != 0) { + perror("malloc(3)"); + return 1; + } + connectiondata->buffer->capacity = 65536; + + /* socket fd int in argv[2]! ^w^ */ + sscanf(argv[2], "%d", &sockie); + aura_printf("received fd:%d\n", sockie); + + ret = fdwatcher_initialise(&fdhandle, 1); + if (ret < 0) { + aura_fprintf(stderr, "fdwatcher_initialise failed\n"); + return 1; + } + + ret = fdwatcher_add(&fdhandle, sockie, (void *)connectiondata); + if (ret < 0) { + aura_fprintf(stderr, "fdwatcher_add failed\n"); + return 1; + } + + fdwatcher_watch(&fdhandle, meowiero); + aura_printf("finished\n"); + + return 0; +} + diff --git a/child.h b/child.h new file mode 100644 index 0000000..2a63c2d --- /dev/null +++ b/child.h @@ -0,0 +1,2 @@ +int childProcessMain(int, char **); + diff --git a/fdwatcher.c b/fdwatcher.c new file mode 100644 index 0000000..8e0cb97 --- /dev/null +++ b/fdwatcher.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include + +#include + +int +fdwatcher_initialise(struct FDWatchHandle *handle, int maxWatchedFds) +{ + size_t pollfdSize = maxWatchedFds * sizeof(handle->watchedFds); + size_t pointersSize = maxWatchedFds * sizeof(void *); + + handle->watchedFds = malloc(pollfdSize); + if (errno != 0) { + perror("fdwatcher_initialise: malloc(3)"); + return -errno; + } + + handle->arbitraryData = malloc(pointersSize); + if (errno != 0) { + perror("fdwatcher_initialise: malloc(3)"); + return -errno; + } + + memset(handle->watchedFds, 0, pollfdSize); + handle->maxWatchedFds = maxWatchedFds; + return 0; +} + +int +fdwatcher_add(struct FDWatchHandle *handle, int fd, void *arbitrary) +{ + struct pollfd *watchedFd = NULL; + + if (handle->maxWatchedFds == handle->watchedFdCount) { + printf("meow\n"); + return -EMFILE; + } + + handle->arbitraryData[handle->watchedFdCount] = arbitrary; + watchedFd = &(handle->watchedFds[handle->watchedFdCount]); + watchedFd->events = POLLIN | POLLHUP | POLLRDHUP; + watchedFd->revents = 0; + watchedFd->fd = fd; + + handle->watchedFdCount = handle->watchedFdCount + 1; + return 0; +} + +static int +_fdwatcher_handleEvents_revents(struct pollfd *pollie, struct FDWatchHandle *handle, + int (*meow)(struct FDWatchHandle *, enum FDWatch_EventType, int, void *), + size_t elementNumber) +{ + int ret = 0; + + if (pollie->revents & POLLHUP || pollie->revents & POLLRDHUP) { + ret = meow(handle, FDWATCH_EVENT_HUP, pollie->fd, handle->arbitraryData[elementNumber]); + if (ret == 0) { + return 1; + } + } + + if (pollie->revents & POLLIN) { + meow(handle, FDWATCH_EVENT_INP, pollie->fd, handle->arbitraryData[elementNumber]); + } + return 0; +} + +static int +_fdwatcher_handleEvents(struct FDWatchHandle *handle, int (*meow)(struct FDWatchHandle *handle, enum FDWatch_EventType, int, void *)) +{ + size_t i = 0; + int ret = 0; + + while (1) { + if (i == handle->watchedFdCount) break; + + struct pollfd *watchedFdEntry = NULL; + watchedFdEntry = &handle->watchedFds[i]; + + if (watchedFdEntry->revents != 0) { + ret = _fdwatcher_handleEvents_revents(watchedFdEntry, handle, meow, i); + watchedFdEntry->revents = 0; + + if (ret != 0) { + return 1; + } + } + i++; + } + + return 0; +} + +int +fdwatcher_watch(struct FDWatchHandle *handle, int (*meow)(struct FDWatchHandle *handle, enum FDWatch_EventType, int, void *)) +{ + int ret = 0; + + while (1) { + ret = poll(handle->watchedFds, handle->watchedFdCount, INT_MAX); + if (errno != 0) { + ret = meow(handle, FDWATCH_EVENT_ERR, 0, NULL); + + if (ret == 1) break; + errno = 0; + continue; + } + + ret = _fdwatcher_handleEvents(handle, meow); + if (ret == 1) { + return 1; + } + } + + return 0; +} + +/* TODO */ +int +fdwatcher_remove(struct FDWatchHandle *handle, int fd) +{ + abort(); +} diff --git a/fdwatcher.h b/fdwatcher.h new file mode 100644 index 0000000..ce90198 --- /dev/null +++ b/fdwatcher.h @@ -0,0 +1,18 @@ +struct FDWatchHandle { + int maxWatchedFds; + int watchedFdCount; + struct pollfd *watchedFds; + void **arbitraryData; +}; + +enum FDWatch_EventType { + FDWATCH_EVENT_ERR = 0, + FDWATCH_EVENT_INP = 1, + FDWATCH_EVENT_OUT = 2, + FDWATCH_EVENT_HUP = 3 +}; + +int fdwatcher_watch(struct FDWatchHandle *, int (*)(struct FDWatchHandle *, enum FDWatch_EventType, int, void *)); +int fdwatcher_initialise(struct FDWatchHandle *, int); +int fdwatcher_remove(struct FDWatchHandle *, int); +int fdwatcher_add(struct FDWatchHandle *, int, void *); diff --git a/logging.h b/logging.h new file mode 100644 index 0000000..6ad5729 --- /dev/null +++ b/logging.h @@ -0,0 +1,29 @@ +#include +#include + +static void +aura_printf(const char *fmt, ...) +{ + va_list args = { 0 }; + + printf("[%d] ", getpid()); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + return; +} + +static void +aura_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list args = { 0 }; + + fprintf(stream, "[%d] ", getpid()); + va_start(args, fmt); + vfprintf(stream, fmt, args); + va_end(args); + + return; +} + diff --git a/main.c b/main.c new file mode 100644 index 0000000..8a87442 --- /dev/null +++ b/main.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#include "fdwatcher.h" +#include "logging.h" +#include "network.h" +#include "parent.h" +#include "child.h" + +int +isChildProcess(int argc, char **argv) +{ + if (argc < 3) { + return 0; + } + + if (strcmp(argv[1], "childprocess") != 0) { + return 0; + } + + return 1; +} + +int +main(int argc, char **argv) +{ + #ifdef __OpenBSD__ + aura_printf("hello, OpenBSD user. for paranoia's sake, pledge(3) will be run.\n"); + pledge("stdio inet", "stdio inet"); + aura_printf("yippie\n"); + #endif + + if (isChildProcess(argc, argv)) { + aura_printf("child process\n"); + return childProcessMain(argc, argv); + } + + return parentProcessMain(); +} diff --git a/network.c b/network.c new file mode 100644 index 0000000..263e2cb --- /dev/null +++ b/network.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include "network.h" + +int +net_listen4(uint32_t ip, uint16_t port, int backlog) +{ + struct sockaddr_in addr_in = { 0 }; + int sock = 0; + int temp = 1; + + if (ip != 0) { + return -ENOSYS; + } + + if (port == 0) { + return -EINVAL; + } + + addr_in.sin_port = htons(port); + sock = socket(AF_INET, SOCK_STREAM, 0); + if (errno != 0) { + perror("socket(3)"); + return -errno; + } + + temp = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(temp)); + if (errno != 0) { + perror("setsockopt(3)"); + close(sock); + return -errno; + } + + bind(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)); + if (errno != 0) { + perror("bind(3)"); + close(sock); + return -errno; + } + + listen(sock, backlog); + if (errno != 0) { + perror("listen(3)"); + close(sock); + return -errno; + } + + return sock; +} + diff --git a/network.h b/network.h new file mode 100644 index 0000000..5db105b --- /dev/null +++ b/network.h @@ -0,0 +1,4 @@ +#include + +int net_listen4(uint32_t, uint16_t, int); + diff --git a/parent.c b/parent.c new file mode 100644 index 0000000..a3cbb4a --- /dev/null +++ b/parent.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include + +#include "fdwatcher.h" +#include "logging.h" +#include "network.h" + +char *meowA = "haze"; +char *meowB = "childprocess"; + +static int +handleNewConnection(int serverfd) +{ + char *childProcessArgv[4] = { meowA, meowB, "", NULL }; + struct sockaddr address = { 0 }; + socklen_t addrSize = sizeof(address); + char chocolate[11] = { 0 }; + pid_t kwiat = 0; + int sock = 0; + + sock = accept(serverfd, &address, &addrSize); + if (errno != 0) { + perror("accept(3)"); + return -1; + } + + kwiat = fork(); + if (kwiat == 0) { + snprintf((char *)&chocolate, 10, "%d", sock); + childProcessArgv[2] = (char *)&chocolate; + close(serverfd); + execve("/proc/self/exe", childProcessArgv, NULL); + perror("execve(3)"); + abort(); + } + close(sock); + + return 0; +} + +static int +meowie(struct FDWatchHandle *handle, enum FDWatch_EventType type, int fd, void *data) +{ + switch (type) { + case FDWATCH_EVENT_INP: + aura_printf("INPUT event in fd:%d\n", fd); + handleNewConnection(fd); + break; + } + + return 1; +} + +int +parentProcessMain(void) +{ + struct FDWatchHandle fdhandle = { 0 }; + int sock = 0; + int ret = 0; + + sock = net_listen4(0, 4096, 0); + if (sock < 0) { + aura_fprintf(stderr, "net_listen4 failed\n"); + return 1; + } + + ret = fdwatcher_initialise(&fdhandle, 1); + if (ret < 0) { + aura_fprintf(stderr, "fdwatcher_initialise failed\n"); + return 1; + } + + ret = fdwatcher_add(&fdhandle, sock, NULL); + if (ret < 0) { + aura_fprintf(stderr, "fdwatcher_add failed\n"); + return 1; + } + + aura_printf("Listening on fd:%d\n", sock); + + fdwatcher_watch(&fdhandle, meowie); +} + diff --git a/parent.h b/parent.h new file mode 100644 index 0000000..8e6503a --- /dev/null +++ b/parent.h @@ -0,0 +1,2 @@ +int parentProcessMain(void); + -- cgit 1.4.1