#include <sys/stat.h>
#include <sys/types.h>
#include <attr/attributes.h>
+#include <attr/xattr.h>
#include <utime.h>
#include <cstdio>
#include <cstdlib>
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);
}
+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:
+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;
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);