]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/vfs/vfs.c
Merge from branch-2-1
[netatalk.git] / libatalk / vfs / vfs.c
index d833e1569f779b17bb39f21a6ba72ae2de5c843a..3156afe33191433b0ac43cf7db77d1cb4d05e43e 100644 (file)
@@ -21,6 +21,9 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,6 +40,8 @@
 #include <atalk/directory.h>
 #include <atalk/unix.h>
 #include <atalk/errchk.h>
+#include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
 
 struct perm {
     uid_t uid;
@@ -327,36 +332,58 @@ static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE)
 {
     EC_INIT;
     bstring s = NULL, d = NULL;
-    const char *name;
-    char *dir = NULL;
+    char *dup1 = NULL;
+    char *dup2 = NULL;
+    char *dup3 = NULL;
+    char *dup4 = NULL;
+    const char *name = NULL;
+    const char *dir = NULL;
 
-    /* get basename */
-    EC_NULL(name = strchr(src, '/'));
-    name++;
-
-    /* build src path to AppleDouble file*/
-    EC_NULL(dir = dirname(strdup(src)));
-    EC_NULL(s = bfromcstr(dir));
-    EC_ZERO(bcatcstr(s, "/.AppleDouble/"));
-    EC_ZERO(bcatcstr(s, name));
-    free(dirname);
-    dir = NULL;
+    struct stat st;
+    EC_ZERO(stat(dst, &st));
 
-    /* build dst path to AppleDouble file*/
-    EC_NULL(dir = dirname(strdup(dst)));
-    EC_NULL(d = bfromcstr(dir));
-    EC_ZERO(bcatcstr(d, "/.AppleDouble/"));
-    EC_ZERO(bcatcstr(d, name));
+    if (S_ISDIR(st.st_mode)) {
+        /* build src path to AppleDouble file*/
+        EC_NULL(s = bfromcstr(src));
+        EC_ZERO(bcatcstr(s, "/.AppleDouble/.Parent"));
 
-    free(dirname);
-    dir = NULL;
+        /* build dst path to AppleDouble file*/
+        EC_NULL(d = bfromcstr(dst));
+        EC_ZERO(bcatcstr(d, "/.AppleDouble/.Parent"));
+    } else {
+        /* get basename */
+
+        /* build src path to AppleDouble file*/
+        EC_NULL(dup1 = strdup(src));
+        EC_NULL(name = basename(strdup(dup1)));
+
+        EC_NULL(dup2 = strdup(src));
+        EC_NULL(dir = dirname(dup2));
+        EC_NULL(s = bfromcstr(dir));
+        EC_ZERO(bcatcstr(s, "/.AppleDouble/"));
+        EC_ZERO(bcatcstr(s, name));
+
+        /* build dst path to AppleDouble file*/
+        EC_NULL(dup4 = strdup(dst));
+        EC_NULL(name = basename(strdup(dup4)));
+
+        EC_NULL(dup3 = strdup(dst));
+        EC_NULL(dir = dirname(dup3));
+        EC_NULL(d = bfromcstr(dir));
+        EC_ZERO(bcatcstr(d, "/.AppleDouble/"));
+        EC_ZERO(bcatcstr(d, name));
+    }
 
-    EC_ZERO(copy_file(sfd, src, dst, 0666));
+    EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666));
 
 EC_CLEANUP:
     bdestroy(s);
     bdestroy(d);
-    if (dir) free(dir);
+    if (dup1) free(dup1);
+    if (dup2) free(dup2);
+    if (dup3) free(dup3);
+    if (dup4) free(dup4);
+
     EC_EXIT;
 }
 
@@ -933,8 +960,10 @@ VFS_MFUNC(setdirowner, VFS_FUNC_ARGS_SETDIROWNER, VFS_FUNC_VARS_SETDIROWNER)
 VFS_MFUNC(deletefile, VFS_FUNC_ARGS_DELETEFILE, VFS_FUNC_VARS_DELETEFILE)
 VFS_MFUNC(renamefile, VFS_FUNC_ARGS_RENAMEFILE, VFS_FUNC_VARS_RENAMEFILE)
 VFS_MFUNC(copyfile, VFS_FUNC_ARGS_COPYFILE, VFS_FUNC_VARS_COPYFILE)
+#ifdef HAVE_ACLS
 VFS_MFUNC(acl, VFS_FUNC_ARGS_ACL, VFS_FUNC_VARS_ACL)
 VFS_MFUNC(remove_acl, VFS_FUNC_ARGS_REMOVE_ACL, VFS_FUNC_VARS_REMOVE_ACL)
+#endif
 VFS_MFUNC(ea_getsize, VFS_FUNC_ARGS_EA_GETSIZE, VFS_FUNC_VARS_EA_GETSIZE)
 VFS_MFUNC(ea_getcontent, VFS_FUNC_ARGS_EA_GETCONTENT, VFS_FUNC_VARS_EA_GETCONTENT)
 VFS_MFUNC(ea_list, VFS_FUNC_ARGS_EA_LIST, VFS_FUNC_VARS_EA_LIST)
@@ -962,8 +991,10 @@ static struct vfs_ops vfs_master_funcs = {
     vfs_deletefile,
     vfs_renamefile,
     vfs_copyfile,
+#ifdef HAVE_ACLS
     vfs_acl,
     vfs_remove_acl,
+#endif
     vfs_ea_getsize,
     vfs_ea_getcontent,
     vfs_ea_list,
@@ -1037,8 +1068,10 @@ static struct vfs_ops netatalk_ea_adouble = {
     /* vfs_deletefile:    */ ea_deletefile,
     /* vfs_renamefile:    */ ea_renamefile,
     /* vfs_copyfile       */ ea_copyfile,
+#ifdef HAVE_ACLS
     /* vfs_acl:           */ NULL,
     /* vfs_remove_acl     */ NULL,
+#endif
     /* vfs_getsize        */ get_easize,
     /* vfs_getcontent     */ get_eacontent,
     /* vfs_list           */ list_eas,
@@ -1058,8 +1091,10 @@ static struct vfs_ops netatalk_ea_sys = {
     /* rf_deletefile:     */ NULL,
     /* rf_renamefile:     */ NULL,
     /* vfs_copyfile:      */ sys_ea_copyfile,
+#ifdef HAVE_ACLS
     /* rf_acl:            */ NULL,
     /* rf_remove_acl      */ NULL,
+#endif
     /* ea_getsize         */ sys_get_easize,
     /* ea_getcontent      */ sys_get_eacontent,
     /* ea_list            */ sys_list_eas,