diff --git a/src/syncevo/ConfigTree.h b/src/syncevo/ConfigTree.h index 4cc51f6a..fc9e7cb4 100644 --- a/src/syncevo/ConfigTree.h +++ b/src/syncevo/ConfigTree.h @@ -81,9 +81,6 @@ class ConfigTree { */ virtual void remove(const std::string &path) = 0; - /** a string identifying the root of the configuration - exact meaning varies */ - virtual std::string getRootPath() const = 0; - /** * Selects which node attached to a path name is to be used. * This is similar in concept to multiple data forks in a file. diff --git a/src/syncevo/FileConfigTree.cpp b/src/syncevo/FileConfigTree.cpp index fd46cbad..27871bad 100644 --- a/src/syncevo/FileConfigTree.cpp +++ b/src/syncevo/FileConfigTree.cpp @@ -38,31 +38,18 @@ using namespace std; SE_BEGIN_CXX FileConfigTree::FileConfigTree(const string &root, - const string &peer, SyncConfig::Layout layout) : m_root(root), - m_peer(peer), m_layout(layout), m_readonly(false) { } -string FileConfigTree::getRootPath() const -{ - return normalizePath(m_root + "/" + m_peer); -} - void FileConfigTree::flush() { BOOST_FOREACH(const NodeCache_t::value_type &node, m_nodes) { node.second->flush(); } - if (m_layout == SyncConfig::SHARED_LAYOUT) { - // ensure that "peers" directory exists for new-style configs, - // not created by flushing nodes for pure context configs but - // needed to detect new-syle configs - mkdir_p(getRootPath() + "/peers"); - } } void FileConfigTree::reload() diff --git a/src/syncevo/FileConfigTree.h b/src/syncevo/FileConfigTree.h index 7c6351cd..fa55215f 100644 --- a/src/syncevo/FileConfigTree.h +++ b/src/syncevo/FileConfigTree.h @@ -40,21 +40,18 @@ class FileConfigTree : public ConfigTree { /** * @param root absolute filesystem path for * .syncj4/evolution or .config/syncevolution - * @param peer the relative path to the peer configuration * @param layout determines file names to be used; - * HTTP_SERVER_LAYOUT and SHARED_LAYOUT are the same except - * that SHARED_LAYOUT creates the "peers" directory during - * flushing + * HTTP_SERVER_LAYOUT and SHARED_LAYOUT are the same, + * whereas SYNC4J_LAYOUT activates some backward-compatibility code */ FileConfigTree(const std::string &root, - const std::string &peer, SyncConfig::Layout layout); void setReadOnly(bool readonly) { m_readonly = readonly; } bool getReadOnly() const { return m_readonly; } + std::string getRoot() const { return m_root; } /* ConfigTree API */ - virtual std::string getRootPath() const; virtual void flush(); virtual void reload(); virtual void remove(const std::string &path); @@ -75,7 +72,6 @@ class FileConfigTree : public ConfigTree { private: const std::string m_root; - const std::string m_peer; SyncConfig::Layout m_layout; bool m_readonly; diff --git a/src/syncevo/SingleFileConfigTree.cpp b/src/syncevo/SingleFileConfigTree.cpp index 4cc4232a..df563922 100644 --- a/src/syncevo/SingleFileConfigTree.cpp +++ b/src/syncevo/SingleFileConfigTree.cpp @@ -52,7 +52,7 @@ boost::shared_ptr SingleFileConfigTree::open(const string &filename) return entry; } - string name = getRootPath() + " - " + normalized; + string name = m_data->getName() + " - " + normalized; boost::shared_ptr data; BOOST_FOREACH(const FileContent_t::value_type &file, m_content) { diff --git a/src/syncevo/SingleFileConfigTree.h b/src/syncevo/SingleFileConfigTree.h index 601a4c43..ca7d4d2a 100644 --- a/src/syncevo/SingleFileConfigTree.h +++ b/src/syncevo/SingleFileConfigTree.h @@ -62,7 +62,6 @@ class SingleFileConfigTree : public ConfigTree { boost::shared_ptr open(const std::string &filename); /* ConfigTree API */ - virtual std::string getRootPath() const { return m_data->getName(); } virtual void flush(); virtual void reload(); virtual void remove(const std::string &path); diff --git a/src/syncevo/SyncConfig.cpp b/src/syncevo/SyncConfig.cpp index fe38ad08..c5c5a81e 100644 --- a/src/syncevo/SyncConfig.cpp +++ b/src/syncevo/SyncConfig.cpp @@ -330,6 +330,7 @@ SyncConfig::SyncConfig() : void SyncConfig::makeVolatile() { m_tree.reset(new VolatileConfigTree()); + m_fileTree.reset(); m_peerNode.reset(new VolatileConfigNode()); m_hiddenPeerNode = m_peerNode; m_globalNode = m_peerNode; @@ -381,6 +382,7 @@ SyncConfig::SyncConfig(const string &peer, if (!access((path + "/spds/syncml/config.txt").c_str(), F_OK)) { m_layout = SYNC4J_LAYOUT; } else { + m_layout = SHARED_LAYOUT; root = getNewRoot(); path = root + "/" + m_peerPath; if (!access((path + "/config.ini").c_str(), F_OK) && @@ -396,9 +398,8 @@ SyncConfig::SyncConfig(const string &peer, } } } - m_tree.reset(new FileConfigTree(root, - m_peerPath.empty() ? m_contextPath : m_peerPath, - m_layout)); + m_fileTree.reset(new FileConfigTree(root, m_layout)); + m_tree = m_fileTree; } string path; @@ -656,13 +657,16 @@ void SyncConfig::migrate(const std::string &config) string SyncConfig::getRootPath() const { - return m_tree->getRootPath(); + return m_fileTree ? + normalizePath(m_fileTree->getRoot() + "/" + + ((m_layout == SYNC4J_LAYOUT || hasPeerProperties()) ? m_peerPath : m_contextPath)) : + ""; } void SyncConfig::addPeers(const string &root, const std::string &configname, SyncConfig::ConfigList &res) { - FileConfigTree tree(root, "", SyncConfig::HTTP_SERVER_LAYOUT); + FileConfigTree tree(root, SyncConfig::HTTP_SERVER_LAYOUT); list servers = tree.getChildren(""); BOOST_FOREACH(const string &server, servers) { // sanity check: only list server directories which actually @@ -930,8 +934,11 @@ list SyncConfig::getPeers() const list res; if (!hasPeerProperties()) { - FileConfigTree tree(getRootPath(), "", SHARED_LAYOUT); - res = tree.getChildren("peers"); + std::string rootPath = getRootPath(); + if (!rootPath.empty()) { + FileConfigTree tree(getRootPath(), SHARED_LAYOUT); + res = tree.getChildren("peers"); + } } return res; @@ -964,6 +971,13 @@ void SyncConfig::preFlush(UserInterface &ui) void SyncConfig::flush() { if (!isEphemeral()) { + if (m_fileTree && m_layout == SHARED_LAYOUT && !hasPeerProperties()) { + // Ensure that "peers" directory exists for new-style + // configs. It would not get created when flushing nodes + // for pure context configs otherwise (it's empty), and we + // need it to detect new-syle configs. + mkdir_p(m_fileTree->getRoot() + "/" + m_contextPath + "/peers"); + } m_tree->flush(); } } @@ -1098,8 +1112,14 @@ SyncSourceNodes SyncConfig::getSyncSourceNodes(const string &name, serverNode = node; } else { // Here we assume that m_tree is a FileConfigTree. Otherwise getRootPath() - // will not point into a normal file system. - cacheDir = m_tree->getRootPath() + "/" + peerPath + "/.cache"; + // will not point into a normal file system. We fall back to not allowing + // the usage of a cache dir by using /dev/null in that case. + std::string rootPath = getRootPath(); + if (rootPath.empty()) { + cacheDir = "/dev/null"; + } else { + cacheDir = rootPath + "/" + peerPath + "/.cache"; + } node = m_tree->open(peerPath, ConfigTree::visible); if (compatMode) { diff --git a/src/syncevo/SyncConfig.h b/src/syncevo/SyncConfig.h index f34b7b3d..32b2f159 100644 --- a/src/syncevo/SyncConfig.h +++ b/src/syncevo/SyncConfig.h @@ -39,6 +39,8 @@ #include SE_BEGIN_CXX +class FileConfigTree; + /** * @defgroup ConfigHandling Configuration Handling * @{ @@ -973,7 +975,7 @@ class SyncConfig { */ void prepareConfigForWrite(); - /** absolute directory name of the configuration root */ + /** absolute directory name of the configuration root, empty if unknown or not available */ std::string getRootPath() const; typedef std::list< std::pair > ConfigList; @@ -1653,6 +1655,11 @@ private: /** holds all config nodes relative to the root that we found */ boost::shared_ptr m_tree; + /** + * Same instance as m_tree, except that we know that it is a FileConfigTree. + */ + boost::shared_ptr m_fileTree; + /** access to global sync properties, independent of the context (for example, "defaultPeer") */ boost::shared_ptr m_globalNode; diff --git a/src/syncevo/VolatileConfigTree.h b/src/syncevo/VolatileConfigTree.h index 3531ab36..8e93c4b2 100644 --- a/src/syncevo/VolatileConfigTree.h +++ b/src/syncevo/VolatileConfigTree.h @@ -33,7 +33,7 @@ SE_BEGIN_CXX class VolatileConfigTree : public FileConfigTree { public: VolatileConfigTree() : - FileConfigTree("/dev/null", "", SyncConfig::SHARED_LAYOUT) + FileConfigTree("/dev/null", SyncConfig::SHARED_LAYOUT) {} virtual void flush() {}