CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
resolveSymbolicLinks.cc
Go to the documentation of this file.
3 
4 #include "boost/filesystem/path.hpp"
5 #include "boost/filesystem/operations.hpp"
6 
7 #include <vector>
8 
9 namespace edm {
10 
11  namespace {
12  namespace bf = boost::filesystem;
13  bool resolveOneSymbolicLink(std::string& fullPath) {
14  if(fullPath.empty()) return false;
15  if(fullPath[0] != '/') return false;
16  std::string pathToResolve;
17  std::vector<std::string> pathElements = edm::tokenize(fullPath, "/");
18  for(auto const& path : pathElements) {
19  if(!path.empty()) {
20  pathToResolve += "/";
21  pathToResolve += path;
22  bf::path symLinkPath(pathToResolve);
23  if (bf::is_symlink(bf::symlink_status(symLinkPath))) {
24  bf::path resolved = bf::read_symlink(symLinkPath);
25  // This check is needed because in weird filesystems
26  // (e.g. AFS), the resolved link may not be accessible.
27  if(!bf::exists(resolved)) {
28  continue;
29  }
30  std::string resolvedPath = resolved.string();
31  auto begin = fullPath.begin();
32  auto end = begin + pathToResolve.size();
33  // resolvedPath may or may not contain the leading "/".
34  if(resolvedPath[0] == '/') {
35  fullPath.replace(begin, end, resolvedPath);
36  } else {
37  fullPath.replace(begin + 1, end, resolvedPath);
38  }
39  return true;
40  }
41  }
42  }
43  return false;
44  }
45  }
46 
47  // Resolves symlinks recursively from anywhere in fullPath.
49  bool found = resolveOneSymbolicLink(fullPath);
50  if(found) {
51  resolveSymbolicLinks(fullPath);
52  }
53  }
54 }
#define end
Definition: vmac.h:37
std::vector< std::string > tokenize(std::string const &input, std::string const &separator)
breaks the input string into tokens, delimited by the separator
Definition: Parse.cc:57
#define begin
Definition: vmac.h:30
void resolveSymbolicLinks(std::string &fullPath)