diff --git a/WEEK-8/rsh_server.c b/WEEK-8/rsh_server.c new file mode 100644 index 0000000000000000000000000000000000000000..07753a40cf8e36dc35249ccdc617841b96ae3c77 --- /dev/null +++ b/WEEK-8/rsh_server.c @@ -0,0 +1,98 @@ + +#include "rshlib.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <arpa/inet.h> + +/** + * Starts the server and listens for client connections. + */ +int start_server(char *ifaces, int port, int is_threaded) { + int server_sock, client_sock; + struct sockaddr_in server, client; + socklen_t client_len = sizeof(client); + + // Create socket + server_sock = socket(AF_INET, SOCK_STREAM, 0); + if (server_sock == -1) { + perror("[ERROR] Could not create server socket"); + return ERR_RDSH_SERVER; + } + + server.sin_family = AF_INET; + server.sin_addr.s_addr = inet_addr(ifaces); + server.sin_port = htons(port); + + // Bind the socket + if (bind(server_sock, (struct sockaddr *)&server, sizeof(server)) < 0) { + perror("[ERROR] Binding failed"); + return ERR_RDSH_SERVER; + } + + // Start listening for connections + listen(server_sock, 3); + printf("[DEBUG] Server listening on %s:%d\n", ifaces, port); + + while ((client_sock = accept(server_sock, (struct sockaddr *)&client, &client_len))) { + printf("[DEBUG] Client connected\n"); + exec_client_requests(client_sock); + close(client_sock); + } + + return OK; +} + +/** + * Handles client requests and executes commands. + */ +int exec_client_requests(int cli_socket) { + char buffer[RDSH_COMM_BUFF_SZ]; + + while (1) { + memset(buffer, 0, sizeof(buffer)); + + // Receive command + int recv_size = recv(cli_socket, buffer, sizeof(buffer), 0); + if (recv_size <= 0) break; + + buffer[recv_size] = '\0'; + + // Check for built-in commands + Built_In_Cmds cmd_type = rsh_match_command(buffer); + if (cmd_type == BI_CMD_EXIT) { + printf("[DEBUG] Client requested exit\n"); + break; + } + if (cmd_type == BI_CMD_STOP_SVR) { + printf("[DEBUG] Client requested server shutdown\n"); + return STOP_SERVER_SC; + } + + // Execute command + FILE *fp = popen(buffer, "r"); + if (fp == NULL) { + send(cli_socket, "[ERROR] Command execution failed\n", 34, 0); + continue; + } + + // Send command output back to client + char output[RDSH_COMM_BUFF_SZ]; + while (fgets(output, sizeof(output), fp) != NULL) { + send(cli_socket, output, strlen(output), 0); + } + + // Send EOF to signal end of command output + send_message_eof(cli_socket); + pclose(fp); + } + + return OK; +} + + +int send_message_eof(int cli_socket) { + return send(cli_socket, &RDSH_EOF_CHAR, 1, 0); +}