X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=libatalk%2Fvfs%2Fvfs.c;h=0d1961cfa92c393065c8ab0128e72031fd57e0d0;hp=0eaacfaee8af8fc5f6babb34709d2e7f7c8022f9;hb=c72d10d6f92fe81d040ab983768d7fdccea7fb2e;hpb=85d268c10175d1e8050188a3a4797b40519a285e diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 0eaacfae..0d1961cf 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -49,11 +49,11 @@ struct perm { gid_t gid; }; -typedef int (*rf_loop)(struct dirent *, char *, void *, int , mode_t ); +typedef int (*rf_loop)(const struct vol *, struct dirent *, char *, void *, int); /* ----------------------------- */ static int -for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int flag, mode_t v_umask) +for_each_adouble(const char *from, const char *name, rf_loop fn, const struct vol *vol, void *data, int flag) { char buf[ MAXPATHLEN + 1]; char *m; @@ -79,7 +79,7 @@ for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int } strlcat(buf, de->d_name, sizeof(buf)); - if (fn && (ret = fn(de, buf, data, flag, v_umask))) { + if (fn && (ret = fn(vol, de, buf, data, flag))) { closedir(dp); return ret; } @@ -89,26 +89,21 @@ for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int return ret; } -/******************************************************************************* - * classic adouble format - *******************************************************************************/ - static int netatalk_name(const char *name) { - return strcasecmp(name,".AppleDouble") && - strcasecmp(name,".AppleDB") && - strcasecmp(name,".AppleDesktop"); + return strcmp(name,".AppleDB") && strcmp(name,".AppleDesktop"); } +/******************************************************************************* + * classic adouble format + *******************************************************************************/ + static int validupath_adouble(VFS_FUNC_ARGS_VALIDUPATH) { if (name[0] != '.') return 1; - if (!(vol->v_flags & AFPVOL_USEDOTS)) - return 0; - - return netatalk_name(name) && strcasecmp(name,".Parent"); + return netatalk_name(name) && strcmp(name,".AppleDouble") && strcasecmp(name,".Parent"); } /* ----------------- */ @@ -132,7 +127,7 @@ static int RF_renamedir_adouble(VFS_FUNC_ARGS_RENAMEDIR) } /* ----------------- */ -static int deletecurdir_adouble_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask) +static int deletecurdir_adouble_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) { struct stat st; int err; @@ -140,7 +135,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))) @@ -155,56 +150,63 @@ static int RF_deletecurdir_adouble(VFS_FUNC_ARGS_DELETECURDIR) /* delete stray .AppleDouble files. this happens to get .Parent files as well. */ - if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, NULL, 1, vol->v_umask))) + if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, vol, NULL, 1))) return err; return netatalk_rmdir(-1, ".AppleDouble" ); } /* ----------------- */ -static int adouble_setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) +static int adouble_setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st) { - return setfilmode(name, ad_hf_mode(mode), st, v_umask); + return setfilmode(vol, name, ad_hf_mode(mode), st); } static int RF_setfilmode_adouble(VFS_FUNC_ARGS_SETFILEMODE) { - return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask); + return adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_HF ), mode, st); } /* ----------------- */ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE) { const char *adouble = vol->ad_path(name, ADFLAGS_DIR ); - int dropbox = vol->v_flags; if (dir_rx_set(mode)) { - if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0 ) + if (ochmod(ad_dir(adouble), + (DIRBITS | mode) & ~vol->v_umask, + st, + vol_syml_opt(vol) | vol_chmod_opt(vol) + ) < 0) return -1; } - if (adouble_setfilmode(vol->ad_path(name, ADFLAGS_DIR ), mode, st, vol->v_umask) < 0) + if (adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_DIR ), mode, st) < 0) return -1; if (!dir_rx_set(mode)) { - if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0 ) + if (ochmod(ad_dir(adouble), + (DIRBITS | mode) & ~vol->v_umask, + st, + vol_syml_opt(vol) | vol_chmod_opt(vol) + ) < 0) return -1 ; } return 0; } /* ----------------- */ -static int setdirmode_adouble_loop(struct dirent *de _U_, char *name, void *data, int flag, mode_t v_umask) +static int setdirmode_adouble_loop(const struct vol *vol, struct dirent *de _U_, char *name, void *data, int flag) { mode_t hf_mode = *(mode_t *)data; struct stat st; - if ( stat( name, &st ) < 0 ) { + if (ostat(name, &st, vol_syml_opt(vol)) < 0 ) { if (flag) return 0; LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s", name, strerror(errno) ); } else if (!S_ISDIR(st.st_mode)) { - if (setfilmode(name, hf_mode , &st, v_umask) < 0) { + if (setfilmode(vol, name, hf_mode, &st) < 0) { /* FIXME what do we do then? */ } } @@ -213,67 +215,38 @@ static int setdirmode_adouble_loop(struct dirent *de _U_, char *name, void *data static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE) { - int dropbox = vol->v_flags; mode_t hf_mode = ad_hf_mode(mode); 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) + if (ochmod(ad_dir(adouble), + (DIRBITS | mode) & ~vol->v_umask, + st, + vol_syml_opt(vol) | vol_chmod_opt(vol) + ) < 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, vol, &hf_mode, 0)) return -1; if (!dir_rx_set(mode)) { - if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox, vol->v_umask) < 0) + if (ochmod(ad_dir(adouble), + (DIRBITS | mode) & ~vol->v_umask, + st, + vol_syml_opt(vol) | vol_chmod_opt(vol) + ) < 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; } @@ -298,7 +271,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) if (errno == ENOENT) { struct adouble ad; - if (lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ + if (ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */ return 0; /* We are here because : @@ -308,8 +281,8 @@ 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); - if (ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666) == 0) { + 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 )) ) err = 0; @@ -375,7 +348,10 @@ static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE) EC_ZERO(bcatcstr(d, name)); } - EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666)); + /* ignore errors */ + if (copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666) != 0) + if (errno != ENOENT) + EC_FAIL; EC_CLEANUP: bdestroy(s); @@ -388,31 +364,24 @@ EC_CLEANUP: EC_EXIT; } -#ifdef HAVE_SOLARIS_ACLS +#ifdef HAVE_NFSV4_ACLS static int RF_solaris_acl(VFS_FUNC_ARGS_ACL) { static char buf[ MAXPATHLEN + 1]; struct stat st; int len; - if ((stat(path, &st)) != 0) - return -1; - if (S_ISDIR(st.st_mode)) { - len = snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path); - if (len < 0 || len >= MAXPATHLEN) - 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->ad_path(path, ADFLAGS_DIR), cmd, count, aces)) != 0) - return -1; - } else - /* set ACL on ressource fork */ - if ((acl(vol->ad_path(path, ADFLAGS_HF), cmd, count, aces)) != 0) - return -1; - - return 0; + if ((stat(path, &st)) != 0) { + if (errno == ENOENT) + return AFP_OK; + return AFPERR_MISC; + } + if (!S_ISDIR(st.st_mode)) { + /* set ACL on ressource fork */ + if ((acl(vol->ad_path(path, ADFLAGS_HF), cmd, count, aces)) != 0) + return AFPERR_MISC; + } + return AFP_OK; } static int RF_solaris_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) @@ -421,20 +390,15 @@ static int RF_solaris_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) static char buf[ MAXPATHLEN + 1]; int len; - if (dir) { - len = snprintf(buf, MAXPATHLEN, "%s/.AppleDouble",path); - if (len < 0 || len >= MAXPATHLEN) - return AFPERR_MISC; - /* remove ACL from .AppleDouble/.Parent first */ - if ((ret = remove_acl_vfs(vol->ad_path(path, ADFLAGS_DIR))) != AFP_OK) - return ret; - /* now remove from .AppleDouble dir */ - if ((ret = remove_acl_vfs(buf)) != AFP_OK) - return ret; - } else - /* remove ACL from ressource fork */ - if ((ret = remove_acl_vfs(vol->ad_path(path, ADFLAGS_HF))) != AFP_OK) - return ret; + if (dir) + return AFP_OK; + + /* remove ACL from ressource fork */ + if ((ret = remove_acl_vfs(vol->ad_path(path, ADFLAGS_HF))) != AFP_OK) { + if (errno == ENOENT) + return AFP_OK; + return ret; + } return AFP_OK; } @@ -444,52 +408,35 @@ static int RF_solaris_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) static int RF_posix_acl(VFS_FUNC_ARGS_ACL) { EC_INIT; - static char buf[ MAXPATHLEN + 1]; struct stat st; - int len; - 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 (stat(path, &st) == -1) + EC_FAIL; - 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 { + if (!S_ISDIR(st.st_mode)) { /* set ACL on ressource fork */ - EC_ZERO_LOG(acl_set_file(vol->ad_path(path, ADFLAGS_HF), type, acl)); + EC_ZERO_ERR( acl_set_file(vol->ad_path(path, ADFLAGS_HF), type, acl), AFPERR_MISC ); } EC_CLEANUP: - if (ret != 0) - return AFPERR_MISC; - return AFP_OK; + if (errno == ENOENT) + EC_STATUS(AFP_OK); + EC_EXIT; } static int RF_posix_remove_acl(VFS_FUNC_ARGS_REMOVE_ACL) { EC_INIT; - static char buf[ MAXPATHLEN + 1]; - int len; - 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); + if (dir) + EC_EXIT_STATUS(AFP_OK); - /* 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); - } + /* remove ACL from ressource fork */ + EC_ZERO_ERR( remove_acl_vfs(vol->ad_path(path, ADFLAGS_HF)), AFPERR_MISC ); EC_CLEANUP: + if (errno == ENOENT) + EC_STATUS(AFP_OK); EC_EXIT; } #endif @@ -499,12 +446,22 @@ EC_CLEANUP: ************************************************************************/ static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH) { - return 1; -} + if (name[0] != '.') + return 1; + +#ifndef HAVE_EAFD + if (name[1] == '_') + return ad_valid_header_osx(name); +#endif + return netatalk_name(name); +} /* ----------------- */ 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 +471,149 @@ 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(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) +{ + if (de->d_name[0] != '.' || de->d_name[0] == '_') + return 1; + + return 0; +} + +static int deletecurdir_ea_osx_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) +{ + int ret; + struct stat sb; + + if (strncmp(name, "._", strlen("._")) == 0) { + if (lstat(name, &sb) != 0) + return -1; + if (S_ISREG(sb.st_mode)) + 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 */ + if ((err = for_each_adouble("deletecurdir_ea_osx", ".", + deletecurdir_ea_osx_loop, + vol, NULL, 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, vol->ad_path(name, ADFLAGS_HF ), mode, st); +#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) { +#ifdef HAVE_EAFD + /* the EA VFS module does this all for us */ return 0; -} - -/* ---------------- */ -static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE) -{ - return 0; -} - -#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] != '.'); -} - -/* ---------------- */ -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)); -} - -/* ---------------- */ -static int RF_deletecurdir_osx(VFS_FUNC_ARGS_DELETECURDIR) -{ - return netatalk_unlink( vol->ad_path(".",0) ); -} +#endif -/* ---------------- */ -static int RF_setdirunixmode_osx(VFS_FUNC_ARGS_SETDIRUNIXMODE) -{ - return adouble_setfilmode(vol->ad_path(name, ADFLAGS_DIR ), mode, st, vol->v_umask); -} + 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; -/* ---------------- */ -static int RF_setdirmode_osx(VFS_FUNC_ARGS_SETDIRMODE) -{ - return 0; -} + /* 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)); + + if (copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666) != 0) { + switch (errno) { + case ENOENT: + break; + default: + LOG(log_error, logtype_afpd, "[VFS] copyfile(\"%s\" -> \"%s\"): %s", + cfrombstr(s), cfrombstr(d), strerror(errno)); + EC_FAIL; + + } + } -/* ---------------- */ -static int RF_setdirowner_osx(VFS_FUNC_ARGS_SETDIROWNER) -{ - return 0; +EC_CLEANUP: + bdestroy(s); + bdestroy(d); + free(dup1); + free(dup2); + free(dup3); + free(dup4); + EC_EXIT; } /* ---------------- */ -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; @@ -612,14 +623,15 @@ static int RF_renamefile_osx(VFS_FUNC_ARGS_RENAMEFILE) struct stat st; err = errno; - if (errno == ENOENT && lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ + if (errno == ENOENT && ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */ return 0; errno = err; return -1; } return 0; -} #endif + return 0; +} /******************************************************************************************** * VFS chaining @@ -795,7 +807,7 @@ static struct vfs_ops netatalk_ea_sys = { * Tertiary VFS modules for ACLs */ -#ifdef HAVE_SOLARIS_ACLS +#ifdef HAVE_NFSV4_ACLS static struct vfs_ops netatalk_solaris_acl_adouble = { /* validupath: */ NULL, /* rf_chown: */ NULL, @@ -844,7 +856,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 */ @@ -859,7 +875,7 @@ void initvol_vfs(struct vol *vol) } /* ACLs */ -#ifdef HAVE_SOLARIS_ACLS +#ifdef HAVE_NFSV4_ACLS vol->vfs_modules[2] = &netatalk_solaris_acl_adouble; #endif #ifdef HAVE_POSIX_ACLS