symlinks are OK if not being followed
[unix-history] / usr / src / sys / ufs / ffs / ufs_vnops.c
index 1342b0d..076f951 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ufs_vnops.c 7.73 (Berkeley) %G%
+ *     @(#)ufs_vnops.c 7.79 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 int ufs_chmod __P((struct vnode *, int, struct proc *));
 int ufs_chown __P((struct vnode *, u_int, u_int, struct proc *));
 
 int ufs_chmod __P((struct vnode *, int, struct proc *));
 int ufs_chown __P((struct vnode *, u_int, u_int, struct proc *));
 
-enum vtype iftovt_tab[16] = {
-       VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
-       VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
-};
-int    vttoif_tab[9] = {
-       0, IFREG, IFDIR, IFBLK, IFCHR, IFLNK, IFSOCK, IFIFO, IFMT,
-};
-
 #ifdef _NOQUAD
 #define        SETHIGH(q, h)   (q).val[_QUAD_HIGHWORD] = (h)
 #define        SETLOW(q, l)    (q).val[_QUAD_LOWWORD] = (l)
 #ifdef _NOQUAD
 #define        SETHIGH(q, h)   (q).val[_QUAD_HIGHWORD] = (h)
 #define        SETLOW(q, l)    (q).val[_QUAD_LOWWORD] = (l)
@@ -608,22 +600,23 @@ relookup(dvp, vpp, cnp)
        struct vnode *dvp, **vpp;
        struct componentname *cnp;
 {
        struct vnode *dvp, **vpp;
        struct componentname *cnp;
 {
-       register char *cp;              /* pointer into pathname argument */
        register struct vnode *dp = 0;  /* the directory we are searching */
        struct vnode *tdp;              /* saved dp */
        struct mount *mp;               /* mount table entry */
        int docache;                    /* == 0 do not cache last component */
        int wantparent;                 /* 1 => wantparent or lockparent flag */
        int rdonly;                     /* lookup read-only flag bit */
        register struct vnode *dp = 0;  /* the directory we are searching */
        struct vnode *tdp;              /* saved dp */
        struct mount *mp;               /* mount table entry */
        int docache;                    /* == 0 do not cache last component */
        int wantparent;                 /* 1 => wantparent or lockparent flag */
        int rdonly;                     /* lookup read-only flag bit */
+       char *cp;                       /* DEBUG: check name ptr/len */
+       int newhash;                    /* DEBUG: check name hash */
        int error = 0;
        int error = 0;
-       int newhash;
 
        /*
         * Setup: break out flag bits into variables.
         */
        wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
        docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
 
        /*
         * Setup: break out flag bits into variables.
         */
        wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
        docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
-       if (cnp->cn_nameiop == DELETE || (wantparent && cnp->cn_nameiop != CREATE))
+       if (cnp->cn_nameiop == DELETE ||
+           (wantparent && cnp->cn_nameiop != CREATE))
                docache = 0;
        rdonly = cnp->cn_flags & RDONLY;
        cnp->cn_flags &= ~ISSYMLINK;
                docache = 0;
        rdonly = cnp->cn_flags & RDONLY;
        cnp->cn_flags &= ~ISSYMLINK;
@@ -641,17 +634,15 @@ relookup(dvp, vpp, cnp)
         * responsibility for freeing the pathname buffer.
         */
 #ifdef NAMEI_DIAGNOSTIC
         * responsibility for freeing the pathname buffer.
         */
 #ifdef NAMEI_DIAGNOSTIC
-       newhash = 0;
-       for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
+       for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
                newhash += (unsigned char)*cp;
        if (newhash != cnp->cn_hash)
                panic("relookup: bad hash");
        if (cnp->cn_namelen != cp - cnp->cn_nameptr)
                panic ("relookup: bad len");
                newhash += (unsigned char)*cp;
        if (newhash != cnp->cn_hash)
                panic("relookup: bad hash");
        if (cnp->cn_namelen != cp - cnp->cn_nameptr)
                panic ("relookup: bad len");
-       { char c = *cp;
-       *cp = '\0';
+       if (*cp != 0)
+               panic("relookup: not last component");
        printf("{%s}: ", cnp->cn_nameptr);
        printf("{%s}: ", cnp->cn_nameptr);
-       *cp = c; }
 #endif
 
        /*
 #endif
 
        /*
@@ -686,12 +677,9 @@ relookup(dvp, vpp, cnp)
 #ifdef DIAGNOSTIC
                if (*vpp != NULL)
                        panic("leaf should be empty");
 #ifdef DIAGNOSTIC
                if (*vpp != NULL)
                        panic("leaf should be empty");
-#endif
-#ifdef NAMEI_DIAGNOSTIC
-               printf("not found\n");
 #endif
                if (cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == DELETE ||
 #endif
                if (cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == DELETE ||
-                   error != ENOENT || *cp != 0)
+                   error != ENOENT)
                        goto bad;
                /*
                 * If creating and at end of pathname, then can consider
                        goto bad;
                /*
                 * If creating and at end of pathname, then can consider
@@ -701,39 +689,26 @@ relookup(dvp, vpp, cnp)
                        error = EROFS;
                        goto bad;
                }
                        error = EROFS;
                        goto bad;
                }
+               /* ASSERT(dvp == ndp->ni_startdir) */
+               if (cnp->cn_flags & SAVESTART)
+                       VREF(dvp);
                /*
                 * We return with ni_vp NULL to indicate that the entry
                 * doesn't currently exist, leaving a pointer to the
                 * (possibly locked) directory inode in ndp->ni_dvp.
                 */
                /*
                 * We return with ni_vp NULL to indicate that the entry
                 * doesn't currently exist, leaving a pointer to the
                 * (possibly locked) directory inode in ndp->ni_dvp.
                 */
-               if (cnp->cn_flags & SAVESTART) {
-                       /*
-                        * startdir == dvp, always
-                        */
-                       VREF(dvp);
-               }
                return (0);
        }
                return (0);
        }
-#ifdef NAMEI_DIAGNOSTIC
-       printf("found\n");
-#endif
-
        dp = *vpp;
        dp = *vpp;
+
 #ifdef DIAGNOSTIC
        /*
         * Check for symbolic link
         */
 #ifdef DIAGNOSTIC
        /*
         * Check for symbolic link
         */
-       if (dp->v_type == VLNK) {
+       if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
                panic ("relookup: symlink found.\n");
                panic ("relookup: symlink found.\n");
-       };
-
-       /*
-        * Check to see if the vnode has been mounted on;
-        * if so find the root of the mounted file system.
-        */
 #endif
 
 #endif
 
-
 nextname:
        /*
         * Check for read-only file systems.
 nextname:
        /*
         * Check for read-only file systems.
@@ -750,10 +725,9 @@ nextname:
                        goto bad2;
                }
        }
                        goto bad2;
                }
        }
-       if (cnp->cn_flags & SAVESTART) {
-               /* ASSERT(dvp==ndp->ni_startdir) */
+       /* ASSERT(dvp == ndp->ni_startdir) */
+       if (cnp->cn_flags & SAVESTART)
                VREF(dvp);
                VREF(dvp);
-       }
        
        if (!wantparent)
                vrele(dvp);
        
        if (!wantparent)
                vrele(dvp);
