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

index d85255f..fa903ca 100644 (file)
@@ -279,6 +279,16 @@ ExtendedStat VfsCatalog::extendedStat(const std::string& path, bool follow) thro
 
   vfsUpdateStat(meta, xattrs);
   meta.stat.st_size = xattrs.getU64(VFS_XATTR "size", 0);
+  if (meta.hasField("checksum.md5")) {
+    meta.csumtype = "MD";
+    meta.csumvalue = meta.getString("checksum.md5");
+  } else if (meta.hasField("checksum.adler32")) {
+    meta.csumtype = "AD";
+    meta.csumvalue = meta.getString("checksum.adler32");
+  } else if (meta.hasField("checksum.crc32")) {
+    meta.csumtype = "CS";
+    meta.csumvalue = meta.getString("checksum.crc32");
+  }
 
   meta["pool"] = std::string("vfs");
 
@@ -680,7 +690,26 @@ void VfsCatalog::setChecksum(const std::string& path,
                                       const std::string& csumtype,
                                       const std::string& csumvalue) throw (DmException)
 {
-  throw DmException(EACCES, "Write mode not supported");;
+  ExtendedStat meta;
+  std::string attrName;
+
+  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 checksum of '%s'", clientName.c_str(), path.c_str());
+  }
+
+  if (csumtype == "MD") attrName = "checksum.md5";
+  else if (csumtype == "AD") attrName = "checksum.adler32";
+  else if (csumtype == "CD") attrName = "checksum.crc32";
+  else
+    vfsThrow(EINVAL, "bad checksum type '%s' (MD, AD or CS required)", csumtype.c_str());
+
+  vfsSetXattr(path, getLocalPath(path), attrName, csumvalue, 0);
 }