From: František Dvořák Date: Thu, 17 Oct 2013 19:57:57 +0000 (+0200) Subject: Implementation of setComment() using xattrs, new helper functions vfsGetXattr(),... X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=7d127a572ce407674a2d6aa1a5013ec55fa46ea2;p=dmlite-plugins-vfs.git Implementation of setComment() using xattrs, new helper functions vfsGetXattr(), vfsRemoveXattr(). --- diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index 6b65abc..d85255f 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -711,16 +712,41 @@ void VfsCatalog::utime(const std::string& path, const struct utimbuf* buf) throw std::string VfsCatalog::getComment(const std::string& path) throw (DmException) { - throw DmException(DMLITE_SYSERR(ENOSYS), - "VfsCatalog does not implement comments"); + ExtendedStat meta; + + if (vfsCheckPermissions(path, S_IREAD)) + vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str()); + + meta = this->vfsExtendedStat(path); + + if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0) + vfsThrow(EACCES, "not enough permissions for '%s' to get comment on '%s'", clientName.c_str(), path.c_str()); + + return vfsGetXattr(path, getLocalPath(path), VFS_XATTR "comment", 0); } void VfsCatalog::setComment(const std::string& path, const std::string& comment) throw (DmException) { - throw DmException(DMLITE_SYSERR(ENOSYS), - "VfsCatalog does not implement comments"); + ExtendedStat meta; + std::string lpath; + + if (vfsCheckPermissions(path, S_IWRITE)) + vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str()); + + meta = this->vfsExtendedStat(path); + + if (getUid(this->secCtx_) != meta.stat.st_uid && + checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0) { + vfsThrow(EACCES, "not enough permissions for '%s' to set comment on '%s'", clientName.c_str(), path.c_str()); + } + + lpath = getLocalPath(path); + if (comment.empty()) + vfsRemoveXattr(path, lpath, VFS_XATTR "comment", 0); + else + vfsSetXattr(path, lpath, VFS_XATTR "comment", comment, 0); } @@ -1215,6 +1241,20 @@ Extensible VfsCatalog::vfsGetXattrs(const std::string& path, const std::string& +std::string VfsCatalog::vfsGetXattr(const std::string& path, const std::string &lpath, const std::string key, int flags) { + int len; + std::string attrValue; + + len = sizeof this->xattrValue; + wrapCall(attr_get(lpath.c_str(), key.c_str(), this->xattrValue, &len, flags), "could not get extended attribute '%s' on '%s'", key.c_str(), path.c_str()); + debug("got '%s' = '%.*s'", key.c_str(), len, this->xattrValue); + + attrValue.assign(this->xattrValue, len); + return attrValue; +} + + + void VfsCatalog::vfsSetXattr(const std::string& path, const std::string& lpath, const std::string key, const std::string value, int flags) { switch (flags & (ATTR_REPLACE | ATTR_CREATE)) { case ATTR_REPLACE: @@ -1234,6 +1274,18 @@ void VfsCatalog::vfsSetXattr(const std::string& path, const std::string& lpath, +void VfsCatalog::vfsRemoveXattr(const std::string& path, const std::string& lpath, const std::string key, int flags) { + if (attr_remove(lpath.c_str(), key.c_str(), flags) == -1) { + if (errno != ENOATTR) + vfsThrowErrno("could not remove extended attribute '%s' on '%s'", key.c_str(), path.c_str()); + debug("'%s' not exists on '%s'", key.c_str(), lpath.c_str()); + } else { + debug("'%s' removed from '%s'", key.c_str(), lpath.c_str()); + } +} + + + regex_t *VfsCatalog::vfsCompileRegex(const char *name, const std::string value) throw (DmException) { regex_t regex; int ret; diff --git a/src/VfsNs.h b/src/VfsNs.h index 33c1e4f..dc31577 100644 --- a/src/VfsNs.h +++ b/src/VfsNs.h @@ -111,7 +111,9 @@ namespace dmlite { ExtendedStat vfsExtendedStat(const std::string& path, bool follow = true, bool perms = true) throw (DmException); PrivateDir* vfsOpenDir(const std::string& lpath, const std::string& path) throw (DmException); Extensible vfsGetXattrs(const std::string& path, const std::string& lpath, bool follow, int amount) throw (DmException); + std::string vfsGetXattr(const std::string& path, const std::string &lpath, const std::string key, int flags); void vfsSetXattr(const std::string& path, const std::string& lpath, const std::string key, const std::string value, int flags); + void vfsRemoveXattr(const std::string& path, const std::string& lpath, const std::string key, int flags); regex_t *vfsCompileRegex(const char *name, const std::string value) throw (DmException); bool vfsEvalRegex(regex_t *allowRegex, regex_t *denyRegex, const char *subj); int vfsCheckPermissions(const std::string& path, mode_t mode);