@@ -1023,7 +997,7 @@ unlinkit:
        if ((fcnp->cn_flags & SAVESTART) == 0)
                panic("ufs_rename: lost from startdir");
        p->p_spare[1]--;
        if ((fcnp->cn_flags & SAVESTART) == 0)
                panic("ufs_rename: lost from startdir");
        p->p_spare[1]--;
-       (void) relookup(fdvp, &fvp, fcnp);   /* NEEDSWORK: startdir stuff */
+       (void) relookup(fdvp, &fvp, fcnp);
        if (fvp != NULL) {
                xp = VTOI(fvp);
                dp = VTOI(fdvp);
        if (fvp != NULL) {
                xp = VTOI(fvp);
                dp = VTOI(fdvp);
@@ -1314,7 +1288,13 @@ ufs_symlink(dvp, vpp, cnp, vap, target)
 }
 
 /*
 }
 
 /*
- * Vnode op for read and write
+ * Vnode op for reading directories.
+ * 
+ * The routine below assumes that the on-disk format of a directory
+ * is the same as that defined by <sys/dirent.h>. If the on-disk
+ * format changes, then it will be necessary to do a conversion
+ * from the on-disk format that read returns to the format defined
+ * by <sys/dirent.h>.
  */
 int
 ufs_readdir(vp, uio, cred, eofflagp)
  */
 int
 ufs_readdir(vp, uio, cred, eofflagp)
@@ -1805,21 +1785,3 @@ bad:
        ufs_iput(ip);
        return (error);
 }
        ufs_iput(ip);
        return (error);
 }
-
-
-#if defined(JOHNH) && 0
-/*
- * A hack to get the kernel to compile.
- */
-int
-hang_addrlist()
-{
-    return 0;
-}
-int
-free_addrlist()
-{
-    return 0;
-}
-#endif
-