]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/directory.c
error code for dirlookup, cname.
[netatalk.git] / etc / afpd / directory.c
index dbb0e65a06a1d0ef302e41a1a35a7cbdce78548a..7f4b44eb1e66254aeded9af2d2ad2b169d15db53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.59 2003-01-26 10:42:40 didg Exp $
+ * $Id: directory.c,v 1.64 2003-03-15 01:34:35 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -131,6 +131,13 @@ int path_isadir(struct path *o_path)
 }
 #endif
 
+int get_afp_errno(const int param)
+{
+    if (afp_errno != AFPERR_DID1)
+        return afp_errno;
+    return param;
+}
+
 /* ------------------- */
 struct dir *
             dirsearch_byname( cdir, name )
@@ -182,7 +189,10 @@ u_int32_t  did;
         return NULL;
     }
     ptr = path + MAXPATHLEN;
-    mpath = utompath(vol, upath);
+    if (NULL == ( mpath = utompath(vol, upath, utf8_encoding()) ) ) {
+        afp_errno = AFPERR_NOOBJ;
+        return NULL;
+    }
     len = strlen(mpath);
     pathlen = len;          /* no 0 in the last part */
     len++;
@@ -193,11 +203,14 @@ u_int32_t did;
         if (ret != NULL) {
             break;
         }
