diff options
author | dzwdz | 2021-09-18 12:15:58 +0200 |
---|---|---|
committer | dzwdz | 2021-09-18 12:15:58 +0200 |
commit | 27cf4b1923629cbf71609311d004914c2508c03a (patch) | |
tree | 10fe57348e148158b5baa93333c946e4b9dbb0b3 /src/init | |
parent | 9741233ac39a1510de5bf3177c5172b4dd315222 (diff) |
`init`: implement a working tar driver
Diffstat (limited to 'src/init')
-rw-r--r-- | src/init/main.c | 75 | ||||
-rw-r--r-- | src/init/tar.c | 61 | ||||
-rw-r--r-- | src/init/tar.h | 3 |
3 files changed, 88 insertions, 51 deletions
diff --git a/src/init/main.c b/src/init/main.c index aef6410..c81f789 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -12,8 +12,8 @@ extern char _initrd; int tty_fd; +void read_file(const char *path, size_t len); void fs_test(void); -void fs_server(handle_t back); __attribute__((section(".text.startup"))) int main(void) { @@ -25,66 +25,43 @@ int main(void) { _syscall_exit(argify("couldn't open tty")); fs_test(); - tar_driver(&_initrd); _syscall_exit(argify("my job here is done.")); } -void fs_test(void) { - handle_t front, back, file; - front = _syscall_fs_create(&back); +void read_file(const char *path, size_t len) { + int fd = _syscall_open(path, len); + static char buf[64]; + int buf_len = 64; - if (_syscall_fork()) { - // child: is the fs server - fs_server(back); + _syscall_write(tty_fd, path, len); + log(": "); + if (fd < 0) { + log("couldn't open.\n"); return; } - // parent: accesses the fs - _syscall_mount(front, argify("/mnt")); - log("requesting file. "); - file = _syscall_open(argify("/mnt/tty")); - log("open returned. "); - _syscall_write(file, argify("hello")); + buf_len = _syscall_read(fd, buf, buf_len); + _syscall_write(tty_fd, buf, buf_len); - // try reading - char buf[8]; - int len = 8; - for (int i = 0; i < 8; i++) - buf[i] = '.'; - len = _syscall_read(file, buf, len); - _syscall_write(tty_fd, buf, len + 1); // read 1 byte past, should be a dot + _syscall_close(fd); } -void fs_server(handle_t back) { - static char buf[64]; - int len, id; - for (;;) { - len = 64; - switch (_syscall_fs_wait(back, buf, &len, &id)) { - case VFSOP_OPEN: - _syscall_write(tty_fd, buf, len); - log(" was opened. "); - _syscall_fs_respond(NULL, 32); // doesn't check the path yet - break; - - case VFSOP_READ: - // all reads output "world" - _syscall_fs_respond("world", 5); - break; - - case VFSOP_WRITE: - // uppercase the buffer - for (int i = 0; i < len; i++) buf[i] &= ~id; // id == 32 - // and passthrough to tty - _syscall_write(tty_fd, buf, len); - _syscall_fs_respond(NULL, len); // return the amt of bytes written - break; +void fs_test(void) { + handle_t front, back, file; + front = _syscall_fs_create(&back); - default: - log("fuck"); - break; - } + if (_syscall_fork()) { + // child: is the fs server + tar_driver(back, &_initrd); + return; } + // parent: accesses the fs + log("\n"); + _syscall_mount(front, argify("/init")); + read_file(argify("/init/fake.txt")); + read_file(argify("/init/1.txt")); + read_file(argify("/init/2.txt")); + read_file(argify("/init/dir/3.txt")); } diff --git a/src/init/tar.c b/src/init/tar.c index a2b03df..d25b8a5 100644 --- a/src/init/tar.c +++ b/src/init/tar.c @@ -1,12 +1,38 @@ #include <init/stdlib.h> +#include <shared/flags.h> #include <shared/syscalls.h> #include <stdint.h> extern int tty_fd; +// TODO struct tar +static int tar_open(const char *path, int len, void *base, size_t base_len); +static int tar_size(void *sector); +static void *tar_find(const char *path, size_t path_len, void *base, size_t base_len); static int oct_parse(char *str, size_t len); -void tar_driver(void *base) { +void tar_driver(handle_t back, void *base) { + static char buf[64]; + int len; + void *id; // IDs usually are integers, but here i'm using them as pointers + // to the metadata sectors + for (;;) { + len = 64; + switch (_syscall_fs_wait(back, buf, &len, (int*)&id)) { + case VFSOP_OPEN: + _syscall_fs_respond(NULL, tar_open(buf, len, base, ~0)); + break; + + case VFSOP_READ: + _syscall_fs_respond(id + 512, tar_size(id)); + break; + + default: + _syscall_fs_respond(NULL, -1); // unsupported + break; + } + } + // iterate over all sectors, printing filenames while (0 == memcmp(base + 257, "ustar", 5)) { int size = oct_parse(base + 124, 12); @@ -21,6 +47,39 @@ void tar_driver(void *base) { _syscall_write(tty_fd, "done.", 5); } +static int tar_open(const char *path, int len, void *base, size_t base_len) { + void *ptr; + + if (len <= 1) return -1; + path += 1; // skip the leading slash + len -= 1; + + ptr = tar_find(path, len, base, ~0); + if (!ptr) return -1; + return (int)ptr; +} + +static int tar_size(void *sector) { + return oct_parse(sector + 124, 12); +} + +static void *tar_find(const char *path, size_t path_len, void *base, size_t base_len) { + int size; + if (path_len > 100) return NULL; // illegal path + + for (size_t off = 0; off < base_len;) { + if (0 != memcmp(base + off + 257, "ustar", 5)) + break; // not a metadata sector + if (0 == memcmp(base + off, path, path_len)) + return base + off; // file found, quit + + size = tar_size(base + off); + off += 512; // skip this metadata sector + off += (size + 511) & ~511; // skip the data sectors + } + return NULL; +} + static int oct_parse(char *str, size_t len) { int res = 0; for (size_t i = 0; i < len; i++) { diff --git a/src/init/tar.h b/src/init/tar.h index 77141b4..71c30fe 100644 --- a/src/init/tar.h +++ b/src/init/tar.h @@ -1,3 +1,4 @@ #pragma once +#include <shared/types.h> -void tar_driver(void *base); +_Noreturn void tar_driver(handle_t back, void *base); |