Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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;
}