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

Elimated optional functions

parent 124bd733
No related branches found
No related tags found
No related merge requests found
......@@ -90,13 +90,13 @@
* function after cleaning things up. See the documentation for client_cleanup()
*
*/
int exec_remote_cmd_loop(char *address, int port)
{
char cmd_buff[RDSH_COMM_BUFF_SZ]; // Use the buffer size from rshlib.h
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 is_eof = 0; // Declare and initialize
// Connect to the server
cli_socket = start_client(address, port);
......@@ -108,19 +108,50 @@ int exec_remote_cmd_loop(char *address, int port)
while (1) {
printf("rsh> ");
if (!fgets(cmd_buff, RDSH_COMM_BUFF_SZ, stdin)) {
break;
break; // Exit on input error or EOF
}
// 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';
}
// 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);
continue;
}
if (cmd.argc == 1) {
chdir(getenv("HOME"));
} else if (cmd.argc == 2) {
if (chdir(cmd.argv[1]) != 0) {
perror("cd");
}
} else {
fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
}
free(cmd._cmd_buffer);
continue;
} else if (strncmp(cmd_buff, "exit", 4) == 0) {
break; // Exit the remote shell
}
if (send(cli_socket, cmd_buff, strlen(cmd_buff), 0) < 0) {
// 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);
}
is_eof = 0;
// Receive the server's response
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
printf("%.*s", (int)recv_bytes, rsp_buff);
if (rsp_buff[recv_bytes - 1] == RDSH_EOF_CHAR) {
is_eof = 1; // Check for EOF character
is_eof = 1; // Mark EOF
break;
}
}
......@@ -128,15 +159,14 @@ int exec_remote_cmd_loop(char *address, int port)
if (recv_bytes < 0) {
perror("recv");
return client_cleanup(cli_socket, NULL, NULL, ERR_RDSH_COMMUNICATION);
}
if (strncmp(cmd_buff, "exit", 4) == 0 || strncmp(cmd_buff, "stop-server", 11) == 0) {
} else if (recv_bytes == 0) {
printf("Server closed the connection\n");
break;
}
}
return client_cleanup(cli_socket, cmd_buff, rsp_buff, OK);
(void)is_eof; // Suppress unused variable warning
return client_cleanup(cli_socket, NULL, NULL, OK);
}
/*
......
......@@ -591,107 +591,3 @@ int rsh_execute_pipeline(int cli_sock, command_list_t *clist) {
return exit_code;
}
/************** OPTIONAL STUFF ***************/
/****
**** NOTE THAT THE FUNCTIONS BELOW ALIGN TO HOW WE CRAFTED THE SOLUTION
**** TO SEE IF A COMMAND WAS BUILT IN OR NOT. YOU CAN USE A DIFFERENT
**** STRATEGY IF YOU WANT. IF YOU CHOOSE TO DO SO PLEASE REMOVE THESE
**** FUNCTIONS AND THE PROTOTYPES FROM rshlib.h
****
*/
/*
* rsh_match_command(const char *input)
* cli_socket: The string command for a built-in command, e.g., dragon,
* cd, exit-server
*
* This optional function accepts a command string as input and returns
* one of the enumerated values from the BuiltInCmds enum as output. For
* example:
*
* Input Output
* exit BI_CMD_EXIT
* dragon BI_CMD_DRAGON
*
* This function is entirely optional to implement if you want to handle
* processing built-in commands differently in your implementation.
*
* Returns:
*
* BI_CMD_*: If the command is built-in returns one of the enumeration
* options, for example "cd" returns BI_CMD_CD
*
* BI_NOT_BI: If the command is not "built-in" the BI_NOT_BI value is
* returned.
*/
Built_In_Cmds rsh_match_command(const char *input)
{
if (strcmp(input, "exit") == 0)
return BI_CMD_EXIT;
if (strcmp(input, "dragon") == 0)
return BI_CMD_DRAGON;
if (strcmp(input, "cd") == 0)
return BI_CMD_CD;
if (strcmp(input, "stop-server") == 0)
return BI_CMD_STOP_SVR;
if (strcmp(input, "rc") == 0)
return BI_CMD_RC;
return BI_NOT_BI;
}
/*
* rsh_built_in_cmd(cmd_buff_t *cmd)
* cmd: The cmd_buff_t of the command, remember, this is the
* parsed version fo the command
*
* This optional function accepts a parsed cmd and then checks to see if
* the cmd is built in or not. It calls rsh_match_command to see if the
* cmd is built in or not. Note that rsh_match_command returns BI_NOT_BI
* if the command is not built in. If the command is built in this function
* uses a switch statement to handle execution if appropriate.
*
* Again, using this function is entirely optional if you are using a different
* strategy to handle built-in commands.
*
* Returns:
*
* BI_NOT_BI: Indicates that the cmd provided as input is not built
* in so it should be sent to your fork/exec logic
* BI_EXECUTED: Indicates that this function handled the direct execution
* of the command and there is nothing else to do, consider
* it executed. For example the cmd of "cd" gets the value of
* BI_CMD_CD from rsh_match_command(). It then makes the libc
* call to chdir(cmd->argv[1]); and finally returns BI_EXECUTED
* BI_CMD_* Indicates that a built-in command was matched and the caller
* is responsible for executing it. For example if this function
* returns BI_CMD_STOP_SVR the caller of this function is
* responsible for stopping the server. If BI_CMD_EXIT is returned
* the caller is responsible for closing the client connection.
*
* AGAIN - THIS IS TOTALLY OPTIONAL IF YOU HAVE OR WANT TO HANDLE BUILT-IN
* COMMANDS DIFFERENTLY.
*/
Built_In_Cmds rsh_built_in_cmd(cmd_buff_t *cmd)
{
Built_In_Cmds ctype = BI_NOT_BI;
ctype = rsh_match_command(cmd->argv[0]);
switch (ctype)
{
// case BI_CMD_DRAGON:
// print_dragon();
// return BI_EXECUTED;
case BI_CMD_EXIT:
return BI_CMD_EXIT;
case BI_CMD_STOP_SVR:
return BI_CMD_STOP_SVR;
case BI_CMD_RC:
return BI_CMD_RC;
case BI_CMD_CD:
chdir(cmd->argv[1]);
return BI_EXECUTED;
default:
return BI_NOT_BI;
}
}
......@@ -54,6 +54,7 @@ static const char RDSH_EOF_CHAR = 0x04;
int start_client(char *address, int port);
int client_cleanup(int cli_socket, char *cmd_buff, char *rsp_buff, int rc);
int exec_remote_cmd_loop(char *address, int port);
int parse_pipeline(const char *cmd_line, command_list_t *clist);
//server prototypes for rsh_server.c - see documentation for each function to
......@@ -70,9 +71,5 @@ int rsh_execute_pipeline(int socket_fd, command_list_t *clist);
Built_In_Cmds rsh_match_command(const char *input);
Built_In_Cmds rsh_built_in_cmd(cmd_buff_t *cmd);
//eliminate from template, for extra credit
void set_threaded_server(int val);
int exec_client_thread(int main_socket, int cli_socket);
void *handle_client(void *arg);
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment