optional added
This commit is contained in:
66
user/find.c
66
user/find.c
@@ -3,20 +3,48 @@
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
void find(char *path, char *filename) {
|
||||
int fd = open(path, 0);
|
||||
int match_pattern(const char *name, const char *pattern) {
|
||||
const char *star = 0;
|
||||
const char *name_ptr = name;
|
||||
const char *pattern_ptr = pattern;
|
||||
|
||||
while (1) {
|
||||
if (*pattern_ptr == '*') {
|
||||
star = pattern_ptr++;
|
||||
name_ptr = name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!*name)
|
||||
return (!*pattern_ptr || (star && !*++pattern_ptr));
|
||||
if (*pattern_ptr == '?' || *pattern_ptr == *name) {
|
||||
pattern_ptr++;
|
||||
name++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (star) {
|
||||
pattern_ptr = star + 1;
|
||||
name = ++name_ptr;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void find(char *path, char *pattern) {
|
||||
char buf[512], *p;
|
||||
int fd;
|
||||
struct dirent de;
|
||||
struct stat st;
|
||||
|
||||
if (fd < 0 || strlen(path) + 1 + DIRSIZ + 1 >= sizeof(buf)) {
|
||||
fprintf(2, "find: Invalid path: %s\n", path);
|
||||
// close(fd);
|
||||
if ((fd = open(path, 0)) < 0) {
|
||||
fprintf(2, "find: cannot open %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
fprintf(2, "find: Failed to stat %s\n", path);
|
||||
fprintf(2, "find: cannot stat %s\n", path);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
@@ -27,36 +55,42 @@ void find(char *path, char *filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(buf, path, strlen(path) + 1);
|
||||
p = buf + strlen(path);
|
||||
if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
|
||||
fprintf(2, "find: path too long\n");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
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, ".") || !strcmp(de.name, ".."))
|
||||
if (de.inum == 0 || !strcmp(de.name, ".") || !strcmp(de.name, ".."))
|
||||
continue;
|
||||
|
||||
memmove(p, de.name, DIRSIZ);
|
||||
p[DIRSIZ] = 0;
|
||||
|
||||
if (stat(buf, &st) < 0) {
|
||||
fprintf(2, "find: Failed to stat %s\n", buf);
|
||||
fprintf(2, "find: cannot stat %s\n", buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st.type == T_DIR) {
|
||||
find(buf, filename);
|
||||
find(buf, pattern);
|
||||
} else if (st.type == T_FILE) {
|
||||
if (!strcmp(filename, "*") || !strcmp(filename, de.name)) {
|
||||
printf("%s\n", buf);
|
||||
if (match_pattern(de.name, pattern)) {
|
||||
fprintf(1, "%s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
printf("Usage: find path filename\n");
|
||||
fprintf(2, "Usage: find <path> <pattern>\n");
|
||||
exit(1);
|
||||
}
|
||||
find(argv[1], argv[2]);
|
||||
|
||||
Reference in New Issue
Block a user