Skip to content
Snippets Groups Projects
Commit 4143e2cd authored by Joey Le's avatar Joey Le
Browse files

Fixed a bunch of the functions. Hopefully it works now

parent 52c21eea
Branches
No related tags found
No related merge requests found
...@@ -263,58 +263,40 @@ static void start_server() { ...@@ -263,58 +263,40 @@ static void start_server() {
* fork(), execvp(), exit(), chdir() * fork(), execvp(), exit(), chdir()
*/ */
int exec_remote_cmd_loop(char *address, int port) {
char cmd_buff[RDSH_COMM_BUFF_SZ];
char rsp_buff[RDSH_COMM_BUFF_SZ];
int cli_socket;
ssize_t recv_bytes;
int is_eof;
// Connect to the server
int exec_local_cmd_loop() { cli_socket = start_client(address, port);
char cmd_buff[SH_CMD_MAX]; if (cli_socket < 0) {
int rc = OK; perror("start client");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_CLIENT);
while (1) {
printf("%s", SH_PROMPT);
if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) {
printf("\n");
break;
} }
cmd_buff[strcspn(cmd_buff, "\n")] = '\0'; while (1) {
printf("rsh> ");
if (strlen(cmd_buff) == 0) { if (!fgets(cmd_buff, RDSH_COMM_BUFF_SZ, stdin)) {
printf("%s\n", CMD_WARN_NO_CMD); break; // Exit on input error or EOF
rc = WARN_NO_CMDS;
continue;
} }
if (strstr(cmd_buff, "|") != NULL) { // Remove the newline character from the command
command_list_t cmd_list; size_t cmd_len = strlen(cmd_buff);
if (parse_pipeline(cmd_buff, &cmd_list) != OK) { if (cmd_len > 0 && cmd_buff[cmd_len - 1] == '\n') {
fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT); cmd_buff[cmd_len - 1] = '\0';
rc = ERR_TOO_MANY_COMMANDS;
continue;
} }
// Execute the pipeline // Handle local commands (e.g., cd, exit)
if (strncmp(cmd_buff, "cd", 2) == 0) {
execute_pipeline(&cmd_list); // Handle cd locally
// Free memory for each command's buffer
for (int i = 0; i < cmd_list.num; i++) {
free(cmd_list.commands[i]._cmd_buffer);
}
} else {
cmd_buff_t cmd; cmd_buff_t cmd;
if (build_cmd_buff(cmd_buff, &cmd) != OK) { if (build_cmd_buff(cmd_buff, &cmd) != OK) {
fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT); fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
rc = ERR_MEMORY;
continue; continue;
} }
if (strcmp(cmd.argv[0], EXIT_CMD) == 0) {
free(cmd._cmd_buffer);
break;
}
if (strcmp(cmd.argv[0], "cd") == 0) {
if (cmd.argc == 1) { if (cmd.argc == 1) {
chdir(getenv("HOME")); chdir(getenv("HOME"));
} else if (cmd.argc == 2) { } else if (cmd.argc == 2) {
...@@ -326,31 +308,35 @@ int exec_local_cmd_loop() { ...@@ -326,31 +308,35 @@ int exec_local_cmd_loop() {
} }
free(cmd._cmd_buffer); free(cmd._cmd_buffer);
continue; continue;
} else if (strncmp(cmd_buff, "exit", 4) == 0) {
break; // Exit the remote shell
} }
pid_t pid = fork(); // Send the command to the server
if (pid < 0) { ssize_t sent_bytes = send(cli_socket, cmd_buff, strlen(cmd_buff), 0);
perror("fork failed"); if (sent_bytes < 0) {
rc = ERR_MEMORY; perror("send");
} else if (pid == 0) { return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
execvp(cmd.argv[0], cmd.argv);
perror("execvp failed");
exit(EXIT_FAILURE);
} else {
int status;
wait(&status);
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
fprintf(stderr, "Command failed with exit code %d\n", WEXITSTATUS(status));
} }
// Receive the server's response
is_eof = 0;
while ((recv_bytes = recv(cli_socket, rsp_buff, RDSH_COMM_BUFF_SZ, 0)) > 0) {
printf("%.*s", (int)recv_bytes, rsp_buff);
if (rsp_buff[recv_bytes - 1] == RDSH_EOF_CHAR) {
is_eof = 1;
break;
} }
} }
free(cmd._cmd_buffer); if (recv_bytes < 0) {
perror("recv");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
} else if (recv_bytes == 0) {
printf("Server closed the connection\n");
break;
} }
} }
return rc; return client_cleanup(cli_socket, NULL, NULL, OK);
} }
...@@ -92,32 +92,49 @@ ...@@ -92,32 +92,49 @@
*/ */
int exec_remote_cmd_loop(char *address, int port) int exec_remote_cmd_loop(char *address, int port)
{ {
char *cmd_buff; char cmd_buff[RDSH_COMM_BUFF_SZ]; // Use the buffer size from rshlib.h
char *rsp_buff; char rsp_buff[RDSH_COMM_BUFF_SZ];
int cli_socket; int cli_socket;
ssize_t io_size; ssize_t recv_bytes;
int is_eof; int is_eof;
// TODO set up cmd and response buffs // Connect to the server
cli_socket = start_client(address, port); cli_socket = start_client(address, port);
if (cli_socket < 0) { if (cli_socket < 0) {
perror("start client"); perror("start client");
return client_cleanup(cli_socket, cmd_buff, rsp_buff, ERR_RDSH_CLIENT); return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_CLIENT);
} }
while (1) while (1) {
{ printf("rsh> ");
// TODO print prompt if (!fgets(cmd_buff, RDSH_COMM_BUFF_SZ, stdin)) {
break;
}
// TODO fgets input if (send(cli_socket, cmd_buff, strlen(cmd_buff), 0) < 0) {
perror("send");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
}
// TODO send() over cli_socket is_eof = 0;
while ((recv_bytes = recv(cli_socket, rsp_buff, RDSH_COMM_BUFF_SZ, 0)) > 0) {
printf("%.*s", (int)recv_bytes, rsp_buff); // Print the received data
if (rsp_buff[recv_bytes - 1] == RDSH_EOF_CHAR) {
is_eof = 1; // Check for EOF character
break;
}
}
// TODO recv all the results if (recv_bytes < 0) {
perror("recv");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
}
// TODO break on exit command if (strncmp(cmd_buff, "exit", 4) == 0 || strncmp(cmd_buff, "stop-server", 11) == 0) {
break;
} }
}
return client_cleanup(cli_socket, cmd_buff, rsp_buff, OK); return client_cleanup(cli_socket, cmd_buff, rsp_buff, OK);
} }
...@@ -151,6 +168,29 @@ int start_client(char *server_ip, int port){ ...@@ -151,6 +168,29 @@ int start_client(char *server_ip, int port){
int ret; int ret;
// TODO set up cli_socket // TODO set up cli_socket
cli_socket = socket(AF_INET, SOCK_STREAM, 0);
if (cli_socket < 0) {
perror("socket");
return ERR_RDSH_CLIENT;
}
// Set up the server address structure
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (inet_pton(AF_INET, server_ip, &addr.sin_addr) <= 0) {
perror("inet_pton");
close(cli_socket);
return ERR_RDSH_CLIENT;
}
// Connect to the server
ret = connect(cli_socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("connect");
close(cli_socket);
return ERR_RDSH_CLIENT;
}
return cli_socket; return cli_socket;
......
...@@ -302,73 +302,109 @@ int boot_server(char *ifaces, int port){ ...@@ -302,73 +302,109 @@ int boot_server(char *ifaces, int port){
*/ */
int exec_client_requests(int cli_socket) { int exec_client_requests(int cli_socket) {
char *io_buff; char cmd_buff[RDSH_COMM_BUFF_SZ];
int io_size; ssize_t recv_bytes;
command_list_t cmd_list;
int rc = OK; int rc = OK;
// Allocate a buffer for I/O operations
io_buff = malloc(RDSH_COMM_BUFF_SZ);
if (io_buff == NULL) {
return ERR_RDSH_SERVER; // Return server error if allocation fails
}
while (1) { while (1) {
// Receive input from the client recv_bytes = recv(cli_socket, cmd_buff, RDSH_COMM_BUFF_SZ, 0);
io_size = recv(cli_socket, io_buff, RDSH_COMM_BUFF_SZ, 0); if (recv_bytes <= 0) {
if (io_size < 0) { close(cli_socket);
perror("recv"); printf("Client disconnected\n");
free(io_buff); return OK;
return ERR_RDSH_COMMUNICATION; // Return communication error
} else if (io_size == 0) {
// Client disconnected
free(io_buff);
return OK; // Return OK to accept another client
} }
// Null-terminate the received data cmd_buff[recv_bytes] = '\0';
io_buff[io_size] = '\0';
// Check for special commands cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
if (strncmp(io_buff, "exit", strlen("exit")) == 0) {
// Client sent the `exit` command if (strlen(cmd_buff) == 0) {
free(io_buff); send_message_string(cli_socket, CMD_WARN_NO_CMD);
return OK; // Return OK to accept another client
} else if (strncmp(io_buff, "stop-server", strlen("stop-server")) == 0) {
// Client sent the `stop-server` command
free(io_buff);
return OK_EXIT; // Return OK_EXIT to stop the server
}
// Parse the input into a command list
rc = parse_pipeline(io_buff, &cmd_list);
if (rc != OK) {
// Handle parsing error
send_message_string(cli_socket, CMD_ERR_RDSH_EXEC);
send_message_eof(cli_socket); send_message_eof(cli_socket);
continue; // Continue to the next iteration rc = WARN_NO_CMDS;
continue;
} }
// Execute the command pipeline if (strstr(cmd_buff, "|") != NULL) {
rc = rsh_execute_pipeline(cli_socket, &cmd_list); command_list_t cmd_list;
if (rc < 0) { if (parse_pipeline(cmd_buff, &cmd_list) != OK) {
// Handle execution error send_message_string(cli_socket, CMD_ERR_PIPE_LIMIT);
send_message_string(cli_socket, CMD_ERR_RDSH_EXEC);
send_message_eof(cli_socket); send_message_eof(cli_socket);
continue; // Continue to the next iteration rc = ERR_TOO_MANY_COMMANDS;
continue;
} }
// Free memory for each command's buffer rc = rsh_execute_pipeline(cli_socket, &cmd_list);
for (int i = 0; i < cmd_list.num; i++) { for (int i = 0; i < cmd_list.num; i++) {
free(cmd_list.commands[i]._cmd_buffer); free(cmd_list.commands[i]._cmd_buffer);
} }
} else {
cmd_buff_t cmd;
if (build_cmd_buff(cmd_buff, &cmd) != OK) {
send_message_string(cli_socket, CMD_ERR_PIPE_LIMIT);
send_message_eof(cli_socket);
rc = ERR_MEMORY;
continue;
}
if (strcmp(cmd.argv[0], EXIT_CMD) == 0) {
free(cmd._cmd_buffer);
send_message_string(cli_socket, "Exiting...\n");
send_message_eof(cli_socket);
return OK;
} else if (strcmp(cmd.argv[0], "stop-server") == 0) {
free(cmd._cmd_buffer);
send_message_string(cli_socket, "Stopping server...\n");
send_message_eof(cli_socket);
return OK_EXIT;
} else if (strcmp(cmd.argv[0], "cd") == 0) {
if (cmd.argc == 1) {
chdir(getenv("HOME"));
} else if (cmd.argc == 2) {
if (chdir(cmd.argv[1]) != 0) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "cd: %s\n", strerror(errno));
send_message_string(cli_socket, error_msg);
}
} else {
send_message_string(cli_socket, CMD_ERR_PIPE_LIMIT);
}
send_message_eof(cli_socket);
free(cmd._cmd_buffer);
continue;
}
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
rc = ERR_MEMORY;
} else if (pid == 0) {
execvp(cmd.argv[0], cmd.argv);
perror("execvp failed");
exit(EXIT_FAILURE);
} else {
int status;
wait(&status);
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Command failed with exit code %d\n", WEXITSTATUS(status));
send_message_string(cli_socket, error_msg);
}
}
}
free(cmd._cmd_buffer);
}
send_message_eof(cli_socket);
} }
// Clean up (this will never be reached due to the while(1) loop) return rc;
free(io_buff);
return WARN_RDSH_NOT_IMPL; // Default return value
} }
/* /*
* send_message_eof(cli_socket) * send_message_eof(cli_socket)
* cli_socket: The server-side socket that is connected to the client * cli_socket: The server-side socket that is connected to the client
...@@ -384,25 +420,16 @@ int exec_client_requests(int cli_socket) { ...@@ -384,25 +420,16 @@ int exec_client_requests(int cli_socket) {
* we were unable to send the EOF character. * we were unable to send the EOF character.
*/ */
int send_message_string(int cli_socket, char *buff) { int send_message_eof(int cli_socket) {
int bytes_sent; if (send(cli_socket, &RDSH_EOF_CHAR, 1, 0) < 0) {
// Send the message
bytes_sent = send(cli_socket, buff, strlen(buff), 0);
if (bytes_sent < 0) {
perror("send"); perror("send");
return ERR_RDSH_COMMUNICATION; return ERR_RDSH_COMMUNICATION;
} }
// Send the EOF character
if (send_message_eof(cli_socket) != OK) {
return ERR_RDSH_COMMUNICATION;
}
return OK; return OK;
} }
/* /*
* send_message_string(cli_socket, char *buff) * send_message_string(cli_socket, char *buff)
* cli_socket: The server-side socket that is connected to the client * cli_socket: The server-side socket that is connected to the client
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment