void TestNzb(std::string TestFilename) { INFO(std::string("Filename: ") + TestFilename); std::string NzbFilename(TestUtil::TestDataDir() + "/nzbfile/"+ TestFilename + ".nzb"); std::string InfoFilename(TestUtil::TestDataDir() + "/nzbfile/"+ TestFilename + ".txt"); NZBFile* pNZBFile = new NZBFile(NzbFilename.c_str(), ""); bool bParsedOK = pNZBFile->Parse(); REQUIRE(bParsedOK == true); FILE* infofile = fopen(InfoFilename.c_str(), FOPEN_RB); REQUIRE(infofile != NULL); char buffer[1024]; while (fgets(buffer, sizeof(buffer), infofile) && *buffer == '#') ; REQUIRE(*buffer); int iFileCount = atoi(buffer); REQUIRE(pNZBFile->GetNZBInfo()->GetFileCount() == iFileCount); for (int i = 0; i < iFileCount; i++) { while (fgets(buffer, sizeof(buffer), infofile) && *buffer == '#') ; REQUIRE(*buffer); FileInfo* pFileInfo = pNZBFile->GetNZBInfo()->GetFileList()->at(i); REQUIRE(pFileInfo != NULL); Util::TrimRight(buffer); REQUIRE(std::string(pFileInfo->GetFilename()) == std::string(buffer)); } fclose(infofile); delete pNZBFile; }
void HistoryCoordinator::HistoryRedownload(DownloadQueue* pDownloadQueue, HistoryList::iterator itHistory, HistoryInfo* pHistoryInfo, bool bRestorePauseState) { if (pHistoryInfo->GetKind() == HistoryInfo::hkUrl) { HistoryReturn(pDownloadQueue, itHistory, pHistoryInfo, false); return; } if (pHistoryInfo->GetKind() != HistoryInfo::hkNzb) { char szNiceName[1024]; pHistoryInfo->GetName(szNiceName, 1024); error("Could not return %s from history back to queue: history item has wrong type", szNiceName); return; } NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo(); bool bPaused = bRestorePauseState && pNZBInfo->GetDeletePaused(); if (!Util::FileExists(pNZBInfo->GetQueuedFilename())) { error("Could not return %s from history back to queue: could not find source nzb-file %s", pNZBInfo->GetName(), pNZBInfo->GetQueuedFilename()); return; } NZBFile* pNZBFile = new NZBFile(pNZBInfo->GetQueuedFilename(), ""); if (!pNZBFile->Parse()) { error("Could not return %s from history back to queue: could not parse nzb-file", pNZBInfo->GetName()); delete pNZBFile; return; } info("Returning %s from history back to queue", pNZBInfo->GetName()); for (FileList::iterator it = pNZBFile->GetNZBInfo()->GetFileList()->begin(); it != pNZBFile->GetNZBInfo()->GetFileList()->end(); it++) { FileInfo* pFileInfo = *it; pFileInfo->SetPaused(bPaused); } if (Util::DirectoryExists(pNZBInfo->GetDestDir())) { detail("Deleting %s", pNZBInfo->GetDestDir()); char szErrBuf[256]; if (!Util::DeleteDirectoryWithContent(pNZBInfo->GetDestDir(), szErrBuf, sizeof(szErrBuf))) { error("Could not delete directory %s: %s", pNZBInfo->GetDestDir(), szErrBuf); } } pNZBInfo->BuildDestDirName(); if (Util::DirectoryExists(pNZBInfo->GetDestDir())) { detail("Deleting %s", pNZBInfo->GetDestDir()); char szErrBuf[256]; if (!Util::DeleteDirectoryWithContent(pNZBInfo->GetDestDir(), szErrBuf, sizeof(szErrBuf))) { error("Could not delete directory %s: %s", pNZBInfo->GetDestDir(), szErrBuf); } } g_pDiskState->DiscardFiles(pNZBInfo); // reset status fields (which are not reset by "HistoryReturn") pNZBInfo->SetMoveStatus(NZBInfo::msNone); pNZBInfo->SetUnpackCleanedUpDisk(false); pNZBInfo->SetParStatus(NZBInfo::psNone); pNZBInfo->SetRenameStatus(NZBInfo::rsNone); pNZBInfo->SetDownloadedSize(0); pNZBInfo->SetDownloadSec(0); pNZBInfo->SetPostTotalSec(0); pNZBInfo->SetParSec(0); pNZBInfo->SetRepairSec(0); pNZBInfo->SetUnpackSec(0); pNZBInfo->SetExtraParBlocks(0); pNZBInfo->ClearCompletedFiles(); pNZBInfo->GetServerStats()->Clear(); pNZBInfo->GetCurrentServerStats()->Clear(); pNZBInfo->CopyFileList(pNZBFile->GetNZBInfo()); g_pQueueCoordinator->CheckDupeFileInfos(pNZBInfo); delete pNZBFile; HistoryReturn(pDownloadQueue, itHistory, pHistoryInfo, false); g_pPrePostProcessor->NZBAdded(pDownloadQueue, pNZBInfo); }
void Run(bool bReload) { g_pLog = new Log(); debug("nzbget %s", Util::VersionRevision()); if (!bReload) { Thread::Init(); } #ifdef WIN32 g_pWinConsole = new WinConsole(); g_pWinConsole->InitAppMode(); #endif g_pServerPool = new ServerPool(); g_pScheduler = new Scheduler(); g_pQueueCoordinator = new QueueCoordinator(); g_pStatMeter = new StatMeter(); g_pScanner = new Scanner(); g_pPrePostProcessor = new PrePostProcessor(); g_pHistoryCoordinator = new HistoryCoordinator(); g_pDupeCoordinator = new DupeCoordinator(); g_pUrlCoordinator = new UrlCoordinator(); g_pFeedCoordinator = new FeedCoordinator(); g_pArticleCache = new ArticleCache(); g_pMaintenance = new Maintenance(); g_pQueueScriptCoordinator = new QueueScriptCoordinator(); debug("Reading options"); g_pOptions = new Options(); g_pOptions->Init(g_iArgumentCount, *g_szArguments); #ifndef WIN32 if (g_pOptions->GetUMask() < 01000) { /* set newly created file permissions */ umask(g_pOptions->GetUMask()); } #endif g_pLog->InitOptions(); g_pScanner->InitOptions(); g_pQueueScriptCoordinator->InitOptions(); if (g_pOptions->GetDaemonMode()) { #ifdef WIN32 info("nzbget %s service-mode", Util::VersionRevision()); #else if (!bReload) { Daemonize(); } info("nzbget %s daemon-mode", Util::VersionRevision()); #endif } else if (g_pOptions->GetServerMode()) { info("nzbget %s server-mode", Util::VersionRevision()); } else if (g_pOptions->GetRemoteClientMode()) { info("nzbget %s remote-mode", Util::VersionRevision()); } if (!bReload) { Connection::Init(); } if (!g_pOptions->GetRemoteClientMode()) { g_pServerPool->InitConnections(); g_pStatMeter->Init(); } InstallErrorHandler(); #ifdef DEBUG if (g_pOptions->GetTestBacktrace()) { TestSegFault(); } #endif if (g_pOptions->GetWebGet()) { ProcessWebGet(); return; } // client request if (g_pOptions->GetClientOperation() != Options::opClientNoOperation) { ProcessClientRequest(); Cleanup(); return; } // Setup the network-server if (g_pOptions->GetServerMode()) { g_pRemoteServer = new RemoteServer(false); g_pRemoteServer->Start(); if (g_pOptions->GetSecureControl()) { g_pRemoteSecureServer = new RemoteServer(true); g_pRemoteSecureServer->Start(); } } // Create the frontend if (!g_pOptions->GetDaemonMode()) { switch (g_pOptions->GetOutputMode()) { case Options::omNCurses: #ifndef DISABLE_CURSES g_pFrontend = new NCursesFrontend(); break; #endif case Options::omColored: g_pFrontend = new ColoredFrontend(); break; case Options::omLoggable: g_pFrontend = new LoggableFrontend(); break; } } // Starting a thread with the frontend if (g_pFrontend) { g_pFrontend->Start(); } // Starting QueueCoordinator and PrePostProcessor if (!g_pOptions->GetRemoteClientMode()) { // Standalone-mode if (!g_pOptions->GetServerMode()) { const char* szCategory = g_pOptions->GetAddCategory() ? g_pOptions->GetAddCategory() : ""; NZBFile* pNZBFile = NZBFile::Create(g_pOptions->GetArgFilename(), szCategory); if (!pNZBFile) { abort("FATAL ERROR: Parsing NZB-document %s failed\n\n", g_pOptions->GetArgFilename() ? g_pOptions->GetArgFilename() : "N/A"); return; } g_pScanner->InitPPParameters(szCategory, pNZBFile->GetNZBInfo()->GetParameters(), false); g_pQueueCoordinator->AddNZBFileToQueue(pNZBFile, NULL, false); delete pNZBFile; } if (g_pOptions->GetSaveQueue() && g_pOptions->GetServerMode()) { g_pDiskState = new DiskState(); } #ifdef WIN32 g_pWinConsole->Start(); #endif g_pQueueCoordinator->Start(); g_pUrlCoordinator->Start(); g_pPrePostProcessor->Start(); g_pFeedCoordinator->Start(); if (g_pOptions->GetArticleCache() > 0) { g_pArticleCache->Start(); } // enter main program-loop while (g_pQueueCoordinator->IsRunning() || g_pUrlCoordinator->IsRunning() || g_pPrePostProcessor->IsRunning() || g_pFeedCoordinator->IsRunning() || #ifdef WIN32 g_pWinConsole->IsRunning() || #endif g_pArticleCache->IsRunning()) { if (!g_pOptions->GetServerMode() && !g_pQueueCoordinator->HasMoreJobs() && !g_pUrlCoordinator->HasMoreJobs() && !g_pPrePostProcessor->HasMoreJobs()) { // Standalone-mode: download completed if (!g_pQueueCoordinator->IsStopped()) { g_pQueueCoordinator->Stop(); } if (!g_pUrlCoordinator->IsStopped()) { g_pUrlCoordinator->Stop(); } if (!g_pPrePostProcessor->IsStopped()) { g_pPrePostProcessor->Stop(); } if (!g_pFeedCoordinator->IsStopped()) { g_pFeedCoordinator->Stop(); } if (!g_pArticleCache->IsStopped()) { g_pArticleCache->Stop(); } } usleep(100 * 1000); } // main program-loop is terminated debug("QueueCoordinator stopped"); debug("UrlCoordinator stopped"); debug("PrePostProcessor stopped"); debug("FeedCoordinator stopped"); debug("ArticleCache stopped"); } ScriptController::TerminateAll(); // Stop network-server if (g_pRemoteServer) { debug("stopping RemoteServer"); g_pRemoteServer->Stop(); int iMaxWaitMSec = 1000; while (g_pRemoteServer->IsRunning() && iMaxWaitMSec > 0) { usleep(100 * 1000); iMaxWaitMSec -= 100; } if (g_pRemoteServer->IsRunning()) { debug("Killing RemoteServer"); g_pRemoteServer->Kill(); } debug("RemoteServer stopped"); } if (g_pRemoteSecureServer) { debug("stopping RemoteSecureServer"); g_pRemoteSecureServer->Stop(); int iMaxWaitMSec = 1000; while (g_pRemoteSecureServer->IsRunning() && iMaxWaitMSec > 0) { usleep(100 * 1000); iMaxWaitMSec -= 100; } if (g_pRemoteSecureServer->IsRunning()) { debug("Killing RemoteSecureServer"); g_pRemoteSecureServer->Kill(); } debug("RemoteSecureServer stopped"); } // Stop Frontend if (g_pFrontend) { if (!g_pOptions->GetRemoteClientMode()) { debug("Stopping Frontend"); g_pFrontend->Stop(); } while (g_pFrontend->IsRunning()) { usleep(50 * 1000); } debug("Frontend stopped"); } Cleanup(); }
bool Scanner::AddFileToQueue(const char* szFilename, const char* szNZBName, const char* szCategory, int iPriority, const char* szDupeKey, int iDupeScore, EDupeMode eDupeMode, NZBParameterList* pParameters, bool bAddTop, bool bAddPaused, NZBInfo* pUrlInfo, int* pNZBID) { const char* szBasename = Util::BaseFileName(szFilename); info("Adding collection %s to queue", szBasename); NZBFile* pNZBFile = NZBFile::Create(szFilename, szCategory); bool bOK = pNZBFile != NULL; if (!bOK) { error("Could not add collection %s to queue", szBasename); } char bakname2[1024]; if (!Util::RenameBak(szFilename, pNZBFile ? "queued" : "error", false, bakname2, 1024)) { bOK = false; char szSysErrStr[256]; error("Could not rename file %s to %s: %s", szFilename, bakname2, Util::GetLastErrorMessage(szSysErrStr, sizeof(szSysErrStr))); } if (bOK) { NZBInfo* pNZBInfo = pNZBFile->GetNZBInfo(); pNZBInfo->SetQueuedFilename(bakname2); if (szNZBName && strlen(szNZBName) > 0) { pNZBInfo->SetName(NULL); #ifdef WIN32 char* szAnsiFilename = strdup(szNZBName); WebUtil::Utf8ToAnsi(szAnsiFilename, strlen(szAnsiFilename) + 1); pNZBInfo->SetFilename(szAnsiFilename); free(szAnsiFilename); #else pNZBInfo->SetFilename(szNZBName); #endif pNZBInfo->BuildDestDirName(); } pNZBInfo->SetDupeKey(szDupeKey); pNZBInfo->SetDupeScore(iDupeScore); pNZBInfo->SetDupeMode(eDupeMode); pNZBInfo->SetPriority(iPriority); if (pUrlInfo) { pNZBInfo->SetURL(pUrlInfo->GetURL()); pNZBInfo->SetUrlStatus(pUrlInfo->GetUrlStatus()); } if (pNZBFile->GetPassword()) { pNZBInfo->GetParameters()->SetParameter("*Unpack:Password", pNZBFile->GetPassword()); } pNZBInfo->GetParameters()->CopyFrom(pParameters); for (::FileList::iterator it = pNZBInfo->GetFileList()->begin(); it != pNZBInfo->GetFileList()->end(); it++) { FileInfo* pFileInfo = *it; pFileInfo->SetPaused(bAddPaused); } g_pQueueCoordinator->AddNZBFileToQueue(pNZBFile, pUrlInfo, bAddTop); if (pNZBID) { *pNZBID = pNZBInfo->GetID(); } } delete pNZBFile; return bOK; }