]> arthur.barton.de Git - netatalk.git/commitdiff
bugfix: dirlookup() return dirsearch error if any (AFPERR_PARAM).
authordidg <didg>
Fri, 24 Jan 2003 07:08:42 +0000 (07:08 +0000)
committerdidg <didg>
Fri, 24 Jan 2003 07:08:42 +0000 (07:08 +0000)
cname():
we always need to call movecwd, even if we extended the cache eg:
cname dir1\0dir2\0\0 have to chdir to dir1. It wasn't the case if dir2 was not
in the cache.

do the right stuff when the user don't have right access to a directory. Some
calls are unfixable (afp_xxxcomment) or will always fail (afp_delete) but it'd
be ok.

etc/afpd/Makefile.am
etc/afpd/afs.c
etc/afpd/appl.c
etc/afpd/desktop.c
etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/filedir.c

index c96ea44b55518da60686858aa575d0390dbf3ba2..c3bc537e2364f243ec044ac241d459d4a5a8e6af 100644 (file)
@@ -5,7 +5,7 @@ nlsdir = @NLSDIR@
 
 SUBDIRS = nls
 
-sbin_PROGRAMS = afpd
+sbin_PROGRAMS = afpd cnid_dump
 
 afpd_SOURCES = unix.c ofork.c main.c switch.c auth.c volume.c directory.c \
         file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
@@ -16,6 +16,8 @@ afpd_SOURCES = unix.c ofork.c main.c switch.c auth.c volume.c directory.c \
 afpd_LDADD = $(top_builddir)/libatalk/libatalk.la
 afpd_LDFLAGS = -export-dynamic
 
+cnid_dump_LDADD = $(top_builddir)/libatalk/libatalk.la
+
 noinst_HEADERS = auth.h codepage.h afp_config.h desktop.h directory.h file.h \
         filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
         uam_auth.h uid.h unix.h volume.h
index 0308dde2659efb400be887598c3275776851c303..67f320b0c0f0a8a6f3afb86aae4407ed4195ef49 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: afs.c,v 1.14 2003-01-08 15:01:32 didg Exp $
+ * $Id: afs.c,v 1.15 2003-01-24 07:08:42 didg Exp $
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
@@ -103,7 +103,7 @@ int         ibuflen, *rbuflen;
     }
     if ( *path->m_name != '\0' ) {
         *rbuflen = 0;
-        return( AFPERR_BITMAP );
+        return (path_isadir( path))? afp_errno: AFPERR_BITMAP;
     }
 
     vi.in_size = 0;
@@ -196,7 +196,7 @@ int         ibuflen, *rbuflen;
     }
     if ( *path->m_name != '\0' ) {
         *rbuflen = 0;
-        return afp_errno;
+        return (path_isadir( path))? afp_errno: AFPERR_BITMAP;
     }
 
     if ((int)ibuf & 1 ) {
index 8173469166bbb8e41f60aef0e3e81621e330e33e..bd7c88ddc8fb2bd1eab416bf62c9c169f19cf306 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: appl.c,v 1.10 2003-01-12 14:39:58 didg Exp $
+ * $Id: appl.c,v 1.11 2003-01-24 07:08:42 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -200,7 +200,7 @@ int         ibuflen, *rbuflen;
     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
         return afp_errno;
     }
-    if ( *path->m_name == '\0' ) {
+    if ( path_isadir(path) ) {
         return( AFPERR_BADTYPE );
     }
 
@@ -283,7 +283,7 @@ int         ibuflen, *rbuflen;
     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
         return afp_errno;
     }
-    if ( *path->m_name == '\0' ) {
+    if ( path_isadir(path) ) {
         return( AFPERR_BADTYPE );
     }
 
@@ -441,7 +441,7 @@ int         ibuflen, *rbuflen;
         return( AFPERR_NOITEM );
     }
 
