]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/vfs/vfs.c
debug instead of error loglevel
[netatalk.git] / libatalk / vfs / vfs.c
index ca37885d01ec51145b2daa59d124470f532522ae..57d64ba1ae5294e601c2b118bdaf7b6a93c0e46f 100644 (file)
@@ -140,7 +140,7 @@ static int deletecurdir_adouble_loop(struct dirent *de, char *name, void *data _
     /* bail if the file exists in the current directory.
      * note: this will not fail with dangling symlinks */
     
-    if (stat(de->d_name, &st) == 0)
+    if (lstat(de->d_name, &st) == 0)
         return AFPERR_DIRNEMPT;
 
     if ((err = netatalk_unlink(name)))
@@ -178,7 +178,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 +186,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 +219,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;
 }
@@ -308,7 +272,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE)
              * create .AppleDouble if the file is already opened, so we
              * use a diff one, it's not a pb,ie it's not the same file, yet.
              */
-            ad_init(&ad, vol->v_adouble, vol->v_ad_options); 
+            ad_init(&ad, vol); 
             if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) == 0) {
                ad_close(&ad, ADFLAGS_HF);
                if (!unix_rename(dirfd, adsrc, -1, vol->ad_path(dst, 0 )) ) 
@@ -331,6 +295,8 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE)
 static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE)
 /* const struct vol *vol, int sfd, const char *src, const char *dst */
 {
+    return 0;
+#if 0
     EC_INIT;
     bstring s = NULL, d = NULL;
     char *dup1 = NULL;
@@ -386,6 +352,7 @@ EC_CLEANUP:
     if (dup4) free(dup4);
 
     EC_EXIT;
+#endif
 }
 
 #ifdef HAVE_SOLARIS_ACLS
@@ -499,12 +466,25 @@ EC_CLEANUP:
  ************************************************************************/
 static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH)
 {
-    return 1;
+    if (name[0] != '.')
+        return 1;
+    
+    if (!(vol->v_flags & AFPVOL_USEDOTS))
+        return 0;
+
+#ifndef HAVE_EAFD
+    if (name[1] == '_')
+        return 0;
+#endif
+    return netatalk_name(name) && strcasecmp(name,".Parent");
 }             
 
 /* ----------------- */
 static int RF_chown_ea(VFS_FUNC_ARGS_CHOWN)
 {
+#ifndef HAVE_EAFD
+    return chown(vol->ad_path(path, ADFLAGS_HF ), uid, gid);
+#endif
     return 0;
 }
 
@@ -514,95 +494,185 @@ static int RF_renamedir_ea(VFS_FUNC_ARGS_RENAMEDIR)
     return 0;
 }
 
+/* Returns 1 if the entry is NOT an ._ file */
+static int deletecurdir_ea_osx_chkifempty_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_)
+{
+    if (de->d_name[0] != '.' || de->d_name[0] == '_')
+        return 1;
+
+    return 0;
+}
+
+static int deletecurdir_ea_osx_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_)
+{
+    int ret;
+    
+    if ((ret = netatalk_unlink(name)) != 0)
+        return ret;
+
+    return 0;
+}
+
 /* ---------------- */
 static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR)
 {
+#ifndef HAVE_EAFD
+    int err;
+    /* delete stray ._AppleDouble files */
+
+    /* first check if there's really no other file besides files starting with ._ */
+    if ((err = for_each_adouble("deletecurdir_ea_osx", ".",
+                                deletecurdir_ea_osx_chkifempty_loop,
+                                NULL, 0, 0)) != 0) {
+        if (err == 1)
+            return AFPERR_DIRNEMPT;
+        return AFPERR_MISC;
+    }
+
+    /* Now delete orphaned ._ files */
+    if ((err = for_each_adouble("deletecurdir_ea_osx", ".",
+                                deletecurdir_ea_osx_loop,
+                                NULL, 0, 0)) != 0)
+        return err;
+
+#endif
     return 0;
 }
 
 /* ---------------- */
 static int RF_setdirunixmode_ea(VFS_FUNC_ARGS_SETDIRUNIXMODE)
 {
+#ifndef HAVE_EAFD
+#endif
     return 0;
 }
 
 static int RF_setfilmode_ea(VFS_FUNC_ARGS_SETFILEMODE)
 {
+#ifndef HAVE_EAFD
+    return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask);
+#endif
     return 0;
 }
 
 /* ---------------- */
 static int RF_setdirmode_ea(VFS_FUNC_ARGS_SETDIRMODE)
 {
+#ifndef HAVE_EAFD
+#endif
     return 0;
 }
 
 /* ---------------- */
 static int RF_setdirowner_ea(VFS_FUNC_ARGS_SETDIROWNER)
 {
+#ifndef HAVE_EAFD
+#endif
        return 0;
 }
 
 static int RF_deletefile_ea(VFS_FUNC_ARGS_DELETEFILE)
 {
+#ifndef HAVE_EAFD
+       return netatalk_unlinkat(dirfd, vol->ad_path(file, ADFLAGS_HF));
+#endif
     return 0;
 }
 static int RF_copyfile_ea(VFS_FUNC_ARGS_COPYFILE)
 {
     return 0;
-}
+#if 0
+    EC_INIT;
 
