1 /*
2  *  This file is part of nzbget. See <http://nzbget.net>.
3  *
4  *  Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
5  *  Copyright (C) 2007-2019 Andrey Prygunkov <hugbug@users.sourceforge.net>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #ifndef OPTIONS_H
23 #define OPTIONS_H
24 
25 #include "NString.h"
26 #include "Thread.h"
27 #include "Util.h"
28 
29 class Options
30 {
31 public:
32 	enum EWriteLog
33 	{
34 		wlNone,
35 		wlAppend,
36 		wlReset,
37 		wlRotate
38 	};
39 	enum EMessageTarget
40 	{
41 		mtNone,
42 		mtScreen,
43 		mtLog,
44 		mtBoth
45 	};
46 	enum EOutputMode
47 	{
48 		omLoggable,
49 		omColored,
50 		omNCurses
51 	};
52 	enum EParCheck
53 	{
54 		pcAuto,
55 		pcAlways,
56 		pcForce,
57 		pcManual
58 	};
59 	enum EParScan
60 	{
61 		psLimited,
62 		psExtended,
63 		psFull,
64 		psDupe
65 	};
66 	enum EHealthCheck
67 	{
68 		hcPause,
69 		hcDelete,
70 		hcPark,
71 		hcNone
72 	};
73 	enum ESchedulerCommand
74 	{
75 		scPauseDownload,
76 		scUnpauseDownload,
77 		scPausePostProcess,
78 		scUnpausePostProcess,
79 		scDownloadRate,
80 		scScript,
81 		scProcess,
82 		scPauseScan,
83 		scUnpauseScan,
84 		scActivateServer,
85 		scDeactivateServer,
86 		scFetchFeed
87 	};
88 	enum EPostStrategy
89 	{
90 		ppSequential,
91 		ppBalanced,
92 		ppAggressive,
93 		ppRocket
94 	};
95 	enum EFileNaming
96 	{
97 		nfAuto,
98 		nfArticle,
99 		nfNzb
100 	};
101 
102 	class OptEntry
103 	{
104 	public:
OptEntry(const char * name,const char * value)105 		OptEntry(const char* name, const char* value) :
106 			m_name(name), m_value(value) {}
SetName(const char * name)107 		void SetName(const char* name) { m_name = name; }
GetName()108 		const char* GetName() { return m_name; }
109 		void SetValue(const char* value);
GetValue()110 		const char* GetValue() { return m_value; }
GetDefValue()111 		const char* GetDefValue() { return m_defValue; }
GetLineNo()112 		int GetLineNo() { return m_lineNo; }
113 		bool Restricted();
114 
115 	private:
116 		CString m_name;
117 		CString m_value;
118 		CString m_defValue;
119 		int m_lineNo = 0;
120 
SetLineNo(int lineNo)121 		void SetLineNo(int lineNo) { m_lineNo = lineNo; }
122 
123 		friend class Options;
124 	};
125 
126 	typedef std::deque<OptEntry> OptEntriesBase;
127 
128 	class OptEntries: public OptEntriesBase
129 	{
130 	public:
131 		OptEntry* FindOption(const char* name);
132 	};
133 
134 	typedef GuardedPtr<OptEntries> GuardedOptEntries;
135 
136 	typedef std::vector<CString> NameList;
137 	typedef std::vector<const char*> CmdOptList;
138 
139 	class Category
140 	{
141 	public:
Category(const char * name,const char * destDir,bool unpack,const char * extensions)142 		Category(const char* name, const char* destDir, bool unpack, const char* extensions) :
143 			m_name(name), m_destDir(destDir), m_unpack(unpack), m_extensions(extensions) {}
GetName()144 		const char* GetName() { return m_name; }
GetDestDir()145 		const char* GetDestDir() { return m_destDir; }
GetUnpack()146 		bool GetUnpack() { return m_unpack; }
GetExtensions()147 		const char* GetExtensions() { return m_extensions; }
GetAliases()148 		NameList* GetAliases() { return &m_aliases; }
149 
150 	private:
151 		CString m_name;
152 		CString m_destDir;
153 		bool m_unpack;
154 		CString m_extensions;
155 		NameList m_aliases;
156 	};
157 
158 	typedef std::deque<Category> CategoriesBase;
159 
160 	class Categories: public CategoriesBase
161 	{
162 	public:
163 		Category* FindCategory(const char* name, bool searchAliases);
164 	};
165 
166 	class Extender
167 	{
168 	public:
169 		virtual void AddNewsServer(int id, bool active, const char* name, const char* host,
170 			int port, int ipVersion, const char* user, const char* pass, bool joinGroup,
171 			bool tls, const char* cipher, int maxConnections, int retention,
172 			int level, int group, bool optional) = 0;
AddFeed(int id,const char * name,const char * url,int interval,const char * filter,bool backlog,bool pauseNzb,const char * category,int priority,const char * extensions)173 		virtual void AddFeed(int id, const char* name, const char* url, int interval,
174 			const char* filter, bool backlog, bool pauseNzb, const char* category,
175 			int priority, const char* extensions) {}
AddTask(int id,int hours,int minutes,int weekDaysBits,ESchedulerCommand command,const char * param)176 		virtual void AddTask(int id, int hours, int minutes, int weekDaysBits, ESchedulerCommand command,
177 			const char* param) {}
SetupFirstStart()178 		virtual void SetupFirstStart() {}
179 	};
180 
181 	Options(const char* exeName, const char* configFilename, bool noConfig,
182 		CmdOptList* commandLineOptions, Extender* extender);
183 	Options(CmdOptList* commandLineOptions, Extender* extender);
184 	~Options();
185 
186 	static bool SplitOptionString(const char* option, CString& optName, CString& optValue);
187 	static void ConvertOldOptions(OptEntries* optEntries);
GetFatalError()188 	bool GetFatalError() { return m_fatalError; }
GuardOptEntries()189 	GuardedOptEntries GuardOptEntries() { return GuardedOptEntries(&m_optEntries, &m_optEntriesMutex); }
190 	void CreateSchedulerTask(int id, const char* time, const char* weekDays,
191 		ESchedulerCommand command, const char* param);
192 
193 	// Options
GetConfigFilename()194 	const char* GetConfigFilename() { return m_configFilename; }
GetConfigErrors()195 	bool GetConfigErrors() { return m_configErrors; }
GetAppDir()196 	const char* GetAppDir() { return m_appDir; }
GetDestDir()197 	const char* GetDestDir() { return m_destDir; }
GetInterDir()198 	const char* GetInterDir() { return m_interDir; }
GetTempDir()199 	const char* GetTempDir() { return m_tempDir; }
GetQueueDir()200 	const char* GetQueueDir() { return m_queueDir; }
GetNzbDir()201 	const char* GetNzbDir() { return m_nzbDir; }
GetWebDir()202 	const char* GetWebDir() { return m_webDir; }
GetConfigTemplate()203 	const char* GetConfigTemplate() { return m_configTemplate; }
GetScriptDir()204 	const char* GetScriptDir() { return m_scriptDir; }
GetRequiredDir()205 	const char* GetRequiredDir() { return m_requiredDir; }
GetNzbLog()206 	bool GetNzbLog() const { return m_nzbLog; }
GetInfoTarget()207 	EMessageTarget GetInfoTarget() const { return m_infoTarget; }
GetWarningTarget()208 	EMessageTarget GetWarningTarget() const { return m_warningTarget; }
GetErrorTarget()209 	EMessageTarget GetErrorTarget() const { return m_errorTarget; }
GetDebugTarget()210 	EMessageTarget GetDebugTarget() const { return m_debugTarget; }
GetDetailTarget()211 	EMessageTarget GetDetailTarget() const { return m_detailTarget; }
GetArticleTimeout()212 	int GetArticleTimeout() { return m_articleTimeout; }
GetUrlTimeout()213 	int GetUrlTimeout() { return m_urlTimeout; }
GetRemoteTimeout()214 	int GetRemoteTimeout() { return m_remoteTimeout; }
GetRawArticle()215 	bool GetRawArticle() { return m_rawArticle; };
GetSkipWrite()216 	bool GetSkipWrite() { return m_skipWrite; };
GetAppendCategoryDir()217 	bool GetAppendCategoryDir() { return m_appendCategoryDir; }
GetContinuePartial()218 	bool GetContinuePartial() { return m_continuePartial; }
GetArticleRetries()219 	int GetArticleRetries() { return m_articleRetries; }
GetArticleInterval()220 	int GetArticleInterval() { return m_articleInterval; }
GetUrlRetries()221 	int GetUrlRetries() { return m_urlRetries; }
GetUrlInterval()222 	int GetUrlInterval() { return m_urlInterval; }
GetFlushQueue()223 	bool GetFlushQueue() { return m_flushQueue; }
GetDupeCheck()224 	bool GetDupeCheck() { return m_dupeCheck; }
GetControlIp()225 	const char* GetControlIp() { return m_controlIp; }
GetControlUsername()226 	const char* GetControlUsername() { return m_controlUsername; }
GetControlPassword()227 	const char* GetControlPassword() { return m_controlPassword; }
GetRestrictedUsername()228 	const char* GetRestrictedUsername() { return m_restrictedUsername; }
GetRestrictedPassword()229 	const char* GetRestrictedPassword() { return m_restrictedPassword; }
GetAddUsername()230 	const char* GetAddUsername() { return m_addUsername; }
GetAddPassword()231 	const char* GetAddPassword() { return m_addPassword; }
GetControlPort()232 	int GetControlPort() { return m_controlPort; }
GetFormAuth()233 	bool GetFormAuth() { return m_formAuth; }
GetSecureControl()234 	bool GetSecureControl() { return m_secureControl; }
GetSecurePort()235 	int GetSecurePort() { return m_securePort; }
GetSecureCert()236 	const char* GetSecureCert() { return m_secureCert; }
GetSecureKey()237 	const char* GetSecureKey() { return m_secureKey; }
GetCertStore()238 	const char* GetCertStore() { return m_certStore; }
GetCertCheck()239 	bool GetCertCheck() { return m_certCheck; }
GetAuthorizedIp()240 	const char* GetAuthorizedIp() { return m_authorizedIp; }
GetLockFile()241 	const char* GetLockFile() { return m_lockFile; }
GetDaemonUsername()242 	const char* GetDaemonUsername() { return m_daemonUsername; }
GetOutputMode()243 	EOutputMode GetOutputMode() { return m_outputMode; }
GetUrlConnections()244 	int GetUrlConnections() { return m_urlConnections; }
GetLogBuffer()245 	int GetLogBuffer() { return m_logBuffer; }
GetWriteLog()246 	EWriteLog GetWriteLog() { return m_writeLog; }
GetLogFile()247 	const char* GetLogFile() { return m_logFile; }
GetRotateLog()248 	int GetRotateLog() { return m_rotateLog; }
GetParCheck()249 	EParCheck GetParCheck() { return m_parCheck; }
GetParRepair()250 	bool GetParRepair() { return m_parRepair; }
GetParScan()251 	EParScan GetParScan() { return m_parScan; }
GetParQuick()252 	bool GetParQuick() { return m_parQuick; }
GetPostStrategy()253 	EPostStrategy GetPostStrategy() { return m_postStrategy; }
GetParRename()254 	bool GetParRename() { return m_parRename; }
GetParBuffer()255 	int GetParBuffer() { return m_parBuffer; }
GetParThreads()256 	int GetParThreads() { return m_parThreads; }
GetRarRename()257 	bool GetRarRename() { return m_rarRename; }
GetHealthCheck()258 	EHealthCheck GetHealthCheck() { return m_healthCheck; }
GetScriptOrder()259 	const char* GetScriptOrder() { return m_scriptOrder; }
GetExtensions()260 	const char* GetExtensions() { return m_extensions; }
GetUMask()261 	int GetUMask() { return m_umask; }
GetUpdateInterval()262 	int GetUpdateInterval() {return m_updateInterval; }
GetCursesNzbName()263 	bool GetCursesNzbName() { return m_cursesNzbName; }
GetCursesTime()264 	bool GetCursesTime() { return m_cursesTime; }
GetCursesGroup()265 	bool GetCursesGroup() { return m_cursesGroup; }
GetCrcCheck()266 	bool GetCrcCheck() { return m_crcCheck; }
GetDirectWrite()267 	bool GetDirectWrite() { return m_directWrite; }
GetWriteBuffer()268 	int GetWriteBuffer() { return m_writeBuffer; }
GetNzbDirInterval()269 	int GetNzbDirInterval() { return m_nzbDirInterval; }
GetNzbDirFileAge()270 	int GetNzbDirFileAge() { return m_nzbDirFileAge; }
GetDiskSpace()271 	int GetDiskSpace() { return m_diskSpace; }
GetTls()272 	bool GetTls() { return m_tls; }
GetCrashTrace()273 	bool GetCrashTrace() { return m_crashTrace; }
GetCrashDump()274 	bool GetCrashDump() { return m_crashDump; }
GetParPauseQueue()275 	bool GetParPauseQueue() { return m_parPauseQueue; }
GetScriptPauseQueue()276 	bool GetScriptPauseQueue() { return m_scriptPauseQueue; }
GetNzbCleanupDisk()277 	bool GetNzbCleanupDisk() { return m_nzbCleanupDisk; }
GetParTimeLimit()278 	int GetParTimeLimit() { return m_parTimeLimit; }
GetKeepHistory()279 	int GetKeepHistory() { return m_keepHistory; }
GetUnpack()280 	bool GetUnpack() { return m_unpack; }
GetDirectUnpack()281 	bool GetDirectUnpack() { return m_directUnpack; }
GetUnpackCleanupDisk()282 	bool GetUnpackCleanupDisk() { return m_unpackCleanupDisk; }
GetUnrarCmd()283 	const char* GetUnrarCmd() { return m_unrarCmd; }
GetSevenZipCmd()284 	const char* GetSevenZipCmd() { return m_sevenZipCmd; }
GetUnpackPassFile()285 	const char* GetUnpackPassFile() { return m_unpackPassFile; }
GetUnpackPauseQueue()286 	bool GetUnpackPauseQueue() { return m_unpackPauseQueue; }
GetExtCleanupDisk()287 	const char* GetExtCleanupDisk() { return m_extCleanupDisk; }
GetParIgnoreExt()288 	const char* GetParIgnoreExt() { return m_parIgnoreExt; }
GetUnpackIgnoreExt()289 	const char* GetUnpackIgnoreExt() { return m_unpackIgnoreExt; }
GetFeedHistory()290 	int GetFeedHistory() { return m_feedHistory; }
GetUrlForce()291 	bool GetUrlForce() { return m_urlForce; }
GetTimeCorrection()292 	int GetTimeCorrection() { return m_timeCorrection; }
GetPropagationDelay()293 	int GetPropagationDelay() { return m_propagationDelay; }
GetArticleCache()294 	int GetArticleCache() { return m_articleCache; }
GetEventInterval()295 	int GetEventInterval() { return m_eventInterval; }
GetShellOverride()296 	const char* GetShellOverride() { return m_shellOverride; }
GetMonthlyQuota()297 	int GetMonthlyQuota() { return m_monthlyQuota; }
GetQuotaStartDay()298 	int GetQuotaStartDay() { return m_quotaStartDay; }
GetDailyQuota()299 	int GetDailyQuota() { return m_dailyQuota; }
GetDirectRename()300 	bool GetDirectRename() { return m_directRename; }
GetReorderFiles()301 	bool GetReorderFiles() { return m_reorderFiles; }
GetFileNaming()302 	EFileNaming GetFileNaming() { return m_fileNaming; }
GetDownloadRate()303 	int GetDownloadRate() const { return m_downloadRate; }
304 
GetCategories()305 	Categories* GetCategories() { return &m_categories; }
FindCategory(const char * name,bool searchAliases)306 	Category* FindCategory(const char* name, bool searchAliases) { return m_categories.FindCategory(name, searchAliases); }
307 
308 	// Current state
SetServerMode(bool serverMode)309 	void SetServerMode(bool serverMode) { m_serverMode = serverMode; }
GetServerMode()310 	bool GetServerMode() { return m_serverMode; }
SetDaemonMode(bool daemonMode)311 	void SetDaemonMode(bool daemonMode) { m_daemonMode = daemonMode; }
GetDaemonMode()312 	bool GetDaemonMode() { return m_daemonMode; }
SetRemoteClientMode(bool remoteClientMode)313 	void SetRemoteClientMode(bool remoteClientMode) { m_remoteClientMode = remoteClientMode; }
GetRemoteClientMode()314 	bool GetRemoteClientMode() { return m_remoteClientMode; }
315 
316 private:
317 	OptEntries m_optEntries;
318 	Mutex m_optEntriesMutex;
319 	Categories m_categories;
320 	bool m_noDiskAccess = false;
321 	bool m_noConfig = false;
322 	bool m_fatalError = false;
323 	Extender* m_extender;
324 
325 	// Options
326 	bool m_configErrors = false;
327 	int m_configLine = 0;
328 	CString m_appDir;
329 	CString m_configFilename;
330 	CString m_destDir;
331 	CString m_interDir;
332 	CString m_tempDir;
333 	CString m_queueDir;
334 	CString m_nzbDir;
335 	CString m_webDir;
336 	CString m_configTemplate;
337 	CString m_scriptDir;
338 	CString m_requiredDir;
339 	EMessageTarget m_infoTarget = mtScreen;
340 	EMessageTarget m_warningTarget = mtScreen;
341 	EMessageTarget m_errorTarget = mtScreen;
342 	EMessageTarget m_debugTarget = mtNone;
343 	EMessageTarget m_detailTarget = mtScreen;
344 	bool m_skipWrite = false;
345 	bool m_rawArticle = false;
346 	bool m_nzbLog = false;
347 	int m_articleTimeout = 0;
348 	int m_urlTimeout = 0;
349 	int m_remoteTimeout = 0;
350 	bool m_appendCategoryDir = false;
351 	bool m_continuePartial = false;
352 	int m_articleRetries = 0;
353 	int m_articleInterval = 0;
354 	int m_urlRetries = 0;
355 	int m_urlInterval = 0;
356 	bool m_flushQueue = false;
357 	bool m_dupeCheck = false;
358 	CString m_controlIp;
359 	CString m_controlUsername;
360 	CString m_controlPassword;
361 	CString m_restrictedUsername;
362 	CString m_restrictedPassword;
363 	CString m_addUsername;
364 	CString m_addPassword;
365 	bool m_formAuth = false;
366 	int m_controlPort = 0;
367 	bool m_secureControl = false;
368 	int m_securePort = 0;
369 	CString m_secureCert;
370 	CString m_secureKey;
371 	CString m_certStore;
372 	bool m_certCheck = false;
373 	CString m_authorizedIp;
374 	CString m_lockFile;
375 	CString m_daemonUsername;
376 	EOutputMode m_outputMode = omLoggable;
377 	int m_urlConnections = 0;
378 	int m_logBuffer = 0;
379 	EWriteLog m_writeLog = wlAppend;
380 	int m_rotateLog = 0;
381 	CString m_logFile;
382 	EParCheck m_parCheck = pcManual;
383 	bool m_parRepair = false;
384 	EParScan m_parScan = psLimited;
385 	bool m_parQuick = true;
386 	EPostStrategy m_postStrategy = ppSequential;
387 	bool m_parRename = false;
388 	int m_parBuffer = 0;
389 	int m_parThreads = 0;
390 	bool m_rarRename = false;
391 	bool m_directRename = false;
392 	EHealthCheck m_healthCheck = hcNone;
393 	CString m_extensions;
394 	CString m_scriptOrder;
395 	int m_umask = 0;
396 	int m_updateInterval = 0;
397 	bool m_cursesNzbName = false;
398 	bool m_cursesTime = false;
399 	bool m_cursesGroup = false;
400 	bool m_crcCheck = false;
401 	bool m_directWrite = false;
402 	int m_writeBuffer = 0;
403 	int m_nzbDirInterval = 0;
404 	int m_nzbDirFileAge = 0;
405 	int m_diskSpace = 0;
406 	bool m_tls = false;
407 	bool m_crashTrace = false;
408 	bool m_crashDump = false;
409 	bool m_parPauseQueue = false;
410 	bool m_scriptPauseQueue = false;
411 	bool m_nzbCleanupDisk = false;
412 	int m_parTimeLimit = 0;
413 	int m_keepHistory = 0;
414 	bool m_unpack = false;
415 	bool m_directUnpack = false;
416 	bool m_unpackCleanupDisk = false;
417 	CString m_unrarCmd;
418 	CString m_sevenZipCmd;
419 	CString m_unpackPassFile;
420 	bool m_unpackPauseQueue;
421 	CString m_extCleanupDisk;
422 	CString m_parIgnoreExt;
423 	CString m_unpackIgnoreExt;
424 	int m_feedHistory = 0;
425 	bool m_urlForce = false;
426 	int m_timeCorrection = 0;
427 	int m_propagationDelay = 0;
428 	int m_articleCache = 0;
429 	int m_eventInterval = 0;
430 	CString m_shellOverride;
431 	int m_monthlyQuota = 0;
432 	int m_quotaStartDay = 0;
433 	int m_dailyQuota = 0;
434 	bool m_reorderFiles = false;
435 	EFileNaming m_fileNaming = nfArticle;
436 	int m_downloadRate = 0;
437 
438 	// Application mode
439 	bool m_serverMode = false;
440 	bool m_daemonMode = false;
441 	bool m_remoteClientMode = false;
442 
443 	void Init(const char* exeName, const char* configFilename, bool noConfig,
444 		CmdOptList* commandLineOptions, bool noDiskAccess, Extender* extender);
445 	void InitDefaults();
446 	void InitOptions();
447 	void InitOptFile();
448 	void InitServers();
449 	void InitCategories();
450 	void InitScheduler();
451 	void InitFeeds();
452 	void InitCommandLineOptions(CmdOptList* commandLineOptions);
453 	void CheckOptions();
454 	int ParseEnumValue(const char* OptName, int argc, const char* argn[], const int argv[]);
455 	int ParseIntValue(const char* OptName, int base);
456 	OptEntry* FindOption(const char* optname);
457 	const char* GetOption(const char* optname);
458 	void SetOption(const char* optname, const char* value);
459 	bool SetOptionString(const char* option);
460 	bool ValidateOptionName(const char* optname, const char* optvalue);
461 	void LoadConfigFile();
462 	void CheckDir(CString& dir, const char* optionName, const char* parentDir,
463 		bool allowEmpty, bool create);
464 	bool ParseTime(const char* time, int* hours, int* minutes);
465 	bool ParseWeekDays(const char* weekDays, int* weekDaysBits);
466 	void ConfigError(const char* msg, ...);
467 	void ConfigWarn(const char* msg, ...);
468 	void LocateOptionSrcPos(const char *optionName);
469 	static void ConvertOldOption(CString& option, CString& value);
470 	static void MergeOldScriptOption(OptEntries* optEntries, const char* optname, bool mergeCategories);
471 	static bool HasScript(const char* scriptList, const char* scriptName);
472 };
473 
474 extern Options* g_Options;
475 
476 #endif
477