void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { char expand[CROSS_LEN] = { 0 }; CFileInfo* dir; if (ignoreLastDir) { char tmp[CROSS_LEN] = { 0 }; Bit32s len=0; const char* pos = strrchr(path,CROSS_FILESPLIT); if (pos) len = (Bit32s)(pos - path); if (len>0) { safe_strncpy(tmp,path,len+1); } else { strcpy(tmp,path); } dir = FindDirInfo(tmp,expand); } else { dir = FindDirInfo(path,expand); } // LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->orgname); // delete file objects... for(Bit32u i=0; i<dir->fileList.size(); i++) { if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0; DeleteFileInfo(dir->fileList[i]); dir->fileList[i] = 0; } // clear lists dir->fileList.clear(); dir->longNameList.clear(); save_dir = 0; }
bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) { // out of range ? if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); return false; } if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) { // free slot DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0; return false; } return true; }
// FindFirst / FindNext bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) { Bit16u dirID; // Cache directory in if (!OpenDir(path,dirID)) return false; //Find a free slot. //If the next one isn't free, move on to the next, if none is free => reset and assume the worst Bit16u local_findcounter = 0; while ( local_findcounter < MAX_OPENDIRS ) { if (dirFindFirst[this->nextFreeFindFirst] == 0) break; if (++this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Wrap around local_findcounter++; } Bit16u dirFindFirstID = this->nextFreeFindFirst++; if (this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Increase and wrap around for the next search. if (local_findcounter == MAX_OPENDIRS) { //Here is the reset from above. // no free slot found... LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next: All slots full. Resetting"); // Clear the internal list then. dirFindFirstID = 0; this->nextFreeFindFirst = 1; //the next free one after this search for(Bitu n=0; n<MAX_OPENDIRS;n++) { // Clear and reuse slot DeleteFileInfo(dirFindFirst[n]); dirFindFirst[n]=0; } } dirFindFirst[dirFindFirstID] = new CFileInfo(); dirFindFirst[dirFindFirstID]-> nextEntry = 0; // Copy entries to use with FindNext for (Bitu i=0; i<dirSearch[dirID]->fileList.size(); i++) { CopyEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]); } // Now re-sort the fileList accordingly to output switch (sortDirType) { case ALPHABETICAL : break; // case ALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); break; case DIRALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirName); break; case ALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByNameRev); break; case DIRALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirNameRev); break; case NOSORT : break; } // LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst : %s (ID:%02X)",path,dirFindFirstID); id = dirFindFirstID; return true; }
/* * Returns True if Entry was deleted from Queue or False if it was scheduled for Deletion. * NOTE: "False" does not mean unsuccess; the entry is (or will be) deleted in any case. */ bool QueueCoordinator::DeleteQueueEntry(DownloadQueue* pDownloadQueue, FileInfo* pFileInfo) { pFileInfo->SetDeleted(true); bool bDownloading = false; for (ActiveDownloads::iterator it = m_ActiveDownloads.begin(); it != m_ActiveDownloads.end(); it++) { ArticleDownloader* pArticleDownloader = *it; if (pArticleDownloader->GetFileInfo() == pFileInfo) { bDownloading = true; pArticleDownloader->Stop(); } } if (!bDownloading) { DeleteFileInfo(pDownloadQueue, pFileInfo, false); } return bDownloading; }
void QueueCoordinator::ArticleCompleted(ArticleDownloader* pArticleDownloader) { debug("Article downloaded"); FileInfo* pFileInfo = pArticleDownloader->GetFileInfo(); NZBInfo* pNZBInfo = pFileInfo->GetNZBInfo(); ArticleInfo* pArticleInfo = pArticleDownloader->GetArticleInfo(); bool bRetry = false; bool fileCompleted = false; DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); if (pArticleDownloader->GetStatus() == ArticleDownloader::adFinished) { pArticleInfo->SetStatus(ArticleInfo::aiFinished); pFileInfo->SetSuccessSize(pFileInfo->GetSuccessSize() + pArticleInfo->GetSize()); pNZBInfo->SetCurrentSuccessSize(pNZBInfo->GetCurrentSuccessSize() + pArticleInfo->GetSize()); pNZBInfo->SetParCurrentSuccessSize(pNZBInfo->GetParCurrentSuccessSize() + (pFileInfo->GetParFile() ? pArticleInfo->GetSize() : 0)); pFileInfo->SetSuccessArticles(pFileInfo->GetSuccessArticles() + 1); pNZBInfo->SetCurrentSuccessArticles(pNZBInfo->GetCurrentSuccessArticles() + 1); } else if (pArticleDownloader->GetStatus() == ArticleDownloader::adFailed) { pArticleInfo->SetStatus(ArticleInfo::aiFailed); pFileInfo->SetFailedSize(pFileInfo->GetFailedSize() + pArticleInfo->GetSize()); pNZBInfo->SetCurrentFailedSize(pNZBInfo->GetCurrentFailedSize() + pArticleInfo->GetSize()); pNZBInfo->SetParCurrentFailedSize(pNZBInfo->GetParCurrentFailedSize() + (pFileInfo->GetParFile() ? pArticleInfo->GetSize() : 0)); pFileInfo->SetFailedArticles(pFileInfo->GetFailedArticles() + 1); pNZBInfo->SetCurrentFailedArticles(pNZBInfo->GetCurrentFailedArticles() + 1); } else if (pArticleDownloader->GetStatus() == ArticleDownloader::adRetry) { pArticleInfo->SetStatus(ArticleInfo::aiUndefined); bRetry = true; } if (!bRetry) { pFileInfo->SetRemainingSize(pFileInfo->GetRemainingSize() - pArticleInfo->GetSize()); pNZBInfo->SetRemainingSize(pNZBInfo->GetRemainingSize() - pArticleInfo->GetSize()); if (pFileInfo->GetPaused()) { pNZBInfo->SetPausedSize(pNZBInfo->GetPausedSize() - pArticleInfo->GetSize()); } pFileInfo->SetCompletedArticles(pFileInfo->GetCompletedArticles() + 1); fileCompleted = (int)pFileInfo->GetArticles()->size() == pFileInfo->GetCompletedArticles(); pFileInfo->GetServerStats()->ListOp(pArticleDownloader->GetServerStats(), ServerStatList::soAdd); pNZBInfo->GetCurrentServerStats()->ListOp(pArticleDownloader->GetServerStats(), ServerStatList::soAdd); pFileInfo->SetPartialChanged(true); } if (!pFileInfo->GetFilenameConfirmed() && pArticleDownloader->GetStatus() == ArticleDownloader::adFinished && pArticleDownloader->GetArticleFilename()) { pFileInfo->SetFilename(pArticleDownloader->GetArticleFilename()); pFileInfo->SetFilenameConfirmed(true); if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce && !pNZBInfo->GetManyDupeFiles() && Util::FileExists(pNZBInfo->GetDestDir(), pFileInfo->GetFilename())) { warn("File \"%s\" seems to be duplicate, cancelling download and deleting file from queue", pFileInfo->GetFilename()); fileCompleted = false; pFileInfo->SetAutoDeleted(true); DeleteQueueEntry(pDownloadQueue, pFileInfo); } } pNZBInfo->SetDownloadedSize(pNZBInfo->GetDownloadedSize() + pArticleDownloader->GetDownloadedSize()); bool deleteFileObj = false; if (fileCompleted && !pFileInfo->GetDeleted()) { // all jobs done DownloadQueue::Unlock(); pArticleDownloader->CompleteFileParts(); pDownloadQueue = DownloadQueue::Lock(); deleteFileObj = true; } CheckHealth(pDownloadQueue, pFileInfo); bool hasOtherDownloaders = false; for (ActiveDownloads::iterator it = m_ActiveDownloads.begin(); it != m_ActiveDownloads.end(); it++) { ArticleDownloader* pDownloader = *it; if (pDownloader != pArticleDownloader && pDownloader->GetFileInfo() == pFileInfo) { hasOtherDownloaders = true; break; } } deleteFileObj |= pFileInfo->GetDeleted() && !hasOtherDownloaders; // remove downloader from downloader list m_ActiveDownloads.erase(std::find(m_ActiveDownloads.begin(), m_ActiveDownloads.end(), pArticleDownloader)); pFileInfo->SetActiveDownloads(pFileInfo->GetActiveDownloads() - 1); pNZBInfo->SetActiveDownloads(pNZBInfo->GetActiveDownloads() - 1); if (deleteFileObj) { DeleteFileInfo(pDownloadQueue, pFileInfo, fileCompleted); pDownloadQueue->Save(); } DownloadQueue::Unlock(); }
void DOS_Drive_Cache::Clear(void) { DeleteFileInfo(dirBase); dirBase = 0; nextFreeFindFirst = 0; for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 0; }
DOS_Drive_Cache::~DOS_Drive_Cache(void) { Clear(); for (Bit32u i=0; i<MAX_OPENDIRS; i++) { DeleteFileInfo(dirFindFirst[i]); dirFindFirst[i]=0; }; }