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(); }
void DownloadBinCommand::Execute() { SNZBDownloadRequest DownloadRequest; if (!ReceiveRequest(&DownloadRequest, sizeof(DownloadRequest))) { return; } char* pRecvBuffer = (char*)malloc(ntohl(DownloadRequest.m_iTrailingDataLength) + 1); char* pBufPtr = pRecvBuffer; // Read from the socket until nothing remains int iResult = 0; int NeedBytes = ntohl(DownloadRequest.m_iTrailingDataLength); while (NeedBytes > 0) { iResult = recv(m_iSocket, pBufPtr, NeedBytes, 0); // Did the recv succeed? if (iResult <= 0) { error("invalid request"); break; } pBufPtr += iResult; NeedBytes -= iResult; } if (NeedBytes == 0) { int iPriority = ntohl(DownloadRequest.m_iPriority); bool bAddPaused = ntohl(DownloadRequest.m_bAddPaused); NZBFile* pNZBFile = NZBFile::CreateFromBuffer(DownloadRequest.m_szFilename, DownloadRequest.m_szCategory, pRecvBuffer, ntohl(DownloadRequest.m_iTrailingDataLength)); if (pNZBFile) { info("Request: Queue collection %s", DownloadRequest.m_szFilename); for (NZBFile::FileInfos::iterator it = pNZBFile->GetFileInfos()->begin(); it != pNZBFile->GetFileInfos()->end(); it++) { FileInfo* pFileInfo = *it; pFileInfo->SetPriority(iPriority); pFileInfo->SetPaused(bAddPaused); } g_pQueueCoordinator->AddNZBFileToQueue(pNZBFile, ntohl(DownloadRequest.m_bAddFirst)); delete pNZBFile; char tmp[1024]; snprintf(tmp, 1024, "Collection %s added to queue", Util::BaseFileName(DownloadRequest.m_szFilename)); tmp[1024-1] = '\0'; SendBoolResponse(true, tmp); } else { char tmp[1024]; snprintf(tmp, 1024, "Download Request failed for %s", Util::BaseFileName(DownloadRequest.m_szFilename)); tmp[1024-1] = '\0'; SendBoolResponse(false, tmp); } } free(pRecvBuffer); }
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; }