1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" #include "kernel/fs.h"
#define MAX_PATH 512
void find(char *curr_path, char *target);
char* fmtname(char *path) { static char buf[DIRSIZ+1]; char *p;
for(p=path+strlen(path); p >= path && *p != '/'; p--) ; p++;
if(strlen(p) >= DIRSIZ) return p; memmove(buf, p, strlen(p)); buf[strlen(p)] = 0; return buf; }
void find(char *curr_path, char *target) { char buf[MAX_PATH], *p; int fd; struct dirent de; struct stat st;
if ((fd = open(curr_path, 0)) < 0) { fprintf(2, "find: cannot open %s\n", curr_path); return; }
if (fstat(fd, &st) < 0) { fprintf(2, "find: cannot stat %s\n", curr_path); close(fd); return; }
switch (st.type) { case T_FILE: { char *f_name = fmtname(curr_path); if (strcmp(f_name, target) == 0) printf("%s\n", curr_path); close(fd); break; }
case T_DIR: memset(buf, 0, sizeof(buf)); int curr_path_len = strlen(curr_path); memcpy(buf, curr_path, curr_path_len); buf[curr_path_len] = '/'; p = buf + curr_path_len + 1; while (read(fd, &de, sizeof(de)) == sizeof(de)) { if (de.inum == 0 || strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0) continue; memmove(p, de.name, DIRSIZ); p[DIRSIZ] = 0; find(buf, target); } close(fd); break; } }
int main(int argc, char *argv[]) { if (argc != 3) { fprintf(2, "usage: find [directory] [target filename]\n"); exit(1); } find(argv[1], argv[2]); exit(0); }
|