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