-        if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) {
+        if ( NULL == (upath = cnid_resolve(vol->v_db, &id, buffer, buflen))
+             ||
+             NULL == (mpath = utompath(vol, upath, utf8_encoding()))
+        ) {
             afp_errno = AFPERR_NOOBJ;
             return NULL;
         }
-        mpath = utompath(vol, upath);
+
         len = strlen(mpath) + 1;
         pathlen += len;
         if (pathlen > 255) {
@@ -528,10 +541,13 @@ struct vol        *vol;
 struct dir     *dir;
 struct path *path;
 {
-    char       *p;
+    path->u_name = mtoupath(vol, path->m_name, utf8_encoding() );
 
-    path->u_name = p = mtoupath(vol, path->m_name );
-    if ( of_stat( path ) != 0 ) {
+    if ( path->u_name == NULL) {
+        afp_errno = AFPERR_PARAM;
+        return NULL;
+    }
+    if (of_stat( path ) != 0 ) {
         return( NULL );
     }
 
@@ -817,6 +833,14 @@ struct dir *dir;
 
 /* free everything down. we don't bother to recolor as this is only
  * called to free the entire tree */
+void dirfreename(struct dir *dir)
+{
+    if (dir->d_u_name != dir->d_m_name) {
+        free(dir->d_u_name);
+    }
+    free(dir->d_m_name);
+}
+
 void dirfree( dir )
 struct dir     *dir;
 {
@@ -831,10 +855,7 @@ struct dir *dir;
     }
 
     if (dir != SENTINEL) {
-        if (dir->d_u_name != dir->d_m_name) {
-            free(dir->d_u_name);
-        }
-        free(dir->d_m_name);
+        dirfreename(dir);
         free( dir );
     }
 }
@@ -1030,8 +1051,10 @@ char     **cpath;
                        /* dir is not valid anymore 
                           we delete dir from the cache and abort.
                        */
-                       if ( dir->d_did == DIRDID_ROOT_PARENT)
+                       if ( dir->d_did == DIRDID_ROOT_PARENT) {
+                           afp_errno = AFPERR_NOOBJ;
                            return NULL;
+                       }
                        if (afp_errno == AFPERR_ACCESS)
                            return NULL;
                        dir_invalidate(vol, dir);
@@ -1046,7 +1069,7 @@ char      **cpath;
 
             if ( cdir == NULL ) {
 
-                if ( len > 0 ) {
+                if ( len > 0 || !ret.u_name) {
                     return NULL;
                 }
 
@@ -1074,7 +1097,7 @@ struct dir        *dir;
         return( 0 );
     }
     if ( dir->d_did == DIRDID_ROOT_PARENT) {
-        afp_errno = AFPERR_PARAM;
+        afp_errno = AFPERR_DID1; /* AFPERR_PARAM;*/
         return( -1 );
     }
 
@@ -1343,12 +1366,12 @@ int getdirparams(const struct vol *vol,
     if ( l_nameoff ) {
         ashort = htons( data - buf );
         memcpy( l_nameoff, &ashort, sizeof( ashort ));
-        data = set_name(data, dir->d_m_name, 0);
+        data = set_name(vol, data, dir->d_m_name, 0);
     }
     if ( utf_nameoff ) {
         ashort = htons( data - buf );
         memcpy( utf_nameoff, &ashort, sizeof( ashort ));
-        data = set_name(data, dir->d_m_name, utf8);
+        data = set_name(vol, data, dir->d_m_name, utf8);
     }
     if ( isad ) {
         ad_close( &ad, ADFLAGS_HF );
@@ -1394,7 +1417,7 @@ int               ibuflen, *rbuflen;
     ibuf += sizeof( bitmap );
 
     if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
-        return afp_errno;
+        return get_afp_errno(AFPERR_NOOBJ); 
     }
 
     /* FIXME access error or not a file */
@@ -1470,7 +1493,7 @@ int setdirparams(const struct vol *vol,
          * Check to see if a create was necessary. If it was, we'll want
          * to set our name, etc.
          */
-        if ( ad_getoflags( &ad, ADFLAGS_HF ) & O_CREAT ) {
+        if ( ad_get_HF_flags( &ad ) & O_CREAT ) {
             ad_setentrylen( &ad, ADEID_NAME, strlen( curdir->d_m_name ));
             memcpy( ad_entry( &ad, ADEID_NAME ), curdir->d_m_name,
                     ad_getentrylen( &ad, ADEID_NAME ));
@@ -1763,7 +1786,7 @@ int               ibuflen, *rbuflen;
     }
 
     if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
-        return afp_errno;
+        return get_afp_errno(AFPERR_PARAM);
     }
     /* cname was able to move curdir to it! */
     if (*s_path->m_name == '\0')
@@ -1923,10 +1946,6 @@ int pathlen;
         return( AFPERR_ACCESS );
     }
 
-    if ( curdir->d_child != NULL ) {
-        return( AFPERR_DIRNEMPT );
-    }
-
     fdir = curdir;
 
     memset(&ad, 0, sizeof(ad));
@@ -1987,24 +2006,30 @@ int pathlen;
                return err;
             }
         }
-        closedir(dp);
     }
 
     if ( movecwd( vol, curdir->d_parent ) < 0 ) {
-        return afp_errno;
+        err = afp_errno;
+        goto delete_done;
     }
 
-    if ( (err = netatalk_rmdir(fdir->d_u_name))) {
-        return err;
-    }
-
-    dirchildremove(curdir, fdir);
+    if ( !(err = netatalk_rmdir(fdir->d_u_name))) {
+        dirchildremove(curdir, fdir);
 #ifdef CNID_DB
-    cnid_delete(vol->v_db, fdir->d_did);
+        cnid_delete(vol->v_db, fdir->d_did);
 #endif /* CNID_DB */
-    dir_remove( vol, fdir );
-
-    return( AFP_OK );
+        dir_remove( vol, fdir );
+        err = AFP_OK;
+    }
+delete_done:
+    if (dp) {
+        /* inode is used as key for cnid.
+         * Close the descriptor only after cnid_delete
+         * has been called. 
+        */
+        closedir(dp);
+    }
+    return err;
 }
 
 int afp_mapid(obj, ibuf, ibuflen, rbuf, rbuflen )
@@ -2211,7 +2236,7 @@ int               ibuflen, *rbuflen;
     }
 
     if (NULL == ( path = cname( vol, parentdir, &ibuf )) ) {
-        return afp_errno;
+        return get_afp_errno(AFPERR_PARAM);
     }
 
     if ( *path->m_name != '\0' ) {