CServerPath CRemoteTreeView::GetPathFromItem(const wxTreeItemId& item) const { std::list<wxString> segments; wxTreeItemId i = item; while (i != GetRootItem()) { const CItemData* const pData = (const CItemData*)GetItemData(i); if (pData) { CServerPath path = pData->m_path; for (std::list<wxString>::const_iterator iter = segments.begin(); iter != segments.end(); ++iter) { if (!path.AddSegment(*iter)) return CServerPath(); } return path; } segments.push_front(GetItemText(i)); i = GetItemParent(i); } return CServerPath(); }
CServerPath DisplayDropHighlight(wxPoint point) { wxTreeItemId hit = GetHit(point); if (!hit) { ClearDropHighlight(); return CServerPath(); } const CServerPath& path = m_pRemoteTreeView->GetPathFromItem(hit); if (path.IsEmpty()) { ClearDropHighlight(); return CServerPath(); } const wxTreeItemId dropHighlight = m_pRemoteTreeView->m_dropHighlight; if (dropHighlight != wxTreeItemId()) m_pRemoteTreeView->SetItemDropHighlight(dropHighlight, false); m_pRemoteTreeView->SetItemDropHighlight(hit, true); m_pRemoteTreeView->m_dropHighlight = hit; return path; }
CServerPath::CServerPath(CString path) { m_nServerType = FZ_SERVERTYPE_FTP; path.TrimLeft( _T(" ") ); path.TrimRight( _T(" ") ); if (path == _MPT("")) { m_bEmpty = TRUE; return; } else m_bEmpty = FALSE; int pos1 = path.Find( _T(":[") ); if (pos1 != -1 && path.Right(1) == _MPT("]") && pos1 != (path.GetLength()-1)) m_nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS; else if (path.GetLength() >= 3 && _istalpha(path[0]) && path[1] == _MPT(':') && (path[2] == _MPT('\\') || path[2] == _MPT('/'))) m_nServerType |= FZ_SERVERTYPE_SUB_FTP_WINDOWS; else if (path[0] == FTP_MVS_DOUBLE_QUOTA && path[path.GetLength() - 1] == FTP_MVS_DOUBLE_QUOTA) m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS; else if (path.GetLength() > 2 && path[0] == _MPT('\'') && path.Right(1) == _T("'") && path.Find(_MPT('/')) == -1 && path.Find(_MPT('\\')) == -1) m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS; else if (path.GetLength() >= 2 && path[0] != _MPT('/') && path.Right(1) == _T(".")) m_nServerType |= FZ_SERVERTYPE_SUB_FTP_UNKNOWN; *this = CServerPath(path, m_nServerType); }
void CRemoteTreeView::OnContextMenu(wxTreeEvent& event) { m_contextMenuItem = event.GetItem(); wxMenu* pMenu = wxXmlResource::Get()->LoadMenu(_T("ID_MENU_REMOTETREE")); if (!pMenu) return; const CServerPath& path = m_contextMenuItem ? GetPathFromItem(m_contextMenuItem) : CServerPath(); if (!m_pState->IsRemoteIdle() || path.empty()) { pMenu->Enable(XRCID("ID_DOWNLOAD"), false); pMenu->Enable(XRCID("ID_ADDTOQUEUE"), false); pMenu->Enable(XRCID("ID_MKDIR"), false); pMenu->Enable(XRCID("ID_MKDIR_CHGDIR"), false); pMenu->Enable(XRCID("ID_DELETE"), false); pMenu->Enable(XRCID("ID_CHMOD"), false); pMenu->Enable(XRCID("ID_RENAME"), false); pMenu->Enable(XRCID("ID_GETURL"), false); } else if (!path.HasParent()) pMenu->Enable(XRCID("ID_RENAME"), false); if (!m_pState->GetLocalDir().IsWriteable()) { pMenu->Enable(XRCID("ID_DOWNLOAD"), false); pMenu->Enable(XRCID("ID_ADDTOQUEUE"), false); } PopupMenu(pMenu); delete pMenu; }
const CServerPath CState::GetRemotePath() const { if (!m_pDirectoryListing) return CServerPath(); return m_pDirectoryListing->path; }
CServerPath CPathCache::Lookup(const tServerCache &serverCache, const CServerPath& source, const wxString subdir) { CSourcePath sourcePath; sourcePath.source = source; sourcePath.subdir = subdir; tServerCacheConstIterator serverIter = serverCache.find(sourcePath); if (serverIter == serverCache.end()) return CServerPath(); return serverIter->second; }
bool CClearPrivateDataDialog::ClearReconnect() { COptions::Get()->SetLastServer(CServer()); COptions::Get()->SetOption(OPTION_LASTSERVERPATH, _T("")); const std::vector<CState*> *states = CContextManager::Get()->GetAllStates(); for (std::vector<CState*>::const_iterator iter = states->begin(); iter != states->end(); ++iter) { CState* pState = *iter; pState->SetLastServer(CServer(), CServerPath()); } return true; }
CServerPath CServerPath::GetParent() const { if (empty() || !HasParent()) return CServerPath(); CServerPath parent(*this); CServerPathData& parent_data = parent.m_data.Get(); parent_data.m_segments.pop_back(); if (m_type == MVS) parent_data.m_prefix = CSparseOptional<wxString>(_T(".")); return parent; }
CServerPath CPathCache::Lookup(const CServer& server, const CServerPath& source, const wxString subdir /*=_T("")*/) { const tCacheConstIterator iter = m_cache.find(server); if (iter == m_cache.end()) return CServerPath(); CServerPath result = Lookup(*iter->second, source, subdir); if (result.IsEmpty()) m_misses++; else m_hits++; return result; }
CServerPath CServerPath::GetParent() const { if (!HasParent()) return CServerPath(); CServerPath parent(*this); CServerPathData& parent_data = parent.m_data.Get(); parent_data.m_segments.pop_back(); if (m_type == MVS) parent_data.m_prefix = _T("."); return parent; }
CServerPath CPathCache::Lookup(CServer const& server, CServerPath const& source, wxString const& subdir) { scoped_lock lock(mutex_); const tCacheConstIterator iter = m_cache.find(server); if (iter == m_cache.end()) return CServerPath(); CServerPath result = Lookup(iter->second, source, subdir); if (result.empty()) m_misses++; else m_hits++; return result; }
CServerPath CServerPath::GetParent() const { if (empty() || !HasParent()) { return CServerPath(); } CServerPath parent(*this); CServerPathData& parent_data = parent.m_data.get(); parent_data.m_segments.pop_back(); if (m_type == MVS) { parent_data.m_prefix = fz::sparse_optional<std::wstring>(L"."); } return parent; }
CServerPath CState::GetSynchronizedDirectory(CLocalPath local_path) { std::list<wxString> segments; while (local_path.HasParent() && local_path != m_sync_browse.local_root) { wxString last; local_path.MakeParent(&last); segments.push_front(last); } if (local_path != m_sync_browse.local_root) return CServerPath(); CServerPath remote_path = m_sync_browse.remote_root; for (std::list<wxString>::const_iterator iter = segments.begin(); iter != segments.end(); ++iter) remote_path.AddSegment(*iter); return remote_path; }
//--------------------------------------------------------------------------- bool TFileZillaIntf::FileTransfer(const wchar_t * LocalFile, const wchar_t * RemoteFile, const wchar_t * RemotePath, bool Get, __int64 Size, int Type, void * UserData) { t_transferfile Transfer; Transfer.localfile = LocalFile; Transfer.remotefile = RemoteFile; Transfer.remotepath = CServerPath(RemotePath); Transfer.get = Get; Transfer.size = Size; Transfer.server = *FServer; // 1 = ascii, 2 = binary Transfer.nType = Type; Transfer.nUserData = UserData; return Check(FFileZillaApi->FileTransfer(Transfer), L"filetransfer"); }
// Help-Function to create a new Directory // Returns the name of the new directory CServerPath CRemoteTreeView::MenuMkdir() { if (!m_pState->IsRemoteIdle()) return CServerPath(); if (!m_contextMenuItem) return CServerPath(); const CServerPath& path = GetPathFromItem(m_contextMenuItem); if (path.empty()) return CServerPath(); CInputDialog dlg; if (!dlg.Create(this, _("Create directory"), _("Please enter the name of the directory which should be created:"))) return CServerPath(); CServerPath newPath = path; // Append a long segment which does (most likely) not exist in the path and // replace it with "New directory" later. This way we get the exact position of // "New directory" and can preselect it in the dialog. wxString tmpName = _T("25CF809E56B343b5A12D1F0466E3B37A49A9087FDCF8412AA9AF8D1E849D01CF"); if (newPath.AddSegment(tmpName)) { wxString pathName = newPath.GetPath(); int pos = pathName.Find(tmpName); wxASSERT(pos != -1); wxString newName = _("New directory"); pathName.Replace(tmpName, newName); dlg.SetValue(pathName); dlg.SelectText(pos, pos + newName.Length()); } if (dlg.ShowModal() != wxID_OK) return CServerPath(); newPath = path; if (!newPath.ChangePath(dlg.GetValue())) { wxBell(); return CServerPath(); } m_pState->m_pCommandQueue->ProcessCommand(new CMkdirCommand(newPath)); return newPath; }
void CRemoteRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing) { if (!pDirectoryListing) { StopRecursiveOperation(); return; } if (m_operationMode == recursive_none || recursion_roots_.empty()) return; if (pDirectoryListing->failed()) { // Ignore this. // It will get handled by the failed command in ListingFailed return; } auto & root = recursion_roots_.front(); wxASSERT(!root.m_dirsToVisit.empty()); if (!m_state.IsRemoteConnected() || root.m_dirsToVisit.empty()) { StopRecursiveOperation(); return; } recursion_root::new_dir dir = root.m_dirsToVisit.front(); root.m_dirsToVisit.pop_front(); if (!BelowRecursionRoot(pDirectoryListing->path, dir)) { NextOperation(); return; } if (m_operationMode == recursive_delete && dir.doVisit && !dir.subdir.empty()) { // After recursing into directory to delete its contents, delete directory itself // Gets handled in NextOperation recursion_root::new_dir dir2 = dir; dir2.doVisit = false; root.m_dirsToVisit.push_front(dir2); } if (dir.link && !dir.recurse) { NextOperation(); return; } // Check if we have already visited the directory if (!root.m_visitedDirs.insert(pDirectoryListing->path).second) { NextOperation(); return; } ++m_processedDirectories; const CServer* pServer = m_state.GetServer(); wxASSERT(pServer); if (!pDirectoryListing->GetCount()) { if (m_operationMode == recursive_transfer) { wxFileName::Mkdir(dir.localDir.GetPath(), 0777, wxPATH_MKDIR_FULL); m_state.RefreshLocalFile(dir.localDir.GetPath()); } else if (m_operationMode == recursive_addtoqueue) { m_pQueue->QueueFile(true, true, _T(""), _T(""), dir.localDir, CServerPath(), *pServer, -1); m_pQueue->QueueFile_Finish(false); } } CFilterManager filter; // Is operation restricted to a single child? bool const restrict = static_cast<bool>(dir.restrict); std::deque<wxString> filesToDelete; const wxString path = pDirectoryListing->path.GetPath(); bool added = false; for (int i = pDirectoryListing->GetCount() - 1; i >= 0; --i) { const CDirentry& entry = (*pDirectoryListing)[i]; if (restrict) { if (entry.name != *dir.restrict) continue; } else if (filter.FilenameFiltered(m_filters, entry.name, path, entry.is_dir(), entry.size, 0, entry.time)) continue; if (!entry.is_dir()) { ++m_processedFiles; } if (entry.is_dir() && (!entry.is_link() || m_operationMode != recursive_delete)) { if (dir.recurse) { recursion_root::new_dir dirToVisit; dirToVisit.parent = pDirectoryListing->path; dirToVisit.subdir = entry.name; dirToVisit.localDir = dir.localDir; dirToVisit.start_dir = dir.start_dir; if (m_operationMode == recursive_transfer || m_operationMode == recursive_addtoqueue) { // Non-flatten case dirToVisit.localDir.AddSegment(CQueueView::ReplaceInvalidCharacters(entry.name)); } if (entry.is_link()) { dirToVisit.link = 1; dirToVisit.recurse = false; } root.m_dirsToVisit.push_front(dirToVisit); } } else { switch (m_operationMode) { case recursive_transfer: case recursive_transfer_flatten: { wxString localFile = CQueueView::ReplaceInvalidCharacters(entry.name); if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION)) localFile = StripVMSRevision(localFile); m_pQueue->QueueFile(m_operationMode == recursive_addtoqueue, true, entry.name, (entry.name == localFile) ? wxString() : localFile, dir.localDir, pDirectoryListing->path, *pServer, entry.size); added = true; } break; case recursive_addtoqueue: case recursive_addtoqueue_flatten: { wxString localFile = CQueueView::ReplaceInvalidCharacters(entry.name); if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION)) localFile = StripVMSRevision(localFile); m_pQueue->QueueFile(true, true, entry.name, (entry.name == localFile) ? wxString() : localFile, dir.localDir, pDirectoryListing->path, *pServer, entry.size); added = true; } break; case recursive_delete: filesToDelete.push_back(entry.name); break; default: break; } } if (m_operationMode == recursive_chmod && m_pChmodDlg) { const int applyType = m_pChmodDlg->GetApplyType(); if (!applyType || (!entry.is_dir() && applyType == 1) || (entry.is_dir() && applyType == 2)) { char permissions[9]; bool res = m_pChmodDlg->ConvertPermissions(*entry.permissions, permissions); wxString newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0, entry.is_dir()); m_state.m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms), CCommandQueue::recursiveOperation); } } } if (added) m_pQueue->QueueFile_Finish(m_operationMode != recursive_addtoqueue && m_operationMode != recursive_addtoqueue_flatten); if (m_operationMode == recursive_delete && !filesToDelete.empty()) m_state.m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, std::move(filesToDelete)), CCommandQueue::recursiveOperation); m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS); NextOperation(); }
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const CLocalPath& localPath) : CFileItem(parent, queued, true, wxEmptyString, wxEmptyString, localPath, CServerPath(), -1) { }
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const wxString& localFile) : CFileItem(parent, queued, true, localFile, _T(""), CServerPath(), -1) { }
void CRemoteRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing) { if (!pDirectoryListing) { StopRecursiveOperation(); return; } if (m_operationMode == recursive_none || recursion_roots_.empty()) return; if (pDirectoryListing->failed()) { // Ignore this. // It will get handled by the failed command in ListingFailed return; } auto & root = recursion_roots_.front(); wxASSERT(!root.m_dirsToVisit.empty()); if (!m_state.IsRemoteConnected() || root.m_dirsToVisit.empty()) { StopRecursiveOperation(); return; } recursion_root::new_dir dir = root.m_dirsToVisit.front(); root.m_dirsToVisit.pop_front(); if (!BelowRecursionRoot(pDirectoryListing->path, dir)) { NextOperation(); return; } if (m_operationMode == recursive_delete && dir.doVisit && !dir.subdir.empty()) { // After recursing into directory to delete its contents, delete directory itself // Gets handled in NextOperation recursion_root::new_dir dir2 = dir; dir2.doVisit = false; root.m_dirsToVisit.push_front(dir2); } if (dir.link && !dir.recurse) { NextOperation(); return; } // Check if we have already visited the directory if (!root.m_visitedDirs.insert(pDirectoryListing->path).second) { NextOperation(); return; } ++m_processedDirectories; const CServer* pServer = m_state.GetServer(); wxASSERT(pServer); if (!pDirectoryListing->GetCount() && m_operationMode == recursive_transfer) { if (m_immediate) { wxFileName::Mkdir(dir.localDir.GetPath(), 0777, wxPATH_MKDIR_FULL); m_state.RefreshLocalFile(dir.localDir.GetPath()); } else { m_pQueue->QueueFile(true, true, _T(""), _T(""), dir.localDir, CServerPath(), *pServer, -1); m_pQueue->QueueFile_Finish(false); } } CFilterManager filter; // Is operation restricted to a single child? bool const restrict = static_cast<bool>(dir.restrict); std::deque<std::wstring> filesToDelete; std::wstring const remotePath = pDirectoryListing->path.GetPath(); if (m_operationMode == recursive_synchronize_download && !dir.localDir.empty()) { // Step one in synchronization: Delete local files not on the server fz::local_filesys fs; if (fs.begin_find_files(fz::to_native(dir.localDir.GetPath()))) { std::list<fz::native_string> paths_to_delete; bool isLink{}; fz::native_string name; bool isDir{}; int64_t size{}; fz::datetime time; int attributes{}; while (fs.get_next_file(name, isLink, isDir, &size, &time, &attributes)) { if (isLink) { continue; } auto const wname = fz::to_wstring(name); if (filter.FilenameFiltered(m_filters.first, wname, dir.localDir.GetPath(), isDir, size, attributes, time)) { continue; } // Local item isn't filtered int remoteIndex = pDirectoryListing->FindFile_CmpCase(fz::to_wstring(name)); if (remoteIndex != -1) { CDirentry const& entry = (*pDirectoryListing)[remoteIndex]; if (!filter.FilenameFiltered(m_filters.second, entry.name, remotePath, entry.is_dir(), entry.size, 0, entry.time)) { // Both local and remote items exist if (isDir == entry.is_dir() || entry.is_link()) { // Normal item, nothing we should do continue; } } } // Local item should be deleted if reaching this point paths_to_delete.push_back(fz::to_native(dir.localDir.GetPath()) + name); } fz::recursive_remove r; r.remove(paths_to_delete); } } bool added = false; for (int i = pDirectoryListing->GetCount() - 1; i >= 0; --i) { const CDirentry& entry = (*pDirectoryListing)[i]; if (restrict) { if (entry.name != *dir.restrict) continue; } else if (filter.FilenameFiltered(m_filters.second, entry.name, remotePath, entry.is_dir(), entry.size, 0, entry.time)) continue; if (!entry.is_dir()) { ++m_processedFiles; } if (entry.is_dir() && (!entry.is_link() || m_operationMode != recursive_delete)) { if (dir.recurse) { recursion_root::new_dir dirToVisit; dirToVisit.parent = pDirectoryListing->path; dirToVisit.subdir = entry.name; dirToVisit.localDir = dir.localDir; dirToVisit.start_dir = dir.start_dir; if (m_operationMode == recursive_transfer || m_operationMode == recursive_synchronize_download) { // Non-flatten case dirToVisit.localDir.AddSegment(CQueueView::ReplaceInvalidCharacters(entry.name)); } if (entry.is_link()) { dirToVisit.link = 1; dirToVisit.recurse = false; } root.m_dirsToVisit.push_front(dirToVisit); } } else { switch (m_operationMode) { case recursive_transfer: case recursive_transfer_flatten: case recursive_synchronize_download: { std::wstring localFile = CQueueView::ReplaceInvalidCharacters(entry.name); if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION)) { localFile = StripVMSRevision(localFile); } m_pQueue->QueueFile(!m_immediate, true, entry.name, (entry.name == localFile) ? std::wstring() : localFile, dir.localDir, pDirectoryListing->path, *pServer, entry.size); added = true; } break; case recursive_delete: filesToDelete.push_back(entry.name); break; default: break; } } if (m_operationMode == recursive_chmod && m_pChmodDlg) { const int applyType = m_pChmodDlg->GetApplyType(); if (!applyType || (!entry.is_dir() && applyType == 1) || (entry.is_dir() && applyType == 2)) { char permissions[9]; bool res = m_pChmodDlg->ConvertPermissions(*entry.permissions, permissions); std::wstring newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0, entry.is_dir()).ToStdWstring(); m_state.m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms), CCommandQueue::recursiveOperation); } } } if (added) { m_pQueue->QueueFile_Finish(m_immediate); } if (m_operationMode == recursive_delete && !filesToDelete.empty()) { m_state.m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, std::move(filesToDelete)), CCommandQueue::recursiveOperation); } m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS); NextOperation(); }
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const { if (*this == path) return *this; if (m_bEmpty || path.m_bEmpty) return CServerPath(); if (m_type != path.m_type || (!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix)) { return CServerPath(); } if (!HasParent()) { if (path.IsSubdirOf(*this, false)) return *this; else return CServerPath(); } else if (!path.HasParent()) { if (IsSubdirOf(path, false)) return path; else return CServerPath(); } CServerPath parent; parent.m_bEmpty = false; parent.m_type = m_type; CServerPathData& parentData = parent.m_data.Get(); std::list<wxString>::const_iterator last = m_data->m_segments.end(); std::list<wxString>::const_iterator last2 = path.m_data->m_segments.end(); if (traits[m_type].prefixmode == 1) { if (m_data->m_prefix.empty()) last--; if (path.m_data->m_prefix.empty()) last2--; parentData.m_prefix = GetParent().m_data->m_prefix; } else parentData.m_prefix = m_data->m_prefix; std::list<wxString>::const_iterator iter = m_data->m_segments.begin(); std::list<wxString>::const_iterator iter2 = path.m_data->m_segments.begin(); while (iter != last && iter2 != last2) { if (*iter != *iter2) { if (!traits[m_type].has_root && parentData.m_segments.empty()) return CServerPath(); else return parent; } parentData.m_segments.push_back(*iter); iter++; iter2++; } return parent; }
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const { if (*this == path) { return *this; } if (empty() || path.empty()) { return CServerPath(); } if (m_type != path.m_type || (!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix)) { return CServerPath(); } if (!HasParent()) { if (path.IsSubdirOf(*this, false)) { return *this; } else { return CServerPath(); } } else if (!path.HasParent()) { if (IsSubdirOf(path, false)) { return path; } else { return CServerPath(); } } CServerPath parent; parent.m_type = m_type; CServerPathData& parentData = parent.m_data.get(); tConstSegmentIter last = m_data->m_segments.end(); tConstSegmentIter last2 = path.m_data->m_segments.end(); if (traits[m_type].prefixmode == 1) { if (!m_data->m_prefix) { --last; } if (!path.m_data->m_prefix) { --last2; } parentData.m_prefix = GetParent().m_data->m_prefix; } else parentData.m_prefix = m_data->m_prefix; tConstSegmentIter iter = m_data->m_segments.begin(); tConstSegmentIter iter2 = path.m_data->m_segments.begin(); while (iter != last && iter2 != last2) { if (*iter != *iter2) { if (!traits[m_type].has_root && parentData.m_segments.empty()) { return CServerPath(); } else { return parent; } } parentData.m_segments.push_back(*iter); ++iter; ++iter2; } return parent; }
void CRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing) { if (!pDirectoryListing) { StopRecursiveOperation(); return; } if (m_operationMode == recursive_none) return; wxASSERT(!m_dirsToVisit.empty()); if (!m_pState->IsRemoteConnected() || m_dirsToVisit.empty()) { StopRecursiveOperation(); return; } CNewDir dir = m_dirsToVisit.front(); m_dirsToVisit.pop_front(); if (!pDirectoryListing->path.IsSubdirOf(m_startDir, false)) { // In some cases (chmod from tree for example) it is neccessary to list the // parent first if (pDirectoryListing->path != m_startDir || !m_allowParent) { NextOperation(); return; } } if (m_operationMode == recursive_delete && dir.doVisit && dir.subdir != _T("")) { // After recursing into directory to delete its contents, delete directory itself // Gets handled in NextOperation CNewDir dir2 = dir; dir2.doVisit = false; m_dirsToVisit.push_front(dir2); } // Check if we have already visited the directory for (std::list<CServerPath>::const_iterator iter = m_visitedDirs.begin(); iter != m_visitedDirs.end(); iter++) { if (*iter == pDirectoryListing->path) { NextOperation(); return; } } m_visitedDirs.push_back(pDirectoryListing->path); const CServer* pServer = m_pState->GetServer(); wxASSERT(pServer); if (!pDirectoryListing->GetCount()) { wxFileName fn(dir.localDir, _T("")); if (m_operationMode == recursive_download) { wxFileName::Mkdir(fn.GetPath(), 0777, wxPATH_MKDIR_FULL); m_pState->RefreshLocalFile(fn.GetFullPath()); } else if (m_operationMode == recursive_addtoqueue) m_pQueue->QueueFile(true, true, fn.GetFullPath(), _T(""), CServerPath(), *pServer, -1); } CFilterDialog filter; // Is operation restricted to a single child? bool restrict = !dir.restrict.IsEmpty(); for (int i = pDirectoryListing->GetCount() - 1; i >= 0; i--) { const CDirentry& entry = (*pDirectoryListing)[i]; if (restrict) { if (entry.name != dir.restrict) continue; } else if (filter.FilenameFiltered(entry.name, entry.dir, entry.size, false)) continue; if (entry.dir && !entry.link) { if (dir.recurse) { CNewDir dirToVisit; wxFileName fn(dir.localDir, _T("")); fn.AppendDir(entry.name); dirToVisit.parent = pDirectoryListing->path; dirToVisit.subdir = entry.name; dirToVisit.localDir = fn.GetFullPath(); dirToVisit.doVisit = true; m_dirsToVisit.push_front(dirToVisit); } } else { switch (m_operationMode) { case recursive_addtoqueue: case recursive_download: { wxFileName fn(dir.localDir, entry.name); m_pQueue->QueueFile(m_operationMode == recursive_addtoqueue, true, fn.GetFullPath(), entry.name, pDirectoryListing->path, *pServer, entry.size); } break; case recursive_delete: m_pState->m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, entry.name)); break; default: break; } } if (m_operationMode == recursive_chmod && m_pChmodDlg) { const int applyType = m_pChmodDlg->GetApplyType(); if (!applyType || (!entry.dir && applyType == 1) || (entry.dir && applyType == 2)) { char permissions[9]; bool res = m_pChmodDlg->ConvertPermissions(entry.permissions, permissions); wxString newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0); m_pState->m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms)); } } } NextOperation(); }
bool CServer::ParseUrl(wxString host, unsigned int port, wxString user, wxString pass, wxString &error, CServerPath &path) { m_type = DEFAULT; if (host == _T("")) { error = _("No host given, please enter a host."); return false; } int pos = host.Find(_T("://")); if (pos != -1) { wxString protocol = host.Left(pos).Lower(); host = host.Mid(pos + 3); if (protocol.Left(3) == _T("fz_")) protocol = protocol.Mid(3); m_protocol = GetProtocolFromPrefix(protocol.Lower()); if (m_protocol == UNKNOWN) { // TODO: http:// once WebDAV is officially supported error = _("Invalid protocol specified. Valid protocols are:\nftp:// for normal FTP,\nsftp:// for SSH file transfer protocol,\nftps:// for FTP over SSL (implicit) and\nftpes:// for FTP over SSL (explicit)."); return false; } } pos = host.Find('@'); if (pos != -1) { // Check if it's something like // user@name:password@host:port/path // => If there are multiple at signs, username/port ends at last at before // the first slash. (Since host and port never contain any at sign) int slash = host.Mid(pos + 1).Find('/'); if (slash != -1) slash += pos + 1; int next_at = host.Mid(pos + 1).Find('@'); while (next_at != -1) { next_at += pos + 1; if (slash != -1 && next_at > slash) break; pos = next_at; next_at = host.Mid(pos + 1).Find('@'); } user = host.Left(pos); host = host.Mid(pos + 1); // Extract password (if any) from username pos = user.Find(':'); if (pos != -1) { pass = user.Mid(pos + 1); user = user.Left(pos); } // Remove leading and trailing whitespace user.Trim(true); user.Trim(false); if (user == _T("")) { error = _("Invalid username given."); return false; } } else { // Remove leading and trailing whitespace user.Trim(true); user.Trim(false); if (user == _T("")) { user = _T("anonymous"); pass = _T("*****@*****.**"); } } pos = host.Find('/'); if (pos != -1) { path = CServerPath(host.Mid(pos)); host = host.Left(pos); } pos = host.Find(':'); if (pos != -1) { if (!pos) { error = _("No host given, please enter a host."); return false; } long tmp; if (!host.Mid(pos + 1).ToLong(&tmp) || tmp < 1 || tmp > 65535) { error = _("Invalid port given. The port has to be a value from 1 to 65535."); return false; } port = tmp; host = host.Left(pos); } else { if (!port) port = GetDefaultPort(m_protocol); else if (port > 65535) { error = _("Invalid port given. The port has to be a value from 1 to 65535."); return false; } } host.Trim(true); host.Trim(false); if (host == _T("")) { error = _("No host given, please enter a host."); return false; } m_host = host; m_port = port; m_user = user; m_pass = pass; m_account = _T(""); if (m_user == _T("") || m_user == _T("anonymous")) m_logonType = ANONYMOUS; else m_logonType = NORMAL; if (m_protocol == UNKNOWN) m_protocol = GetProtocolFromPort(port); return true; }
CFolderItem::CFolderItem(CServerItem* parent, bool queued, CLocalPath const& localPath) : CFileItem(parent, queued, true, std::wstring(), std::wstring(), localPath, CServerPath(), -1) { }