+static const std::string rfn2path(const std::string &rfn) {
+ Url url;
+ std::string sep, path;
+
+ // directory for each server, add path
+ url = Url(rfn);
+ if (!url.domain.empty() && !url.path.empty() && url.path[0] != '/') sep = "/";
+ else sep = "";
+
+ path = url.domain + sep + url.path;
+
+ // 1) add '/' to start, if needed
+ // 2) RFN could be a directory ==> entry is just the file
+ if (!path.empty()) {
+ if (path[0] != '/') path = "/" + path;
+ if (path[path.size() - 1] == '/') path.resize(path.size() - 1);
+ }
+
+ return path;
+}
+
+
+
VfsCatalog::VfsCatalog(const std::string& host, const std::string& prefix, const std::string &allow, const std::string &deny, const std::string allowWrite, const std::string denyWrite) throw (DmException): Catalog(),
hostName_(host), umask_(022)
{
void VfsCatalog::rfnCreate(const std::string& path, const std::string& rfn) throw(DmException) {
- Url url;
std::string curdir, file, lpath, sep;
std::vector<std::string> components;
struct stat fstat;
FILE *f;
- // directory for each server, add path
- url = Url(rfn);
- if (!url.domain.empty() && !url.path.empty()) sep = "/";
- else sep = "";
- curdir = url.domain + sep + url.path;
-
+ curdir = rfn2path(rfn);
if (curdir.empty())
vfsThrow(EINVAL, "empty replica file name");
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
std::vector<std::string> components;
bool wasNonEmpty;
- // local path to replica entry
- url = Url(rfn);
- lpath = this->prefix_ + "/" + VFS_REPLICAS_TREE;
- if (!url.domain.empty())
- lpath += "/" + url.domain;
- if (!url.path.empty() && url.path[0] != '/') lpath += "/";
- lpath += url.path;
- // RFN could be a directory ==> entry is just the file
- if (lpath[lpath.size() - 1] == '/')
- lpath.resize(lpath.size() - 1);
+ curdir = rfn2path(rfn);
+ if (curdir.empty()) {
+ log(LOG_WARNING, "empty replica file name, deleting replica entry from '%s' ignored", path.c_str());
+ return;
+ }
+ lpath = this->prefix_ + "/" + VFS_REPLICAS_TREE + curdir;
// check if we can remove replica information
if ((f = fopen(lpath.c_str(), "r")) == NULL) {
// cleanup directories
try {
lpath = this->prefix_ + "/" + VFS_REPLICAS_TREE;
- curdir = "";
- if (!url.domain.empty())
- curdir += "/" + url.domain;
- if (!url.path.empty() && url.path[0] != '/') curdir += "/";
- components = Url::splitPath(curdir + url.path);
+ components = Url::splitPath(curdir);
wasNonEmpty = false;
- do {
+ while (!wasNonEmpty && components.size() > 2) {
components.pop_back();
lpath = this->prefix_ + "/" + VFS_REPLICAS_TREE + Url::joinPath(components);
debug("deleted replica entry subdirectory '%s'", lpath.c_str());
} else
wasNonEmpty = true;
- } while (!wasNonEmpty && components.size() > 2);
+ }
} catch (DmException e) {
// not critical, but log a warning
#ifndef DEBUG