aboutsummaryrefslogtreecommitdiffstats
path: root/server.c
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-01-21 23:28:00 -0800
committerAdam Soltys <[email protected]>2025-01-21 23:28:00 -0800
commit9662c2754834599a1074d12565279674c20af467 (patch)
tree1d77aaedf19b035378236305af582c903e025467 /server.c
parenteb4e16b5599e67a65962db2a07629dfdcdda57dc (diff)
downloadcoinos-server-9662c2754834599a1074d12565279674c20af467.tar.gz
coinos-server-9662c2754834599a1074d12565279674c20af467.zip
notes and stuff
Diffstat (limited to 'server.c')
-rw-r--r--server.c236
1 files changed, 148 insertions, 88 deletions
diff --git a/server.c b/server.c
index 8522785b..8f65a793 100644
--- a/server.c
+++ b/server.c
@@ -6,119 +6,179 @@
#include <unistd.h>
#define SOCKET_PATH "/sockets/ctrl"
-#define BUFFER_SIZE 262144
+#define INITIAL_BUFFER_SIZE 1024
-void handle_client(const char *result_socket, const char *command);
+void handle_client(const char *result_socket, const char *command, const char *data);
int main() {
- int server_fd, client_fd;
- struct sockaddr_un server_addr;
- char buffer[BUFFER_SIZE];
+ int server_fd, client_fd;
+ struct sockaddr_un server_addr;
- unlink(SOCKET_PATH);
+ // Unlink the socket file in case it exists
+ unlink(SOCKET_PATH);
- server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (server_fd == -1) {
- perror("socket failed");
- exit(EXIT_FAILURE);
- }
+ server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (server_fd == -1) {
+ perror("socket failed");
+ exit(EXIT_FAILURE);
+ }
- memset(&server_addr, 0, sizeof(struct sockaddr_un));
- server_addr.sun_family = AF_UNIX;
- strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
+ memset(&server_addr, 0, sizeof(struct sockaddr_un));
+ server_addr.sun_family = AF_UNIX;
+ strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
- if (bind(server_fd, (struct sockaddr *)&server_addr,
- sizeof(struct sockaddr_un)) == -1) {
- perror("bind failed");
- close(server_fd);
- exit(EXIT_FAILURE);
- }
+ if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_un)) == -1) {
+ perror("bind failed");
+ close(server_fd);
+ exit(EXIT_FAILURE);
+ }
- if (listen(server_fd, 5) == -1) {
- perror("listen failed");
- close(server_fd);
- exit(EXIT_FAILURE);
- }
+ if (listen(server_fd, 5) == -1) {
+ perror("listen failed");
+ close(server_fd);
+ exit(EXIT_FAILURE);
+ }
- printf("Server listening on %s\n", SOCKET_PATH);
+ printf("Server listening on %s\n", SOCKET_PATH);
- while (1) {
+ while (1) {
+ client_fd = accept(server_fd, NULL, NULL);
+ if (client_fd == -1) {
+ perror("accept failed");
+ continue;
+ }
- client_fd = accept(server_fd, NULL, NULL);
- if (client_fd == -1) {
- perror("accept failed");
- continue;
- }
+ size_t buffer_size = INITIAL_BUFFER_SIZE;
+ char *buffer = malloc(buffer_size);
+ if (!buffer) {
+ perror("malloc failed");
+ close(client_fd);
+ continue;
+ }
- memset(buffer, 0, BUFFER_SIZE);
- ssize_t num_bytes = read(client_fd, buffer, BUFFER_SIZE - 1);
- if (num_bytes > 0) {
+ size_t total_bytes_read = 0;
+ ssize_t num_bytes;
- buffer[num_bytes] = '\0';
+ while ((num_bytes = read(client_fd, buffer + total_bytes_read, buffer_size - total_bytes_read - 1)) > 0) {
+ total_bytes_read += num_bytes;
- printf("Received: %s\n", buffer);
+ // Expand buffer if necessary
+ if (total_bytes_read >= buffer_size - 1) {
+ buffer_size *= 2;
+ char *new_buffer = realloc(buffer, buffer_size);
+ if (!new_buffer) {
+ perror("realloc failed");
+ free(buffer);
+ close(client_fd);
+ continue;
+ }
+ buffer = new_buffer;
+ }
+ }
- char result_socket[BUFFER_SIZE], command[BUFFER_SIZE];
- if (sscanf(buffer, "%s %[^\n]", result_socket, command) == 2) {
- printf("Result socket: %s\n", result_socket);
- printf("Command: %s\n", command);
+ if (num_bytes == -1) {
+ perror("read failed");
+ free(buffer);
+ close(client_fd);
+ continue;
+ }
- handle_client(result_socket, command);
- } else {
- fprintf(stderr, "Invalid input format\n");
- }
- }
+ buffer[total_bytes_read] = '\0'; // Null-terminate the string
+
+ printf("Received: %s\n", buffer);
+
+ // Split message into result_socket, command, and data
+ char *result_socket = strtok(buffer, " ");
+ char *command = strtok(NULL, "\n");
+ char *data = strtok(NULL, "");
- close(client_fd);
- }
+ if (result_socket && command) {
+ printf("Result socket: %s\n", result_socket);
+ printf("Command: %s\n", command);
+ if (data) {
+ printf("Data: %s\n", data);
+ }
+ handle_client(result_socket, command, data);
+ } else {
+ fprintf(stderr, "Invalid input format\n");
+ }
+
+ free(buffer);
+ close(client_fd);
+ }
- close(server_fd);
- unlink(SOCKET_PATH);
- return 0;
+ close(server_fd);
+ unlink(SOCKET_PATH);
+ return 0;
}
-void handle_client(const char *result_socket, const char *command) {
- pid_t pid = fork();
+void handle_client(const char *result_socket, const char *command, const char *data) {
+ pid_t pid = fork();
- if (pid == 0) {
+ if (pid == 0) {
+ int result_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (result_fd == -1) {
+ perror("result socket failed");
+ exit(EXIT_FAILURE);
+ }
- int result_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (result_fd == -1) {
- perror("result socket failed");
- exit(EXIT_FAILURE);
- }
+ struct sockaddr_un result_addr;
+ memset(&result_addr, 0, sizeof(struct sockaddr_un));
+ result_addr.sun_family = AF_UNIX;
+ strncpy(result_addr.sun_path, result_socket, sizeof(result_addr.sun_path) - 1);
- struct sockaddr_un result_addr;
- memset(&result_addr, 0, sizeof(struct sockaddr_un));
- result_addr.sun_family = AF_UNIX;
- strncpy(result_addr.sun_path, result_socket,
- sizeof(result_addr.sun_path) - 1);
+ if (connect(result_fd, (struct sockaddr *)&result_addr, sizeof(struct sockaddr_un)) == -1) {
+ perror("connect to result socket failed");
+ close(result_fd);
+ exit(EXIT_FAILURE);
+ }
- if (connect(result_fd, (struct sockaddr *)&result_addr,
- sizeof(struct sockaddr_un)) == -1) {
- perror("connect to result socket failed");
- close(result_fd);
- exit(EXIT_FAILURE);
- }
+ int pipe_fd[2];
+ if (pipe(pipe_fd) == -1) {
+ perror("pipe failed");
+ close(result_fd);
+ exit(EXIT_FAILURE);
+ }
- FILE *cmd_output = popen(command, "r");
- if (cmd_output == NULL) {
- perror("popen failed");
- close(result_fd);
- exit(EXIT_FAILURE);
- }
+ pid_t cmd_pid = fork();
+ if (cmd_pid == 0) {
+ // Child process: run the command
+ dup2(pipe_fd[0], STDIN_FILENO); // Redirect stdin
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ close(result_fd);
- char output_buffer[BUFFER_SIZE];
- while (fgets(output_buffer, sizeof(output_buffer), cmd_output) != NULL) {
- write(result_fd, output_buffer, strlen(output_buffer));
- }
+ execlp("/bin/sh", "sh", "-c", command, (char *)NULL);
+ perror("execlp failed");
+ exit(EXIT_FAILURE);
+ }
- pclose(cmd_output);
- shutdown(result_fd, SHUT_WR);
- close(result_fd);
- unlink(result_socket);
- exit(0);
- } else if (pid < 0) {
- perror("fork failed");
- }
+ // Parent process: send data and collect output
+ close(pipe_fd[0]); // Close read end of the pipe
+
+ if (data) {
+ write(pipe_fd[1], data, strlen(data));
+ }
+ close(pipe_fd[1]); // Close write end of the pipe
+
+ FILE *cmd_output = fdopen(result_fd, "w");
+ if (!cmd_output) {
+ perror("fdopen failed");
+ close(result_fd);
+ exit(EXIT_FAILURE);
+ }
+
+ char output_buffer[INITIAL_BUFFER_SIZE];
+ while (fgets(output_buffer, sizeof(output_buffer), cmd_output) != NULL) {
+ write(result_fd, output_buffer, strlen(output_buffer));
+ }
+
+ fclose(cmd_output);
+ shutdown(result_fd, SHUT_WR);
+ close(result_fd);
+ unlink(result_socket);
+ exit(0);
+ } else if (pid < 0) {
+ perror("fork failed");
+ }
}