diff options
author | Mole Shang <[email protected]> | 2024-01-17 11:33:39 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-01-17 11:33:39 +0800 |
commit | daa90a639a35e9f99747c92bb28946ac414615bd (patch) | |
tree | cc119f4e037015b2fdff2b4ed8d989b8db66e3b0 /user/find.c | |
parent | c424f997808269559f7968c812860fd1f1974a13 (diff) | |
download | xv6-labs-daa90a639a35e9f99747c92bb28946ac414615bd.tar.gz xv6-labs-daa90a639a35e9f99747c92bb28946ac414615bd.tar.bz2 xv6-labs-daa90a639a35e9f99747c92bb28946ac414615bd.zip |
lab util: finishutil
Diffstat (limited to 'user/find.c')
-rw-r--r-- | user/find.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/user/find.c b/user/find.c new file mode 100644 index 0000000..e185e9d --- /dev/null +++ b/user/find.c @@ -0,0 +1,84 @@ +#include "kernel/types.h" + +#include "kernel/fcntl.h" +#include "kernel/fs.h" +#include "kernel/stat.h" +#include "user/user.h" + +char* +fmtname(char* path) +{ + char* p; + + // Find first character after last slash. + for (p = path + strlen(path); p >= path && *p != '/'; p--) + ; + p++; + return p; +} + +void +find(char* root_path, char* filename) +{ + static char buf[512]; + char* p; + int fd; + struct dirent de; + struct stat st; + + if ((fd = open(root_path, O_RDONLY)) < 0) { + fprintf(2, "find: cannot open %s\n", root_path); + return; + } + if (fstat(fd, &st) < 0) { + fprintf(2, "find: cannot stat %s\n", root_path); + close(fd); + return; + } + + switch (st.type) { + case T_FILE: + if (!strcmp(fmtname(root_path), filename)) { + printf("%s\n", root_path); + } + break; + case T_DIR: + if (strlen(root_path) + 1 + DIRSIZ + 1 > sizeof(buf)) { + printf("find: path too long\n"); + break; + } + + strcpy(buf, root_path); + + p = buf + strlen(buf); + *p++ = '/'; + while (read(fd, &de, sizeof(de)) == sizeof(de)) { + if (de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = '\0'; + + // printf("i'm finding %s!\n", fmtname(buf)); + + if (!strcmp(fmtname(buf), ".") || !strcmp(fmtname(buf), "..")) { + continue; + } + + find(buf, filename); + } + } + close(fd); +} + +int +main(int argc, char* argv[]) +{ + if (argc < 3) { + fprintf(2, "usage: find [root_path] filename...\n"); + exit(1); + } + + for (int i = 2; i < argc; i++) { + find(argv[1], argv[i]); + } +} |