yaffs: Add handling for . and .. at end of path
[yaffs2.git] / direct / yaffsfs.c
index 69cf0a48ad9e424d7fc53890683cc1af61682e87..7afde717b97655b253e619bd43014cdb19a5337c 100644 (file)
@@ -515,17 +515,17 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path,
                thisMatchLength = 0;
                matching = 1;
 
+
                if(!p)
                        continue;
 
-               while (matching && *p && *leftOver) {
-                       /* Skip over any /s */
-                       while (yaffsfs_IsPathDivider(*p))
-                               p++;
+               /* Skip over any leading  /s */
+               while (yaffsfs_IsPathDivider(*p))
+                       p++;
+               while (yaffsfs_IsPathDivider(*leftOver))
+                       leftOver++;
 
-                       /* Skip over any /s */
-                       while (yaffsfs_IsPathDivider(*leftOver))
-                               leftOver++;
+               while (matching && *p && *leftOver) {
 
                        /* Now match the text part */
                        while (matching &&
@@ -539,6 +539,16 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path,
                                        matching = 0;
                                }
                        }
+
+                       if ((*p && !yaffsfs_IsPathDivider(*p)) ||
+                           (*leftOver && !yaffsfs_IsPathDivider(*leftOver)))
+                               matching = 0;
+                       else {
+                               while (yaffsfs_IsPathDivider(*p))
+                                       p++;
+                               while (yaffsfs_IsPathDivider(*leftOver))
+                                       leftOver++;
+                       }
                }
 
                /* Skip over any /s in leftOver */
@@ -559,7 +569,6 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path,
                        retval = dev;
                        longestMatch = thisMatchLength;
                }
-
        }
        return retval;
 }
@@ -738,7 +747,20 @@ static struct yaffs_obj *yaffsfs_FindObject(struct yaffs_obj *relDir,
        if (dirOut)
                *dirOut = dir;
 
-       if (dir && *name)
+       /* At this stage we have looked up directory part and have the name part
+        * in name if there is one.
+        *
+        *  eg /nand/x/ will give us a name of ""
+        *     /nand/x will give us a name of "x"
+        *
+        * Since the name part might be "." or ".." which need to be fixed.
+        */
+       if (dir && (yaffs_strcmp(name, _Y("..")) == 0)) {
+               dir = dir->parent;
+               obj = dir;
+       } else if (dir && (yaffs_strcmp(name, _Y(".")) == 0))
+               obj = dir;
+       else if (dir && *name)
                obj = yaffs_find_by_name(dir, name);
        else
                obj = dir;
@@ -3419,6 +3441,7 @@ static yaffs_DIR *yaffsfs_opendir_reldir_no_lock(struct yaffs_obj *reldir,
        }
 
        obj = yaffsfs_FindObject(reldir, dirname, 0, 1, NULL, &notDir, &loop);
+       obj = yaffsfs_FollowLink(obj, 0, &loop);
 
        if (!obj && notDir)
                yaffsfs_SetError(-ENOTDIR);