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
No related branches found
No related tags found
No related merge requests found
......@@ -263,58 +263,40 @@ static void start_server() {
* 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;
int exec_local_cmd_loop() {
char cmd_buff[SH_CMD_MAX];
int rc = OK;
while (1) {
printf("%s", SH_PROMPT);
if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) {
printf("\n");
break;
// Connect to the server
cli_socket = start_client(address, port);
if (cli_socket < 0) {
perror("start client");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_CLIENT);
}
cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
if (strlen(cmd_buff) == 0) {
printf("%s\n", CMD_WARN_NO_CMD);
rc = WARN_NO_CMDS;
continue;
while (1) {
printf("rsh> ");
if (!fgets(cmd_buff, RDSH_COMM_BUFF_SZ, stdin)) {
break; // Exit on input error or EOF
}
if (strstr(cmd_buff, "|") != NULL) {
command_list_t cmd_list;
if (parse_pipeline(cmd_buff, &cmd_list) != OK) {
fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
rc = ERR_TOO_MANY_COMMANDS;
continue;
// Remove the newline character from the command
size_t cmd_len = strlen(cmd_buff);
if (cmd_len > 0 && cmd_buff[cmd_len - 1] == '\n') {
cmd_buff[cmd_len - 1] = '\0';
}
// Execute the pipeline
execute_pipeline(&cmd_list);
// Free memory for each command's buffer
for (int i = 0; i < cmd_list.num; i++) {
free(cmd_list.commands[i]._cmd_buffer);
}
} else {
// Handle local commands (e.g., cd, exit)
if (strncmp(cmd_buff, "cd", 2) == 0) {
// Handle cd locally
cmd_buff_t cmd;
if (build_cmd_buff(cmd_buff, &cmd) != OK) {
fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
rc = ERR_MEMORY;
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) {
chdir(getenv("HOME"));
} else if (cmd.argc == 2) {
......@@ -326,31 +308,35 @@ int exec_local_cmd_loop() {
}
free(cmd._cmd_buffer);
continue;
} else if (strncmp(cmd_buff, "exit", 4) == 0) {
break; // Exit the remote shell
}
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) {
fprintf(stderr, "Command failed with exit code %d\n", WEXITSTATUS(status));
// Send the command to the server
ssize_t sent_bytes = send(cli_socket, cmd_buff, strlen(cmd_buff), 0);
if (sent_bytes < 0) {
perror("send");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
}
// 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 @@
*/
int exec_remote_cmd_loop(char *address, int port)
{
char *cmd_buff;
char *rsp_buff;
char cmd_buff[RDSH_COMM_BUFF_SZ]; // Use the buffer size from rshlib.h
char rsp_buff[RDSH_COMM_BUFF_SZ];
int cli_socket;
ssize_t io_size;
ssize_t recv_bytes;
int is_eof;
// TODO set up cmd and response buffs
// Connect to the server
cli_socket = start_client(address, port);
if (cli_socket < 0) {
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)
{
// TODO print prompt
while (1) {
printf("rsh> ");
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);
}
......@@ -151,6 +168,29 @@ int start_client(char *server_ip, int port){
int ret;
// 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;
......
......@@ -302,73 +302,109 @@ int boot_server(char *ifaces, int port){
*/
int exec_client_requests(int cli_socket) {
char *io_buff;
int io_size;
command_list_t cmd_list;
char cmd_buff[RDSH_COMM_BUFF_SZ];
ssize_t recv_bytes;
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) {
// Receive input from the client
io_size = recv(cli_socket, io_buff, RDSH_COMM_BUFF_SZ, 0);
if (io_size < 0) {
perror("recv");
free(io_buff);
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
recv_bytes = recv(cli_socket, cmd_buff, RDSH_COMM_BUFF_SZ, 0);
if (recv_bytes <= 0) {
close(cli_socket);
printf("Client disconnected\n");
return OK;
}
// Null-terminate the received data
io_buff[io_size] = '\0';
cmd_buff[recv_bytes] = '\0';
// Check for special commands
if (strncmp(io_buff, "exit", strlen("exit")) == 0) {
// Client sent the `exit` command
free(io_buff);
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);
cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
if (strlen(cmd_buff) == 0) {
send_message_string(cli_socket, CMD_WARN_NO_CMD);
send_message_eof(cli_socket);
continue; // Continue to the next iteration
rc = WARN_NO_CMDS;
continue;
}
// Execute the command pipeline
rc = rsh_execute_pipeline(cli_socket, &cmd_list);
if (rc < 0) {
// Handle execution error
send_message_string(cli_socket, CMD_ERR_RDSH_EXEC);
if (strstr(cmd_buff, "|") != NULL) {
command_list_t cmd_list;
if (parse_pipeline(cmd_buff, &cmd_list) != OK) {
send_message_string(cli_socket, CMD_ERR_PIPE_LIMIT);
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++) {
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)
free(io_buff);
return WARN_RDSH_NOT_IMPL; // Default return value
return rc;
}
/*
* send_message_eof(cli_socket)
* cli_socket: The server-side socket that is connected to the client
......@@ -384,25 +420,16 @@ int exec_client_requests(int cli_socket) {
* we were unable to send the EOF character.
*/
int send_message_string(int cli_socket, char *buff) {
int bytes_sent;
// Send the message
bytes_sent = send(cli_socket, buff, strlen(buff), 0);
if (bytes_sent < 0) {
int send_message_eof(int cli_socket) {
if (send(cli_socket, &RDSH_EOF_CHAR, 1, 0) < 0) {
perror("send");
return ERR_RDSH_COMMUNICATION;
}
// Send the EOF character
if (send_message_eof(cli_socket) != OK) {
return ERR_RDSH_COMMUNICATION;
}
return OK;
}
/*
* send_message_string(cli_socket, char *buff)
* 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