From 2821f125c91c192cdd28997e78f366f2db2d39c4 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 6 Jun 2020 17:19:55 +0200 Subject: stuff works --- 03_exercise/.srv_pid | 2 +- 03_exercise/CMakeLists.txt | 19 ++++++ 03_exercise/cli/client | Bin 27408 -> 28384 bytes 03_exercise/cli/client.c | 154 ++++++++++++++++++++++++++------------------- 03_exercise/srv/server | Bin 60872 -> 0 bytes 03_exercise/srv/server.c | 6 +- 03_exercise/srv/shell.c | 19 +++--- CMakeLists.txt | 1 + 8 files changed, 121 insertions(+), 80 deletions(-) create mode 100644 03_exercise/CMakeLists.txt delete mode 100755 03_exercise/srv/server diff --git a/03_exercise/.srv_pid b/03_exercise/.srv_pid index f376adb..ab09251 100644 --- a/03_exercise/.srv_pid +++ b/03_exercise/.srv_pid @@ -1 +1 @@ -892256 +1493889 diff --git a/03_exercise/CMakeLists.txt b/03_exercise/CMakeLists.txt new file mode 100644 index 0000000..a03d39b --- /dev/null +++ b/03_exercise/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) + +project(remote_shell C) + +set(CMAKE_C_COMPILER gcc) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED True) +add_compile_definitions(_GNU_SOURCE) + +find_package(Sanitizers) + +add_executable(client cli/client.c) +add_executable(server srv/prompt_utils.c srv/array.c srv/shell.c srv/process.c srv/server.c srv/builtins.c) + +target_compile_options(client INTERFACE ${PROJECT_WARNINGS}) +target_compile_options(server INTERFACE ${PROJECT_WARNINGS}) + +add_sanitizers(client) +add_sanitizers(server) diff --git a/03_exercise/cli/client b/03_exercise/cli/client index 8da5d5a..0fcf5c1 100755 Binary files a/03_exercise/cli/client and b/03_exercise/cli/client differ diff --git a/03_exercise/cli/client.c b/03_exercise/cli/client.c index d64dd62..c1bc5d1 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -8,20 +8,21 @@ #include #include #include +#include #define PORT 9000 #define HOST "127.0.0.1" #define BUF_SIZE 2048 -int cfd; +int sock; /* Signal Handler for SIGINT */ void sigintHandler(int sig_num) { errno = 0; - if (fcntl(cfd, F_GETFD) != -1 || errno != EBADF) { - write(cfd, "exit\n", 6); - close(cfd); + if (fcntl(sock, F_GETFD) != -1 || errno != EBADF) { + write(sock, "exit\n", 6); + close(sock); } printf("Terminating client\n"); fflush(stdout); @@ -81,86 +82,109 @@ void send_file(int server_fd, char *path) { close(file_fd); } +#define BREAK 1 +#define CONTINUE 2 + +int parse(int server_sock, char *buffer, ssize_t length) { + char cmd[4]; + char path[BUF_SIZE - 3]; + memcpy(cmd, buffer, 3); + cmd[3] = 0; + memcpy(path, buffer + 4, BUF_SIZE - 4); + path[strlen(path) - 1] = 0; + if (strcmp(cmd, "put") == 0) { + if (strlen(path) == 0) { + fprintf(stderr, "path missing\n"); + } else { + printf("got put with %s\n", path); + send_file(sock, path); + } + return CONTINUE; + } + + buffer[length] = '\0'; + + if (strspn(buffer, " \n\t") == strlen(buffer)) { + // skip empty lines - empty being just spaces or tabs + return CONTINUE; + } + + if (write(server_sock, buffer, strlen(buffer)) < 0) + die("Could not send message"); + + if (strcmp(buffer, "exit\n") == 0) { + return BREAK; + } + + return 0; +} + +void read_stdin(int *done); + +void read_server_sock(int *done); + int main() { + setvbuf(stdout, NULL, _IONBF, 0); + struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(HOST) }; - char buf[BUF_SIZE]; - if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) die("Could not open socket"); - if (connect(cfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) die("Could not connect to socket"); - char *line = NULL; - size_t cap = 0; - __ssize_t length; + signal(SIGINT, &sigintHandler); - if (read(cfd, buf, BUF_SIZE) < 0) - die("Could not receive message"); + pid_t pid = fork(); - printf("%s\n", buf); - memset(buf, 0, BUF_SIZE); - - while (1) { - printf("$> "); - //printf("[C] awaiting command\n"); - if ((length = getline(&line, &cap, stdin)) < 0) { - fprintf(stderr, "Failed to read from STDIN"); - fflush(stderr); - exit(-1); - } + int done = 0; + if (pid == 0) { + read_stdin(&done); + } else { + read_server_sock(&done); + } - if (strspn(line, " \n\t") == strlen(line)) { - // skip empty lines - empty being just spaces or tabs - continue; - } + close(sock); + return 0; +} - char cmd[4]; - char path[BUF_SIZE - 3]; - memcpy(cmd, line, 3); - cmd[3] = 0; - memcpy(path, line + 4, BUF_SIZE - 4); - path[strlen(path) - 1] = 0; - printf("cmd: \"%s\"\n", cmd); - printf("path: \"%s\"\n", path); - if (strcmp(cmd, "put") == 0) { - if (strlen(path) == 0) { - fprintf(stderr, "path missing\n"); - } else { - printf("got put with %s\n", path); - send_file(cfd, path); +void read_server_sock(int *done) { + char server_buffer[BUF_SIZE]; + ssize_t length; + + while (!*done) { + if ((length = read(sock, server_buffer, BUF_SIZE)) > 0) { + server_buffer[length] = '\0'; + printf("%s", server_buffer); + if (server_buffer[length - 1] == '\n') { + printf("$> "); + fflush(stdout); } - free(line); - line = NULL; - continue; } + } +} - strncpy(buf, line, strlen(line) + 1); - - //printf("[C] pre send: \"%s\"\n", buf); - - if (write(cfd, buf, strlen(line)) < 0) - die("Could not send message"); - if (strcmp(line, "exit\n") == 0) { - free(line); - line = NULL; - break; +void read_stdin(int *done) { + char stdinp_buffer[BUF_SIZE]; + ssize_t length; + + while (!*done) { + if ((length = read(STDIN_FILENO, stdinp_buffer, BUF_SIZE)) > 0) { + switch (parse(sock, stdinp_buffer, length)) { + case CONTINUE: + continue; + case BREAK: + *done = 1; + break; + default: + break; + } } - - if (read(cfd, buf, BUF_SIZE) < 0) - die("Could not receive message"); - - printf("%s", buf); - memset(buf, 0, BUF_SIZE); - free(line); - line = NULL; } - - close(cfd); - return 0; } diff --git a/03_exercise/srv/server b/03_exercise/srv/server deleted file mode 100755 index 69edeea..0000000 Binary files a/03_exercise/srv/server and /dev/null differ diff --git a/03_exercise/srv/server.c b/03_exercise/srv/server.c index 5c23196..8527b83 100644 --- a/03_exercise/srv/server.c +++ b/03_exercise/srv/server.c @@ -50,7 +50,7 @@ int main() { int status = shell(cfd); /* - while ((bytes = read(cfd, in_buf, BUF_SIZE)) != 0) { + while ((bytes = read(sock, in_buf, BUF_SIZE)) != 0) { if (bytes < 0) die("Couldn't receive message"); @@ -68,14 +68,14 @@ int main() { memcpy(out_buf + sizeof("got: ") - 1, in_buf, BUF_SIZE - sizeof("got: ") + 1); } - if (write(cfd, out_buf, sizeof(out_buf)) < 0) + if (write(sock, out_buf, sizeof(out_buf)) < 0) die("Couldn't send message"); memset(in_buf, 0, BUF_SIZE); memset(out_buf, 0, BUF_SIZE); }*/ - printf("srv: closing down\n"); + //printf("srv: closing down\n"); close(cfd); close(sfd); diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 792a26c..449905b 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -58,8 +58,6 @@ void receive_file(int sock, char *path, int size) { } } -const char *const get_current_dir_name(); - void signal_handler(int signal) { if (signal == SIGINT) { for (size_t i = 0; i < arrayLen(processes); ++i) { @@ -75,14 +73,8 @@ int shell(int in_fd) { setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); - dup2(in_fd, 1); - dup2(in_fd, 2); - - // I don't think the shell should exit on SIG_TERM - if (signal(SIGINT, SIG_IGN) == SIG_ERR) { - perror("Couldn't ignore sigterm"); - exit(errno); - } + dup2(in_fd, STDOUT_FILENO); + dup2(in_fd, STDERR_FILENO); printf("Welcome! Available built-ins are:\n" "cd: `cd ` - if no path is given, return to the current dir\n" @@ -94,12 +86,14 @@ int shell(int in_fd) { ); char const *const original_wd = get_current_dir_name(); + //char const *prompt = relative_path(original_wd, original_wd); bool done = false; while (!done) { char line[BUF_SIZE]; __ssize_t length; + fflush(stdout); if ((length = read(in_fd, line, BUF_SIZE)) < 0) { fprintf(stderr, "Failed to read from STDIN"); fflush(stderr); @@ -112,6 +106,10 @@ int shell(int in_fd) { } line[length - 1] = '\0'; // cut the line feed + if (strlen(line) == 0) { + continue; + } + processes = NULL; parse_line(line, &processes); @@ -154,7 +152,6 @@ int shell(int in_fd) { /*if (ret) printf("[%i] ", ret);*/ } - signal(SIGINT, SIG_IGN); } free_processes(&processes); diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d0441e..5a4192a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) add_subdirectory(02_exercise) +add_subdirectory(03_exercise) set(CLANG_WARNINGS -Wall -- cgit v1.2.3-54-g00ecf