-    if ( *path->m_name == '\0' || path->st_errno ) {
+    if ( path_isadir(path) || path->st_errno ) {
         *rbuflen = 0;
         return( AFPERR_NOITEM );
     }
index b92318fca07998c5380ac5aa158756d17070ee4c..629da9d1affa776895fc5f2706fcb147109091d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.c,v 1.21 2003-01-12 14:39:58 didg Exp $
+ * $Id: desktop.c,v 1.22 2003-01-24 07:08:42 didg Exp $
  *
  * See COPYRIGHT.
  *
@@ -762,6 +762,7 @@ int         ibuflen, *rbuflen;
     int                        clen;
     u_int32_t           did;
     u_int16_t          vid;
+    int                 isadir;
 
     *rbuflen = 0;
     ibuf += 2;
@@ -794,14 +795,15 @@ int               ibuflen, *rbuflen;
         return AFPERR_ACCESS;
     }
 
-    if (*path->m_name == '\0' || !(of = of_findname(path))) {
+    isadir = path_isadir(path);
+    if (isadir || !(of = of_findname(path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
 
     if (ad_open( upath , vol_noadouble(vol) |
-                 (( *path->m_name == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+                 (( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                  O_RDWR|O_CREAT, 0666, adp) < 0 ) {
         return( AFPERR_ACCESS );
     }
@@ -834,10 +836,11 @@ int               ibuflen, *rbuflen;
     struct dir         *dir;
     struct ofork        *of;
     struct path         *s_path;
-    char               *path, *upath;
+    char               *upath;
     u_int32_t          did;
     u_int16_t          vid;
-
+    int                 isadir;
+    
     *rbuflen = 0;
     ibuf += 2;
 
@@ -858,15 +861,14 @@ int               ibuflen, *rbuflen;
     }
 
     upath = s_path->u_name;
-    path  = s_path->m_name;
-
-    if (*path == '\0' || !(of = of_findname(s_path))) {
+    isadir = path_isadir(s_path);
+    if (isadir || !(of = of_findname(s_path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
     if ( ad_open( upath,
-                  (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+                  ( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
                   O_RDONLY, 0666, adp) < 0 ) {
         return( AFPERR_NOITEM );
     }
@@ -900,9 +902,10 @@ int                ibuflen, *rbuflen;
     struct dir         *dir;
     struct ofork        *of;
     struct path         *s_path;
-    char               *path, *upath;
+    char               *upath;
     u_int32_t          did;
     u_int16_t          vid;
+    int                 isadir;
 
     *rbuflen = 0;
     ibuf += 2;
@@ -924,19 +927,19 @@ int               ibuflen, *rbuflen;
     }
 
     upath = s_path->u_name;
-    path  = s_path->m_name;
     if (check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
-    if (path == '\0' || !(of = of_findname(s_path))) {
+    isadir = path_isadir(s_path);
+    if (isadir || !(of = of_findname(s_path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
 
     if ( ad_open( upath,
-                  (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+                   (isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
                   O_RDWR, 0, adp) < 0 ) {
         switch ( errno ) {
         case ENOENT :
index 44d40daf1143c9cc4c4acb9ff21d53f18ebe4beb..260dca07f32bb2a91095e8b6e0c58fa72a4334b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.57 2003-01-21 09:58:58 didg Exp $
+ * $Id: directory.c,v 1.58 2003-01-24 07:08:42 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -121,6 +121,36 @@ u_int32_t  did;
     return NULL;
 }
 
+/* ------------------- */
+#ifdef ATACC
+int path_isadir(struct path *o_path)
+{
+    return o_path->m_name == '\0' || /* we are in a it */
+           !o_path->st_valid ||      /* in cache but we can't chdir in it */ 
+           (!o_path->st_errno && S_ISDIR(o_path->st.st_mode)); /* not in cache an can't chdir */
+}
+#endif
+
+/* ------------------- */
+struct dir *
+            dirsearch_byname( cdir, name )
+            struct dir *cdir;
+            const char *name;
+{
+struct dir *dir;
+
+    if (!strcmp(name, "."))
+        return cdir;
+    dir = cdir->d_child;
+    while (dir) {
+        if ( strcmp( dir->d_u_name, name ) == 0 ) {
+            break;
+        }
+        dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
+    }
+    return dir;
+}            
+
 /* -----------------------------------------
  * if did is not in the cache resolve it with cnid 
  * 
@@ -143,7 +173,7 @@ u_int32_t   did;
     char *mpath;
     
     ret = dirsearch(vol, did);
-    if (ret != NULL)
+    if (ret != NULL || afp_errno == AFPERR_PARAM)
         return ret;
 
     id = did;
@@ -450,8 +480,9 @@ struct dir *dir;
 {
        if (curdir == dir) {
            /* v_root can't be deleted */
-               if (movecwd(vol, vol->v_root) < 0) 
-                       printf("Yuup cant change dir to v_root\n");
+               if (movecwd(vol, vol->v_root) < 0) {
+            LOG(log_error, logtype_afpd, "cname can't chdir to : %s", vol->v_root);
+        }
        }
        /* FIXME */
     dirchildremove(dir->d_parent, dir);
@@ -788,24 +819,37 @@ struct dir *dirnew(const char *m_name, const char *u_name)
 }
 
 /* -------------------------------------------------- */
-/* XXX: this needs to be changed to handle path types 
+/* cname 
  return
  if it's a filename:
       in extenddir:
          compute unix name
-         stat the file
-      return mac name
+         stat the file or errno 
+      return 
+         filename
+         curdir: filename parent directory
+         
  if it's a dirname:
       not in the cache
           in extenddir
               compute unix name
-              stat the dir
+              stat the dir or errno
+          return
+              if chdir error 
+                 dirname 
+                 curdir: dir parent directory
+              sinon
+                 dirname: ""
+                 curdir: dir   
       in the cache 
-
-  u_name can be
-  XXXX u_name can be an alias on m_name if the m_name is
-  a valid unix name.
-  
+          return
+              if chdir error
+                 dirname
+                 curdir: dir parent directory 
+              else
+                 dirname: ""
+                 curdir: dir   
+                 
 */
 struct path *
 cname( vol, dir, cpath )
@@ -861,16 +905,22 @@ char      **cpath;
     ret.st_valid = 0;
     for ( ;; ) {
         if ( len == 0 ) {
-            if ( !extend && movecwd( vol, dir ) < 0 ) {
+            if (movecwd( vol, dir ) < 0 ) {
                /* it's tricky:
                   movecwd failed some of dir path are not there anymore.
                   FIXME Is it true with other errors?
                   so we remove dir from the cache 
                */
-               if (dir->d_did == DIRDID_ROOT_PARENT) 
-                   return NULL;
-               if (afp_errno == AFPERR_ACCESS)
-                   return NULL;                
+               if (dir->d_did == DIRDID_ROOT_PARENT)
+                   return NULL;
+               if (afp_errno == AFPERR_ACCESS) {
+                    if ( movecwd( vol, dir->d_parent ) < 0 ) {
+                        return NULL;                   
+                   }
+                   ret.m_name = dir->d_m_name;
+                   ret.u_name = dir->d_u_name;
+                   return &ret;
+               }
 
                dir_invalidate(vol, dir);
                return NULL;
@@ -929,10 +979,11 @@ char      **cpath;
                        /* dir is not valid anymore 
                           we delete dir from the cache and abort.
                        */
-                       if ( dir->d_did != DIRDID_ROOT_PARENT && 
-                             (afp_errno != AFPERR_ACCESS)) {
-                           dir_invalidate(vol, dir);
-                       }
+                       if ( dir->d_did == DIRDID_ROOT_PARENT)
+                           return NULL;
+                       if (afp_errno == AFPERR_ACCESS)
+                           return NULL;
+                       dir_invalidate(vol, dir);
                         return NULL;
                     }
                     cdir = extenddir( vol, dir, &ret );
@@ -1295,8 +1346,9 @@ int               ibuflen, *rbuflen;
         return afp_errno;
     }
 
+    /* FIXME access error or not a file */
     if ( *path->m_name != '\0' ) {
-        return( AFPERR_BADTYPE ); /* not a directory */
+        return (path_isadir( path))? afp_errno:AFPERR_BADTYPE ;
     }
 
     /*
@@ -1655,13 +1707,13 @@ int             ibuflen, *rbuflen;
     memcpy( &did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
     if (NULL == ( dir = dirlookup( vol, did )) ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno; /* was AFPERR_NOOBJ */
     }
 
     if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
         return afp_errno;
     }
-    /* FIXME check done elswhere? cname was able to move curdir to it! */
+    /* cname was able to move curdir to it! */
     if (*s_path->m_name == '\0')
         return AFPERR_EXIST;
 
@@ -2169,7 +2221,7 @@ int               ibuflen, *rbuflen;
     }
 
     if ( *path->m_name != '\0' ) {
-        return( AFPERR_BADTYPE ); /* not a directory */
+        return (path_isadir(path))? afp_errno:AFPERR_BADTYPE ;
     }
 
     if ( !path->st_valid && of_stat(path ) < 0 ) {
index 4149687dd55998ce0869916a1b3edd915a2413c9..81345dd7222558495f3bb37aca0fd1e4ea3fe3ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.h,v 1.8 2003-01-08 15:01:34 didg Exp $
+ * $Id: directory.h,v 1.9 2003-01-24 07:08:42 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -69,6 +69,17 @@ struct path {
     struct stat st;
 };
 
+#ifndef ATACC
+static __inline__ int path_isadir(struct path *o_path)
+{
+    return o_path->m_name == '\0' || /* we are in a it */
+           !o_path->st_valid ||      /* in cache but we can't chdir in it */ 
+           (!o_path->st_errno && S_ISDIR(o_path->st.st_mode)); /* not in cache an can't chdir */
+}
+#else
+extern int path_isadir(struct path *o_path);
+#endif
+
 /* child addition/removal macros */
 #define dirchildadd(a, b) do { \
        if (!(a)->d_child) \
@@ -167,6 +178,7 @@ extern struct dir       *dirnew __P((const char *, const char *));
 extern void             dirfree __P((struct dir *));
 extern struct dir      *dirsearch __P((const struct vol *, u_int32_t));
 extern struct dir      *dirlookup __P((const struct vol *, u_int32_t));
+extern struct dir       *dirsearch_byname __P((struct dir *,const char *));
 
 extern struct dir      *adddir __P((struct vol *, struct dir *, 
                                                struct path *));
index d9f276900b2e184fae68f7ee50006844a77a0f9b..1a7c437cd867f4336b2032f0e1b2c134f2011a59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: enumerate.c,v 1.32 2003-01-21 07:55:07 didg Exp $
+ * $Id: enumerate.c,v 1.33 2003-01-24 07:08:42 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -98,7 +98,7 @@ struct path     *path;
            - someone else have moved the directory.
            - it's a symlink inside the share.
            - it's an ID reused, the old directory was deleted but not
-             the cnid record and the server reused the inode for 
+             the cnid record and the server've reused the inode for 
              the new dir.
            for HASH (we should get ride of HASH) 
            - someone else have moved the directory.
@@ -270,7 +270,7 @@ int     ext;
 
     if (NULL == ( dir = dirlookup( vol, did )) ) {
         *rbuflen = 0;
-        return( AFPERR_NODIR );
+        return (afp_errno == AFPERR_NOOBJ)?AFPERR_NODIR:afp_errno;
     }
 
     memcpy( &fbitmap, ibuf, sizeof( fbitmap ));
@@ -325,15 +325,18 @@ int     ext;
     header *=sizeof( u_char );
     
     maxsz = min(maxsz, *rbuflen);
+    o_path = cname( vol, dir, &ibuf );
 
-    if (NULL == ( o_path = cname( vol, dir, &ibuf )) ) {
-        *rbuflen = 0;
-        return( AFPERR_NODIR );
-    }
+    if (afp_errno == AFPERR_NOOBJ) 
+        afp_errno = AFPERR_NODIR;
 
+    *rbuflen = 0;
+    if (NULL == o_path ) {
+        return afp_errno;
+    }
     if ( *o_path->m_name != '\0') {
-        *rbuflen = 0;
-        return( AFPERR_BADTYPE );
+        /* it's a file or it's a dir and extendir() was unable to chdir in it */
+        return (path_isadir(o_path))? afp_errno:AFPERR_BADTYPE ;
     }
 
     data = rbuf + 3 * sizeof( u_int16_t );
@@ -346,7 +349,10 @@ int     ext;
      */
     if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) {
         sd.sd_last = sd.sd_buf;
-        if ( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) {
+        /* if dir was in the cache we don't have the inode */
+        if (( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) ||
+              (ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) 
+        {
             switch (errno) {
             case EACCES:
                return AFPERR_ACCESS;
@@ -359,19 +365,6 @@ int     ext;
             }
         }
         curdir->ctime  = o_path->st.st_ctime; /* play safe */
-        if ((ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) {
-            *rbuflen = 0;
-            switch (errno) {
-            case EACCES:
-               return AFPERR_ACCESS;
-            case ENOTDIR:
-                return AFPERR_BADTYPE;
-            case ENOMEM:
-                return AFPERR_MISC;
-            default:
-                return AFPERR_NODIR;
-            }
-        }
         curdir->offcnt = ret;
         *sd.sd_last = 0;
 
@@ -393,7 +386,6 @@ int     ext;
         len = *(sd.sd_last)++;
         if ( len == 0 ) {
             sd.sd_did = 0;     /* invalidate sd struct to force re-read */
-            *rbuflen = 0;
             return( AFPERR_NOOBJ );
         }
         sd.sd_last += len + 1;
@@ -447,25 +439,18 @@ int     ext;
                 sd.sd_last += len + 1;
                 continue;
             }
-            dir = curdir->d_child;
-            s_path.m_name = NULL;
-            while (dir) {
-                if ( strcmp( dir->d_u_name, s_path.u_name ) == 0 ) {
-                    break;
-                }
-                dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
-            }
+            dir = dirsearch_byname(curdir, s_path.u_name);
             if (!dir) {
                 s_path.m_name = utompath(vol, s_path.u_name);
                 if ((dir = adddir( vol, curdir, &s_path)) == NULL) {
-                    *rbuflen = 0;
                     return AFPERR_MISC;
                 }
             }
-
+            else {
+                s_path.m_name = NULL;
+            }
             if (( ret = getdirparams(vol, dbitmap, &s_path, dir,
                                      data + header , &esz )) != AFP_OK ) {
-                *rbuflen = 0;
                 return( ret );
             }
 
@@ -477,7 +462,6 @@ int     ext;
             s_path.m_name = utompath(vol, s_path.u_name);
             if (( ret = getfilparams(vol, fbitmap, &s_path, curdir, 
                                      data + header , &esz )) != AFP_OK ) {
-                *rbuflen = 0;
                 return( ret );
             }
         }
@@ -496,7 +480,6 @@ int     ext;
          */
         if ( maxsz < sz + esz + header) {
             if (first) { /* maxsz can't hold a single reply */
-                *rbuflen = 0;
                 return AFPERR_PARAM;
             }
             sd.sd_last = start;
@@ -526,7 +509,6 @@ int     ext;
     }
 
     if ( actcnt == 0 ) {
-        *rbuflen = 0;
         sd.sd_did = 0;         /* invalidate sd struct to force re-read */
         return( AFPERR_NOOBJ );
     }
index 33ba7f54f8c579db4839e5be22161367bd6ba5f5..88f1ad12cdc3c5045663a9c2c726db059c7c960a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.76 2003-01-21 10:09:13 didg Exp $
+ * $Id: file.c,v 1.77 2003-01-24 07:08:42 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -655,7 +655,7 @@ int         ibuflen, *rbuflen;
     memcpy(&did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
     if (NULL == ( dir = dirlookup( vol, did )) ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno; /* was AFPERR_NOOBJ */
     }
 
     memcpy(&bitmap, ibuf, sizeof( bitmap ));
@@ -666,7 +666,7 @@ int         ibuflen, *rbuflen;
         return afp_errno;
     }
 
-    if ( *s_path->m_name == '\0' ) {
+    if (path_isadir(s_path)) {
         return( AFPERR_BADTYPE ); /* it's a directory */
     }
 
@@ -1052,7 +1052,7 @@ int               ibuflen, *rbuflen;
     if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
         return afp_errno;
     }
-    if ( *s_path->m_name == '\0' ) {
+    if ( path_isadir(s_path) ) {
         return( AFPERR_BADTYPE );
     }
 
@@ -1069,6 +1069,10 @@ int              ibuflen, *rbuflen;
         return AFPERR_DENYCONF;
 
     p = ctoupath( vol, curdir, newname );
+    if (!p) {
+        return AFPERR_PARAM;
+    
+    }
 #ifdef FORCE_UIDGID
     /* FIXME svid != dvid && dvid's user can't read svid */
 #endif
@@ -1087,7 +1091,7 @@ int               ibuflen, *rbuflen;
         return afp_errno;
     }
     if ( *s_path->m_name != '\0' ) {
-        return( AFPERR_BADTYPE ); /* not a directory. AFPERR_PARAM? */
+        return (path_isadir( s_path))? AFPERR_PARAM:AFPERR_BADTYPE ;
     }
 
     /* one of the handful of places that knows about the path type */
@@ -1532,10 +1536,10 @@ int             ibuflen, *rbuflen;
     }
 
     if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
-        return( AFPERR_PARAM );
+        return afp_errno; /* was AFPERR_PARAM */
     }
 
-    if ( *s_path->m_name == '\0' ) {
+    if ( path_isadir(s_path) ) {
         return( AFPERR_BADTYPE );
     }
 
@@ -1806,10 +1810,10 @@ int             ibuflen, *rbuflen;
     }
 
     if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
-        return( AFPERR_PARAM );
+        return afp_errno; /* was AFPERR_PARAM */
     }
 
-    if ( *path->m_name == '\0' ) {
+    if ( path_isadir(path) ) {
         return( AFPERR_BADTYPE );   /* it's a dir */
     }
 
@@ -1839,6 +1843,10 @@ int              ibuflen, *rbuflen;
     strcpy(spath, path->m_name);
     strcpy(supath, upath); /* this is for the cnid changing */
     p = absupath( vol, sdir, upath);
+    if (!p) {
+        /* pathname too long */
+        return AFPERR_PARAM ;
+    }
 
     /* look for the source cnid. if it doesn't exist, don't worry about
      * it. */
@@ -1855,7 +1863,7 @@ int               ibuflen, *rbuflen;
         return( AFPERR_PARAM );
     }
 
-    if ( *path->m_name == '\0' ) {
+    if ( path_isadir(path) ) {
         return( AFPERR_BADTYPE );
     }
 
index 8b4177cf4573e1c97e97f9b6cd7c6f3c2fbdd5c5..281887c54a3834a5dcc20bfd934958e621c0a68f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.39 2003-01-21 09:58:58 didg Exp $
+ * $Id: filedir.c,v 1.40 2003-01-24 07:08:43 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -197,12 +197,11 @@ int               ibuflen, *rbuflen;
     buflen = 0;
     if (S_ISDIR(st->st_mode)) {
         if (dbitmap) {
-            if (*s_path->m_name != '\0') {
-                /* the dir wasn't in the cache and we weren't able to chdir in it.
-                */
-                return AFPERR_ACCESS;
-            }
-            ret = getdirparams(vol, dbitmap, s_path, curdir,
+            dir = dirsearch_byname(curdir, s_path->u_name);
+            if (!dir) 
+                return AFPERR_NOOBJ;
+
+            ret = getdirparams(vol, dbitmap, s_path, dir,
                                  rbuf + 3 * sizeof( u_int16_t ), &buflen );
             if (ret != AFP_OK )
                 return( ret );
@@ -366,6 +365,9 @@ int         isdir;
         id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
 #endif /* CNID_DB */
         p = ctoupath( vol, sdir, oldname );
+        if (!p) { 
+            return AFPERR_PARAM; /* pathname too long */
+        }
         path.st_valid = 0;
         path.u_name = p;
         if ((opened = of_findname(&path))) {
@@ -378,6 +380,9 @@ int         isdir;
         id = sdir->d_did; /* we already have the CNID */
 #endif /* CNID_DB */
         p = ctoupath( vol, sdir->d_parent, oldname );
+        if (!p) {
+            return AFPERR_PARAM;
+        }
         adflags = ADFLAGS_DIR;
     }
     /*
@@ -486,8 +491,17 @@ int                ibuflen, *rbuflen;
     sdir = curdir;
     newname = obj->newtmp;
     oldname = obj->oldtmp;
+    isdir = path_isadir(path);
     if ( *path->m_name != '\0' ) {
         strcpy(oldname, path->m_name); /* an extra copy for of_rename */
+        if (isdir) {
+            /* curdir parent dir, need to move sdir back 
+             * FIXME search by unix name or mac name?
+            */
+            sdir = dirsearch_byname(curdir, path->u_name);
+            if (!sdir)
+                return AFPERR_NOOBJ;           
+        }
     }
     else {
         if ( sdir->d_parent == NULL ) { /* root directory */
@@ -497,7 +511,6 @@ int         ibuflen, *rbuflen;
         if ( movecwd( vol, sdir->d_parent ) < 0 ) {
             return afp_errno;
         }
-        isdir = 1;
         strcpy(oldname, sdir->d_m_name);
     }
 
@@ -563,8 +576,13 @@ int                ibuflen, *rbuflen;
     }
 
     upath = s_path->u_name;
-    if ( *s_path->m_name == '\0' ) {
-        rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
+    if ( path_isadir( s_path) ) {
+       if (*s_path->m_name != '\0') {
+           rc = AFPERR_ACCESS; 
+       }
+       else {
+            rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
+        }
     } else if (of_findname(s_path)) {
         rc = AFPERR_BUSY;
     } else if (AFP_OK == (rc = deletefile( upath, 1))) {
@@ -599,15 +617,24 @@ char      *u;
     len = strlen( u );
     p -= len;
     strncpy( p, u, len );
-    for ( d = dir; d->d_parent; d = d->d_parent ) {
-        *--p = '/';
+    if (dir) for ( d = dir; d->d_parent; d = d->d_parent ) {
         u = d->d_u_name;
         len = strlen( u );
+        if (p -len -1 < path) {
+            /* FIXME 
+               rather rare so LOG error and/or client message ?
+            */
+            return NULL;
+        }
+        *--p = '/';
         p -= len;
         strncpy( p, u, len );
     }
-    *--p = '/';
     len = strlen( vol->v_path );
+    if (p -len -1 < path) {
+        return NULL;
+    }
+    *--p = '/';
     p -= len;
     strncpy( p, vol->v_path, len );
 
@@ -630,7 +657,7 @@ int         ibuflen, *rbuflen;
 {
     struct vol *vol;
     struct dir *sdir, *ddir;
-    int         isdir = 0;
+    int         isdir;
     char       *oldname, *newname;
     struct path *path;
     int                did;
@@ -669,17 +696,22 @@ int               ibuflen, *rbuflen;
 
     /* source pathname */
     if (NULL == ( path = cname( vol, sdir, &ibuf )) ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
 
     sdir = curdir;
     newname = obj->newtmp;
     oldname = obj->oldtmp;
+    
+    isdir = path_isadir(path);
     if ( *path->m_name != '\0' ) {
-        /* not a directory */
+        if (isdir) {
+            sdir = dirsearch_byname(curdir, path->u_name);
+            if (!sdir)
+                return AFPERR_NOOBJ;           
+       }
         strcpy(oldname, path->m_name); /* an extra copy for of_rename */
     } else {
-        isdir = 1;
         strcpy(oldname, sdir->d_m_name);
     }
 
@@ -691,7 +723,7 @@ int         ibuflen, *rbuflen;
         return( AFPERR_NOOBJ );
     }
     if ( *path->m_name != '\0' ) {
-        return( AFPERR_BADTYPE );
+        return (path_isadir(path))?afp_errno:AFPERR_BADTYPE;
     }
 
     /* one more place where we know about path type */