void CRecursiveOperation::StartRecursiveOperation(enum OperationMode mode, const CServerPath& startDir, const std::list<CFilter>& filters, bool allowParent /*=false*/, const CServerPath& finalDir /*=CServerPath()*/) { wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none")); wxCHECK_RET(m_pState->IsRemoteConnected(), _T("StartRecursiveOperation while disconnected")); wxCHECK_RET(!startDir.empty(), _T("Empty startDir in StartRecursiveOperation")); if (mode == recursive_chmod && !m_pChmodDlg) return; if ((mode == recursive_download || mode == recursive_addtoqueue || mode == recursive_download_flatten || mode == recursive_addtoqueue_flatten) && !m_pQueue) return; if (m_dirsToVisit.empty()) { // Nothing to do in this case return; } m_operationMode = mode; m_pState->NotifyHandlers(STATECHANGE_REMOTE_IDLE); m_startDir = startDir; if (finalDir.empty()) m_finalDir = startDir; else m_finalDir = finalDir; m_allowParent = allowParent; m_filters = filters; NextOperation(); }
void CRemoteRecursiveOperation::StartRecursiveOperation(OperationMode mode, std::vector<CFilter> const& filters, CServerPath const& finalDir) { wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none")); wxCHECK_RET(m_state.IsRemoteConnected(), _T("StartRecursiveOperation while disconnected")); wxCHECK_RET(!finalDir.empty(), _T("Empty final dir in recursive operation")); if (mode == recursive_chmod && !m_pChmodDlg) return; if ((mode == recursive_transfer || mode == recursive_addtoqueue || mode == recursive_transfer_flatten || mode == recursive_addtoqueue_flatten) && !m_pQueue) return; if (recursion_roots_.empty()) { // Nothing to do in this case return; } m_processedFiles = 0; m_processedDirectories = 0; m_operationMode = mode; m_state.NotifyHandlers(STATECHANGE_REMOTE_IDLE); m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS); m_filters = filters; NextOperation(); }
void CRecursiveOperation::ListingFailed(int error) { if (m_operationMode == recursive_none) return; if( (error & FZ_REPLY_CANCELED) == FZ_REPLY_CANCELED) { // User has cancelled operation StopRecursiveOperation(); return; } wxASSERT(!m_dirsToVisit.empty()); if (m_dirsToVisit.empty()) return; CNewDir dir = m_dirsToVisit.front(); m_dirsToVisit.pop_front(); if ((error & FZ_REPLY_CRITICALERROR) != FZ_REPLY_CRITICALERROR && !dir.second_try) { // Retry, could have been a temporary socket creating failure // (e.g. hitting a blocked port) or a disconnect (e.g. no-filetransfer-timeout) dir.second_try = true; m_dirsToVisit.push_front(dir); } NextOperation(); }
void CRecursiveOperation::StartRecursiveOperation(enum OperationMode mode, const CServerPath& startDir, bool allowParent /*=false*/, const CServerPath& finalDir /*=CServerPath()*/) { wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none")); wxCHECK_RET(m_pState->IsRemoteConnected(), _T("StartRecursiveOperation while disconnected")); wxCHECK_RET(!startDir.IsEmpty(), _T("Empty startDir in StartRecursiveOperation")); if (mode == recursive_chmod && !m_pChmodDlg) return; if ((mode == recursive_download || mode == recursive_addtoqueue) && !m_pQueue) return; if (m_dirsToVisit.empty()) { // Nothing to do in this case return; } m_operationMode = mode; m_startDir = startDir; if (finalDir.IsEmpty()) m_finalDir = startDir; else m_finalDir = finalDir; m_allowParent = allowParent; NextOperation(); }
void CRemoteRecursiveOperation::ListingFailed(int error) { if (m_operationMode == recursive_none || recursion_roots_.empty()) return; if( (error & FZ_REPLY_CANCELED) == FZ_REPLY_CANCELED) { // User has cancelled operation StopRecursiveOperation(); return; } auto & root = recursion_roots_.front(); wxCHECK_RET(!root.m_dirsToVisit.empty(), _T("Empty dirs to visit")); recursion_root::new_dir dir = root.m_dirsToVisit.front(); root.m_dirsToVisit.pop_front(); if ((error & FZ_REPLY_CRITICALERROR) != FZ_REPLY_CRITICALERROR && !dir.second_try) { // Retry, could have been a temporary socket creating failure // (e.g. hitting a blocked port) or a disconnect (e.g. no-filetransfer-timeout) dir.second_try = true; root.m_dirsToVisit.push_front(dir); } NextOperation(); }
VError DB4DJournalParser::_CheckFile( VDB4DProgressIndicator *inProgressIndicator ) { VError error = VE_OK; if ( fFileStream ) { sLONG8 streamPos = 0; if ( inProgressIndicator ) { inProgressIndicator->BeginSession( fFileStream->GetSize(), GetString(1005, 24) ); } while ( error == VE_OK ) { CDB4DJournalData *jData = NULL; uLONG8 globalOperation; error = NextOperation( fTotalOperationCount, &globalOperation, fTotalOperationCount ? NULL : &jData ); if ( jData ) { jData->Release(); } if (globalOperation != 0) fLastOperation = globalOperation; if (fFirstOperation == 0) fFirstOperation = globalOperation; if ( inProgressIndicator ) { if ( !inProgressIndicator->Progress( streamPos ) ) error = VE_STREAM_USER_ABORTED; else if ( fTotalOperationCount%128 == 0 ) VTask::Yield(); } if ( fTotalOperationCount%512 == 0 ) { streamPos = fFileStream->GetPos(); fModuloDataOffset.AppendLong8(streamPos); } } if ( error == VE_STREAM_EOF ) { fFileStream->ResetLastError(); error = VE_OK; } if ( inProgressIndicator ) { inProgressIndicator->EndSession(); } } else { error = VE_UNIMPLEMENTED; // not initialized } return error; }
void CRecursiveOperation::LinkIsNotDir() { if (m_operationMode == recursive_none) return; wxASSERT(!m_dirsToVisit.empty()); if (m_dirsToVisit.empty()) return; CNewDir dir = m_dirsToVisit.front(); m_dirsToVisit.pop_front(); const CServer* pServer = m_pState->GetServer(); if (!pServer) { NextOperation(); return; } if (m_operationMode == recursive_delete) { if (!dir.subdir.empty()) { std::list<wxString> files; files.push_back(dir.subdir); m_pState->m_pCommandQueue->ProcessCommand(new CDeleteCommand(dir.parent, files)); } NextOperation(); return; } else if (m_operationMode != recursive_list ) { CLocalPath localPath = dir.localDir; wxString localFile = dir.subdir; if (m_operationMode != recursive_addtoqueue_flatten && m_operationMode != recursive_download_flatten) localPath.MakeParent(); m_pQueue->QueueFile(m_operationMode == recursive_addtoqueue || m_operationMode == recursive_addtoqueue_flatten, true, dir.subdir, (dir.subdir == localFile) ? wxString() : localFile, localPath, dir.parent, *pServer, -1); m_pQueue->QueueFile_Finish(m_operationMode != recursive_addtoqueue); } NextOperation(); }
void CRecursiveOperation::ListingFailed() { if (m_operationMode == recursive_none) return; wxASSERT(!m_dirsToVisit.empty()); if (m_dirsToVisit.empty()) return; m_dirsToVisit.pop_front(); NextOperation(); }
void CRemoteRecursiveOperation::LinkIsNotDir() { if (m_operationMode == recursive_none || recursion_roots_.empty()) { return; } auto & root = recursion_roots_.front(); wxCHECK_RET(!root.m_dirsToVisit.empty(), _T("Empty dirs to visit")); recursion_root::new_dir dir = root.m_dirsToVisit.front(); root.m_dirsToVisit.pop_front(); const CServer* pServer = m_state.GetServer(); if (!pServer) { NextOperation(); return; } if (m_operationMode == recursive_delete) { if (!dir.subdir.empty()) { std::deque<std::wstring> files; files.push_back(dir.subdir); m_state.m_pCommandQueue->ProcessCommand(new CDeleteCommand(dir.parent, std::move(files)), CCommandQueue::recursiveOperation); } NextOperation(); return; } else if (m_operationMode != recursive_list) { CLocalPath localPath = dir.localDir; std::wstring localFile = dir.subdir; if (m_operationMode != recursive_transfer_flatten) { localPath.MakeParent(); } m_pQueue->QueueFile(!m_immediate, true, dir.subdir, (dir.subdir == localFile) ? std::wstring() : localFile, localPath, dir.parent, *pServer, -1); m_pQueue->QueueFile_Finish(m_immediate); } NextOperation(); }
void Mac::TransmitDoneTask(void) { ThreadError error; bool rxPending; error = otPlatRadioHandleTransmitDone(&rxPending); mAckTimer.Stop(); if (error == kThreadError_ChannelAccessFailure && mCsmaAttempts < kMaxCSMABackoffs) { mCsmaAttempts++; StartCsmaBackoff(); ExitNow(); } mCsmaAttempts = 0; switch (mState) { case kStateActiveScan: mAckTimer.Start(mScanDuration); break; case kStateTransmitBeacon: SentFrame(true); break; case kStateTransmitData: if (rxPending) { mReceiveTimer.Start(kDataPollTimeout); } else { mReceiveTimer.Stop(); } SentFrame(error == kThreadError_None); break; default: assert(false); break; } exit: NextOperation(); }
VError DB4DJournalParser::SetCurrentOperation( uLONG8 inOperation, CDB4DJournalData **outJournalData ) { VError error = VE_OK; if ( fFileStream ) { if ( inOperation == fCurrentOperation ) { *outJournalData = fCurrentData; if (fCurrentData != nil) fCurrentData->Retain(); } else { if ((inOperation < fCurrentOperation) || (inOperation > (fCurrentOperation+4096))) { if ( inOperation%512 ) { fFileStream->SetPos(fModuloDataOffset.GetLong8((inOperation/512)+1)); fCurrentOperation = ((inOperation/512)*512); } else { fFileStream->SetPos(fModuloDataOffset.GetLong8(inOperation/512)); fCurrentOperation = (((inOperation-1)/512)*512); } } *outJournalData = NULL; while ( error == VE_OK && fCurrentOperation < inOperation ) { if ( *outJournalData ) (*outJournalData)->Release(); error = NextOperation( fCurrentOperation, NULL, outJournalData ); } } if ( *outJournalData && error != VE_OK ) { (*outJournalData)->Release(); *outJournalData = NULL; } } else { *outJournalData = NULL; error = VE_UNIMPLEMENTED; // not initialized } return error; }
void Mac::HandleAckTimer(void) { otPlatRadioIdle(); switch (mState) { case kStateActiveScan: do { mScanChannels >>= 1; mScanChannel++; if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { mActiveScanHandler(mActiveScanContext, NULL); ScheduleNextTransmission(); ExitNow(); } } while ((mScanChannels & 1) == 0); StartCsmaBackoff(); break; case kStateTransmitData: otLogDebgMac("ack timer fired\n"); SentFrame(false); break; default: assert(false); break; } exit: NextOperation(); }
void CRemoteRecursiveOperation::StartRecursiveOperation(OperationMode mode, ActiveFilters const& filters, CServerPath const& finalDir, bool immediate) { wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none")); wxCHECK_RET(m_state.IsRemoteConnected(), _T("StartRecursiveOperation while disconnected")); wxCHECK_RET(!finalDir.empty(), _T("Empty final dir in recursive operation")); if (mode == recursive_chmod && !m_pChmodDlg) { return; } if ((mode == recursive_transfer || mode == recursive_transfer_flatten) && !m_pQueue) { return; } if (recursion_roots_.empty()) { // Nothing to do in this case return; } m_processedFiles = 0; m_processedDirectories = 0; m_immediate = immediate; m_operationMode = mode; if ((mode == CRecursiveOperation::recursive_transfer || mode == CRecursiveOperation::recursive_transfer_flatten) && immediate) { m_actionAfterBlocker = m_pQueue->GetActionAfterBlocker(); } m_state.NotifyHandlers(STATECHANGE_REMOTE_IDLE); m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS); m_filters = filters; NextOperation(); }
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(); }
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(); }
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(); }
void Mac::HandleReceiveTimer(void) { otLogInfoMac("data poll timeout!\n"); NextOperation(); }