diff options
author | dzwdz | 2022-07-31 21:25:24 +0200 |
---|---|---|
committer | dzwdz | 2022-07-31 21:25:24 +0200 |
commit | d59f6bbcbb01730447d998931e089e0d4a7effb9 (patch) | |
tree | be4a109c919d0c5cfe4c02b0dc65da8466c3dd6f /src/user | |
parent | 70948d9a9ec613b17c2cdff9e76b5b35f40565ac (diff) |
user: implement a minimal `find`
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/find/find.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/user/app/find/find.c b/src/user/app/find/find.c new file mode 100644 index 0000000..502a190 --- /dev/null +++ b/src/user/app/find/find.c @@ -0,0 +1,66 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define eprintf(fmt, ...) fprintf(stderr, "find: "fmt"\n" __VA_OPT__(,) __VA_ARGS__) + +void recurse(char *path) { + FILE *f = fopen(path, "r"); + const int buf_len = 4096; + char *buf; + + if (!f) { + eprintf("couldn't open %s", path); + return; + } + + buf = malloc(buf_len); + for (;;) { + int len = fread(buf, 1, buf_len, f); + int pos = 0; + if (len <= 0) break; + while (pos < len) { + if (buf[pos] == '\0') { + eprintf("%s has an empty entry, bailing", path); + break; + } + const char *end = memchr(buf + pos, 0, len - pos); + if (!end) { + eprintf("buf overflowed, unimplemented"); // TODO + break; + } + printf("%s%s\n", path, buf + pos); + + size_t entrylen = end - (buf + pos) + 1; + if (end[-1] == '/') { + // append onto end of the current path + // TODO no overflow check + char *pend = path + strlen(path); + memcpy(pend, buf + pos, entrylen); + recurse(path); + *pend = '\0'; + } + pos += entrylen; + } + } + fclose(f); + free(buf); +} + +void find(const char *path) { + // TODO export PATH_MAX + char *buf = malloc(4096); + memcpy(buf, path, strlen(path)+1); + recurse(buf); + free(buf); +} + +int main(int argc, char **argv) { + if (argc < 2) { + recurse("/"); + } else { + for (int i = 1; i < argc; i++) + recurse(argv[i]); + } + return 0; +} |