diff options
author | dzwdz | 2022-08-20 11:11:57 +0200 |
---|---|---|
committer | dzwdz | 2022-08-20 11:11:57 +0200 |
commit | f22f019aeba00ccb3cc35fe763c3e87bf5690040 (patch) | |
tree | 6f7338b526dca6eebc865096dbdbd3af90cda335 /src/user/app/ethdump/fs.c | |
parent | 2a16c1f6f9118e7127d532421ae19b959b3f1d87 (diff) |
user/ethdump: turn into a file server
Diffstat (limited to 'src/user/app/ethdump/fs.c')
-rw-r--r-- | src/user/app/ethdump/fs.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/user/app/ethdump/fs.c b/src/user/app/ethdump/fs.c new file mode 100644 index 0000000..5078a13 --- /dev/null +++ b/src/user/app/ethdump/fs.c @@ -0,0 +1,65 @@ +#include "proto.h" +#include <camellia/syscalls.h> +#include <stdlib.h> +#include <string.h> +#include <user/lib/fs/dir.h> + +enum { + H_ROOT, + H_ETHER, +}; + +void fs_thread(void *arg) { (void)arg; + const size_t buflen = 4096; + char *buf = malloc(buflen); + for (;;) { + struct fs_wait_response res; + handle_t h = _syscall_fs_wait(buf, buflen, &res); + if (h < 0) break; + switch (res.op) { + long ret; + case VFSOP_OPEN: + ret = -1; + if (res.len < buflen) { + buf[res.len] = '\0'; + if (!strcmp("/", buf)) ret = H_ROOT; + else if (!strcmp("/raw", buf)) ret = H_ETHER; + } + _syscall_fs_respond(h, (void*)ret, ret, 0); + break; + case VFSOP_READ: + switch ((long)res.id) { + struct dirbuild db; + struct queue_entry *qe; + case H_ROOT: + dir_start(&db, res.offset, buf, sizeof buf); + dir_append(&db, "raw"); + _syscall_fs_respond(h, buf, dir_finish(&db), 0); + break; + case H_ETHER: + qe = malloc(sizeof *qe); + qe->h = h; + qe->next = ether_queue; + ether_queue = qe; + break; + default: + _syscall_fs_respond(h, NULL, -1, 0); + } + break; + case VFSOP_WRITE: + switch ((long)res.id) { + case H_ETHER: + ret = _syscall_write(state.raw_h, buf, res.len, 0, 0); + _syscall_fs_respond(h, NULL, ret, 0); + break; + default: + _syscall_fs_respond(h, NULL, -1, 0); + } + break; + default: + _syscall_fs_respond(h, NULL, -1, 0); + break; + } + } + free(buf); +} |