|
|
|
@ -17,6 +17,54 @@ struct mufs_dir { |
|
|
|
|
uint32_t va; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static char *mufs_abspath(const char *path) |
|
|
|
|
{ |
|
|
|
|
char *s, *p, *next, *prev; |
|
|
|
|
|
|
|
|
|
if (!(s = malloc(strlen(path) + 2))) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
strcpy(s, path); |
|
|
|
|
|
|
|
|
|
for (p = s, next = p + strcspn(p, "/"); *p != '\0'; next = p + strcspn(p, "/")) { |
|
|
|
|
char c = *next; |
|
|
|
|
|
|
|
|
|
*next = '\0'; |
|
|
|
|
|
|
|
|
|
if (*p == '\0' || strcmp(p, ".") == 0) { |
|
|
|
|
memmove(p, next + 1, strlen(next + 1) + 1); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (strcmp(p, "..") == 0) { |
|
|
|
|
if (!(prev = strrchr(s, '/'))) { |
|
|
|
|
memmove(p, next + 1, strlen(next + 1) + 1); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*prev = '\0'; |
|
|
|
|
|
|
|
|
|
if (!(prev = strrchr(s, '/'))) { |
|
|
|
|
memmove(s, next + 1, strlen(next + 1) + 1); |
|
|
|
|
p = s; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memmove(prev + 1, next + 1, strlen(next + 1) + 1); |
|
|
|
|
p = prev + 1; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*next = c; |
|
|
|
|
p = next + 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memmove(s + 1, s, strlen(s) + 1); |
|
|
|
|
*s = '/'; |
|
|
|
|
|
|
|
|
|
return s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct mufs_dir *mufs_opendir2(struct mufs *fs, struct mufs_dirent *entry) |
|
|
|
|
{ |
|
|
|
|
struct mufs_dir *dir; |
|
|
|
@ -54,22 +102,19 @@ static struct mufs_tree *resolve_path(struct mufs *fs, const char *path) |
|
|
|
|
if (!path || *path == '\0') |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
while (*path == '/') |
|
|
|
|
++path; |
|
|
|
|
if (!(s = mufs_abspath(path))) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
if (*path == '\0') |
|
|
|
|
if (strcmp(s, "/") == 0) |
|
|
|
|
return &fs->root; |
|
|
|
|
|
|
|
|
|
if (!(s = strdup(path))) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
if (!(dir = mufs_opendir2(fs, NULL))) |
|
|
|
|
goto err_free_s; |
|
|
|
|
|
|
|
|
|
for (p = s; *p != '\0'; p = end) { |
|
|
|
|
for (p = s + 1; *p != '\0'; p = end) { |
|
|
|
|
end = p + strcspn(p, "/"); |
|
|
|
|
|
|
|
|
|
while (*end == '/') |
|
|
|
|
if (*end == '/') |
|
|
|
|
*end++ = '\0'; |
|
|
|
|
|
|
|
|
|
while ((ret = mufs_readdir(dir, &entry)) == 0) { |
|
|
|
@ -250,15 +295,14 @@ int mufs_mkdir(struct mufs *fs, const char *path) |
|
|
|
|
if (!path || *path == '\0') |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (!(s = mufs_abspath(path))) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
/* TODO: already exists. */ |
|
|
|
|
if (resolve_path(fs, path)) |
|
|
|
|
if (resolve_path(fs, s)) { |
|
|
|
|
free(s); |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
while (*path == '/') |
|
|
|
|
++path; |
|
|
|
|
|
|
|
|
|
if (!(s = strdup(path))) |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(name = strrchr(s, '/'))) { |
|
|
|
|
name = s; |
|
|
|
|