Implementation of setComment() using xattrs, new helper functions vfsGetXattr(),...
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Tue, 15 Oct 2013 13:43:30 +0000 (15:43 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 17 Oct 2013 19:57:57 +0000 (21:57 +0200)
src/VfsNs.cpp
src/VfsNs.h

index a6d52ba..38cb2dc 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>
@@ -704,16 +705,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);
 }
 
 
@@ -1158,6 +1184,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:
@@ -1177,6 +1217,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 d8fa1fb..a409077 100644 (file)
@@ -105,7 +105,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);