bool CControlSocket::SetFileExistsAction(CFileExistsNotification *pFileExistsNotification) { wxASSERT(pFileExistsNotification); if (!m_pCurOpData || m_pCurOpData->opId != Command::transfer) { LogMessage(__TFILE__, __LINE__, this, MessageType::Debug_Info, _T("No or invalid operation in progress, ignoring request reply %f"), pFileExistsNotification->GetRequestID()); return false; } CFileTransferOpData *pData = static_cast<CFileTransferOpData *>(m_pCurOpData); switch (pFileExistsNotification->overwriteAction) { case CFileExistsNotification::overwrite: SendNextCommand(); break; case CFileExistsNotification::overwriteNewer: if (!pFileExistsNotification->localTime.IsValid() || !pFileExistsNotification->remoteTime.IsValid()) SendNextCommand(); else if (pFileExistsNotification->download && pFileExistsNotification->localTime.IsEarlierThan(pFileExistsNotification->remoteTime)) SendNextCommand(); else if (!pFileExistsNotification->download && pFileExistsNotification->localTime.IsLaterThan(pFileExistsNotification->remoteTime)) SendNextCommand(); else { if (pData->download) { wxString filename = pData->remotePath.FormatFilename(pData->remoteFile); LogMessage(MessageType::Status, _("Skipping download of %s"), filename); } else { LogMessage(MessageType::Status, _("Skipping upload of %s"), pData->localFile); } ResetOperation(FZ_REPLY_OK); } break; case CFileExistsNotification::overwriteSize: /* First compare flags both size known but different, one size known and the other not (obviously they are different). Second compare flags the remaining case in which we need to send command : both size unknown */ if ((pFileExistsNotification->localSize != pFileExistsNotification->remoteSize) || (pFileExistsNotification->localSize == -1)) SendNextCommand(); else { if (pData->download) { wxString filename = pData->remotePath.FormatFilename(pData->remoteFile); LogMessage(MessageType::Status, _("Skipping download of %s"), filename); } else { LogMessage(MessageType::Status, _("Skipping upload of %s"), pData->localFile); } ResetOperation(FZ_REPLY_OK); } break; case CFileExistsNotification::overwriteSizeOrNewer: if (!pFileExistsNotification->localTime.IsValid() || !pFileExistsNotification->remoteTime.IsValid()) SendNextCommand(); /* First compare flags both size known but different, one size known and the other not (obviously they are different). Second compare flags the remaining case in which we need to send command : both size unknown */ else if ((pFileExistsNotification->localSize != pFileExistsNotification->remoteSize) || (pFileExistsNotification->localSize == -1)) SendNextCommand(); else if (pFileExistsNotification->download && pFileExistsNotification->localTime.IsEarlierThan(pFileExistsNotification->remoteTime)) SendNextCommand(); else if (!pFileExistsNotification->download && pFileExistsNotification->localTime.IsLaterThan(pFileExistsNotification->remoteTime)) SendNextCommand(); else { if (pData->download) { wxString filename = pData->remotePath.FormatFilename(pData->remoteFile); LogMessage(MessageType::Status, _("Skipping download of %s"), filename); } else { LogMessage(MessageType::Status, _("Skipping upload of %s"), pData->localFile); } ResetOperation(FZ_REPLY_OK); } break; case CFileExistsNotification::resume: if (pData->download && pData->localFileSize != -1) pData->resume = true; else if (!pData->download && pData->remoteFileSize != -1) pData->resume = true; SendNextCommand(); break; case CFileExistsNotification::rename: if (pData->download) { wxFileName fn = pData->localFile; fn.SetFullName(pFileExistsNotification->newName); pData->localFile = fn.GetFullPath(); wxLongLong size; bool isLink; if (CLocalFileSystem::GetFileInfo(pData->localFile, isLink, &size, 0, 0) == CLocalFileSystem::file) pData->localFileSize = size.GetValue(); else pData->localFileSize = -1; if (CheckOverwriteFile() == FZ_REPLY_OK) SendNextCommand(); } else { pData->remoteFile = pFileExistsNotification->newName; CDirectoryCache cache; CDirentry entry; bool dir_did_exist; bool matched_case; if (cache.LookupFile(entry, *m_pCurrentServer, pData->tryAbsolutePath ? pData->remotePath : m_CurrentPath, pData->remoteFile, dir_did_exist, matched_case) && matched_case) { wxLongLong size = entry.size; pData->remoteFileSize = size.GetValue(); if (entry.has_date()) pData->fileTime = entry.time; if (CheckOverwriteFile() != FZ_REPLY_OK) break; } else { pData->fileTime = CDateTime(); pData->remoteFileSize = -1; } SendNextCommand(); } break; case CFileExistsNotification::skip: if (pData->download) { wxString filename = pData->remotePath.FormatFilename(pData->remoteFile); LogMessage(MessageType::Status, _("Skipping download of %s"), filename); } else { LogMessage(MessageType::Status, _("Skipping upload of %s"), pData->localFile); } ResetOperation(FZ_REPLY_OK); break; default: LogMessage(__TFILE__, __LINE__, this, MessageType::Debug_Warning, _T("Unknown file exists action: %d"), pFileExistsNotification->overwriteAction); ResetOperation(FZ_REPLY_INTERNALERROR); return false; } return true; }
int CControlSocket::CheckOverwriteFile() { if (!m_pCurOpData) { LogMessage(__TFILE__, __LINE__, this, MessageType::Debug_Info, _T("Empty m_pCurOpData")); ResetOperation(FZ_REPLY_INTERNALERROR); return FZ_REPLY_ERROR; } CFileTransferOpData *pData = static_cast<CFileTransferOpData *>(m_pCurOpData); if (pData->download) { if (!wxFile::Exists(pData->localFile)) return FZ_REPLY_OK; } CDirentry entry; bool dirDidExist; bool matchedCase; CDirectoryCache cache; CServerPath remotePath; if (pData->tryAbsolutePath || m_CurrentPath.empty()) remotePath = pData->remotePath; else remotePath = m_CurrentPath; bool found = cache.LookupFile(entry, *m_pCurrentServer, remotePath, pData->remoteFile, dirDidExist, matchedCase); // Ignore entries with wrong case if (found && !matchedCase) found = false; if (!pData->download) { if (!found && pData->remoteFileSize == -1 && !pData->fileTime.IsValid()) return FZ_REPLY_OK; } CFileExistsNotification *pNotification = new CFileExistsNotification; pNotification->download = pData->download; pNotification->localFile = pData->localFile; pNotification->remoteFile = pData->remoteFile; pNotification->remotePath = pData->remotePath; pNotification->localSize = pData->localFileSize; pNotification->remoteSize = pData->remoteFileSize; pNotification->ascii = !pData->transferSettings.binary; if (pData->download && pNotification->localSize != -1) pNotification->canResume = true; else if (!pData->download && pNotification->remoteSize != -1) pNotification->canResume = true; else pNotification->canResume = false; pNotification->localTime = CLocalFileSystem::GetModificationTime(pData->localFile); if (pData->fileTime.IsValid()) pNotification->remoteTime = pData->fileTime; if (found) { if (!pData->fileTime.IsValid()) { if (entry.has_date()) { pNotification->remoteTime = entry.time; pData->fileTime = entry.time; } } } SendAsyncRequest(pNotification); return FZ_REPLY_WOULDBLOCK; }
int CControlSocket::CheckOverwriteFile() { if (!m_pCurOpData) { LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Empty m_pCurOpData")); ResetOperation(FZ_REPLY_INTERNALERROR); return FZ_REPLY_ERROR; } CFileTransferOpData *pData = static_cast<CFileTransferOpData *>(m_pCurOpData); if (pData->download) { if (!wxFile::Exists(pData->localFile)) return FZ_REPLY_OK; } CDirentry entry; bool dirDidExist; bool matchedCase; CDirectoryCache cache; CServerPath remotePath; if (pData->tryAbsolutePath || m_CurrentPath.IsEmpty()) remotePath = pData->remotePath; else remotePath = m_CurrentPath; bool found = cache.LookupFile(entry, *m_pCurrentServer, remotePath, pData->remoteFile, dirDidExist, matchedCase); // Ignore entries with wrong case if (found && !matchedCase) found = false; if (!pData->download) { if (!found && pData->remoteFileSize == -1 && !pData->fileTime.IsValid()) return FZ_REPLY_OK; } CFileExistsNotification *pNotification = new CFileExistsNotification; pNotification->download = pData->download; pNotification->localFile = pData->localFile; pNotification->remoteFile = pData->remoteFile; pNotification->remotePath = pData->remotePath; pNotification->localSize = pData->localFileSize; pNotification->remoteSize = pData->remoteFileSize; pNotification->ascii = !pData->transferSettings.binary; wxStructStat buf; int result; result = wxStat(pData->localFile, &buf); if (!result) { pNotification->localTime = wxDateTime(buf.st_mtime); if (!pNotification->localTime.IsValid()) pNotification->localTime = wxDateTime(buf.st_ctime); } if (pData->fileTime.IsValid()) pNotification->remoteTime = pData->fileTime; if (found) { if (!pData->fileTime.IsValid()) { if (entry.hasDate) { pNotification->remoteTime = entry.time; pData->fileTime = entry.time; } } } pNotification->requestNumber = m_pEngine->GetNextAsyncRequestNumber(); pData->waitForAsyncRequest = true; m_pEngine->AddNotification(pNotification); return FZ_REPLY_WOULDBLOCK; }