X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fvfs.c;h=dadedc5bbee20c21ac384b0ee7d19f435656c069;hb=refs%2Ftags%2Fafter-renameat;hp=a423bf63357eaa01ddeeccb5cd1d5b95c4b39dbe;hpb=b68f217b9f84112647fae7087f6e62f5328c3f42;p=netatalk.git diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index a423bf63..dadedc5b 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -148,7 +149,7 @@ static int RF_deletecurdir_adouble(VFS_FUNC_ARGS_DELETECURDIR) as well. */ if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, NULL, 1, vol->v_umask))) return err; - return netatalk_rmdir( ".AppleDouble" ); + return netatalk_rmdir(-1, ".AppleDouble" ); } /* ----------------- */ @@ -272,7 +273,7 @@ static int RF_setdirowner_adouble(VFS_FUNC_ARGS_SETDIROWNER) /* ----------------- */ static int RF_deletefile_adouble(VFS_FUNC_ARGS_DELETEFILE) { - return netatalk_unlink(vol->ad_path(file, ADFLAGS_HF)); + return netatalk_unlinkat(dirfd, vol->ad_path(file, ADFLAGS_HF)); } /* ----------------- */ @@ -282,16 +283,16 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) int err = 0; strcpy( adsrc, vol->ad_path(src, 0 )); - if (unix_rename( adsrc, vol->ad_path(dst, 0 )) < 0) { + if (unix_rename(dirfd, adsrc, -1, vol->ad_path(dst, 0 )) < 0) { struct stat st; err = errno; if (errno == ENOENT) { struct adouble ad; - if (stat(adsrc, &st)) /* source has no ressource fork, */ + if (lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ return 0; - + /* We are here because : * -there's no dest folder. * -there's no .AppleDouble in the dest folder. @@ -302,7 +303,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) ad_init(&ad, vol->v_adouble, vol->v_ad_options); if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) { ad_close(&ad, ADFLAGS_HF); - if (!unix_rename( adsrc, vol->ad_path(dst, 0 )) ) + if (!unix_rename(dirfd, adsrc, -1, vol->ad_path(dst, 0 )) ) err = 0; else err = errno; @@ -336,11 +337,11 @@ static int RF_solaris_acl(VFS_FUNC_ARGS_ACL) 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) + if ((acl(vol->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) + if ((acl(vol->ad_path(path, ADFLAGS_HF), cmd, count, aces)) != 0) return -1; return 0; @@ -357,14 +358,14 @@ static int RF_solaris_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) if (len < 0 || len >= MAXPATHLEN) return AFPERR_MISC; /* remove ACL from .AppleDouble/.Parent first */ - if ((ret = remove_acl(vol->vfs->ad_path(path, ADFLAGS_DIR))) != AFP_OK) + if ((ret = remove_acl(vol->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) + if ((ret = remove_acl(vol->ad_path(path, ADFLAGS_HF))) != AFP_OK) return ret; return AFP_OK; @@ -426,7 +427,7 @@ static int ads_delete_rf(char *name) */ if ((err = for_each_adouble("deletecurdir", name, deletecurdir_ads1_loop, NULL, 1, 0))) return err; - return netatalk_rmdir(name); + return netatalk_rmdir(-1, name); } static int deletecurdir_ads_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_) @@ -445,11 +446,12 @@ static int deletecurdir_ads_loop(struct dirent *de, char *name, void *data _U_, static int RF_deletecurdir_ads(VFS_FUNC_ARGS_DELETECURDIR) { int err; - + /* delete stray .AppleDouble files. this happens to get .Parent files as well. */ if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_ads_loop, NULL, 1, 0))) return err; - return netatalk_rmdir( ".AppleDouble" ); + + return netatalk_rmdir(-1, ".AppleDouble" ); } /* ------------------- */ @@ -658,9 +660,31 @@ static int RF_setdirowner_ads(VFS_FUNC_ARGS_SETDIROWNER) /* ------------------- */ static int RF_deletefile_ads(VFS_FUNC_ARGS_DELETEFILE) { - char *ad_p = ad_dir(vol->ad_path(file, ADFLAGS_HF )); + int ret = 0; + int cwd = -1; + char *ad_p; + + ad_p = ad_dir(vol->ad_path(file, ADFLAGS_HF )); + + if (dirfd != -1) { + if (((cwd = open(".", O_RDONLY)) == -1) || (fchdir(dirfd) != 0)) { + ret = AFPERR_MISC; + goto exit; + } + } + + ret = ads_delete_rf(ad_p); + + if (dirfd != -1 && fchdir(cwd) != 0) { + LOG(log_error, logtype_afpd, "RF_deletefile_ads: cant chdir back. exit!"); + exit(EXITERR_SYS); + } + +exit: + if (cwd != -1) + close(cwd); - return ads_delete_rf(ad_p); + return ret; } /* --------------------------- */ @@ -670,14 +694,14 @@ static int RF_renamefile_ads(VFS_FUNC_ARGS_RENAMEFILE) int err = 0; strcpy( adsrc, ad_dir(vol->ad_path(src, 0 ))); - if (unix_rename( adsrc, ad_dir(vol->ad_path(dst, 0 ))) < 0) { + if (unix_rename(dirfd, adsrc, -1, ad_dir(vol->ad_path(dst, 0 ))) < 0) { struct stat st; err = errno; if (errno == ENOENT) { struct adouble ad; - if (stat(adsrc, &st)) /* source has no ressource fork, */ + if (lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ return 0; /* We are here because : @@ -692,8 +716,8 @@ static int RF_renamefile_ads(VFS_FUNC_ARGS_RENAMEFILE) ad_close(&ad, ADFLAGS_HF); /* We must delete it */ - RF_deletefile_ads(vol, dst ); - if (!unix_rename( adsrc, ad_dir(vol->ad_path(dst, 0 ))) ) + RF_deletefile_ads(vol, -1, dst ); + if (!unix_rename(dirfd, adsrc, -1, ad_dir(vol->ad_path(dst, 0 ))) ) err = 0; else err = errno; @@ -724,7 +748,7 @@ static int RF_renamedir_osx(VFS_FUNC_ARGS_RENAMEDIR) { /* We simply move the corresponding ad file as well */ char tempbuf[258]="._"; - return rename(vol->ad_path(oldpath,0),strcat(tempbuf,newpath)); + return unix_rename(dirfd, vol->ad_path(oldpath,0), -1, strcat(tempbuf,newpath)); } /* ---------------- */ @@ -759,11 +783,11 @@ static int RF_renamefile_osx(VFS_FUNC_ARGS_RENAMEFILE) strcpy( adsrc, vol->ad_path(src, 0 )); - if (unix_rename( adsrc, vol->ad_path(dst, 0 )) < 0) { + if (unix_rename(dirfd, adsrc, -1, vol->ad_path(dst, 0 )) < 0) { struct stat st; err = errno; - if (errno == ENOENT && stat(adsrc, &st)) /* source has no ressource fork, */ + if (errno == ENOENT && lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ return 0; errno = err; return -1; @@ -868,6 +892,7 @@ static struct vfs_ops netatalk_adouble = { /* vfs_setdirowner: */ RF_setdirowner_adouble, /* vfs_deletefile: */ RF_deletefile_adouble, /* vfs_renamefile: */ RF_renamefile_adouble, + /* vfs_copyfile: */ NULL, NULL }; @@ -882,6 +907,7 @@ static struct vfs_ops netatalk_adouble_osx = { /* vfs_setdirowner: */ RF_setdirowner_osx, /* vfs_deletefile: */ RF_deletefile_adouble, /* vfs_renamefile: */ RF_renamefile_osx, + /* vfs_copyfile: */ NULL, NULL }; @@ -897,6 +923,7 @@ static struct vfs_ops netatalk_adouble_sfm = { /* vfs_setdirowner: */ RF_setdirowner_ads, /* vfs_deletefile: */ RF_deletefile_ads, /* vfs_renamefile: */ RF_renamefile_ads, + /* vfs_copyfile: */ NULL, NULL }; @@ -925,8 +952,7 @@ static struct vfs_ops netatalk_ea_adouble = { /* vfs_remove */ remove_ea }; -#ifdef HAVE_SOLARIS_EAS -static struct vfs_ops netatalk_ea_solaris = { +static struct vfs_ops netatalk_ea_sys = { /* validupath: */ NULL, /* rf_chown: */ NULL, /* rf_renamedir: */ NULL, @@ -937,16 +963,15 @@ static struct vfs_ops netatalk_ea_solaris = { /* rf_setdirowner: */ NULL, /* rf_deletefile: */ NULL, /* rf_renamefile: */ NULL, - /* vfs_copyfile: */ NULL, + /* vfs_copyfile: */ sys_ea_copyfile, /* rf_acl: */ NULL, /* rf_remove_acl */ NULL, - /* ea_getsize */ sol_get_easize, - /* ea_getcontent */ sol_get_eacontent, - /* ea_list */ sol_list_eas, - /* ea_set */ sol_set_ea, - /* ea_remove */ sol_remove_ea + /* ea_getsize */ sys_get_easize, + /* ea_getcontent */ sys_get_eacontent, + /* ea_list */ sys_list_eas, + /* ea_set */ sys_set_ea, + /* ea_remove */ sys_remove_ea }; -#endif /* * Tertiary VFS modules for ACLs @@ -966,7 +991,7 @@ static struct vfs_ops netatalk_solaris_acl_adouble = { /* rf_renamefile: */ NULL, /* vfs_copyfile */ NULL, /* rf_acl: */ RF_solaris_acl, - /* rf_remove_acl */ RF_remove_acl, + /* rf_remove_acl */ RF_solaris_remove_acl, NULL }; #endif @@ -991,20 +1016,14 @@ void initvol_vfs(struct vol *vol) } /* Extended Attributes */ - if (vol->v_vfs_ea == AFPVOL_EA_SOLARIS) { - -#ifdef HAVE_SOLARIS_EAS - LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with Solaris native EAs."); - vol->vfs_modules[1] = &netatalk_ea_solaris; -#else - LOG(log_error, logtype_afpd, "initvol_vfs: Can't enable Solaris EA support."); - goto enable_adea; -#endif - } else { - enable_adea: - /* default: AFPVOL_EA_AD */ - LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with adouble files."); + if (vol->v_vfs_ea == AFPVOL_EA_SYS) { + LOG(log_debug, logtype_afpd, "initvol_vfs: enabling EA support with native EAs"); + vol->vfs_modules[1] = &netatalk_ea_sys; + } else if (vol->v_vfs_ea == AFPVOL_EA_AD) { + LOG(log_debug, logtype_afpd, "initvol_vfs: enabling EA support with adouble files"); vol->vfs_modules[1] = &netatalk_ea_adouble; + } else { + LOG(log_debug, logtype_afpd, "initvol_vfs: volume without EA support"); } /* ACLs */