Basic IPC stuff

This commit is contained in:
Casey 2024-02-21 15:36:58 +03:00
parent 92abc822ec
commit 3671e34d4e
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
3 changed files with 159 additions and 6 deletions

48
src/common.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef _SFXD_COMMON_H_
#define _SFXD_COMMON_H_
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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

View File

@ -1,6 +1,40 @@
#include "common.h"
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main(void) { int main(int argc, char **argv) {
printf("Hi!\n"); 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);
} }

View File

@ -1,6 +1,77 @@
#include "common.h"
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main(void) { struct msg_target {
printf("Hi!\n"); 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);
} }