]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/vfs/vfs.c
Merge remote branch 'sf/product-2-2' into develop
[netatalk.git] / libatalk / vfs / vfs.c
index 044000922796b6eab4fb3a4d69f2877aa6021148..8495d8c22fba19dd88789b82c6822bfb4a4fb3d6 100644 (file)
@@ -89,26 +89,21 @@ for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int
     return ret;
 }
 
-/*******************************************************************************
- * classic adouble format 
- *******************************************************************************/
-
 static int netatalk_name(const char *name)
 {
-    return strcasecmp(name,".AppleDouble") &&
-        strcasecmp(name,".AppleDB") &&
-        strcasecmp(name,".AppleDesktop");
+    return strcmp(name,".AppleDB") && strcmp(name,".AppleDesktop");        
 }
 
+/*******************************************************************************
+ * classic adouble format 
+ *******************************************************************************/
+
 static int validupath_adouble(VFS_FUNC_ARGS_VALIDUPATH)
 {
     if (name[0] != '.')
         return 1;
     
-    if (!(vol->v_flags & AFPVOL_USEDOTS))
-        return 0;
-        
-    return netatalk_name(name) && strcasecmp(name,".Parent");
+    return netatalk_name(name) && strcmp(name,".AppleDouble") && strcasecmp(name,".Parent");
 }                                           
 
 /* ----------------- */
@@ -178,7 +173,7 @@ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE)
     int  dropbox = vol->v_flags;
 
     if (dir_rx_set(mode)) {
-        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0 ) 
+        if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 ) 
             return -1;
     }
 
@@ -186,7 +181,7 @@ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE)
         return -1;
 
     if (!dir_rx_set(mode)) {
-        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0 ) 
+        if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 ) 
             return  -1 ;
     }
     return 0;
@@ -219,61 +214,25 @@ static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE)
     const char  *adouble_p = ad_dir(adouble);
 
     if (dir_rx_set(mode)) {
-        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0) 
+        if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0) 
             return -1;
     }
 
-    if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, &hf_mode, vol_noadouble(vol), vol->v_umask))
+    if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, &hf_mode, 0, vol->v_umask))
         return -1;
 
     if (!dir_rx_set(mode)) {
-        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0) 
+        if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0) 
             return  -1 ;
     }
     return 0;
 }
 
-/* ----------------- */
-static int setdirowner_adouble_loop(struct dirent *de _U_, char *name, void *data, int flag _U_, mode_t v_umask _U_)
-{
-    struct perm   *owner  = data;
-
-    if ( chown( name, owner->uid, owner->gid ) < 0 && errno != EPERM ) {
-         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-                owner->uid, owner->gid, fullpathname(name), strerror(errno) );
-         /* return ( -1 ); Sometimes this is okay */
-    }
-    return 0;
-}
-
 static int RF_setdirowner_adouble(VFS_FUNC_ARGS_SETDIROWNER)
 {
-    int           noadouble = vol_noadouble(vol);
-    char          *adouble_p;
-    struct stat   st;
-    struct perm   owner;
-    
-    owner.uid = uid;
-    owner.gid = gid;
-
-    adouble_p = ad_dir(vol->ad_path(name, ADFLAGS_DIR ));
-
-    if (for_each_adouble("setdirowner", adouble_p, setdirowner_adouble_loop, &owner, noadouble, vol->v_umask)) 
-        return -1;
-
-    /*
-     * We cheat: we know that chown doesn't do anything.
-     */
-    if ( stat( ".AppleDouble", &st ) < 0) {
-        if (errno == ENOENT && noadouble)
-            return 0;
-        LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s", fullpathname(".AppleDouble"), strerror(errno) );
-        return -1;
-    }
-    if ( gid && gid != st.st_gid && chown( ".AppleDouble", uid, gid ) < 0 && errno != EPERM ) {
+    if (lchown(".AppleDouble", uid, gid) < 0 && errno != EPERM ) {
         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-            uid, gid,fullpathname(".AppleDouble"), strerror(errno) );
-        /* return ( -1 ); Sometimes this is okay */
+            uid, gid,fullpathname(".AppleDouble"), strerror(errno));
     }
     return 0;
 }
