From bdfa1ea20a4cc653e91ab82a1fc20dfb799d1997 Mon Sep 17 00:00:00 2001 From: geniusgogo <2041245+geniusgogo@users.noreply.github.com> Date: Wed, 10 Apr 2024 23:55:29 +0800 Subject: [PATCH] fix symlink (#8755) Signed-off-by: geniusgogo --- components/dfs/dfs_v2/src/dfs_file.c | 97 ++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 6 deletions(-) diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c index 8a9cac7602..53e110ef59 100644 --- a/components/dfs/dfs_v2/src/dfs_file.c +++ b/components/dfs/dfs_v2/src/dfs_file.c @@ -51,6 +51,13 @@ static int _get_parent_path(const char *fullpath, char *path) char *str = 0; str = strrchr(fullpath, '/'); + + /* skip last '/' */ + if (str && *(str + 1) == '\0') + { + str = strrchr(str - 1, '/'); + } + if (str) { len = str - fullpath; @@ -84,6 +91,27 @@ static int _try_readlink(const char *path, struct dfs_mnt *mnt, char *link) return ret; } +static char *_dfs_normalize_path(const char *path, int path_len, const char *link_fn, int link_len) +{ + char *tmp_path, *fp; + + tmp_path = (char *)rt_malloc(path_len + link_len + 2); + if (!tmp_path) + { + return RT_NULL; + } + + memcpy(tmp_path, path, path_len); + tmp_path[path_len] = '/'; + memcpy(tmp_path + path_len + 1, link_fn, link_len); + tmp_path[path_len + 1 + link_len] = '\0'; + + fp = dfs_normalize_path(NULL, tmp_path); + rt_free(tmp_path); + + return fp; +} + static int _insert_link_path(const char *link_fn, int link_len, char *tmp_path, int *index) { int ret = -1; @@ -284,16 +312,73 @@ char *dfs_file_realpath(struct dfs_mnt **mnt, const char *fullpath, int mode) link_len = _try_readlink(path, *mnt, link_fn); if (link_len > 0) { - int ret = _insert_link_path(link_fn, link_len, tmp_path, &index); - - if (ret == 1) + if (link_fn[0] == '/') { - /* link_fn[0] == '/' */ + int ret = _insert_link_path(link_fn, link_len, tmp_path, &index); + if (ret < 0) + { + goto _ERR_RET; + } path_len = 0; } - else if (ret < 0) + else { - goto _ERR_RET; + char *fp = _dfs_normalize_path(path, path_len, link_fn, link_len); + if (fp) + { + int pos = rt_strncmp(path, fp, path_len); + if (pos == 0) + { + int ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index); + if (ret < 0) + { + rt_free(fp); + goto _ERR_RET; + } + } + else + { + int pos; + + while(1) + { + while(path_len > 0 && path[path_len] != '/') + { + path_len--; + } + + if (path_len > 0) + { + pos = rt_strncmp(path, fp, path_len); + } + else + { + pos = -1; + } + + if (pos == 0 || path_len == 0) + { + int ret; + + ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index); + if (ret < 0) + { + rt_free(fp); + goto _ERR_RET; + } + else + { + break; + } + } + else + { + path_len--; + } + } + } + rt_free(fp); + } } } else