fix symlink handling in resolve_path
This commit is contained in:
parent
db6187be39
commit
1dbdbd20d3
129
src/fs.c
129
src/fs.c
|
@ -24,6 +24,7 @@ static unsigned int fs_cwd_inode_ptr;
|
|||
static struct fs_file_description fs_file_descriptions[FS_MAX_OPEN_FD];
|
||||
|
||||
static int extract_basename(char *path, char *name);
|
||||
static int read_symlink(int symlink_inode_ptr, char *path);
|
||||
|
||||
|
||||
static int read_block(unsigned int block_no, void *data)
|
||||
|
@ -953,21 +954,22 @@ static void resolve_path(struct resolved_path * const rp, const char * const ori
|
|||
if (path[i] != '/') {
|
||||
next_fname[next_fname_ptr] = path[i];
|
||||
next_fname_ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// path[i] == '/', trying to change current directory
|
||||
if ((path[i] != '/') && (i+1 < path_len))
|
||||
continue;
|
||||
|
||||
if (!next_fname_ptr)
|
||||
continue;
|
||||
|
||||
if (i+1 == path_len)
|
||||
continue;
|
||||
|
||||
int res = find_fname_in_directory(current_inode_ptr, next_fname);
|
||||
if (res < 0) {
|
||||
pr_warn("directory '%s' does not exist\n", next_fname);
|
||||
if (i+1 < path_len) {
|
||||
pr_warn("parent '%s' does not exist\n", next_fname);
|
||||
rp->parent_inode_ptr = -1;
|
||||
}
|
||||
|
||||
rp->target_inode_ptr = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -975,12 +977,53 @@ static void resolve_path(struct resolved_path * const rp, const char * const ori
|
|||
read_block(read_inode_ptr(res), &d);
|
||||
|
||||
if (d.ftype == SYMLINK) {
|
||||
if (i+1 < path_len) {
|
||||
char symlink_path[FS_MAX_PATH_LEN+1];
|
||||
int symlink_path_len = read_symlink(res, symlink_path);
|
||||
|
||||
if (symlink_path_len < 0) {
|
||||
pr_warn("broken symlink\n");
|
||||
rp->parent_inode_ptr = -1;
|
||||
rp->target_inode_ptr = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (symlink_path[0] == '/') {
|
||||
memmove(&(path[symlink_path_len]), &(path[i+1]), path_len-i-1);
|
||||
strcpy(path, &(symlink_path[1]));
|
||||
path[symlink_path_len-1] = '/';
|
||||
path_len = symlink_path_len + path_len - i - 1;
|
||||
i = -1;
|
||||
|
||||
next_fname_ptr = 0;
|
||||
strcpy(current_fname, "/");
|
||||
memset(next_fname, 0, FS_MAX_FNAME_LEN);
|
||||
} else {
|
||||
memmove(&(path[symlink_path_len+1]), &(path[i+1]), path_len-i-1);
|
||||
strcpy(path, symlink_path);
|
||||
path[symlink_path_len] = '/';
|
||||
path_len = symlink_path_len + path_len - i;
|
||||
i = -1;
|
||||
|
||||
next_fname_ptr = 0;
|
||||
strcpy(current_fname, next_fname);
|
||||
memset(next_fname, 0, FS_MAX_FNAME_LEN);
|
||||
}
|
||||
} else {
|
||||
if (!(params & FOLLOW_LAST_SYMLINK)) {
|
||||
rp->target_inode_ptr = res;
|
||||
strcpy(rp->parent_fname, current_fname);
|
||||
strcpy(rp->target_fname, next_fname);
|
||||
break;
|
||||
}
|
||||
|
||||
char symlink_path[FS_MAX_PATH_LEN+1];
|
||||
int symlink_path_len = read_symlink(res, symlink_path);
|
||||
|
||||
if (symlink_path_len < 0) {
|
||||
pr_warn("broken symlink\n");
|
||||
rp->parent_inode_ptr = -1;
|
||||
rp->target_inode_ptr = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -989,69 +1032,55 @@ static void resolve_path(struct resolved_path * const rp, const char * const ori
|
|||
rp->target_inode_ptr = 0;
|
||||
strcpy(rp->parent_fname, "/");
|
||||
strcpy(rp->target_fname, "/");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (symlink_path[0] == '/') {
|
||||
res = 0;
|
||||
memmove(&(path[symlink_path_len]), &(path[i+1]), path_len-i-1);
|
||||
path[symlink_path_len-1] = '/';
|
||||
memcpy(path, &(symlink_path[1]), symlink_path_len-1);
|
||||
path_len = symlink_path_len + path_len - i + 1;
|
||||
strcpy(path, &(symlink_path[1]));
|
||||
path_len = symlink_path_len - 1;
|
||||
i = -1;
|
||||
strcpy(next_fname, "/");
|
||||
|
||||
next_fname_ptr = 0;
|
||||
strcpy(current_fname, "/");
|
||||
memset(next_fname, 0, FS_MAX_FNAME_LEN);
|
||||
} else {
|
||||
memmove(&(path[symlink_path_len+1]), &(path[i+1]), path_len-i-1);
|
||||
path[symlink_path_len] = '/';
|
||||
memcpy(path, symlink_path, symlink_path_len);
|
||||
path_len = symlink_path_len + path_len - i + 2;
|
||||
strcpy(path, symlink_path);
|
||||
path_len = symlink_path_len;
|
||||
i = -1;
|
||||
}
|
||||
} else if (d.ftype == REGULAR) {
|
||||
pr_warn("'%s' is a regular file\n", next_fname);
|
||||
rp->parent_inode_ptr = -1;
|
||||
break;
|
||||
} else if (d.ftype == DIRECTORY) {
|
||||
pr("Found directory '%s'\n", next_fname);
|
||||
current_inode_ptr = res;
|
||||
rp->parent_inode_ptr = res;
|
||||
}
|
||||
|
||||
next_fname_ptr = 0;
|
||||
strcpy(current_fname, next_fname);
|
||||
memset(next_fname, 0, FS_MAX_FNAME_LEN);
|
||||
}
|
||||
|
||||
if (rp->parent_inode_ptr < 0) {
|
||||
rp->target_inode_ptr = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(rp->parent_fname, current_fname);
|
||||
|
||||
{
|
||||
int res = find_fname_in_directory(current_inode_ptr, next_fname);
|
||||
if (res < 0) {
|
||||
pr_warn("target fname '%s' does not exist\n", next_fname);
|
||||
} else if (d.ftype == REGULAR) {
|
||||
if (i+1 < path_len) {
|
||||
pr_warn("'%s': regular file not in the end of a path\n", next_fname);
|
||||
rp->parent_inode_ptr = -1;
|
||||
rp->target_inode_ptr = -1;
|
||||
}
|
||||
|
||||
struct fs_inode i;
|
||||
read_block(res, &i);
|
||||
|
||||
if (i.ftype == SYMLINK && (params & FOLLOW_LAST_SYMLINK))
|
||||
struct
|
||||
/*
|
||||
rp->target_inode_ptr = res;
|
||||
strcpy(rp->target_fname, next_fname);
|
||||
*/
|
||||
break;
|
||||
} else {
|
||||
rp->target_inode_ptr = res;
|
||||
strcpy(rp->parent_fname, current_fname);
|
||||
strcpy(rp->target_fname, next_fname);
|
||||
}
|
||||
} else if (d.ftype == DIRECTORY) {
|
||||
if (i+1 < path_len) {
|
||||
pr("Found directory '%s'\n", next_fname);
|
||||
current_inode_ptr = res;
|
||||
rp->parent_inode_ptr = res;
|
||||
|
||||
next_fname_ptr = 0;
|
||||
strcpy(current_fname, next_fname);
|
||||
memset(next_fname, 0, FS_MAX_FNAME_LEN);
|
||||
} else {
|
||||
rp->target_inode_ptr = res;
|
||||
strcpy(rp->parent_fname, current_fname);
|
||||
strcpy(rp->target_fname, next_fname);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue