Browse Source

fix symlink (#8755)

Signed-off-by: geniusgogo <xpxyr@sina.com>
geniusgogo 1 year ago
parent
commit
bdfa1ea20a
1 changed files with 91 additions and 6 deletions
  1. 91 6
      components/dfs/dfs_v2/src/dfs_file.c

+ 91 - 6
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;
     char *str = 0;
 
 
     str = strrchr(fullpath, '/');
     str = strrchr(fullpath, '/');
+
+    /* skip last '/' */
+    if (str && *(str + 1) == '\0')
+    {
+        str = strrchr(str - 1, '/');
+    }
+
     if (str)
     if (str)
     {
     {
         len = str - fullpath;
         len = str - fullpath;
@@ -84,6 +91,27 @@ static int _try_readlink(const char *path, struct dfs_mnt *mnt, char *link)
     return ret;
     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)
 static int _insert_link_path(const char *link_fn, int link_len, char *tmp_path, int *index)
 {
 {
     int ret = -1;
     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);
             link_len = _try_readlink(path, *mnt, link_fn);
             if (link_len > 0)
             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;
                     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
             else