summaryrefslogtreecommitdiff
path: root/src/user/fs
diff options
context:
space:
mode:
authordzwdz2022-07-24 15:07:57 +0200
committerdzwdz2022-07-24 15:07:57 +0200
commit9f3fdb830f61cd8c8c1f1db9d03cba1c546c1a7e (patch)
treef5ec030c736f5201332c51cb99169b288185b84b /src/user/fs
parent0228be3fd404cdebecf6d21b8964f6063f12dfbe (diff)
user: change the directory structure to prepare for multiple binaries
Diffstat (limited to 'src/user/fs')
-rw-r--r--src/user/fs/misc.c163
-rw-r--r--src/user/fs/misc.h16
-rw-r--r--src/user/fs/tar.c158
-rw-r--r--src/user/fs/tar.h4
4 files changed, 0 insertions, 341 deletions
diff --git a/src/user/fs/misc.c b/src/user/fs/misc.c
deleted file mode 100644
index fa1115d..0000000
--- a/src/user/fs/misc.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <user/fs/misc.h>
-#include <user/lib/stdlib.h>
-#include <shared/flags.h>
-#include <shared/mem.h>
-#include <shared/syscalls.h>
-#include <stdbool.h>
-
-bool fork2_n_mount(const char *path) {
- handle_t h;
- if (_syscall_fork(FORK_NEWFS, &h) > 0) { /* parent */
- _syscall_mount(h, path, strlen(path));
- close(h);
- return true;
- }
- return false;
-}
-
-void fs_passthru(const char *prefix) {
- struct fs_wait_response res;
- const size_t buf_len = 1024;
- char *buf = malloc(buf_len);
- int prefix_len = prefix ? strlen(prefix) : 0;
- if (!buf) _syscall_exit(1);
-
- while (!_syscall_fs_wait(buf, buf_len, &res)) {
- switch (res.op) {
- case VFSOP_OPEN:
- if (prefix) {
- if (prefix_len + res.len > buf_len) {
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
-
- // TODO memmove
- char tmp[64];
- memcpy(tmp, buf, res.len);
- memcpy(buf + prefix_len, tmp, res.len);
- memcpy(buf, prefix, prefix_len);
- res.len += prefix_len;
- }
- _syscall_fs_respond(NULL, _syscall_open(buf, res.len, res.flags), FSR_DELEGATE);
- break;
-
- default:
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
- }
- _syscall_exit(0);
-}
-
-void fs_whitelist(const char **list) {
- struct fs_wait_response res;
- const size_t buf_len = 1024;
- char *buf = malloc(buf_len);
- bool allow;
- if (!buf) _syscall_exit(1);
-
- while (!_syscall_fs_wait(buf, buf_len, &res)) {
- switch (res.op) {
- case VFSOP_OPEN:
- allow = false;
- // TODO reverse dir_inject
- for (const char **iter = list; *iter; iter++) {
- size_t len = strlen(*iter); // inefficient, whatever
- if (len <= res.len && !memcmp(buf, *iter, len)) {
- allow = true;
- break;
- }
- }
- _syscall_fs_respond(NULL, allow ? _syscall_open(buf, res.len, res.flags) : -1, FSR_DELEGATE);
- break;
-
- default:
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
- }
- _syscall_exit(0);
-}
-
-
-void fs_dir_inject(const char *path) {
- struct fs_dir_handle {
- const char *inject;
- int delegate, inject_len;
- };
-
- const size_t path_len = strlen(path);
- struct fs_wait_response res;
- struct fs_dir_handle *data;
- const size_t buf_len = 1024;
- char *buf = malloc(buf_len);
- int ret, inject_len;
-
- if (!buf) _syscall_exit(1);
-
- while (!_syscall_fs_wait(buf, buf_len, &res)) {
- data = res.id;
- switch (res.op) {
- case VFSOP_OPEN:
- if (buf[res.len - 1] == '/' &&
- res.len < path_len && !memcmp(path, buf, res.len))
- {
- /* opening a directory that we're injecting into */
-
- data = malloc(sizeof *data);
- data->delegate = _syscall_open(buf, res.len, res.flags);
- data->inject = path + res.len;
-
- /* inject up to the next slash */
- inject_len = 0;
- while (data->inject[inject_len] && data->inject[inject_len] != '/')
- inject_len++;
- if (data->inject[inject_len] == '/')
- inject_len++;
- data->inject_len = inject_len;
-
- _syscall_fs_respond(data, 0, 0);
- } else {
- _syscall_fs_respond(NULL, _syscall_open(buf, res.len, res.flags), FSR_DELEGATE);
- }
- break;
-
- case VFSOP_CLOSE:
- if (data->delegate >= 0)
- close(data->delegate);
- _syscall_fs_respond(NULL, 0, 0);
- break;
-
- case VFSOP_READ:
- if (res.offset > 0) _syscall_fs_respond(NULL, 0, 0); // TODO working offsets
-
- int out_len = data->inject_len;
- memcpy(buf, data->inject, out_len);
- buf[out_len++] = '\0';
-
- if (data->delegate >= 0) {
- int to_read = res.capacity < buf_len ? res.capacity : buf_len;
- to_read -= out_len;
- ret = _syscall_read(data->delegate, buf + out_len, to_read, 0);
- if (ret > 0) out_len += ret;
- // TODO deduplicate entries
- }
-
- _syscall_fs_respond(buf, out_len, 0);
- break;
-
- case VFSOP_WRITE:
- if (data->delegate >= 0)
- ret = _syscall_write(data->delegate, buf, res.len, res.offset);
- else
- ret = -1;
- _syscall_fs_respond(NULL, ret, 0);
- break;
-
- default:
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
- }
- _syscall_exit(0);
-}
diff --git a/src/user/fs/misc.h b/src/user/fs/misc.h
deleted file mode 100644
index 3a8b071..0000000
--- a/src/user/fs/misc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-#include <user/lib/stdlib.h>
-#include <stdbool.h>
-
-bool fork2_n_mount(const char *path);
-
-void fs_passthru(const char *prefix);
-void fs_whitelist(const char **list);
-
-void fs_dir_inject(const char *path);
-
-/** Mounts something and injects its path into the fs */
-// TODO path needs to have a trailing slash
-#define MOUNT(path, impl) \
- if (!fork2_n_mount(path)) {_klogf("impl %s", path); impl;} \
- if (!fork2_n_mount("/")) {_klogf("dir for %s", path); fs_dir_inject(path);}
diff --git a/src/user/fs/tar.c b/src/user/fs/tar.c
deleted file mode 100644
index 60deccd..0000000
--- a/src/user/fs/tar.c
+++ /dev/null
@@ -1,158 +0,0 @@
-#include <user/lib/stdlib.h>
-#include <shared/flags.h>
-#include <shared/syscalls.h>
-#include <stdint.h>
-
-#define BUF_SIZE 64
-
-static void *tar_open(const char *path, int len, void *base, size_t base_len);
-static void tar_read(struct fs_wait_response *res, 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);
-
-
-static const char *root_fakemeta = ""; /* see comment in tar_open */
-
-
-void tar_driver(void *base) {
- static char buf[BUF_SIZE];
- struct fs_wait_response res;
- void *ptr;
- while (!_syscall_fs_wait(buf, BUF_SIZE, &res)) {
- switch (res.op) {
- case VFSOP_OPEN:
- ptr = tar_open(buf, res.len, base, ~0);
- _syscall_fs_respond(ptr, ptr ? 0 : -1, 0);
- break;
-
- case VFSOP_READ:
- tar_read(&res, base, ~0);
- break;
-
- default:
- _syscall_fs_respond(NULL, -1, 0); // unsupported
- break;
- }
- }
- _syscall_exit(0);
-}
-
-static void *tar_open(const char *path, int len, void *base, size_t base_len) {
- if (len <= 0) return NULL;
- path += 1; // skip the leading slash
- len -= 1;
-
- /* TAR archives don't (seem to) contain an entry for the root dir, so i'm
- * returning a fake one. this isn't a full entry because i'm currently too
- * lazy to create a full one - thus, it has to be special cased in tar_read */
- if (len == 0)
- return (void*)root_fakemeta;
-
- return tar_find(path, len, base, base_len);
-}
-
-static void tar_read(struct fs_wait_response *res, void *base, size_t base_len) {
- void *meta = (void*)res->id;
- char type = *(char*)(meta + 156);
- size_t meta_len;
- int size;
-
- static char buf[BUF_SIZE]; // TODO reuse a single buffer
- size_t buf_pos = 0;
-
- if (meta == root_fakemeta) type = '5'; /* see comment in tar_open() */
-
- switch (type) {
- case '\0':
- case '0': /* normal files */
- size = tar_size(meta);
- if (res->offset < 0 || res->offset > size) {
- // TODO support negative offsets
- _syscall_fs_respond(NULL, -1, 0);
- } else {
- _syscall_fs_respond(meta + 512 + res->offset, size - res->offset, 0);
- }
- break;
-
- case '5': /* directory */
- meta_len = strlen(meta);
- size_t to_skip = res->offset;
-
- /* find files in dir */
- for (size_t off = 0; off < base_len;) {
- if (0 != memcmp(base + off + 257, "ustar", 5))
- break; // not a metadata sector
- // TODO more meaningful variable names and clean code up
-
- /* check if prefix matches */
- if (0 == memcmp(base + off, meta, meta_len) &&
- *(char*)(base + off + meta_len) != '\0') {
- char *suffix = base + off + meta_len;
- size_t suffix_len = strlen(suffix);
-
- /* check if the path contains any non-trailing slashes */
- char *next = suffix;
- while (*next && *next != '/') next++;
- if (*next == '/') next++;
- if (*next == '\0') {
- if (to_skip > suffix_len) {
- to_skip -= suffix_len;
- } else {
- suffix += to_skip;
- suffix_len -= to_skip;
- to_skip = 0;
-
- /* it doesn't - so let's add it to the result */
- memcpy(buf + buf_pos, suffix, suffix_len);
- buf[buf_pos + suffix_len] = '\0';
- buf_pos += suffix_len + 1;
- // TODO no buffer overrun check
- }
- }
- }
-
- size = tar_size(base + off);
- off += 512; // skip this metadata sector
- off += (size + 511) & ~511; // skip the data sectors
- }
-
- _syscall_fs_respond(buf, buf_pos, 0);
- break;
-
- default:
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
-}
-
-static int tar_size(void *sector) {
- return oct_parse(sector + 124, 11);
-}
-
-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) &&
- *(char*)(base + off + path_len) == '\0')
- 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++) {
- res *= 8;
- res += str[i] - '0'; // no format checking
- }
- return res;
-}
diff --git a/src/user/fs/tar.h b/src/user/fs/tar.h
deleted file mode 100644
index c1dee78..0000000
--- a/src/user/fs/tar.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-#include <shared/types.h>
-
-_Noreturn void tar_driver(void *base);