summaryrefslogtreecommitdiff
path: root/user/find.c
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2024-02-13 19:39:56 +0800
committerMole Shang <[email protected]>2024-02-13 19:39:56 +0800
commit89ef6f717ed4b3e702e5f6f906f58fe1ea27d366 (patch)
tree760cce316675479a6cca77551438e8d2cc5fe9ae /user/find.c
parentcfae93475dfb4cb5cfe264f4c029136e1447c262 (diff)
parent4a6593f1a6f666c618d303a4858c4c6d31b41c63 (diff)
downloadxv6-labs-89ef6f717ed4b3e702e5f6f906f58fe1ea27d366.tar.gz
xv6-labs-89ef6f717ed4b3e702e5f6f906f58fe1ea27d366.tar.bz2
xv6-labs-89ef6f717ed4b3e702e5f6f906f58fe1ea27d366.zip
Merge branch 'cow' into net
Conflicts: .gitignore Makefile conf/lab.mk kernel/defs.h kernel/syscall.c kernel/vm.c user/pingpong.c user/user.h user/usys.pl
Diffstat (limited to 'user/find.c')
-rw-r--r--user/find.c84
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]);
+ }
+}