#include "kernel/types.h" #include "user/user.h" #include "kernel/stat.h" #include "kernel/fs.h" int fmtname(const char *path) { int p; for(p=strlen(path); p >= 0 && *(path + p) != '/'; p--); p++; return p; } void find(const char *path, const char* target) { char buf[512], *p; int fd; struct dirent de; struct stat st; if((fd = open(path, 0)) < 0){ fprintf(2, "find: cannot open %s\n", path); return; } if(fstat(fd, &st) < 0){ fprintf(2, "find: cannot stat %s\n", path); close(fd); return; } switch(st.type){ case T_DEVICE: case T_FILE: if (strcmp(path + fmtname(path), target) == 0) { printf("%s\n", path); } break; case T_DIR: if (strcmp(path + fmtname(path), target) == 0) { printf("%s\n", path); } if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ printf("find: path too long\n"); break; } strcpy(buf, path); p = buf+strlen(buf); *p++ = '/'; while(read(fd, &de, sizeof(de)) == sizeof(de)){ if(de.inum == 0) continue; if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0) continue; memmove(p, de.name, DIRSIZ); p[DIRSIZ] = 0; if(stat(buf, &st) < 0){ printf("find: cannot stat %s\n", buf); continue; } find(buf, target); } break; } close(fd); } int main(int argc, char** argv) { if (argc != 3) { printf("\x1b[31mInvalid arguments\x1b[0m\n"); printf("\x1b[32musage\x1b[0m: find \n"); exit(0); } find(argv[1], argv[2]); exit(0); }