#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]); } }