Implementation of setComment() using xattrs, new helper functions vfsGetXattr(),...
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 17 Oct 2013 19:57:57 +0000 (21:57 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 23 Feb 2014 13:16:18 +0000 (14:16 +0100)
src/VfsNs.cpp
src/VfsNs.h

index 6b65abc..d85255f 100644 (file)
@@ -4,6 +4,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <attr/attributes.h>
+#include <attr/xattr.h>
 #include <utime.h>
 #include <cstdio>
 #include <cstdlib>
@@ -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;
index 33c1e4f..dc31577 100644 (file)
@@ -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);