]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/directory.c
Make dot files visible by default with usedots, add invisibledots for the old behavio...
[netatalk.git] / etc / afpd / directory.c
index 0431c188eff24936332144b0a2967e2c4882e146..224f397973e7500aacaf5c60049d4f7a1d9e262c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.78 2005-04-30 21:33:41 didg Exp $
+ * $Id: directory.c,v 1.83 2006-09-19 23:00:49 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -152,11 +152,7 @@ dirsearch_byname( const struct vol *vol, struct dir *cdir, char *name)
 {
 struct dir *dir = NULL;
 
-    if (cdir->d_did == DIRDID_ROOT_PARENT) {
-        if ( !strcmp(vol->v_dir->d_u_name, name)) {
-            dir = vol->v_dir;
-        }
-    } else if ( cdir->d_child) {
+    if ((cdir->d_did != DIRDID_ROOT_PARENT) && (cdir->d_child)) {
         struct dir key;
         hnode_t *hn;
         
@@ -1414,7 +1410,20 @@ char     **cpath;
             }
             else {
 noucsfallback:
-                cdir = dirsearch_byname(vol, dir, ret.u_name);
+                if (dir->d_did == DIRDID_ROOT_PARENT) {
+                    /* root parent has only one child and d_m_name is *NOT* utm (d_u_name)
+                     * d_m_name is the Mac volume name
+                     * d_u_name is the volume unix directory name
+                     *
+                    */
+                    cdir = NULL;
+                    if (!strcmp(vol->v_dir->d_m_name, ret.m_name)) {
+                       cdir = vol->v_dir;
+                    }
+                }
+               else {
+                    cdir = dirsearch_byname(vol, dir, ret.u_name);
+                }
             }
 
             if (cdir == NULL && scdir != NULL) {
@@ -1592,6 +1601,12 @@ int dirreenumerate(struct dir *dir, struct stat *st)
     return st->st_ctime == dir->ctime && (dir->d_flags & DIRF_CNID);
 }
 
+/* --------------------- */
+static int invisible_dots(const struct vol *vol, const char *name)
+{ 
+  return vol_inv_dots(vol) && *name  == '.' && strcmp(name, ".") && strcmp(name, "..");
+}
+
 /* ------------------------------ 
    (".", curdir)
    (name, dir) with curdir:name == dir, from afp_enumerate
@@ -1645,8 +1660,7 @@ int getdirparams(const struct vol *vol,
         case DIRPBIT_ATTR :
             if ( isad ) {
                 ad_getattr(&ad, &ashort);
-            } else if (*dir->d_u_name == '.' && strcmp(dir->d_u_name, ".") 
-                        && strcmp(dir->d_u_name, "..")) {
+            } else if (invisible_dots(vol, dir->d_u_name)) {
                 ashort = htons(ATTRBIT_INVISIBLE);
             } else
                 ashort = 0;
@@ -1689,12 +1703,10 @@ int getdirparams(const struct vol *vol,
                 ashort = htons(FINDERINFO_CLOSEDVIEW);
                 memcpy(data + FINDERINFO_FRVIEWOFF, &ashort, sizeof(ashort));
 
-                /* dot files are by default invisible */
-                if (*dir->d_u_name  == '.' && strcmp(dir->d_u_name , ".") &&
-                        strcmp(dir->d_u_name , "..")) {
+                /* dot files are by default visible */
+                if (invisible_dots(vol, dir->d_u_name)) {
                     ashort = htons(FINDERINFO_INVISIBLE);
-                    memcpy(data + FINDERINFO_FRFLAGOFF,
-                           &ashort, sizeof(ashort));
+                    memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
                 }
             }
             data += 32;
@@ -1803,7 +1815,7 @@ int getdirparams(const struct vol *vol,
             
         default :
             if ( isad ) {
-                ad_close( &ad, ADFLAGS_HF );
+                ad_close_metadata( &ad );
             }
             return( AFPERR_BITMAP );
         }
@@ -1821,7 +1833,7 @@ int getdirparams(const struct vol *vol,
         data = set_name(vol, data, pdid, dir->d_m_name, dir->d_did, utf8);
     }
     if ( isad ) {
-        ad_close( &ad, ADFLAGS_HF );
+        ad_close_metadata( &ad );
     }
     *buflen = data - buf;
     return( AFP_OK );
@@ -1952,7 +1964,7 @@ int setdirparams(const struct vol *vol,
     u_int16_t           bitmap = d_bitmap;
     u_char              finder_buf[32];
     u_int32_t          upriv;
-    mode_t              mpriv;          /* uninitialized, OK 310105 */
+    mode_t              mpriv = 0;        
     u_int16_t           upriv_bit = 0;
 
     bit = 0;
@@ -2006,7 +2018,7 @@ int setdirparams(const struct vol *vol,
             ma.ma_world = *buf++;
             ma.ma_group = *buf++;
             ma.ma_owner = *buf++;
-            mpriv = mtoumode( &ma );
+            mpriv = mtoumode( &ma ) | vol->v_perm;
             if (dir_rx_set(mpriv) && setdirmode( vol, upath, mpriv) < 0 ) {
                 err = set_dir_errors(path, "setdirmode", errno);
                 bitmap = 0;
@@ -2026,20 +2038,21 @@ int setdirparams(const struct vol *vol,
             break;
        case DIRPBIT_UNIXPR :
            if (vol_unix_priv(vol)) {
-               /* Skip UID and GID for now, there seems to be no way to set them from an OSX client anyway */
-                buf += sizeof( aint );
-                buf += sizeof( aint );
+                memcpy( &owner, buf, sizeof(owner)); /* FIXME need to change owner too? */
+                buf += sizeof( owner );
+                memcpy( &group, buf, sizeof( group ));
+                buf += sizeof( group );
 
                 change_mdate = 1;
                 change_parent_mdate = 1;
                 memcpy( &upriv, buf, sizeof( upriv ));
                 buf += sizeof( upriv );
-                upriv = ntohl (upriv);
+                upriv = ntohl (upriv) | vol->v_perm;
                 if (dir_rx_set(upriv)) {
                     /* maybe we are trying to set perms back */
                     if ( setdirunixmode(vol, upath, upriv) < 0 ) {
                         bitmap = 0;
-                        err = set_dir_errors(path, "setdirmode", errno);
+                        err = set_dir_errors(path, "setdirunixmode", errno);
                     }
                 }
                 else {
@@ -2060,8 +2073,7 @@ int setdirparams(const struct vol *vol,
     }
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (ad_open( upath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
-                 O_RDWR|O_CREAT, 0666, &ad) < 0) {
+    if (ad_open_metadata( upath, vol_noadouble(vol)|ADFLAGS_DIR, O_CREAT, &ad) < 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
@@ -2157,27 +2169,14 @@ int setdirparams(const struct vol *vol,
                 goto setdirparam_done;
             }
             break;
-
         case DIRPBIT_GID :
             if (dir->d_did == DIRDID_ROOT)
                 setdeskowner( -1, ntohl(group) ); 
-
-#if 0       /* don't error if we can't set the desktop owner. */
-                err = set_dir_errors(path, "setdeskowner", errno);
-                if (isad && err == AFPERR_PARAM) {
-                    err = AFP_OK; /* ???*/
-                }
-                else {
-                    goto setdirparam_done;
-                }
-#endif /* 0 */
-
             if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
                 err = set_dir_errors(path, "setdirowner", errno);
                 goto setdirparam_done;
             }
             break;
-
         case DIRPBIT_ACCESS :
             if (dir->d_did == DIRDID_ROOT) {
                 setdeskmode(mpriv);
@@ -2202,21 +2201,29 @@ int setdirparams(const struct vol *vol,
        case DIRPBIT_UNIXPR :
            if (vol_unix_priv(vol)) {
                 if (dir->d_did == DIRDID_ROOT) {
-                    setdeskmode( upriv );
                     if (!dir_rx_set(upriv)) {
                         /* we can't remove read and search for owner on volume root */
                         err = AFPERR_ACCESS;
                         goto setdirparam_done;
                     }
+                    setdeskowner( -1, ntohl(group) ); 
+                    setdeskmode( upriv );
+                }
+                if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
+                    err = set_dir_errors(path, "setdirowner", errno);
+                    goto setdirparam_done;
                 }
 
                 if ( upriv_bit && setdirunixmode(vol, upath, upriv) < 0 ) {
-                    err = set_dir_errors(path, "setdirmode", errno);
+                    err = set_dir_errors(path, "setdirunixmode", errno);
                     goto setdirparam_done;
                 }
-                break;
             }
-            /* fall through */
+            else {
+                err = AFPERR_BITMAP;
+                goto setdirparam_done;
+            }
+            break;
         default :
             err = AFPERR_BITMAP;
             goto setdirparam_done;
@@ -2246,8 +2253,8 @@ setdirparam_done:
                 ad_setid(&ad, st->st_dev, st->st_ino,  dir->d_did, dir->d_parent->d_did, vol->v_stamp);
             }
         }
-        ad_flush( &ad, ADFLAGS_HF );
-        ad_close( &ad, ADFLAGS_HF );
+        ad_flush_metadata( &ad);
+        ad_close_metadata( &ad);
     }
 
     if (change_parent_mdate && dir->d_did != DIRDID_ROOT
@@ -2329,8 +2336,7 @@ int       ibuflen _U_, *rbuflen;
     }
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if (ad_open( ".", vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
-                 O_RDWR|O_CREAT, 0666, &ad ) < 0)  {
+    if (ad_open_metadata( ".", vol_noadouble(vol)|ADFLAGS_DIR, O_CREAT, &ad ) < 0)  {
         if (vol_noadouble(vol))
             goto createdir_done;
         return( AFPERR_ACCESS );
@@ -2338,8 +2344,8 @@ int       ibuflen _U_, *rbuflen;
     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);
 
-    ad_flush( &ad, ADFLAGS_HF );
-    ad_close( &ad, ADFLAGS_HF );
+    ad_flush_metadata( &ad);
+    ad_close_metadata( &ad);
 
 createdir_done:
     memcpy( rbuf, &dir->d_did, sizeof( u_int32_t ));
@@ -2400,10 +2406,10 @@ struct dir      *dir, *newparent;
     
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (!ad_open( dst, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR, 0, &ad)) {
+    if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
         ad_setname(&ad, newname);
-        ad_flush( &ad, ADFLAGS_HF );
-        ad_close( &ad, ADFLAGS_HF );
+        ad_flush_metadata( &ad);
+        ad_close_metadata( &ad);
     }
 
     dir_hash_del(vol, dir);