]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/vfs_adouble.c
Add FPSyncFork, set command 76 to afp_null, move everything from switch.c to auth.c
[netatalk.git] / etc / afpd / vfs_adouble.c
index 8e9768c6688c594cf9a4c152400c2f1542a3a882..847863e42f1222d3297ce3db9d606626ecb79c9c 100644 (file)
 #include "volume.h"
 #include "unix.h"
 
+#ifdef HAVE_NFSv4_ACLS
+extern int remove_acl(const char *name);
+#endif
+
 struct perm {
     uid_t uid;
     gid_t gid;
@@ -385,7 +389,7 @@ int RF_renamefile_ads(const struct vol *vol, const char *src, const char *dst)
                struct adouble    ad;
 
             if (stat(adsrc, &st)) /* source has no ressource fork, */
-                return AFP_OK;
+                return 0;
             
             /* We are here  because :
              * -there's no dest folder. 
@@ -421,16 +425,19 @@ int RF_renamefile_ads(const struct vol *vol, const char *src, const char *dst)
  classic adouble format 
 */
 
-static int validupath_adouble(const struct vol *vol, const char *name) 
+static int netatalk_name(const char *name)
 {
-     return (vol->v_flags & AFPVOL_USEDOTS) ?
-         strcasecmp(name,".AppleDB") &&
-         strcasecmp(name,".AppleDouble") &&
-         strcasecmp(name,".AppleDesktop") &&
-         strcasecmp(name,".Parent")
-                                           : name[0] != '.';
+    return strcasecmp(name,".AppleDB") &&
+        strcasecmp(name,".AppleDouble") &&
+        strcasecmp(name,".AppleDesktop");
 }
 
+static int validupath_adouble(const struct vol *vol, const char *name) 
+{
+    return (vol->v_flags & AFPVOL_USEDOTS) ? 
+        netatalk_name(name) && strcasecmp(name,".Parent"): name[0] != '.';
+}                                           
+
 /* ----------------- */
 static int RF_chown_adouble(const struct vol *vol, const char *path, uid_t uid, gid_t gid)
 
@@ -621,7 +628,7 @@ int RF_renamefile_adouble(const struct vol *vol, const char *src, const char *ds
                struct adouble    ad;
 
             if (stat(adsrc, &st)) /* source has no ressource fork, */
-                return AFP_OK;
+                return 0;
             
             /* We are here  because :
              * -there's no dest folder. 
@@ -650,6 +657,54 @@ int RF_renamefile_adouble(const struct vol *vol, const char *src, const char *ds
        return 0;
 }
 
+#ifdef HAVE_NFSv4_ACLS
+static int RF_acl(const struct vol *vol, const char *path, int cmd, int count, ace_t *aces)
+{
+    static char buf[ MAXPATHLEN + 1];
+    struct stat st;
+
+    if ((stat(path, &st)) != 0)
+       return -1;
+    if (S_ISDIR(st.st_mode)) {
+       if ((snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path)) < 0)
+           return -1;
+       /* set acl on .AppleDouble dir first */
+       if ((acl(buf, cmd, count, aces)) != 0)
+           return -1;
+       /* now set ACL on ressource fork */
+       if ((acl(vol->vfs->ad_path(path, ADFLAGS_DIR), cmd, count, aces)) != 0)
+           return -1;
+    } else
+       /* set ACL on ressource fork */
+       if ((acl(vol->vfs->ad_path(path, ADFLAGS_HF), cmd, count, aces)) != 0)
+           return -1;
+
+    return 0;
+}
+
+static int RF_remove_acl(const struct vol *vol, const char *path, int dir)
+{
+    int ret;
+    static char buf[ MAXPATHLEN + 1];
+
+    if (dir) {
+       if ((snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path)) < 0)
+           return AFPERR_MISC;
+       /* remove ACL from .AppleDouble/.Parent first */
+       if ((ret = remove_acl(vol->vfs->ad_path(path, ADFLAGS_DIR))) != AFP_OK)
+           return ret;
+       /* now remove from .AppleDouble dir */
+       if ((ret = remove_acl(buf)) != AFP_OK)
+           return ret;
+    } else
+       /* remove ACL from ressource fork */
+       if ((ret = remove_acl(vol->vfs->ad_path(path, ADFLAGS_HF))) != AFP_OK)
+           return ret;
+
+    return AFP_OK;
+}
+#endif
+
 struct vfs_ops netatalk_adouble = {
     /* ad_path:           */ ad_path,
     /* validupath:        */ validupath_adouble,
@@ -662,15 +717,20 @@ struct vfs_ops netatalk_adouble = {
     /* rf_setdirowner:    */ RF_setdirowner_adouble,
     /* rf_deletefile:     */ RF_deletefile_adouble,
     /* rf_renamefile:     */ RF_renamefile_adouble,
+#ifdef HAVE_NFSv4_ACLS
+    /* rf_acl:            */ RF_acl,
+    /* rf_remove_acl      */ RF_remove_acl
+#endif
 };
 
 /* =======================================
  osx adouble format 
  */
-static int validupath_osx(const struct vol *vol _U_, const char *name) 
+static int validupath_osx(const struct vol *vol, const char *name) 
 {
-    return strncasecmp(name,".Apple", 6) && strncasecmp(name,"._", 2);
-}
+    return strncmp(name,"._", 2) && (
+      (vol->v_flags & AFPVOL_USEDOTS) ? netatalk_name(name): name[0] != '.');
+}             
 
 /* ---------------- */
 int RF_renamedir_osx(const struct vol *vol, const char *oldpath, const char *newpath)
@@ -710,9 +770,20 @@ RF_setdirowner_osx(const struct vol *vol _U_, const char *path _U_, uid_t uid _U
 int RF_renamefile_osx(const struct vol *vol, const char *src, const char *dst)
 {
     char  adsrc[ MAXPATHLEN + 1];
+    int   err = 0;
 
     strcpy( adsrc, vol->vfs->ad_path( src, 0 ));
-    return unix_rename( adsrc, vol->vfs->ad_path( dst, 0 ));
+
+    if (unix_rename( adsrc, vol->vfs->ad_path( dst, 0 )) < 0) {
+        struct stat st;
+
+        err = errno;
+        if (errno == ENOENT && stat(adsrc, &st)) /* source has no ressource fork, */
+            return 0;
+        errno = err;
+        return -1;
+    }
+    return 0;
 }
 
 struct vfs_ops netatalk_adouble_osx = {