summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-06-08 10:52:06 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-06-08 10:52:06 +0200
commit0940e27cb8dc9829130e141c599efee780cc4d67 (patch)
tree42109be4a9bb4ae41b337655460e0c78cd30ffc1
parent6333c6510ae56b65a2f36bde55c8618a08260e10 (diff)
downloadbetriebssysteme-0940e27cb8dc9829130e141c599efee780cc4d67.tar.gz
betriebssysteme-0940e27cb8dc9829130e141c599efee780cc4d67.zip
stuff works, i think
-rwxr-xr-x03_exercise/cli/clientbin28464 -> 30912 bytes
-rw-r--r--03_exercise/cli/client.c284
-rw-r--r--03_exercise/srv/shell.c79
-rw-r--r--03_exercise/testbin5 -> 0 bytes
4 files changed, 257 insertions, 106 deletions
diff --git a/03_exercise/cli/client b/03_exercise/cli/client
index c593e95..ecaa0d8 100755
--- a/03_exercise/cli/client
+++ b/03_exercise/cli/client
Binary files 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 <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <stdbool.h>
#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) {
+ // "<<!bytecount!name"
+ char cmd[4];
+
+ memcpy(cmd, buffer, 3);
+ cmd[3] = 0;
+
+ if (strcmp(cmd, "<<!") == 0) {
+ printf("[c]: \"%s\"\n", buffer);
+ int offset = 3;
+ int i = offset;
+ char rest[BUF_SIZE - 3];
+ size_t file_size;
+ for (; i < BUF_SIZE; ++i) {
+ if (buffer[i] == '!')
+ break;
+ rest[i - offset] = buffer[i];
+ }
+ rest[i - offset] = 0;
+ file_size = atoi(rest);
+
+ offset = ++i;
+ for (; i < BUF_SIZE; ++i) {
+ if (buffer[i] == '!')
+ break;
+ rest[i - offset] = buffer[i];
+ }
+ rest[i - offset] = 0;
+ char path[strlen(rest) + 1];
+ memcpy(path, rest, strlen(rest));
+ path[strlen(rest)] = 0;
+ path[strlen(rest) - 1] = 0;
+
+ receive_file(server_sock, path, file_size);
+
+ return true;
+ }
+ return false;
+}
+
+void read_server_sock() {
+ char server_buffer[BUF_SIZE];
+
+ while (1) {
+ ssize_t length;
+ if ((length = read(server_sock, server_buffer, BUF_SIZE)) > 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, "<<!%ld!", sz);
- sprintf(&(buffer[3 + length + 1]), "%s\n", path);
+ sprintf(&(buffer[3 + length + 1]), "%s!\n", path);
+
+ printf("[c] \"%s\"\n", buffer);
- write(server_fd, buffer, strlen(buffer));
+ write(server_sock, buffer, strlen(buffer));
memset(buffer, 0, BUF_SIZE);
errno = 0;
while (read(file_fd, buffer, sizeof(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, "<<!%ld!", sz);
+ sprintf(&(buffer[3 + length + 1]), "%s\n", path);
+
+ write(client_fd, buffer, strlen(buffer));
+
+ usleep(150);
+
+ memset(buffer, 0, BUF_SIZE);
+
+ errno = 0;
+ while (read(file_fd, buffer, sizeof(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 <path>\n");
+ fprintf(stderr, "usage: cd <path>");
+ 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
--- a/03_exercise/test
+++ /dev/null
Binary files differ