]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/directory.c
Merge master
[netatalk.git] / etc / afpd / directory.c
index 6af0bbf6f9e04929c834dba06e20ae3b340ba153..c87c9c93e7fbdd8993680d0fbdcb88cce31815d7 100644 (file)
@@ -29,6 +29,8 @@
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/errchk.h>
+#include <atalk/globals.h>
+#include <atalk/fce_api.h>
 
 #include "directory.h"
 #include "dircache.h"
@@ -37,7 +39,6 @@
 #include "fork.h"
 #include "file.h"
 #include "filedir.h"
-#include "globals.h"
 #include "unix.h"
 #include "mangle.h"
 #include "hash.h"
@@ -537,7 +538,7 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
     int          utf8;
     int          err = 0;
 
-    LOG(log_debug, logtype_afpd, "dirlookup(did: %u)", ntohl(did));
+    LOG(log_debug, logtype_afpd, "dirlookup(did: %u): START", ntohl(did));
 
     /* check for did 0, 1 and 2 */
     if (did == 0 || vol == NULL) { /* 1 */
@@ -561,12 +562,13 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
             goto exit;
         }
         if (lstat(cfrombstr(ret->d_fullpath), &st) != 0) {
-            LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {lstat: %s}", ntohl(did), strerror(errno));
+            LOG(log_debug, logtype_afpd, "dirlookup(did: %u, path: \"%s\"): lstat: %s",
+                ntohl(did), cfrombstr(ret->d_fullpath), strerror(errno));
             switch (errno) {
             case ENOENT:
             case ENOTDIR:
                 /* It's not there anymore, so remove it */
-                LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {calling dir_remove()}", ntohl(did));
+                LOG(log_debug, logtype_afpd, "dirlookup(did: %u): calling dir_remove", ntohl(did));
                 dir_remove(vol, ret);
                 afp_errno = AFPERR_NOOBJ;
                 ret = NULL;
@@ -588,6 +590,7 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
 
     /* Get it from the database */
     cnid = did;
+    LOG(log_debug, logtype_afpd, "dirlookup(did: %u): querying CNID database", ntohl(did));
     if ((upath = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL) {
         afp_errno = AFPERR_NOOBJ;
         err = 1;
@@ -605,7 +608,8 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
      * - DIRDID_ROOT is hit
      * - a cached entry is found
      */
-    LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {recursion for did: %u}", ntohl(pdid));
+    LOG(log_debug, logtype_afpd, "dirlookup(did: %u): recursion for did: %u",
+        ntohl(did), ntohl(pdid));
     if ((pdir = dirlookup(vol, pdid)) == NULL) {
         err = 1;
         goto exit;
@@ -620,7 +624,8 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
     }
 
     /* stat it and check if it's a dir */
-    LOG(log_debug, logtype_afpd, "dirlookup: {stating %s}", cfrombstr(fullpath));
+    LOG(log_debug, logtype_afpd, "dirlookup(did: %u): stating \"%s\"",
+        ntohl(did), cfrombstr(fullpath));
 
     if (lstat(cfrombstr(fullpath), &st) != 0) { /* 5a */
         switch (errno) {
@@ -678,7 +683,7 @@ exit:
         }
     }
     if (ret)
-        LOG(log_debug, logtype_afpd, "dirlookup(did: %u): pdid: %u, \"%s\"",
+        LOG(log_debug, logtype_afpd, "dirlookup(did: %u): RESULT: pdid: %u, path: \"%s\"",
             ntohl(ret->d_did), ntohl(ret->d_pdid), cfrombstr(ret->d_fullpath));
 
     return ret;
@@ -691,7 +696,7 @@ int caseenumerate(const struct vol *vol, struct path *path, struct dir *dir)
     DIR               *dp;
     struct dirent     *de;
     int               ret;
-    static u_int32_t  did = 0;
+    static uint32_t  did = 0;
     static char       cname[MAXPATHLEN];
     static char       lname[MAXPATHLEN];
     ucs2_t        u2_path[MAXPATHLEN];
@@ -827,6 +832,7 @@ struct dir *dir_new(const char *m_name,
     dir->dcache_ino = st->st_ino;
     if (!S_ISDIR(st->st_mode))
         dir->d_flags = DIRF_ISFILE;
+    dir->d_rights_cache = 0xffffffff;
     return dir;
 }
 
@@ -893,7 +899,7 @@ struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, i
 
     /* get_id needs adp for reading CNID from adouble file */
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if ((ad_open_metadata(path->u_name, ADFLAGS_DIR, 0, &ad)) == 0) /* 1 */
+    if ((ad_open(&ad, path->u_name, ADFLAGS_HF | ADFLAGS_DIR)) == 0) /* 1 */
         adp = &ad;
 
     /* Get CNID */
@@ -1123,8 +1129,8 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath)
     struct dir  *cdir;
     char        *data, *p;
     int         len;
-    u_int32_t   hint;
-    u_int16_t   len16;
+    uint32_t   hint;
+    uint16_t   len16;
     int         size = 0;
     int         toUTF8 = 0;
 
@@ -1436,7 +1442,7 @@ int file_access(struct path *path, int mode)
 }
 
 /* --------------------- */
-void setdiroffcnt(struct dir *dir, struct stat *st,  u_int32_t count)
+void setdiroffcnt(struct dir *dir, struct stat *st,  uint32_t count)
 {
     dir->d_offcnt = count;
     dir->d_ctime = st->st_ctime;
@@ -1458,7 +1464,7 @@ int dirreenumerate(struct dir *dir, struct stat *st)
 */
 
 int getdirparams(const struct vol *vol,
-                 u_int16_t bitmap, struct path *s_path,
+                 uint16_t bitmap, struct path *s_path,
                  struct dir *dir,
                  char *buf, size_t *buflen )
 {
@@ -1466,10 +1472,10 @@ int getdirparams(const struct vol *vol,
     struct adouble  ad;
     char        *data, *l_nameoff = NULL, *utf_nameoff = NULL;
     int         bit = 0, isad = 0;
-    u_int32_t           aint;
-    u_int16_t       ashort;
+    uint32_t           aint;
+    uint16_t       ashort;
     int                 ret;
-    u_int32_t           utf8 = 0;
+    uint32_t           utf8 = 0;
     cnid_t              pdid;
     struct stat *st = &s_path->st;
     char *upath = s_path->u_name;
@@ -1481,10 +1487,21 @@ int getdirparams(const struct vol *vol,
                    (1 << DIRPBIT_FINFO)))) {
 
         ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-        if ( !ad_metadata( upath, ADFLAGS_CREATE|ADFLAGS_DIR, &ad) ) {
+        if ( !ad_metadata( upath, ADFLAGS_DIR, &ad) ) {
             isad = 1;
             if (ad.ad_md->adf_flags & O_CREAT) {
                 /* We just created it */
+                if (s_path->m_name == NULL) {
+                    if ((s_path->m_name = utompath(vol,
+                                                   upath,
+                                                   dir->d_did,
+                                                   utf8_encoding())) == NULL) {
+                        LOG(log_error, logtype_afpd,
+                            "getdirparams(\"%s\"): can't assign macname",
+                            cfrombstr(dir->d_fullpath));
+                        return AFPERR_MISC;
+                    }
+                }
                 ad_setname(&ad, s_path->m_name);
                 ad_setid( &ad,
                           s_path->st.st_dev,
@@ -1568,13 +1585,13 @@ int getdirparams(const struct vol *vol,
             if (dir->d_m_name) /* root of parent can have a null name */
                 l_nameoff = data;
             else
-                memset(data, 0, sizeof(u_int16_t));
-            data += sizeof( u_int16_t );
+                memset(data, 0, sizeof(uint16_t));
+            data += sizeof( uint16_t );
             break;
 
         case DIRPBIT_SNAME :
-            memset(data, 0, sizeof(u_int16_t));
-            data += sizeof( u_int16_t );
+            memset(data, 0, sizeof(uint16_t));
+            data += sizeof( uint16_t );
             break;
 
         case DIRPBIT_DID :
@@ -1629,8 +1646,8 @@ int getdirparams(const struct vol *vol,
                 if (dir->d_m_name) /* root of parent can have a null name */
                     utf_nameoff = data;
                 else
-                    memset(data, 0, sizeof(u_int16_t));
-                data += sizeof( u_int16_t );
+                    memset(data, 0, sizeof(uint16_t));
+                data += sizeof( uint16_t );
                 aint = 0;
                 memcpy(data, &aint, sizeof( aint ));
                 data += sizeof( aint );
@@ -1713,8 +1730,8 @@ int afp_setdirparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
     struct vol  *vol;
     struct dir  *dir;
     struct path *path;
-    u_int16_t   vid, bitmap;
-    u_int32_t   did;
+    uint16_t   vid, bitmap;
+    uint32_t   did;
     int     rc;
 
     *rbuflen = 0;
@@ -1769,7 +1786,7 @@ int afp_setdirparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
  *
  * assume path == '\0' eg. it's a directory in canonical form
  */
-int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *buf )
+int setdirparams(struct vol *vol, struct path *path, uint16_t d_bitmap, char *buf )
 {
     struct maccess  ma;
     struct adouble  ad;
@@ -1781,16 +1798,16 @@ int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *b
     int         bit, isad = 1;
     int                 cdate, bdate;
     int                 owner, group;
-    u_int16_t       ashort, bshort, oshort;
+    uint16_t       ashort, bshort, oshort;
     int                 err = AFP_OK;
     int                 change_mdate = 0;
     int                 change_parent_mdate = 0;
     int                 newdate = 0;
-    u_int16_t           bitmap = d_bitmap;
+    uint16_t           bitmap = d_bitmap;
     u_char              finder_buf[32];
-    u_int32_t       upriv;
+    uint32_t       upriv;
     mode_t              mpriv = 0;
-    u_int16_t           upriv_bit = 0;
+    uint16_t           upriv_bit = 0;
 
     bit = 0;
     upath = path->u_name;
@@ -1898,7 +1915,7 @@ int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *b
     }
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (ad_open_metadata( upath, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
+    if (ad_open(&ad, upath, ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) != 0) {
         /*
          * Check to see what we're trying to set.  If it's anything
          * but ACCESS, UID, or GID, give an error.  If it's any of those
@@ -1920,7 +1937,7 @@ int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *b
          * Check to see if a create was necessary. If it was, we'll want
          * to set our name, etc.
          */
-        if ( (ad_get_HF_flags( &ad ) & O_CREAT)) {
+        if ( (ad_get_MD_flags( &ad ) & O_CREAT)) {
             ad_setname(&ad, cfrombstr(curdir->d_m_name));
         }
     }
@@ -1963,7 +1980,7 @@ int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *b
         case DIRPBIT_FINFO :
             if (isad) {
                 /* Fixes #2802236 */
-                u_int16_t *fflags = (u_int16_t *)(finder_buf + FINDERINFO_FRFLAGOFF);
+                uint16_t *fflags = (uint16_t *)(finder_buf + FINDERINFO_FRFLAGOFF);
                 *fflags &= htons(~FINDERINFO_ISHARED);
                 /* #2802236 end */
                 if (  dir->d_did == DIRDID_ROOT ) {
@@ -2108,8 +2125,8 @@ int afp_syncdir(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
     int                  dfd;
     struct vol           *vol;
     struct dir           *dir;
-    u_int32_t            did;
-    u_int16_t            vid;
+    uint32_t            did;
+    uint16_t            vid;
 
     *rbuflen = 0;
     ibuf += 2;
@@ -2197,8 +2214,8 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
     struct dir      *dir;
     char        *upath;
     struct path         *s_path;
-    u_int32_t       did;
-    u_int16_t       vid;
+    uint32_t       did;
+    uint16_t       vid;
     int                 err;
 
     *rbuflen = 0;
@@ -2251,7 +2268,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
     }
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if (ad_open_metadata( ".", ADFLAGS_DIR, O_CREAT, &ad ) < 0)  {
+    if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) < 0)  {
         if (vol_noadouble(vol))
             goto createdir_done;
         return( AFPERR_ACCESS );
@@ -2259,12 +2276,14 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
     ad_setname(&ad, s_path->m_name);
     ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp);
 
+    fce_register_new_dir(s_path);
+
     ad_flush( &ad);
     ad_close_metadata( &ad);
 
 createdir_done:
-    memcpy( rbuf, &dir->d_did, sizeof( u_int32_t ));
-    *rbuflen = sizeof( u_int32_t );
+    memcpy( rbuf, &dir->d_did, sizeof( uint32_t ));
+    *rbuflen = sizeof( uint32_t );
     setvoltime(obj, vol );
     return( AFP_OK );
 }
@@ -2317,7 +2336,7 @@ int renamedir(const struct vol *vol,
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
+    if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_DIR) == 0) {
         ad_setname(&ad, newname);
         ad_flush( &ad);
         ad_close_metadata( &ad);
@@ -2334,7 +2353,7 @@ int deletecurdir(struct vol *vol)
     struct dir  *fdir, *pdir;
     DIR *dp;
     struct adouble  ad;
-    u_int16_t       ashort;
+    uint16_t       ashort;
     int err;
 
     if ((pdir = dirlookup(vol, curdir->d_pdid)) == NULL) {
@@ -2415,7 +2434,7 @@ int afp_mapid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *r
     struct passwd   *pw;
     struct group    *gr;
     char        *name;
-    u_int32_t           id;
+    uint32_t           id;
     int         len, sfunc;
     int         utf8 = 0;
 
@@ -2496,9 +2515,6 @@ int afp_mapid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *r
             rbuf += sizeof( id );
             *rbuflen = 2 * sizeof( id );
             break;
-        case UUID_LOCAL:
-            free(name);
-            return (AFPERR_NOITEM);
         default:
             return AFPERR_MISC;
         }
@@ -2512,7 +2528,7 @@ int afp_mapid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *r
         len = strlen( name );
 
     if (utf8) {
-        u_int16_t tp = htons(len);
+        uint16_t tp = htons(len);
         memcpy(rbuf, &tp, sizeof(tp));
         rbuf += sizeof(tp);
         *rbuflen += 2;
@@ -2535,8 +2551,8 @@ int afp_mapname(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, siz
     struct passwd   *pw;
     struct group    *gr;
     int             len, sfunc;
-    u_int32_t       id;
-    u_int16_t       ulen;
+    uint32_t       id;
+    uint16_t       ulen;
 
     ibuf++;
     sfunc = (unsigned char) *ibuf++;
@@ -2623,8 +2639,8 @@ int afp_closedir(AFPObj *obj _U_, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
 #if 0
     struct vol   *vol;
     struct dir   *dir;
-    u_int16_t    vid;
-    u_int32_t    did;
+    uint16_t    vid;
+    uint32_t    did;
 #endif /* 0 */
 
     *rbuflen = 0;
@@ -2659,8 +2675,8 @@ int afp_opendir(AFPObj *obj _U_, char *ibuf, size_t ibuflen  _U_, char *rbuf, si
     struct vol      *vol;
     struct dir      *parentdir;
     struct path     *path;
-    u_int32_t       did;
-    u_int16_t       vid;
+    uint32_t       did;
+    uint16_t       vid;
 
     *rbuflen = 0;
     ibuf += 2;