@@ -375,7 +334,10 @@ static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE)
         EC_ZERO(bcatcstr(d, name));
     }
 
-    EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666));
+    /* ignore errors */
+    if (copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666) != 0)
+        if (errno != ENOENT)
+            EC_FAIL;
 
 EC_CLEANUP:
     bdestroy(s);
@@ -502,15 +464,12 @@ static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH)
     if (name[0] != '.')
         return 1;
     
-    if (!(vol->v_flags & AFPVOL_USEDOTS))
-        return 0;
-
 #ifndef HAVE_EAFD
     if (name[1] == '_')
-        return 0;
+        return ad_valid_header_osx(name);
 #endif
-    return netatalk_name(name) && strcasecmp(name,".Parent");
-}             
+    return netatalk_name(name);
+}
 
 /* ----------------- */
 static int RF_chown_ea(VFS_FUNC_ARGS_CHOWN)
@@ -613,48 +572,12 @@ static int RF_deletefile_ea(VFS_FUNC_ARGS_DELETEFILE)
 }
 static int RF_copyfile_ea(VFS_FUNC_ARGS_COPYFILE)
 {
-    EC_INIT;
-
-    /* copy meta EA */
-    if (copy_ea(AD_EA_META, sfd, src, dst, 0666) != 0)
-        return AFPERR_MISC;
-
-    /* copy reso */
 #ifdef HAVE_EAFD
-    int sfile = -1, dfile = -1, sea = -1, dea = -1;
-
-    if ((sfile = openat(sfd, src, O_RDONLY)) == -1) {
-        ret = AFPERR_MISC;
-        goto copyresoerr;
-    }
-
-    if ((dfile = open(dts, O_WRONLY)) == -1) {
-        ret = AFPERR_MISC;
-        goto copyresoerr;
-    }
-
-    if ((sea = openat(sfile, AD_EA_RESO, O_RDONLY | O_XATTR)) == -1) {
-        ret = AFPERR_MISC;
-        goto copyresoerr;
-    }
-
-    if ((dea = openat(dfile, AD_EA_RESO, O_RDWR | O_CREAT | O_XATTR)) == -1) {
-        ret = AFPERR_MISC;
-        goto copyresoerr;
-    }
-
-    ret = copy_file_fd(sea, dea);
-
-copyresoerr:
-    if (sfile != -1) close(sfile);
-    if (dfile != -1) close(dfile);
-    if (sea != -1) close(sea);
-    if (dea != -1) close(dea);
-    if (ret != 0)
-        return ret;
+    /* the EA VFS module does this all for us */
+    return 0;
+#endif
 
-EC_CLEANUP:
-#else
+    EC_INIT;
     bstring s = NULL, d = NULL;
     char *dup1 = NULL;
     char *dup2 = NULL;
@@ -685,7 +608,17 @@ EC_CLEANUP:
     EC_ZERO(bcatcstr(d, "/._"));
     EC_ZERO(bcatcstr(d, name));
 
-    EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666));
+    if (copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666) != 0) {
+        switch (errno) {
+        case ENOENT:
+            break;
+        default:
+            LOG(log_error, logtype_afpd, "[VFS] copyfile(\"%s\" -> \"%s\"): %s",
+                cfrombstr(s), cfrombstr(d), strerror(errno));
+            EC_FAIL;
+                    
+        }
+    }
 
 EC_CLEANUP:
     bdestroy(s);
@@ -694,8 +627,6 @@ EC_CLEANUP:
     free(dup2);
     free(dup3);
     free(dup4);
-#endif
-out:
     EC_EXIT;
 }
 
@@ -945,7 +876,11 @@ void initvol_vfs(struct vol *vol)
         vol->ad_path = ad_path;
     } else {
         vol->vfs_modules[0] = &netatalk_adouble_ea;
+#ifdef HAVE_EAFD
         vol->ad_path = ad_path_ea;
+#else
+        vol->ad_path = ad_path_osx;
+#endif
     }
 
     /* Extended Attributes */