Fix replicas with empty path, replica server only or replica path only is enough.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 8 Dec 2013 18:23:11 +0000 (19:23 +0100)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 23 Feb 2014 13:16:20 +0000 (14:16 +0100)
src/VfsNs.cpp

index 8e50fe0..2e4b8b5 100644 (file)
@@ -1880,29 +1880,31 @@ Replica VfsCatalog::replicaDeserialize(const std::string& attr1, const std::stri
 
 void VfsCatalog::rfnCreate(const std::string& path, const std::string& rfn) throw(DmException) {
   Url url;
-  std::string curdir, file, lpath;
+  std::string curdir, file, lpath, sep;
   std::vector<std::string> components;
   struct stat fstat;
   FILE *f;
 
-  // replicas root directory
-  curdir = this->prefix_ + "/" + VFS_REPLICAS_TREE;
-  if (mkdir(curdir.c_str(), 0755) == 0)
-    debug("created replicas root directory '%s'", curdir.c_str());
-
-  // directory for each server (conflicts with proper names are OK and unlikely)
+  // directory for each server, add path
   url = Url(rfn);
-  if (!url.domain.empty()) {
-    curdir += "/" + url.domain;
-    if (mkdir(curdir.c_str(), 0755) == 0)
-      debug("created replicas server directory '%s' for '%s'", curdir.c_str(), url.domain.c_str());
-  }
+  if (!url.domain.empty() && !url.path.empty()) sep = "/";
+  else sep = "";
+  curdir = url.domain + sep + url.path;
+
+  if (curdir.empty())
+    vfsThrow(EINVAL, "empty replica file name");
+
+  // replicas root directory
+  lpath = this->prefix_ + "/" + VFS_REPLICAS_TREE;
+  if (mkdir(lpath.c_str(), 0755) == 0)
+    debug("created replicas root directory '%s'", lpath.c_str());
 
   // RFN tree
-  components = Url::splitPath(url.path);
+  components = Url::splitPath(curdir);
   file = components.back();
   components.pop_back();
   if (components.size() >= 1 && components[0] != "/") components[0] = "/" + components[0];
+  curdir = lpath;
   for (size_t i = 0; i < components.size(); i++) {
     // the first component always '/', let's use it as separator
     if (i < 2) curdir += components[i];
@@ -2015,8 +2017,6 @@ void VfsCatalog::rfnDelete(const std::string& path, const std::string& rfn) thro
 ///
 /// test emptiness of directory
 ///
-/// On errors, just log the problem and consider the directory non-empty.
-///
 bool VfsCatalog::isEmptyDir(const std::string& lpath) throw (DmException) {
   DIR *dir;
   struct dirent entry, *rentry;