From 3671e34d4eea6c7d3a91377ca890b753a112a8ff Mon Sep 17 00:00:00 2001 From: hkc Date: Wed, 21 Feb 2024 15:36:58 +0300 Subject: [PATCH] Basic IPC stuff --- src/common.h | 48 ++++++++++++++++++++++++++++++++ src/sfxc.c | 40 +++++++++++++++++++++++++-- src/sfxd.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 src/common.h diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..6984f23 --- /dev/null +++ b/src/common.h @@ -0,0 +1,48 @@ +#ifndef _SFXD_COMMON_H_ +#define _SFXD_COMMON_H_ + +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 8192 +#define DAEMON_SOCKET_PATH "/tmp/sfxd-ipc" +#define CLIENT_SOCKET_PATH "/tmp/sfxd-client-%ld" + +#define PANIC_FMT(FMT, ...) _panic(__LINE__, __FILE__, errno, FMT, __VA_ARGS__) +#define PANIC(TXT) _panic(__LINE__, __FILE__, errno, TXT) +#define EXPECT(CODE, CONDITION) { \ + ssize_t __res = (CODE); \ + if (!(__res CONDITION)) \ + PANIC_FMT("%s failed condition: %zd %s", #CODE, __res, #CONDITION); \ +} + +static inline void _panic(int line, const char *filename, int _errno, const char *fmt, ...) { + fprintf(stderr, "Panic at %s:%d\nMessage: ", filename, line); + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\nerrno: %d (%s)\n", _errno, strerror(_errno)); + + exit(EXIT_FAILURE); +} + +static inline uint32_t adler32(const void *buf, size_t buflength) { + const uint8_t *buffer = (const uint8_t*)buf; + + uint32_t s1 = 1; + uint32_t s2 = 0; + + for (size_t n = 0; n < buflength; n++) { + s1 = (s1 + buffer[n]) % 65521; + s2 = (s2 + s1) % 65521; + } + return (s2 << 16) | s1; +} + +#endif diff --git a/src/sfxc.c b/src/sfxc.c index cbcecc0..c37a0d8 100644 --- a/src/sfxc.c +++ b/src/sfxc.c @@ -1,6 +1,40 @@ +#include "common.h" #include -#include +#include +#include +#include +#include +#include -int main(void) { - printf("Hi!\n"); +int main(int argc, char **argv) { + struct sockaddr_un sa_server, sa_client; + int sock_fd; + static char buffer[BUFFER_SIZE]; + + EXPECT(sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0), > 0); + + memset(&sa_server, 0, sizeof(sa_server)); + memset(&sa_client, 0, sizeof(sa_client)); + + sa_server.sun_family = sa_client.sun_family = AF_UNIX; + snprintf(sa_client.sun_path, sizeof(sa_client.sun_path), CLIENT_SOCKET_PATH, (long)getpid()); + strncpy(sa_server.sun_path, DAEMON_SOCKET_PATH, sizeof(sa_server.sun_path) - 1); + + EXPECT(bind(sock_fd, (struct sockaddr *)&sa_client, sizeof(struct sockaddr_un)), == 0); + + for (int i = 1; i < argc; i++) { + strncat(buffer, argv[1], BUFFER_SIZE - strlen(buffer) - 1); + if (i != argc - 1) { + strncat(buffer, " ", BUFFER_SIZE - strlen(buffer) - 1); + } + } + + EXPECT(sendto(sock_fd, buffer, strlen(buffer), 0, (struct sockaddr *)&sa_server, sizeof(sa_server)), == strlen(buffer)); + int data_len; + while ((data_len = recv(sock_fd, buffer, BUFFER_SIZE, 0)) > 0) { + printf("%.*s", data_len, buffer); + } + + unlink(sa_client.sun_path); + exit(EXIT_SUCCESS); } diff --git a/src/sfxd.c b/src/sfxd.c index cbcecc0..dead19a 100644 --- a/src/sfxd.c +++ b/src/sfxd.c @@ -1,6 +1,77 @@ +#include "common.h" +#include #include -#include +#include +#include +#include +#include -int main(void) { - printf("Hi!\n"); +struct msg_target { + FILE *file_handle; + int sock_fd; + struct sockaddr *sock_addr; + ssize_t sock_addr_size; +}; + +ssize_t send_data(struct msg_target tgt, const void *data, size_t len); +void execute_command(struct msg_target tgt, const char *command, const char *params); + +int main(int argc, char **argv) { + + struct sockaddr_un sa_server, sa_client; + int sock_fd; + static char buffer[BUFFER_SIZE]; + + char *sock_path = DAEMON_SOCKET_PATH; + + EXPECT(sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0), > 0); + + memset(&sa_server, 0, sizeof(sa_server)); + memset(&sa_client, 0, sizeof(sa_client)); + + sa_server.sun_family = AF_UNIX; + strncpy(sa_server.sun_path, sock_path, sizeof(sa_server.sun_path) - 1); + + unlink(sa_server.sun_path); + EXPECT(bind(sock_fd, (struct sockaddr *)&sa_server, sizeof(struct sockaddr_un)), >= 0); + + ssize_t data_len; + socklen_t sl_client = sizeof(sa_client); + while ((data_len = recvfrom(sock_fd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&sa_client, &sl_client)) != -1) { + buffer[data_len] = '\0'; + struct sockaddr_un *sau_client = &sa_client; + char *command = buffer; + char *params = strchr(buffer, ' '); + if (params != NULL) { + *params = '\0'; + params++; + } + execute_command((struct msg_target) { 0, sock_fd, (struct sockaddr *)&sa_client, sl_client }, command, params); + EXPECT(sendto(sock_fd, "OK\n", 4, 0, (struct sockaddr *)&sa_client, sl_client), == 4); + EXPECT(sendto(sock_fd, "", 0, 0, (struct sockaddr *)&sa_client, sl_client), == 0); + sl_client = sizeof(sa_client); + } + + unlink(sa_server.sun_path); +} + +ssize_t send_data(struct msg_target tgt, const void *data, size_t len) { + ssize_t written; + if (tgt.file_handle) { + if ((written = fwrite(data, 1, len, tgt.file_handle)) != len) { + PANIC_FMT("fwrite(ptr=%p, size=%zd, nmemb=%zd, stream=%p) -> %zd", + data, 1, len, tgt.file_handle, written); + } + } else { + if ((written = sendto(tgt.sock_fd, data, len, 0, tgt.sock_addr, tgt.sock_addr_size)) != len) { + PANIC_FMT("sendto(socket=%d, message=%p, length=%zd, flags=%d, dest_addr=%p, dest_len=%zd) -> %zd", + tgt.sock_fd, data, len, 0, tgt.sock_addr, tgt.sock_addr_size, written); + } + } + + return written; +} + +void execute_command(struct msg_target tgt, const char *command, const char *params) { + send_data(tgt, "WAAAAAAAAAAAAAA\n", 16); }