diff options
| author | Adam Soltys <[email protected]> | 2025-01-21 23:28:00 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-01-21 23:28:00 -0800 |
| commit | 9662c2754834599a1074d12565279674c20af467 (patch) | |
| tree | 1d77aaedf19b035378236305af582c903e025467 /server.c | |
| parent | eb4e16b5599e67a65962db2a07629dfdcdda57dc (diff) | |
| download | coinos-server-9662c2754834599a1074d12565279674c20af467.tar.gz coinos-server-9662c2754834599a1074d12565279674c20af467.zip | |
notes and stuff
Diffstat (limited to 'server.c')
| -rw-r--r-- | server.c | 236 |
1 files changed, 148 insertions, 88 deletions
@@ -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"); + } } |