-/* ---------------- */
-static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE)
-{
-    return 0;
-}
+    /* copy meta EA */
+    if (copy_ea(AD_EA_META, sfd, src, dst, 0666) != 0)
+        return AFPERR_MISC;
 
-#if 0
-/*************************************************************************
- * osx adouble format 
- ************************************************************************/
-static int validupath_osx(VFS_FUNC_ARGS_VALIDUPATH)
-{
-    return strncmp(name,"._", 2) && (
-      (vol->v_flags & AFPVOL_USEDOTS) ? netatalk_name(name): name[0] != '.');
-}             
+    /* copy reso */
+#ifdef HAVE_EAFD
+    int sfile = -1, dfile = -1, sea = -1, dea = -1;
 
-/* ---------------- */
-static int RF_renamedir_osx(VFS_FUNC_ARGS_RENAMEDIR)
-{
-    /* We simply move the corresponding ad file as well */
-    char   tempbuf[258]="._";
-    return unix_rename(dirfd, vol->ad_path(oldpath,0), -1, strcat(tempbuf,newpath));
-}
+    if ((sfile = openat(sfd, src, O_RDONLY)) == -1) {
+        ret = AFPERR_MISC;
+        goto copyresoerr;
+    }
 
-/* ---------------- */
-static int RF_deletecurdir_osx(VFS_FUNC_ARGS_DELETECURDIR)
-{
-    return netatalk_unlink( vol->ad_path(".",0) );
-}
+    if ((dfile = open(dts, O_WRONLY)) == -1) {
+        ret = AFPERR_MISC;
+        goto copyresoerr;
+    }
 
-/* ---------------- */
-static int RF_setdirunixmode_osx(VFS_FUNC_ARGS_SETDIRUNIXMODE)
-{
-    return adouble_setfilmode(vol->ad_path(name, ADFLAGS_DIR ), mode, st, vol->v_umask);
-}
+    if ((sea = openat(sfile, AD_EA_RESO, O_RDONLY | O_XATTR)) == -1) {
+        ret = AFPERR_MISC;
+        goto copyresoerr;
+    }
 
-/* ---------------- */
-static int RF_setdirmode_osx(VFS_FUNC_ARGS_SETDIRMODE)
-{
-    return 0;
-}
+    if ((dea = openat(dfile, AD_EA_RESO, O_RDWR | O_CREAT | O_XATTR)) == -1) {
+        ret = AFPERR_MISC;
+        goto copyresoerr;
+    }
 
-/* ---------------- */
-static int RF_setdirowner_osx(VFS_FUNC_ARGS_SETDIROWNER)
-{
-       return 0;
+    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;
+
+EC_CLEANUP:
+#else
+    bstring s = NULL, d = NULL;
+    char *dup1 = NULL;
+    char *dup2 = NULL;
+    char *dup3 = NULL;
+    char *dup4 = NULL;
+    const char *name = NULL;
+    const char *dir = NULL;
+
+    /* get basename */
+
+    /* build src path to ._ 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, "/._"));
+    EC_ZERO(bcatcstr(s, name));
+
+    /* build dst path to ._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, "/._"));
+    EC_ZERO(bcatcstr(d, name));
+
+    EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666));
+
+EC_CLEANUP:
+    bdestroy(s);
+    bdestroy(d);
+    free(dup1);
+    free(dup2);
+    free(dup3);
+    free(dup4);
+#endif
+out:
+    EC_EXIT;
+#endif
 }
 
 /* ---------------- */
-static int RF_renamefile_osx(VFS_FUNC_ARGS_RENAMEFILE)
+static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE)
 {
+#ifndef HAVE_EAFD
     char  adsrc[ MAXPATHLEN + 1];
     int   err = 0;
 
@@ -618,8 +688,9 @@ static int RF_renamefile_osx(VFS_FUNC_ARGS_RENAMEFILE)
         return -1;
     }
     return 0;
-}
 #endif
+    return 0;
+}
 
 /********************************************************************************************
  * VFS chaining
@@ -844,7 +915,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 */