From 0940e27cb8dc9829130e141c599efee780cc4d67 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 8 Jun 2020 10:52:06 +0200 Subject: stuff works, i think --- 03_exercise/cli/client | Bin 28464 -> 30912 bytes 03_exercise/cli/client.c | 284 +++++++++++++++++++++++++++++++---------------- 03_exercise/srv/shell.c | 79 +++++++++++-- 03_exercise/test | Bin 5 -> 0 bytes 4 files changed, 257 insertions(+), 106 deletions(-) delete mode 100644 03_exercise/test diff --git a/03_exercise/cli/client b/03_exercise/cli/client index c593e95..ecaa0d8 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 ea4eda9..f3a4479 100644 --- a/03_exercise/cli/client.c +++ b/03_exercise/cli/client.c @@ -9,40 +9,201 @@ #include #include #include +#include #define PORT 9000 #define HOST "127.0.0.1" #define BUF_SIZE 2048 -int sock; +#define BREAK 1 +#define CONTINUE 2 + +int server_sock; pid_t pid; /* Signal Handler for SIGINT */ +void sigintHandler(int sig_num); + +static inline void die(char const *msg); + +int write_all(int target_sock, char *buffer, size_t size); + +void send_file(char *path); + +int parse(char *buffer, ssize_t length); + +void read_stdin(); + +_Noreturn void read_server_sock(); + +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) + }; + + if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("Could not open socket"); + + if (connect(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) + die("Could not connect to socket"); + + signal(SIGINT, &sigintHandler); + + pid = fork(); + + if (pid != 0) { + read_stdin(); + } else { + read_server_sock(); + } + + close(server_sock); + return 0; +} + +void receive_file(int recv_sock, char *path, int size) { + char buffer[512]; + int file_fd; + int received; + + if ((file_fd = open(path, (O_WRONLY | O_CREAT | O_TRUNC), 0644)) == -1) { perror("Open"); } + + received = 0; + + /* Read all data */ + while (received < size) { + int nread; + if ((nread = read(recv_sock, buffer + received, size - received)) < 0) { + perror("Read"); + //pthread_exit(NULL); + exit(1); + } + + received += nread; + } + + if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { + printf("successfully got remote file \"%s\"\n", path); + } + + close(file_fd); +} + +bool check_get(char *buffer) { + // "< 0) { + server_buffer[length] = '\0'; + + // get issued, as it seems + if (check_get(server_buffer)) { + printf("$> "); + fflush(stdout); + continue; + } + + printf("%s", server_buffer); + if (length == 1 && server_buffer[length - 1] == '\n') { + printf("$> "); + fflush(stdout); + } + } + } +} + +void read_stdin() { + char stdin_buffer[BUF_SIZE]; + + bool done = false; + while (!done) { + ssize_t length; + memset(stdin_buffer, 0, BUF_SIZE); + if ((length = read(STDIN_FILENO, stdin_buffer, BUF_SIZE)) > 0) { + switch (parse(stdin_buffer, length)) { + case CONTINUE: + continue; + case BREAK: + done = true; + break; + default: + break; + } + } + } + kill(pid, SIGKILL); +} + void sigintHandler(int sig_num) { + (void) sig_num; errno = 0; - if (fcntl(sock, F_GETFD) != -1 || errno != EBADF) { - write(sock, "exit\n", 6); - close(sock); + if (fcntl(server_sock, F_GETFD) != -1 || errno != EBADF) { + write(server_sock, "exit\n", 6); + close(server_sock); } - printf("Terminating client\n"); - fflush(stdout); - kill(pid, SIGKILL); - exit(-1); + errno = 0; + die("Terminating client\n"); } -static inline void die(const char *msg) { +static inline void die(char const *msg) { perror(msg); + kill(pid, SIGKILL); exit(-1); } -int write_all(int sock, char *buffer, int size) { - int nwrite, sent = 0; +int write_all(int target_sock, char *buffer, size_t size) { + int sent = 0; while (sent < size) { - if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { - perror("Write"); - exit(1); + int nwrite; + if ((nwrite = write(target_sock, buffer + sent, size - sent)) < 0) { + die("Write"); } sent += nwrite; @@ -51,7 +212,7 @@ int write_all(int sock, char *buffer, int size) { return sent; } -void send_file(int server_fd, char *path) { +void send_file(char *path) { printf("Trying to send \"%s\" to remote...\n", path); char buffer[BUF_SIZE]; memset(buffer, 0, BUF_SIZE); @@ -72,16 +233,18 @@ void send_file(int server_fd, char *path) { return; } - int length = snprintf(NULL, 0, "%ld", sz); + int length = snprintf(NULL, 0, "%ld", sz); sprintf(buffer, "< 0) { - printf("Sent %i bytes\n", write_all(server_fd, buffer, strlen(buffer) + 1)); + printf("Sent %i bytes\n", write_all(server_sock, buffer, strlen(buffer) + 1)); } if (errno) @@ -92,10 +255,7 @@ void send_file(int server_fd, char *path) { printf("done.\n"); } -#define BREAK 1 -#define CONTINUE 2 - -int parse(int server_sock, char *buffer, ssize_t length) { +int parse(char *buffer, ssize_t length) { char cmd[4]; char path[BUF_SIZE - 3]; memcpy(cmd, buffer, 3); @@ -106,7 +266,7 @@ int parse(int server_sock, char *buffer, ssize_t length) { if (strlen(path) == 0) { fprintf(stderr, "path missing\n"); } else { - send_file(sock, path); + send_file(path); } return CONTINUE; } @@ -121,82 +281,10 @@ int parse(int server_sock, char *buffer, ssize_t length) { if (write(server_sock, buffer, strlen(buffer)) < 0) die("Could not send message"); + // TODO: exit should only close the connection (cleanly), NOT terminate the server 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) - }; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - die("Could not open socket"); - - if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) - die("Could not connect to socket"); - - signal(SIGINT, &sigintHandler); - - pid = fork(); - - int done = 0; - if (pid != 0) { - read_stdin(&done); - } else { - read_server_sock(&done); - } - - close(sock); - return 0; -} - -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); - } - } - } - kill(pid, SIGKILL); -} - - -void read_stdin(int *done) { - char stdinp_buffer[BUF_SIZE]; - ssize_t length; - - while (!*done) { - memset(stdinp_buffer, 0, BUF_SIZE); - 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; - } - } - } - kill(pid, SIGKILL); -} +} \ No newline at end of file diff --git a/03_exercise/srv/shell.c b/03_exercise/srv/shell.c index 5d7d33d..7a90945 100644 --- a/03_exercise/srv/shell.c +++ b/03_exercise/srv/shell.c @@ -18,13 +18,13 @@ char *get_current_dir_name(void); process *processes; -int write_all(int sock, char *buffer, int size) { +int write_all(int target_sock, char *buffer, size_t size) { int nwrite, sent = 0; while (sent < size) { - if ((nwrite = write(sock, buffer + sent, size - sent)) < 0) { + if ((nwrite = write(target_sock, buffer + sent, size - sent)) < 0) { perror("Write"); - exit(1); + return -1; } sent += nwrite; @@ -54,11 +54,60 @@ void receive_file(int sock, char *path, int size) { } if (write_all(file_fd, buffer, strlen(buffer) + 1) == strlen(buffer) + 1) { - printf("successfully wrote to remote file \"%s/%s\"\n", get_current_dir_name(), path); + printf("successfully wrote to remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); + } else { + printf("error writing remote file \"%s/%s\"", get_current_dir_name(), path); + printf("\n"); } + close(file_fd); } +void send_file(int client_fd, char *path) { + printf("Trying to get \"%s\" from remote...\n", path); + char buffer[BUF_SIZE]; + memset(buffer, 0, BUF_SIZE); + int tmp_fd, file_fd; + + if ((tmp_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } + FILE *file = fdopen(tmp_fd, "r"); + fseek(file, 0L, SEEK_END); + long int sz = ftell(file); + fseek(file, 0L, SEEK_SET); + fclose(file); + close(tmp_fd); + if ((file_fd = open(path, O_RDONLY)) == -1) { + perror("Open"); + return; + } + + int length = snprintf(NULL, 0, "%ld", sz); + sprintf(buffer, "< 0) { + /*printf("Sent %i bytes\n", */write_all(client_fd, buffer, strlen(buffer) + 1)/*)*/; + } + + if (errno) + perror("wad"); + + close(file_fd); + + //printf("done.\n"); +} + void signal_handler(int signal) { if (signal == SIGINT) { for (size_t i = 0; i < arrayLen(processes); ++i) { @@ -121,8 +170,9 @@ int shell(int in_fd) { "fg: `fg pid` - pulls a process from the background back in the foreground\n" "\n" "You can put processes in the background using `&`\n" - "And with `|` you can pipe the output from one process to the input of another\n" + "And with `|` you can pipe the output from one process to the input of another" ); + printf("\n$> "); char const *const original_wd = get_current_dir_name(); //char const *prompt = relative_path(original_wd, original_wd); @@ -158,6 +208,7 @@ int shell(int in_fd) { if (strcmp(processes[0].argv[0], "cd") == 0) { if (arrayLen(processes) != 1) { perror("Can't chain cd with other processes"); + printf("\n"); } int ret; switch (arrayLen(processes[0].argv)) { @@ -168,18 +219,28 @@ int shell(int in_fd) { ret = chdir(original_wd); break; default: - fprintf(stderr, "usage: cd \n"); + fprintf(stderr, "usage: cd "); + fprintf(stderr, "\n"); fflush(stderr); ret = -1; } if (ret) printf("[%i] ", ret); - else - printf("%s\n", get_current_dir_name()); + else { + printf("%s", get_current_dir_name()); + printf("\n"); + } } else if (strcmp(processes[0].argv[0], "exit") == 0) { done = true; + } else if (strcmp(processes[0].argv[0], "get") == 0) { + if (arrayLen(processes[0].argv) != 3) { + printf("please provide a file name to get!"); + printf("\n"); + } else { + send_file(in_fd, processes[0].argv[1]); + } } else if (strcmp(processes[0].argv[0], "wait") == 0) { builtin_wait(processes[0], false); } else if (strcmp(processes[0].argv[0], "fg") == 0) { @@ -194,12 +255,14 @@ int shell(int in_fd) { /*if (ret) printf("[%i] ", ret);*/ } + printf("\n"); } free_processes(&processes); } printf("Disconnecting..."); + printf("\n"); free((void *) original_wd); diff --git a/03_exercise/test b/03_exercise/test deleted file mode 100644 index b4098bc..0000000 Binary files a/03_exercise/test and /dev/null differ -- cgit v1.2.3-54-g00ecf