X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fvfs.c;h=0eaacfaee8af8fc5f6babb34709d2e7f7c8022f9;hb=be96d276348da0a7e66eeec844b306e8a5fa8fac;hp=09684192e985648e42e3ce059b168f9a3fa33c81;hpb=ded40a0b6cdb144ae3fc59cea4cc3378d1541007;p=netatalk.git diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 09684192..0eaacfae 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -21,8 +21,13 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#include +#include +#include #include #include +#include +#include #include #include @@ -34,6 +39,10 @@ #include #include #include +#include +#include +#include +#include struct perm { uid_t uid; @@ -106,7 +115,7 @@ static int validupath_adouble(VFS_FUNC_ARGS_VALIDUPATH) static int RF_chown_adouble(VFS_FUNC_ARGS_CHOWN) { struct stat st; - char *ad_p; + const char *ad_p; ad_p = vol->ad_path(path, ADFLAGS_HF ); @@ -148,7 +157,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" ); } /* ----------------- */ @@ -165,7 +174,7 @@ static int RF_setfilmode_adouble(VFS_FUNC_ARGS_SETFILEMODE) /* ----------------- */ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE) { - char *adouble = vol->ad_path(name, ADFLAGS_DIR ); + const char *adouble = vol->ad_path(name, ADFLAGS_DIR ); int dropbox = vol->v_flags; if (dir_rx_set(mode)) { @@ -206,8 +215,8 @@ static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE) { int dropbox = vol->v_flags; mode_t hf_mode = ad_hf_mode(mode); - char *adouble = vol->ad_path(name, ADFLAGS_DIR ); - char *adouble_p = ad_dir(adouble); + const char *adouble = vol->ad_path(name, ADFLAGS_DIR ); + const char *adouble_p = ad_dir(adouble); if (dir_rx_set(mode)) { if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0) @@ -272,7 +281,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 +291,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. @@ -300,9 +309,9 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) * 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); - if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) { + if (ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666) == 0) { 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; @@ -319,7 +328,67 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) return 0; } -#ifdef HAVE_NFSv4_ACLS +static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE) +/* const struct vol *vol, int sfd, const char *src, const char *dst */ +{ + EC_INIT; + 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; + + struct stat st; + EC_ZERO(stat(dst, &st)); + + if (S_ISDIR(st.st_mode)) { + /* build src path to AppleDouble file*/ + EC_NULL(s = bfromcstr(src)); + EC_ZERO(bcatcstr(s, "/.AppleDouble/.Parent")); + + /* 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, cfrombstr(s), cfrombstr(d), 0666)); + +EC_CLEANUP: + bdestroy(s); + bdestroy(d); + if (dup1) free(dup1); + if (dup2) free(dup2); + if (dup3) free(dup3); + if (dup4) free(dup4); + + EC_EXIT; +} + +#ifdef HAVE_SOLARIS_ACLS static int RF_solaris_acl(VFS_FUNC_ARGS_ACL) { static char buf[ MAXPATHLEN + 1]; @@ -357,359 +426,139 @@ 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->ad_path(path, ADFLAGS_DIR))) != AFP_OK) + if ((ret = remove_acl_vfs(vol->ad_path(path, ADFLAGS_DIR))) != AFP_OK) return ret; /* now remove from .AppleDouble dir */ - if ((ret = remove_acl(buf)) != AFP_OK) + if ((ret = remove_acl_vfs(buf)) != AFP_OK) return ret; } else /* remove ACL from ressource fork */ - if ((ret = remove_acl(vol->ad_path(path, ADFLAGS_HF))) != AFP_OK) + if ((ret = remove_acl_vfs(vol->ad_path(path, ADFLAGS_HF))) != AFP_OK) return ret; return AFP_OK; } #endif -/********************************************************************************* - * sfm adouble format - *********************************************************************************/ -static int ads_chown_loop(struct dirent *de _U_, char *name, void *data, int flag _U_, mode_t v_umask _U_) +#ifdef HAVE_POSIX_ACLS +static int RF_posix_acl(VFS_FUNC_ARGS_ACL) { - struct perm *owner = data; - - if (chown( name , owner->uid, owner->gid ) < 0) { - return -1; - } - return 0; -} - -static int RF_chown_ads(VFS_FUNC_ARGS_CHOWN) -{ - struct stat st; - char *ad_p; - struct perm owner; - - owner.uid = uid; - owner.gid = gid; - - - ad_p = ad_dir(vol->ad_path(path, ADFLAGS_HF )); + EC_INIT; + static char buf[ MAXPATHLEN + 1]; + struct stat st; + int len; - if ( stat( ad_p, &st ) < 0 ) { - /* ignore */ - return 0; + if (S_ISDIR(st.st_mode)) { + len = snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path); + if (len < 0 || len >= MAXPATHLEN) + EC_FAIL; + /* set acl on .AppleDouble dir first */ + EC_ZERO_LOG(acl_set_file(buf, type, acl)); + + if (type == ACL_TYPE_ACCESS) + /* set ACL on ressource fork (".Parent") too */ + EC_ZERO_LOG(acl_set_file(vol->ad_path(path, ADFLAGS_DIR), type, acl)); + } else { + /* set ACL on ressource fork */ + EC_ZERO_LOG(acl_set_file(vol->ad_path(path, ADFLAGS_HF), type, acl)); } - if (chown( ad_p, uid, gid ) < 0) { - return -1; - } - return for_each_adouble("chown_ads", ad_p, ads_chown_loop, &owner, 1, vol->v_umask); -} - -/* --------------------------------- */ -static int deletecurdir_ads1_loop(struct dirent *de _U_, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_) -{ - return netatalk_unlink(name); +EC_CLEANUP: + if (ret != 0) + return AFPERR_MISC; + return AFP_OK; } -static int ads_delete_rf(char *name) +static int RF_posix_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) { - int err; - - if ((err = for_each_adouble("deletecurdir", name, deletecurdir_ads1_loop, NULL, 1, 0))) - return err; - /* FIXME - * it's a problem for a nfs mounted folder, there's .nfsxxx around - * for linux the following line solve it. - * but it could fail if rm .nfsxxx create a new .nfsyyy :( - */ - if ((err = for_each_adouble("deletecurdir", name, deletecurdir_ads1_loop, NULL, 1, 0))) - return err; - return netatalk_rmdir(name); -} + EC_INIT; + static char buf[ MAXPATHLEN + 1]; + int len; -static int deletecurdir_ads_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_) -{ - struct stat st; - - /* bail if the file exists in the current directory. - * note: this will not fail with dangling symlinks */ - - if (stat(de->d_name, &st) == 0) { - return AFPERR_DIRNEMPT; + if (dir) { + len = snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path); + if (len < 0 || len >= MAXPATHLEN) + return AFPERR_MISC; + /* remove ACL from .AppleDouble/.Parent first */ + EC_ZERO_LOG_ERR(remove_acl_vfs(vol->ad_path(path, ADFLAGS_DIR)), AFPERR_MISC); + + /* now remove from .AppleDouble dir */ + EC_ZERO_LOG_ERR(remove_acl_vfs(buf), AFPERR_MISC); + } else { + /* remove ACL from ressource fork */ + EC_ZERO_LOG_ERR(remove_acl_vfs(vol->ad_path(path, ADFLAGS_HF)), AFPERR_MISC); } - return ads_delete_rf(name); -} -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" ); +EC_CLEANUP: + EC_EXIT; } +#endif -/* ------------------- */ -struct set_mode { - mode_t mode; - struct stat *st; -}; - -static int ads_setfilmode_loop(struct dirent *de _U_, char *name, void *data, int flag _U_, mode_t v_umask) +/************************************************************************* + * EA adouble format + ************************************************************************/ +static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH) { - struct set_mode *param = data; - - return setfilmode(name, param->mode, param->st, v_umask); -} + return 1; +} -static int ads_setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) +/* ----------------- */ +static int RF_chown_ea(VFS_FUNC_ARGS_CHOWN) { - mode_t file_mode = ad_hf_mode(mode); - mode_t dir_mode = file_mode; - struct set_mode param; - - if ((dir_mode & (S_IRUSR | S_IWUSR ))) - dir_mode |= S_IXUSR; - if ((dir_mode & (S_IRGRP | S_IWGRP ))) - dir_mode |= S_IXGRP; - if ((dir_mode & (S_IROTH | S_IWOTH ))) - dir_mode |= S_IXOTH; - - /* change folder */ - dir_mode |= DIRBITS; - if (dir_rx_set(dir_mode)) { - if (chmod( name, dir_mode ) < 0) - return -1; - } - param.st = st; - param.mode = file_mode; - if (for_each_adouble("setfilmode_ads", name, ads_setfilmode_loop, ¶m, 0, v_umask) < 0) - return -1; - - if (!dir_rx_set(dir_mode)) { - if (chmod( name, dir_mode ) < 0) - return -1; - } - return 0; } -static int RF_setfilmode_ads(VFS_FUNC_ARGS_SETFILEMODE) +/* ---------------- */ +static int RF_renamedir_ea(VFS_FUNC_ARGS_RENAMEDIR) { - return ads_setfilmode(ad_dir(vol->ad_path(name, ADFLAGS_HF )), mode, st, vol->v_umask); + return 0; } -/* ------------------- */ -static int RF_setdirunixmode_ads(VFS_FUNC_ARGS_SETDIRUNIXMODE) +/* ---------------- */ +static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR) { - char *adouble = vol->ad_path(name, ADFLAGS_DIR ); - char ad_p[ MAXPATHLEN + 1]; - int dropbox = vol->v_flags; - - strlcpy(ad_p,ad_dir(adouble), MAXPATHLEN + 1); - - if (dir_rx_set(mode)) { - - /* .AppleDouble */ - if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, dropbox, vol->v_umask) < 0) - return -1; - - /* .AppleDouble/.Parent */ - if (stickydirmode(ad_p, DIRBITS | mode, dropbox, vol->v_umask) < 0) - return -1; - } - - if (ads_setfilmode(ad_dir(vol->ad_path(name, ADFLAGS_DIR)), mode, st, vol->v_umask) < 0) - return -1; - - if (!dir_rx_set(mode)) { - if (stickydirmode(ad_p, DIRBITS | mode, dropbox, vol->v_umask) < 0) - return -1 ; - if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, dropbox, vol->v_umask) < 0) - return -1; - } return 0; } -/* ------------------- */ -struct dir_mode { - mode_t mode; - int dropbox; -}; - -static int setdirmode_ads_loop(struct dirent *de _U_, char *name, void *data, int flag, mode_t v_umask) +/* ---------------- */ +static int RF_setdirunixmode_ea(VFS_FUNC_ARGS_SETDIRUNIXMODE) { - - struct dir_mode *param = data; - int ret = 0; /* 0 ignore error, -1 */ - - if (dir_rx_set(param->mode)) { - if (stickydirmode(name, DIRBITS | param->mode, param->dropbox, v_umask) < 0) { - if (flag) { - return 0; - } - return ret; - } - } - if (ads_setfilmode(name, param->mode, NULL, v_umask) < 0) - return ret; - - if (!dir_rx_set(param->mode)) { - if (stickydirmode(name, DIRBITS | param->mode, param->dropbox, v_umask) < 0) { - if (flag) { - return 0; - } - return ret; - } - } return 0; } -static int RF_setdirmode_ads(VFS_FUNC_ARGS_SETDIRMODE) +static int RF_setfilmode_ea(VFS_FUNC_ARGS_SETFILEMODE) { - char *adouble = vol->ad_path(name, ADFLAGS_DIR ); - char ad_p[ MAXPATHLEN + 1]; - struct dir_mode param; - - param.mode = mode; - param.dropbox = vol->v_flags; - - strlcpy(ad_p,ad_dir(adouble), sizeof(ad_p)); - - if (dir_rx_set(mode)) { - /* .AppleDouble */ - if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, param.dropbox, vol->v_umask) < 0) - return -1; - } - - if (for_each_adouble("setdirmode_ads", ad_dir(ad_p), setdirmode_ads_loop, ¶m, vol_noadouble(vol), vol->v_umask)) - return -1; - - if (!dir_rx_set(mode)) { - if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, param.dropbox, vol->v_umask) < 0 ) - return -1; - } return 0; } -/* ------------------- */ -static int setdirowner_ads1_loop(struct dirent *de _U_, char *name, void *data, int flag _U_, mode_t v_umask _U_) +/* ---------------- */ +static int RF_setdirmode_ea(VFS_FUNC_ARGS_SETDIRMODE) { - 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 setdirowner_ads_loop(struct dirent *de _U_, char *name, void *data, int flag, mode_t v_umask _U_) +/* ---------------- */ +static int RF_setdirowner_ea(VFS_FUNC_ARGS_SETDIROWNER) { - struct perm *owner = data; - - if (for_each_adouble("setdirowner", name, setdirowner_ads1_loop, data, flag, 0) < 0) - return -1; - - 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; + return 0; } -static int RF_setdirowner_ads(VFS_FUNC_ARGS_SETDIROWNER) +static int RF_deletefile_ea(VFS_FUNC_ARGS_DELETEFILE) { - int noadouble = vol_noadouble(vol); - char adouble_p[ MAXPATHLEN + 1]; - struct stat st; - struct perm owner; - - owner.uid = uid; - owner.gid = gid; - - strlcpy(adouble_p, ad_dir(vol->ad_path(name, ADFLAGS_DIR )), sizeof(adouble_p)); - - if (for_each_adouble("setdirowner", ad_dir(adouble_p), setdirowner_ads_loop, &owner, noadouble, 0)) - 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 ) { - LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s", - uid, gid,fullpathname(".AppleDouble"), strerror(errno) ); - /* return ( -1 ); Sometimes this is okay */ - } return 0; } - -/* ------------------- */ -static int RF_deletefile_ads(VFS_FUNC_ARGS_DELETEFILE) +static int RF_copyfile_ea(VFS_FUNC_ARGS_COPYFILE) { - char *ad_p = ad_dir(vol->ad_path(file, ADFLAGS_HF )); - - return ads_delete_rf(ad_p); + return 0; } -/* --------------------------- */ -static int RF_renamefile_ads(VFS_FUNC_ARGS_RENAMEFILE) +/* ---------------- */ +static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE) { - char adsrc[ MAXPATHLEN + 1]; - int err = 0; - - strcpy( adsrc, ad_dir(vol->ad_path(src, 0 ))); - if (unix_rename( adsrc, 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, */ - return 0; - - /* We are here because : - * -there's no dest folder. - * -there's no .AppleDouble in the dest folder. - * if we use the struct adouble passed in parameter it will not - * 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); - if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) { - 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 ))) ) - err = 0; - else - err = errno; - } - else { /* it's something else, bail out */ - err = errno; - } - } - } - if (err) { - errno = err; - return -1; - } - return 0; + return 0; } +#if 0 /************************************************************************* * osx adouble format ************************************************************************/ @@ -724,7 +573,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,17 +608,18 @@ 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; } return 0; } +#endif /******************************************************************************************** * VFS chaining @@ -815,8 +665,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) @@ -844,8 +696,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, @@ -854,10 +708,10 @@ static struct vfs_ops vfs_master_funcs = { }; /* - * Primary adouble modules: default, osx, sfm + * Primary adouble modules: v2, ea */ -static struct vfs_ops netatalk_adouble = { +static struct vfs_ops netatalk_adouble_v2 = { /* vfs_validupath: */ validupath_adouble, /* vfs_chown: */ RF_chown_adouble, /* vfs_renamedir: */ RF_renamedir_adouble, @@ -868,35 +722,22 @@ static struct vfs_ops netatalk_adouble = { /* vfs_setdirowner: */ RF_setdirowner_adouble, /* vfs_deletefile: */ RF_deletefile_adouble, /* vfs_renamefile: */ RF_renamefile_adouble, + /* vfs_copyfile: */ RF_copyfile_adouble, NULL }; -static struct vfs_ops netatalk_adouble_osx = { - /* vfs_validupath: */ validupath_osx, - /* vfs_chown: */ RF_chown_adouble, - /* vfs_renamedir: */ RF_renamedir_osx, - /* vfs_deletecurdir: */ RF_deletecurdir_osx, - /* vfs_setfilmode: */ RF_setfilmode_adouble, - /* vfs_setdirmode: */ RF_setdirmode_osx, - /* vfs_setdirunixmode:*/ RF_setdirunixmode_osx, - /* vfs_setdirowner: */ RF_setdirowner_osx, - /* vfs_deletefile: */ RF_deletefile_adouble, - /* vfs_renamefile: */ RF_renamefile_osx, - NULL -}; - -/* samba sfm format. ad_path shouldn't be set her */ -static struct vfs_ops netatalk_adouble_sfm = { - /* vfs_validupath: */ validupath_adouble, - /* vfs_chown: */ RF_chown_ads, - /* vfs_renamedir: */ RF_renamedir_adouble, - /* vfs_deletecurdir: */ RF_deletecurdir_ads, - /* vfs_setfilmode: */ RF_setfilmode_ads, - /* vfs_setdirmode: */ RF_setdirmode_ads, - /* vfs_setdirunixmode:*/ RF_setdirunixmode_ads, - /* vfs_setdirowner: */ RF_setdirowner_ads, - /* vfs_deletefile: */ RF_deletefile_ads, - /* vfs_renamefile: */ RF_renamefile_ads, +static struct vfs_ops netatalk_adouble_ea = { + /* vfs_validupath: */ validupath_ea, + /* vfs_chown: */ RF_chown_ea, + /* vfs_renamedir: */ RF_renamedir_ea, + /* vfs_deletecurdir: */ RF_deletecurdir_ea, + /* vfs_setfilmode: */ RF_setfilmode_ea, + /* vfs_setdirmode: */ RF_setdirmode_ea, + /* vfs_setdirunixmode:*/ RF_setdirunixmode_ea, + /* vfs_setdirowner: */ RF_setdirowner_ea, + /* vfs_deletefile: */ RF_deletefile_ea, + /* vfs_renamefile: */ RF_renamefile_ea, + /* vfs_copyfile: */ RF_copyfile_ea, NULL }; @@ -916,8 +757,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, @@ -937,8 +780,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, @@ -950,7 +795,7 @@ static struct vfs_ops netatalk_ea_sys = { * Tertiary VFS modules for ACLs */ -#ifdef HAVE_NFSv4_ACLS +#ifdef HAVE_SOLARIS_ACLS static struct vfs_ops netatalk_solaris_acl_adouble = { /* validupath: */ NULL, /* rf_chown: */ NULL, @@ -969,37 +814,56 @@ static struct vfs_ops netatalk_solaris_acl_adouble = { }; #endif +#ifdef HAVE_POSIX_ACLS +static struct vfs_ops netatalk_posix_acl_adouble = { + /* validupath: */ NULL, + /* rf_chown: */ NULL, + /* rf_renamedir: */ NULL, + /* rf_deletecurdir: */ NULL, + /* rf_setfilmode: */ NULL, + /* rf_setdirmode: */ NULL, + /* rf_setdirunixmode: */ NULL, + /* rf_setdirowner: */ NULL, + /* rf_deletefile: */ NULL, + /* rf_renamefile: */ NULL, + /* vfs_copyfile */ NULL, + /* rf_acl: */ RF_posix_acl, + /* rf_remove_acl */ RF_posix_remove_acl, + NULL +}; +#endif + /* ---------------- */ void initvol_vfs(struct vol *vol) { vol->vfs = &vfs_master_funcs; /* Default adouble stuff */ - if (vol->v_adouble == AD_VERSION2_OSX) { - vol->vfs_modules[0] = &netatalk_adouble_osx; - vol->ad_path = ad_path_osx; - } - else if (vol->v_adouble == AD_VERSION1_SFM) { - vol->vfs_modules[0] = &netatalk_adouble_sfm; - vol->ad_path = ad_path_sfm; - } - else { - vol->vfs_modules[0] = &netatalk_adouble; + if (vol->v_adouble == AD_VERSION2) { + vol->vfs_modules[0] = &netatalk_adouble_v2; vol->ad_path = ad_path; + } else { + vol->vfs_modules[0] = &netatalk_adouble_ea; + vol->ad_path = ad_path_ea; } /* Extended Attributes */ if (vol->v_vfs_ea == AFPVOL_EA_SYS) { - LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with native EAs."); + LOG(log_debug, logtype_afpd, "initvol_vfs: enabling EA support with native EAs"); vol->vfs_modules[1] = &netatalk_ea_sys; - } else { - /* default: AFPVOL_EA_AD */ - LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with adouble files."); + } 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 */ -#ifdef HAVE_NFSv4_ACLS +#ifdef HAVE_SOLARIS_ACLS vol->vfs_modules[2] = &netatalk_solaris_acl_adouble; #endif +#ifdef HAVE_POSIX_ACLS + vol->vfs_modules[2] = &netatalk_posix_acl_adouble; +#endif + }