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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" #include "kernel/fs.h"
char* getname(char *path) { char *p;
for(p=path+strlen(path); p >= path && *p != '/'; p--) ;
p++; return p; }
void find(char *path, char *target) { if (strcmp(target, ".") == 0) { exit(0); }
if (strcmp(target, "..") == 0) { exit(0); }
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_FILE: if (strcmp(getname(path), target) == 0) { printf("%s\n", getname(buf)); } break;
case T_DIR: 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; memmove(p, de.name, DIRSIZ); p[DIRSIZ] = 0; if(stat(buf, &st) < 0){ printf("find: cannot stat %s\n", buf); continue; }
char fname[DIRSIZ+1]; memmove(fname, de.name, DIRSIZ); fname[DIRSIZ] = 0;
if (strcmp(fname, ".") == 0) { continue; }
if (strcmp(fname, "..") == 0) { continue; }
char cpath[512]; int path_len = strlen(path); memmove(cpath, path, path_len); cpath[path_len] = '/'; memmove(cpath + path_len + 1, fname, strlen(fname)); cpath[path_len + 1 + strlen(fname)] = 0;
if (st.type == T_DIR) {
find(cpath, target);
} else if (st.type == T_FILE) {
if (strcmp(fname, target) == 0) { printf("%s/", path); printf("%s\n", fname); } } } break; } close(fd); }
int main(int argc, char *argv[]) { if (argc == 1) { printf("find error: too few parameters!\n"); exit(1); }
if (argc > 3) { printf("find error: too many parameters!\n"); exit(1); }
if(argc == 2){ find(".", argv[1]); exit(0); }
find(argv[1], argv[2]);
exit(0); }
|