TiXmlElement* CSiteManager::GetElementByPath(TiXmlElement* pNode, std::list<wxString> &segments) { while (!segments.empty()) { const wxString segment = segments.front(); segments.pop_front(); TiXmlElement* pChild; for (pChild = pNode->FirstChildElement(); pChild; pChild = pChild->NextSiblingElement()) { const char* value = pChild->Value(); if (strcmp(value, "Server") && strcmp(value, "Folder") && strcmp(value, "Bookmark")) continue; wxString name = GetTextElement_Trimmed(pChild, "Name"); if (name.empty()) name = GetTextElement_Trimmed(pChild); if (name.empty()) continue; if (name == segment) break; } if (!pChild) return 0; pNode = pChild; continue; } return pNode; }
TiXmlElement* CSiteManager::GetElementByPath(TiXmlElement* pNode, std::list<wxString> const& segments) { for (std::list<wxString>::const_iterator it = segments.begin(); it != segments.end(); ++it) { const wxString & segment = *it; TiXmlElement* pChild; for (pChild = pNode->FirstChildElement(); pChild; pChild = pChild->NextSiblingElement()) { const char* value = pChild->Value(); if (strcmp(value, "Server") && strcmp(value, "Folder") && strcmp(value, "Bookmark")) continue; wxString name = GetTextElement_Trimmed(pChild, "Name"); if (name.empty()) name = GetTextElement_Trimmed(pChild); if (name.empty()) continue; if (name == segment) break; } if (!pChild) return 0; pNode = pChild; continue; } return pNode; }
bool CImportDialog::ImportSites(TiXmlElement* pSitesToImport, TiXmlElement* pExistingSites) { for (TiXmlElement* pImportFolder = pSitesToImport->FirstChildElement("Folder"); pImportFolder; pImportFolder = pImportFolder->NextSiblingElement("Folder")) { wxString name = GetTextElement_Trimmed(pImportFolder, "Name"); if (name == _T("")) name = GetTextElement_Trimmed(pImportFolder); if (name == _T("")) continue; wxString newName = name; int i = 2; TiXmlElement* pFolder; while (!(pFolder = GetFolderWithName(pExistingSites, newName))) { newName = wxString::Format(_T("%s %d"), name.c_str(), i++); } ImportSites(pImportFolder, pFolder); } for (TiXmlElement* pImportSite = pSitesToImport->FirstChildElement("Server"); pImportSite; pImportSite = pImportSite->NextSiblingElement("Server")) { wxString name = GetTextElement_Trimmed(pImportSite, "Name"); if (name == _T("")) name = GetTextElement_Trimmed(pImportSite); if (name == _T("")) continue; // Find free name wxString newName = name; int i = 2; while (HasEntryWithName(pExistingSites, newName)) { newName = wxString::Format(_T("%s %d"), name.c_str(), i++); } TiXmlElement* pServer = pExistingSites->InsertEndChild(*pImportSite)->ToElement(); AddTextElement(pServer, "Name", newName, true); AddTextElement(pServer, newName); } return true; }
bool CSiteManager::AddBookmark(wxString sitePath, const wxString& name, const wxString &local_dir, const CServerPath &remote_dir, bool sync) { if (local_dir.empty() && remote_dir.IsEmpty()) return false; if (sitePath[0] != '0') return false; sitePath = sitePath.Mid(1); // We have to synchronize access to sitemanager.xml so that multiple processed don't write // to the same file or one is reading while the other one writes. CInterProcessMutex mutex(MUTEX_SITEMANAGER); CXmlFile file; TiXmlElement* pDocument = file.Load(_T("sitemanager")); if (!pDocument) { wxString msg = file.GetError() + _T("\n") + _("The bookmark could not be added."); wxMessageBox(msg, _("Error loading xml file"), wxICON_ERROR); return false; } TiXmlElement* pElement = pDocument->FirstChildElement("Servers"); if (!pElement) return false; std::list<wxString> segments; if (!UnescapeSitePath(sitePath, segments)) { wxMessageBox(_("Site path is malformed."), _("Invalid site path")); return 0; } TiXmlElement* pChild = GetElementByPath(pElement, segments); if (!pChild || strcmp(pChild->Value(), "Server")) { wxMessageBox(_("Site does not exist."), _("Invalid site path")); return 0; } // Bookmarks TiXmlElement *pInsertBefore = 0; TiXmlElement* pBookmark; for (pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { TiXmlHandle handle(pBookmark); wxString old_name = GetTextElement_Trimmed(pBookmark, "Name"); if (old_name.empty()) continue; if (name == old_name) { wxMessageBox(_("Name of bookmark already exists."), _("New bookmark"), wxICON_EXCLAMATION); return false; } if (name < old_name && !pInsertBefore) pInsertBefore = pBookmark; } if (pInsertBefore) pBookmark = pChild->InsertBeforeChild(pInsertBefore, TiXmlElement("Bookmark"))->ToElement(); else pBookmark = pChild->LinkEndChild(new TiXmlElement("Bookmark"))->ToElement(); AddTextElement(pBookmark, "Name", name); if (!local_dir.empty()) AddTextElement(pBookmark, "LocalDir", local_dir); if (!remote_dir.IsEmpty()) AddTextElement(pBookmark, "RemoteDir", remote_dir.GetSafePath()); if (sync) AddTextElementRaw(pBookmark, "SyncBrowsing", "1"); wxString error; if (!file.Save(&error)) { if (COptions::Get()->GetOptionVal(OPTION_DEFAULT_KIOSKMODE) == 2) return true; wxString msg = wxString::Format(_("Could not write \"%s\", the selected sites could not be exported: %s"), file.GetFileName().GetFullPath().c_str(), error.c_str()); wxMessageBox(msg, _("Error writing xml file"), wxICON_ERROR); } return true; }
bool CSiteManager::GetBookmarks(wxString sitePath, std::list<wxString> &bookmarks) { wxChar c = sitePath[0]; if (c != '0' && c != '1') return false; sitePath = sitePath.Mid(1); // We have to synchronize access to sitemanager.xml so that multiple processed don't write // to the same file or one is reading while the other one writes. CInterProcessMutex mutex(MUTEX_SITEMANAGER); CXmlFile file; TiXmlElement* pDocument = 0; if (c == '0') pDocument = file.Load(_T("sitemanager")); else { const wxString& defaultsDir = wxGetApp().GetDefaultsDir(); if (defaultsDir == _T("")) return false; pDocument = file.Load(wxFileName(defaultsDir, _T("fzdefaults.xml"))); } if (!pDocument) { wxMessageBox(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return false; } TiXmlElement* pElement = pDocument->FirstChildElement("Servers"); if (!pElement) return false; std::list<wxString> segments; if (!UnescapeSitePath(sitePath, segments)) { wxMessageBox(_("Site path is malformed."), _("Invalid site path")); return 0; } TiXmlElement* pChild = GetElementByPath(pElement, segments); if (pChild && !strcmp(pChild->Value(), "Bookmark")) pChild = pChild->Parent()->ToElement(); if (!pChild || strcmp(pChild->Value(), "Server")) return 0; // Bookmarks for (TiXmlElement* pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { TiXmlHandle handle(pBookmark); wxString name = GetTextElement_Trimmed(pBookmark, "Name"); if (name.empty()) continue; wxString localPath; CServerPath remotePath; TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text(); if (localDir) localPath = ConvLocal(localDir->Value()); TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text(); if (remoteDir) remotePath.SetSafePath(ConvLocal(remoteDir->Value())); if (localPath.empty() && remotePath.IsEmpty()) continue; bookmarks.push_back(name); } return true; }
bool CSiteManager::Load(TiXmlElement *pElement, CSiteManagerXmlHandler* pHandler) { wxASSERT(pElement); wxASSERT(pHandler); for (TiXmlElement* pChild = pElement->FirstChildElement(); pChild; pChild = pChild->NextSiblingElement()) { if (!strcmp(pChild->Value(), "Folder")) { wxString name = GetTextElement_Trimmed(pChild); if (name.empty()) continue; const bool expand = GetTextAttribute(pChild, "expanded") != _T("0"); if (!pHandler->AddFolder(name, expand)) return false; Load(pChild, pHandler); if (!pHandler->LevelUp()) return false; } else if (!strcmp(pChild->Value(), "Server")) { CSiteManagerItemData_Site* data = ReadServerElement(pChild); if (data) { pHandler->AddSite(data); // Bookmarks for (TiXmlElement* pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { TiXmlHandle handle(pBookmark); wxString name = GetTextElement_Trimmed(pBookmark, "Name"); if (name.empty()) continue; CSiteManagerItemData* data = new CSiteManagerItemData(CSiteManagerItemData::BOOKMARK); TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text(); if (localDir) data->m_localDir = GetTextElement(pBookmark, "LocalDir"); TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text(); if (remoteDir) data->m_remoteDir.SetSafePath(ConvLocal(remoteDir->Value())); if (data->m_localDir.empty() && data->m_remoteDir.IsEmpty()) { delete data; continue; } if (!data->m_localDir.empty() && !data->m_remoteDir.IsEmpty()) data->m_sync = GetTextElementBool(pBookmark, "SyncBrowsing", false); pHandler->AddBookmark(name, data); } if (!pHandler->LevelUp()) return false; } } } return true; }
bool GetServer(pugi::xml_node node, CServer& server) { wxASSERT(node); std::wstring host = GetTextElement(node, "Host"); if (host.empty()) { return false; } int port = GetTextElementInt(node, "Port"); if (port < 1 || port > 65535) { return false; } if (!server.SetHost(host, port)) { return false; } int const protocol = GetTextElementInt(node, "Protocol"); if (protocol < 0 || protocol > ServerProtocol::MAX_VALUE) { return false; } server.SetProtocol(static_cast<ServerProtocol>(protocol)); int type = GetTextElementInt(node, "Type"); if (type < 0 || type >= SERVERTYPE_MAX) { return false; } server.SetType(static_cast<ServerType>(type)); int logonType = GetTextElementInt(node, "Logontype"); if (logonType < 0 || logonType >= LOGONTYPE_MAX) { return false; } server.SetLogonType(static_cast<LogonType>(logonType)); if (server.GetLogonType() != ANONYMOUS) { std::wstring user = GetTextElement(node, "User"); std::wstring pass, key; if ((long)NORMAL == logonType || (long)ACCOUNT == logonType) { auto passElement = node.child("Pass"); if (passElement) { std::wstring encoding = GetTextAttribute(passElement, "encoding"); if (encoding == _T("base64")) { std::string decoded = fz::base64_decode(passElement.child_value()); pass = fz::to_wstring_from_utf8(decoded); } else if (!encoding.empty()) { server.SetLogonType(ASK); } else { pass = GetTextElement(passElement); } } } else if ((long)KEY == logonType) { key = GetTextElement(node, "Keyfile"); // password should be empty if we're using a key file pass.clear(); server.SetKeyFile(key); } if (!server.SetUser(user, pass)) { return false; } if ((long)ACCOUNT == logonType) { std::wstring account = GetTextElement(node, "Account"); if (account.empty()) { return false; } if (!server.SetAccount(account)) { return false; } } } int timezoneOffset = GetTextElementInt(node, "TimezoneOffset"); if (!server.SetTimezoneOffset(timezoneOffset)) { return false; } wxString pasvMode = GetTextElement(node, "PasvMode"); if (pasvMode == _T("MODE_PASSIVE")) server.SetPasvMode(MODE_PASSIVE); else if (pasvMode == _T("MODE_ACTIVE")) server.SetPasvMode(MODE_ACTIVE); else server.SetPasvMode(MODE_DEFAULT); int maximumMultipleConnections = GetTextElementInt(node, "MaximumMultipleConnections"); server.MaximumMultipleConnections(maximumMultipleConnections); wxString encodingType = GetTextElement(node, "EncodingType"); if (encodingType == _T("Auto")) { server.SetEncodingType(ENCODING_AUTO); } else if (encodingType == _T("UTF-8")) { server.SetEncodingType(ENCODING_UTF8); } else if (encodingType == _T("Custom")) { std::wstring customEncoding = GetTextElement(node, "CustomEncoding"); if (customEncoding.empty()) { return false; } if (!server.SetEncodingType(ENCODING_CUSTOM, customEncoding)) { return false; } } else { server.SetEncodingType(ENCODING_AUTO); } if (CServer::SupportsPostLoginCommands(server.GetProtocol())) { std::vector<std::wstring> postLoginCommands; auto element = node.child("PostLoginCommands"); if (element) { for (auto commandElement = element.child("Command"); commandElement; commandElement = commandElement.next_sibling("Command")) { std::wstring command = fz::to_wstring_from_utf8(commandElement.child_value()); if (!command.empty()) { postLoginCommands.emplace_back(std::move(command)); } } } if (!server.SetPostLoginCommands(postLoginCommands)) { return false; } } server.SetBypassProxy(GetTextElementInt(node, "BypassProxy", false) == 1); server.SetName(GetTextElement_Trimmed(node, "Name")); if (server.GetName().empty()) { server.SetName(GetTextElement_Trimmed(node)); } return true; }
bool GetServer(TiXmlElement *node, CServer& server) { wxASSERT(node); wxString host = GetTextElement(node, "Host"); if (host.empty()) return false; int port = GetTextElementInt(node, "Port"); if (port < 1 || port > 65535) return false; if (!server.SetHost(host, port)) return false; int const protocol = GetTextElementInt(node, "Protocol"); if (protocol < 0 || protocol > ServerProtocol::MAX_VALUE) { return false; } server.SetProtocol(static_cast<ServerProtocol>(protocol)); int type = GetTextElementInt(node, "Type"); if (type < 0 || type >= SERVERTYPE_MAX) return false; server.SetType((enum ServerType)type); int logonType = GetTextElementInt(node, "Logontype"); if (logonType < 0) return false; server.SetLogonType((enum LogonType)logonType); if (server.GetLogonType() != ANONYMOUS) { wxString user = GetTextElement(node, "User"); wxString pass; if ((long)NORMAL == logonType || (long)ACCOUNT == logonType) pass = GetTextElement(node, "Pass"); if (!server.SetUser(user, pass)) return false; if ((long)ACCOUNT == logonType) { wxString account = GetTextElement(node, "Account"); if (account.empty()) return false; if (!server.SetAccount(account)) return false; } } int timezoneOffset = GetTextElementInt(node, "TimezoneOffset"); if (!server.SetTimezoneOffset(timezoneOffset)) return false; wxString pasvMode = GetTextElement(node, "PasvMode"); if (pasvMode == _T("MODE_PASSIVE")) server.SetPasvMode(MODE_PASSIVE); else if (pasvMode == _T("MODE_ACTIVE")) server.SetPasvMode(MODE_ACTIVE); else server.SetPasvMode(MODE_DEFAULT); int maximumMultipleConnections = GetTextElementInt(node, "MaximumMultipleConnections"); server.MaximumMultipleConnections(maximumMultipleConnections); wxString encodingType = GetTextElement(node, "EncodingType"); if (encodingType == _T("Auto")) server.SetEncodingType(ENCODING_AUTO); else if (encodingType == _T("UTF-8")) server.SetEncodingType(ENCODING_UTF8); else if (encodingType == _T("Custom")) { wxString customEncoding = GetTextElement(node, "CustomEncoding"); if (customEncoding.empty()) return false; if (!server.SetEncodingType(ENCODING_CUSTOM, customEncoding)) return false; } else server.SetEncodingType(ENCODING_AUTO); if (CServer::SupportsPostLoginCommands(server.GetProtocol())) { std::vector<wxString> postLoginCommands; TiXmlElement* pElement = node->FirstChildElement("PostLoginCommands"); if (pElement) { TiXmlElement* pCommandElement = pElement->FirstChildElement("Command"); while (pCommandElement) { TiXmlNode* textNode = pCommandElement->FirstChild(); if (textNode && textNode->ToText()) { wxString command = ConvLocal(textNode->Value()); if (!command.empty()) postLoginCommands.push_back(command); } pCommandElement = pCommandElement->NextSiblingElement("Command"); } } if (!server.SetPostLoginCommands(postLoginCommands)) return false; } server.SetBypassProxy(GetTextElementInt(node, "BypassProxy", false) == 1); server.SetName(GetTextElement_Trimmed(node, "Name")); if (server.GetName().empty()) server.SetName(GetTextElement_Trimmed(node)); return true; }