2025-12-14 17:17:48 +01:00
// Copyright (C) 2025, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System ;
using System.Linq ;
using System.Collections.Generic ;
using Duplicati.Library.Interface ;
using Duplicati.Library.Utility ;
using System.Globalization ;
using System.Threading ;
using Duplicati.Library.Utility.Options ;
using System.Diagnostics.CodeAnalysis ;
using Duplicati.Library.Snapshots ;
using System.Runtime.Versioning ;
using Duplicati.Library.Snapshots.MacOS ;
namespace Duplicati.Library.Main
{
/// <summary>
/// A class for keeping all Duplicati options in one place,
/// and provide typesafe access to the options
/// </summary>
public class Options
{
/// <summary>
/// The default block hash algorithm
/// </summary>
private const string DEFAULT_BLOCK_HASH_ALGORITHM = "SHA256" ;
/// <summary>
/// The default file hash algorithm
/// </summary>
private const string DEFAULT_FILE_HASH_ALGORITHM = "SHA256" ;
/// <summary>
/// The default block size, chose to minimize hash numbers but allow smaller upload sizes.
/// </summary>
private const string DEFAULT_BLOCKSIZE = "1mb" ;
/// <summary>
/// The default threshold value
/// </summary>
private const long DEFAULT_THRESHOLD = 25 ;
/// <summary>
/// The default value for maximum number of small files
/// </summary>
private const long DEFAULT_SMALL_FILE_MAX_COUNT = 20 ;
/// <summary>
/// Default size of volumes
/// </summary>
private const string DEFAULT_VOLUME_SIZE = "50mb" ;
/// <summary>
/// Default value for keep-versions
/// </summary>
private const int DEFAULT_KEEP_VERSIONS = 0 ;
/// <summary>
/// The default threshold for purging log data
/// </summary>
private const string DEFAULT_LOG_RETENTION = "30D" ;
/// <summary>
/// The default activity timeout
/// </summary>
private const string DEFAULT_READ_WRITE_TIMEOUT = "30s" ;
/// <summary>
/// The default number of concurrent uploads
/// </summary>
private const int DEFAULT_ASYNCHRONOUS_UPLOAD_LIMIT = 4 ;
/// <summary>
/// The backends where throttling is disabled by default
/// </summary>
private const string DEFAULT_THROTTLE_DISABLED_BACKENDS = "" ;
/// <summary>
/// The default retry delay
/// </summary>
private const string DEFAULT_RETRY_DELAY = "10s" ;
/// <summary>
/// The default number of retries
/// </summary>
private const int DEFAULT_NUMBER_OF_RETRIES = 5 ;
/// <summary>
/// The default number of backup test samples
/// </summary>
private const long DEFAULT_BACKUP_TEST_SAMPLES = 1 ;
/// <summary>
/// The default snapshot policy
/// </summary>
private static readonly OptimizationStrategy DEFAULT_SNAPSHOT_POLICY = PermissionHelper . HasSeBackupPrivilege ()
? OptimizationStrategy . Auto
: OptimizationStrategy . Off ;
/// <summary>
/// The default policy for BackupRead
/// </summary>
private static readonly OptimizationStrategy DEFAULT_BACKUPREAD_POLICY = OptimizationStrategy . Off ;
/// <summary>
/// The default MacOS photos handling strategy
/// </summary>
private static readonly MacOSPhotosHandling DEFAULT_MACOS_PHOTOS_HANDLING = MacOSPhotosHandling . PhotosAndLibrary ;
/// <summary>
/// The default number of compressor instances
/// </summary>
private static readonly int DEFAULT_COMPRESSORS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default number of file processors instances
/// </summary>
private static readonly int DEFAULT_FILE_PROCESSORS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default number of hasher instances
/// </summary>
private static readonly int DEFAULT_BLOCK_HASHERS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default threshold for warning about coming close to quota
/// </summary>
private const int DEFAULT_QUOTA_WARNING_THRESHOLD = 10 ;
/// <summary>
/// The default value for the maximum size of the restore cache
/// </summary>
private const string DEFAULT_RESTORE_CACHE_MAX = "4gb" ;
/// <summary>
/// The default value for the percentage of the restore cache to evict when full
/// </summary>
private const int DEFAULT_RESTORE_CACHE_EVICT = 50 ;
/// <summary>
/// The default value for the number of file processors during restore
/// </summary>
private static readonly int DEFAULT_RESTORE_FILE_PROCESSORS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default value for the maximum size of the restore volume cache is 100 times the volume size. E.g. for 50MB volumes, the default cache size is 5GB.
/// </summary>
private const string DEFAULT_RESTORE_VOLUME_CACHE_HINT = "" ;
/// <summary>
/// The default value for the number of volume decryptors during restore
/// </summary>
private static readonly int DEFAULT_RESTORE_VOLUME_DECRYPTORS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default value for the number of volume decompressors during restore
/// </summary>
private static readonly int DEFAULT_RESTORE_VOLUME_DECOMPRESSORS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default value for the number of volume downloaders during restore
/// </summary>
private static readonly int DEFAULT_RESTORE_VOLUME_DOWNLOADERS = Math . Max ( 1 , Environment . ProcessorCount / 2 );
/// <summary>
/// The default value for the size of the channel buffers during restore
/// </summary>
private static readonly int DEFAULT_RESTORE_CHANNEL_BUFFER_SIZE = Environment . ProcessorCount ;
/// <summary>
/// An enumeration that describes the supported strategies for an optimization
/// </summary>
public enum OptimizationStrategy
{
/// <summary>
/// The optimization feature is created if possible, but silently ignored if it fails
/// </summary>
Auto ,
/// <summary>
/// The optimization feature is created if possible, but an error is logged if it fails
/// </summary>
On ,
/// <summary>
/// The optimization feature is deactivated
/// </summary>
Off ,
/// <summary>
/// The optimization feature is created, and the backup is aborted if it fails
/// </summary>
Required
}
/// <summary>
/// The possible settings for the symlink strategy
/// </summary>
public enum SymlinkStrategy
{
/// <summary>
/// Store information about the symlink
/// </summary>
Store ,
/// <summary>
/// Treat symlinks as normal files or folders
/// </summary>
Follow ,
/// <summary>
/// Ignore all symlinks
/// </summary>
Ignore
}
/// <summary>
/// The possible settings for the remote test strategy
/// </summary>
public enum RemoteTestStrategy
{
/// <summary>
/// Test the remote volumes
/// </summary>
True = 0 ,
/// <summary>
/// Do not test the remote volumes
/// </summary>
False = 1 ,
/// <summary>
/// Test only the list and index volumes
/// </summary>
ListAndIndexes = 2 ,
/// <summary>
/// Test only the index files
/// </summary>
IndexesOnly = 3 ,
/// <summary>
/// Alias for IndexesOnly
/// </summary>
IndexOnly = 3
}
/// <summary>
/// The possible settings for the hardlink strategy
/// </summary>
public enum HardlinkStrategy
{
/// <summary>
/// Process only the first hardlink
/// </summary>
First ,
/// <summary>
/// Process all hardlinks
/// </summary>
All ,
/// <summary>
/// Ignore all hardlinks
/// </summary>
None
}
/// <summary>
/// The possible settings for index file usage
/// </summary>
public enum IndexFileStrategy
{
/// <summary>
/// Disables usage of index files
/// </summary>
None ,
/// <summary>
/// Stores only block lookup information in the index files
/// </summary>
Lookup ,
/// <summary>
/// Stores both block lookup and block lists in the index files
/// </summary>
Full
}
private static readonly string DEFAULT_COMPRESSED_EXTENSION_FILE = System . IO . Path . Combine ( Duplicati . Library . AutoUpdater . UpdaterManager . INSTALLATIONDIR , "default_compressed_extensions.txt" );
/// <summary>
/// Lock that protects the options collection
/// </summary>
protected readonly object m_lock = new object ();
protected readonly Dictionary < string , string? > m_options ;
/// <summary>
/// Lookup table for compression hints
/// </summary>
private Dictionary < string , CompressionHint >? m_compressionHints ;
public Options ( Dictionary < string , string? > options )
{
m_options = options ;
}
public Dictionary < string , string? > RawOptions => m_options ;
/// <summary>
/// Returns a list of strings that are not supported on the commandline as options, but used internally
/// </summary>
public static string [] InternalOptions => [
"main-action"
];
/// <summary>
/// Returns a list of options that are intentionally duplicate
/// </summary>
public static readonly IReadOnlySet < string > KnownDuplicates =
AuthOptionsHelper . GetOptions (). Select ( x => x . Name )
. Concat ( SslOptionsHelper . GetOptions (). Select ( x => x . Name ))
. Concat ( TimeoutOptionsHelper . GetOptions (). Select ( x => x . Name ))
. Concat ( AuthIdOptionsHelper . GetOptions ( "" ). Select ( x => x . Name ))
. ToHashSet ( StringComparer . OrdinalIgnoreCase );
/// <summary>
/// A default backup name
/// </summary>
public static string DefaultBackupName => System . IO . Path . GetFileNameWithoutExtension ( Library . Utility . Utility . getEntryAssembly (). Location );
/// <summary>
/// Gets the options that are conditional based on the operating system
/// </summary>
/// <returns>An enumerable of command line arguments</returns>
private IEnumerable < ICommandLineArgument > GetOSConditionalCommands ()
{
var items = new List < ICommandLineArgument >();
2026-02-04 15:02:31 +01:00
if ( OperatingSystem . IsWindows () || OperatingSystem . IsLinux () || OperatingSystem . IsMacOS ())
2025-12-14 17:17:48 +01:00
yield return new CommandLineArgument ( "snapshot-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . SnapshotpolicyShort , Strings . Options . SnapshotpolicyLong , DEFAULT_SNAPSHOT_POLICY . ToString (), null , Enum . GetNames ( typeof ( OptimizationStrategy )));
if ( OperatingSystem . IsWindows ())
{
yield return new CommandLineArgument ( "snapshot-provider" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . SnapshotproviderShort , Strings . Options . SnapshotproviderLong , WindowsSnapshot . DEFAULT_WINDOWS_SNAPSHOT_PROVIDER . ToString (), null , Enum . GetNames ( typeof ( Snapshots . WindowsSnapshotProvider )));
yield return new CommandLineArgument ( "vss-exclude-writers" , CommandLineArgument . ArgumentType . String , Strings . Options . VssexcludewritersShort , Strings . Options . VssexcludewritersLong , "{e8132975-6f93-4464-a53e-1050253ae220}" );
yield return new CommandLineArgument ( "vss-use-mapping" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . VssusemappingShort , Strings . Options . VssusemappingLong , "false" );
yield return new CommandLineArgument ( "usn-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . UsnpolicyShort , Strings . Options . UsnpolicyLong , "off" , null , Enum . GetNames ( typeof ( OptimizationStrategy )));
yield return new CommandLineArgument ( "backupread-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . BackupreadpolicyShort , Strings . Options . BackupreadpolicyLong , DEFAULT_BACKUPREAD_POLICY . ToString (), null , Enum . GetNames ( typeof ( OptimizationStrategy )));
}
if ( OperatingSystem . IsLinux () || OperatingSystem . IsMacOS ())
yield return new CommandLineArgument ( "ignore-advisory-locking" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . IgnoreadvisorylockingShort , Strings . Options . IgnoreadvisorylockingLong , "false" );
if ( OperatingSystem . IsMacOS () || OperatingSystem . IsLinux ())
yield return new CommandLineArgument ( "disable-backup-exclusion-xattr" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablebackupexclusionxattrShort , Strings . Options . DisablebackupexclusionxattrLong , "false" );
if ( OperatingSystem . IsMacOS ())
{
yield return new CommandLineArgument ( "photos-handling" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . DisablephotohandlingShort , Strings . Options . DisablephotohandlingLong , DEFAULT_MACOS_PHOTOS_HANDLING . ToString (), null , Enum . GetNames ( typeof ( MacOSPhotosHandling )));
yield return new CommandLineArgument ( "photos-library-path" , CommandLineArgument . ArgumentType . Path , Strings . Options . MacosphotoslibrarypathShort , Strings . Options . MacosphotoslibrarypathLong );
}
}
/// <summary>
/// Gets all supported commands
/// </summary>
public IList < ICommandLineArgument > SupportedCommands =>
[
new CommandLineArgument("dblock-size", CommandLineArgument.ArgumentType.Size, Strings.Options.DblocksizeShort, Strings.Options.DblocksizeLong, DEFAULT_VOLUME_SIZE),
new CommandLineArgument("auto-cleanup", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AutocleanupShort, Strings.Options.AutocleanupLong, "false"),
new CommandLineArgument("unittest-mode", CommandLineArgument.ArgumentType.Boolean, Strings.Options.UnittestmodeShort, Strings.Options.UnittestmodeLong, "false"),
new CommandLineArgument("control-files", CommandLineArgument.ArgumentType.Path, Strings.Options.ControlfilesShort, Strings.Options.ControlfilesLong),
new CommandLineArgument("skip-file-hash-checks", CommandLineArgument.ArgumentType.Boolean, Strings.Options.SkipfilehashchecksShort, Strings.Options.SkipfilehashchecksLong, "false"),
new CommandLineArgument("dont-read-manifests", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DontreadmanifestsShort, Strings.Options.DontreadmanifestsLong, "false"),
new CommandLineArgument("restore-path", CommandLineArgument.ArgumentType.String, Strings.Options.RestorepathShort, Strings.Options.RestorepathLong),
new CommandLineArgument("time", CommandLineArgument.ArgumentType.DateTime, Strings.Options.TimeShort, Strings.Options.TimeLong, "now"),
new CommandLineArgument("version", CommandLineArgument.ArgumentType.String, Strings.Options.VersionShort, Strings.Options.VersionLong, ""),
new CommandLineArgument("all-versions", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllversionsShort, Strings.Options.AllversionsLong, "false"),
new CommandLineArgument("list-prefix-only", CommandLineArgument.ArgumentType.Boolean, Strings.Options.ListprefixonlyShort, Strings.Options.ListprefixonlyLong, "false"),
2026-01-27 14:10:31 +01:00
new CommandLineArgument("soft-delete-prefix", CommandLineArgument.ArgumentType.String, Strings.Options.SoftdeleteprefixShort, Strings.Options.SoftdeleteprefixLong),
new CommandLineArgument("prevent-backend-rename", CommandLineArgument.ArgumentType.Boolean, Strings.Options.PreventbackendrenameShort, Strings.Options.PreventbackendrenameLong, "false"),
2025-12-14 17:17:48 +01:00
new CommandLineArgument("list-folder-contents", CommandLineArgument.ArgumentType.Boolean, Strings.Options.ListfoldercontentsShort, Strings.Options.ListfoldercontentsLong, "false"),
new CommandLineArgument("list-sets-only", CommandLineArgument.ArgumentType.Boolean, Strings.Options.ListsetsonlyShort, Strings.Options.ListsetsonlyLong, "false"),
new CommandLineArgument("disable-autocreate-folder", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisableautocreatefolderShort, Strings.Options.DisableautocreatefolderLong, "false"),
new CommandLineArgument("allow-missing-source", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowmissingsourceShort, Strings.Options.AllowmissingsourceLong, "false"),
new CommandLineArgument("prevent-empty-source", CommandLineArgument.ArgumentType.Boolean, Strings.Options.PreventemptysourceShort, Strings.Options.PreventemptysourceLong, "false"),
new CommandLineArgument("disable-filetime-check", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablefiletimecheckShort, Strings.Options.DisablefiletimecheckLong, "false"),
new CommandLineArgument("check-filetime-only", CommandLineArgument.ArgumentType.Boolean, Strings.Options.CheckfiletimeonlyShort, Strings.Options.CheckfiletimeonlyLong, "false"),
new CommandLineArgument("disable-time-tolerance", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisabletimetoleranceShort, Strings.Options.DisabletimetoleranceLong, "false"),
new CommandLineArgument("tempdir", CommandLineArgument.ArgumentType.Path, Strings.Options.TempdirShort, Strings.Options.TempdirLong, System.IO.Path.GetTempPath()),
new CommandLineArgument("thread-priority", CommandLineArgument.ArgumentType.Enumeration, Strings.Options.ThreadpriorityShort, Strings.Options.ThreadpriorityLong, "normal", null, new string[] { "highest" , "high" , "abovenormal" , "normal" , "belownormal" , "low" , "lowest" , "idle" }, Strings . Options . ThreadpriorityDeprecated ),
new CommandLineArgument ( "prefix" , CommandLineArgument . ArgumentType . String , Strings . Options . PrefixShort , Strings . Options . PrefixLong , "duplicati" ),
new CommandLineArgument ( "passphrase" , CommandLineArgument . ArgumentType . Password , Strings . Options . PassphraseShort , Strings . Options . PassphraseLong ),
new CommandLineArgument ( "new-passphrase" , CommandLineArgument . ArgumentType . Password , Strings . Options . PassphraseShort , Strings . Options . PassphraseLong ),
new CommandLineArgument ( "no-encryption" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NoencryptionShort , Strings . Options . NoencryptionLong , "false" ),
new CommandLineArgument ( "number-of-retries" , CommandLineArgument . ArgumentType . Integer , Strings . Options . NumberofretriesShort , Strings . Options . NumberofretriesLong , DEFAULT_NUMBER_OF_RETRIES . ToString ()),
new CommandLineArgument ( "retry-delay" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . RetrydelayShort , Strings . Options . RetrydelayLong , DEFAULT_RETRY_DELAY ),
new CommandLineArgument ( "retry-with-exponential-backoff" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RetrywithexponentialbackoffShort , Strings . Options . RetrywithexponentialbackoffLong , "false" ),
new CommandLineArgument ( "synchronous-upload" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . SynchronousuploadShort , Strings . Options . SynchronousuploadLong , "false" ),
new CommandLineArgument ( "asynchronous-upload-limit" , CommandLineArgument . ArgumentType . Integer , Strings . Options . AsynchronousconcurrentuploadlimitShort , Strings . Options . AsynchronousconcurrentuploadlimitLong , DEFAULT_ASYNCHRONOUS_UPLOAD_LIMIT . ToString (), [ "asynchronous-concurrent-upload-limit" ]),
new CommandLineArgument ( "asynchronous-upload-folder" , CommandLineArgument . ArgumentType . Path , Strings . Options . AsynchronousuploadfolderShort , Strings . Options . AsynchronousuploadfolderLong , System . IO . Path . GetTempPath ()),
new CommandLineArgument ( "disable-streaming-transfers" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisableStreamingShort , Strings . Options . DisableStreamingLong , "false" ),
new CommandLineArgument ( "throttle-upload" , CommandLineArgument . ArgumentType . Size , Strings . Options . ThrottleuploadShort , Strings . Options . ThrottleuploadLong , "0kb" ),
new CommandLineArgument ( "throttle-download" , CommandLineArgument . ArgumentType . Size , Strings . Options . ThrottledownloadShort , Strings . Options . ThrottledownloadLong , "0kb" ),
new CommandLineArgument ( "throttle-disabled" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablethrottleShort , Strings . Options . DisablethrottleLong , "false" ),
new CommandLineArgument ( "throttle-disabled-backends" , CommandLineArgument . ArgumentType . String , Strings . Options . DisablethrottlebackendsShort , Strings . Options . DisablethrottlebackendsLong ( "throttle-disabled" ), DEFAULT_THROTTLE_DISABLED_BACKENDS ),
new CommandLineArgument ( "skip-files-larger-than" , CommandLineArgument . ArgumentType . Size , Strings . Options . SkipfileslargerthanShort , Strings . Options . SkipfileslargerthanLong ),
new CommandLineArgument ( "upload-unchanged-backups" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . UploadUnchangedBackupsShort , Strings . Options . UploadUnchangedBackupsLong , "false" ),
new CommandLineArgument ( "encryption-module" , CommandLineArgument . ArgumentType . String , Strings . Options . EncryptionmoduleShort , Strings . Options . EncryptionmoduleLong , "aes" ),
new CommandLineArgument ( "compression-module" , CommandLineArgument . ArgumentType . String , Strings . Options . CompressionmoduleShort , Strings . Options . CompressionmoduleLong , "zip" ),
new CommandLineArgument ( "enable-module" , CommandLineArgument . ArgumentType . String , Strings . Options . EnablemoduleShort , Strings . Options . EnablemoduleLong ),
new CommandLineArgument ( "disable-module" , CommandLineArgument . ArgumentType . String , Strings . Options . DisablemoduleShort , Strings . Options . DisablemoduleLong ),
new CommandLineArgument ( "debug-output" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DebugoutputShort , Strings . Options . DebugoutputLong , "false" ),
new CommandLineArgument ( "debug-retry-errors" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DebugretryerrorsShort , Strings . Options . DebugretryerrorsLong , "false" ),
new CommandLineArgument ( "log-file" , CommandLineArgument . ArgumentType . Path , Strings . Options . LogfileShort , Strings . Options . LogfileLong ),
new CommandLineArgument ( "log-file-log-level" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . LogfileloglevelShort , Strings . Options . LogfileloglevelLong , "Warning" , null , Enum . GetNames ( typeof ( Duplicati . Library . Logging . LogMessageType ))),
new CommandLineArgument ( "log-file-log-filter" , CommandLineArgument . ArgumentType . String , Strings . Options . LogfilelogfiltersShort , Strings . Options . LogfilelogfiltersLong ( System . IO . Path . PathSeparator . ToString ()), null ),
new CommandLineArgument ( "log-file-log-ignore" , CommandLineArgument . ArgumentType . String , Strings . Options . LogfilelogignoreShort , Strings . Options . LogfilelogignoreLong ( System . IO . Path . PathSeparator . ToString ()), null ),
new CommandLineArgument ( "console-log-level" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . ConsoleloglevelShort , Strings . Options . ConsoleloglevelLong , "Warning" , null , Enum . GetNames ( typeof ( Duplicati . Library . Logging . LogMessageType ))),
new CommandLineArgument ( "console-log-filter" , CommandLineArgument . ArgumentType . String , Strings . Options . ConsolelogfiltersShort , Strings . Options . ConsolelogfiltersLong ( System . IO . Path . PathSeparator . ToString ()), null ),
new CommandLineArgument ( "console-log-ignore" , CommandLineArgument . ArgumentType . String , Strings . Options . ConsolelogignoreShort , Strings . Options . ConsolelogignoreLong ( System . IO . Path . PathSeparator . ToString ()), null ),
new CommandLineArgument ( "log-level" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . LoglevelShort , Strings . Options . LoglevelLong , "Warning" , null , Enum . GetNames ( typeof ( Duplicati . Library . Logging . LogMessageType )), Strings . Options . LogLevelDeprecated ( "log-file-log-level" , "console-log-level" )),
new CommandLineArgument ( "suppress-warnings" , CommandLineArgument . ArgumentType . String , Strings . Options . SuppresswarningsShort , Strings . Options . SuppresswarningsLong ),
new CommandLineArgument ( "log-http-requests" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . LoghttprequestsShort , Strings . Options . LoghttprequestsLong , "false" ),
new CommandLineArgument ( "log-socket-data" , CommandLineArgument . ArgumentType . Integer , Strings . Options . LogsocketdataShort , Strings . Options . LogsocketdataLong , "-1" ),
new CommandLineArgument ( "profile-all-database-queries" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ProfilealldatabasequeriesShort , Strings . Options . ProfilealldatabasequeriesLong , "false" ),
2026-01-14 09:58:19 +01:00
new CommandLineArgument ( "store-metadata-content-in-database" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . StoremetadatacontentindatabaseShort , Strings . Options . StoremetadatacontentindatabaseLong , "false" ),
2025-12-14 17:17:48 +01:00
new CommandLineArgument ( "list-verify-uploads" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ListverifyuploadsShort , Strings . Options . ListverifyuploadsLong , "false" ),
new CommandLineArgument ( "allow-sleep" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . AllowsleepShort , Strings . Options . AllowsleepLong , "false" ),
new CommandLineArgument ( "use-background-io-priority" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . UsebackgroundiopriorityShort , Strings . Options . UsebackgroundiopriorityLong , "false" ),
new CommandLineArgument ( "no-connection-reuse" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NoconnectionreuseShort , Strings . Options . NoconnectionreuseLong , "false" ),
new CommandLineArgument ( "quota-size" , CommandLineArgument . ArgumentType . Size , Strings . Options . QuotasizeShort , Strings . Options . QuotasizeLong ),
new CommandLineArgument ( "quota-warning-threshold" , CommandLineArgument . ArgumentType . Integer , Strings . Options . QuotaWarningThresholdShort , Strings . Options . QuotaWarningThresholdLong , DEFAULT_QUOTA_WARNING_THRESHOLD . ToString ()),
new CommandLineArgument ( "quota-disable" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . QuotaDisableShort , Strings . Options . QuotaDisableLong ( "quota-size" ), "false" ),
new CommandLineArgument ( "symlink-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . SymlinkpolicyShort , Strings . Options . SymlinkpolicyLong ( "store" , "ignore" , "follow" ), Enum . GetName ( typeof ( SymlinkStrategy ), SymlinkStrategy . Store ), null , Enum . GetNames ( typeof ( SymlinkStrategy ))),
new CommandLineArgument ( "hardlink-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . HardlinkpolicyShort , Strings . Options . HardlinkpolicyLong ( "first" , "all" , "none" ), Enum . GetName ( typeof ( HardlinkStrategy ), HardlinkStrategy . All ), null , Enum . GetNames ( typeof ( HardlinkStrategy ))),
new CommandLineArgument ( "exclude-files-attributes" , CommandLineArgument . ArgumentType . String , Strings . Options . ExcludefilesattributesShort , Strings . Options . ExcludefilesattributesLong ( Enum . GetNames ( typeof ( System . IO . FileAttributes )))),
new CommandLineArgument ( "compression-extension-file" , CommandLineArgument . ArgumentType . Path , Strings . Options . CompressionextensionfileShort , Strings . Options . CompressionextensionfileLong ( DEFAULT_COMPRESSED_EXTENSION_FILE ), DEFAULT_COMPRESSED_EXTENSION_FILE ),
new CommandLineArgument ( "machine-id" , CommandLineArgument . ArgumentType . String , Strings . Options . MachineidShort , Strings . Options . MachineidLong , Library . AutoUpdater . DataFolderManager . InstallID ),
new CommandLineArgument ( "machine-name" , CommandLineArgument . ArgumentType . String , Strings . Options . MachinenameShort , Strings . Options . MachinenameLong , Library . AutoUpdater . DataFolderManager . MachineName ),
new CommandLineArgument ( "backup-id" , CommandLineArgument . ArgumentType . String , Strings . Options . BackupidShort , Strings . Options . BackupidLong , "" ),
new CommandLineArgument ( "backup-name" , CommandLineArgument . ArgumentType . String , Strings . Options . BackupnameShort , Strings . Options . BackupnameLong , DefaultBackupName ),
new CommandLineArgument ( "next-scheduled-run" , CommandLineArgument . ArgumentType . String , Strings . Options . NextscheduledrunShort , Strings . Options . NextscheduledrunLong ),
new CommandLineArgument ( "verbose" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . VerboseShort , Strings . Options . VerboseLong , "false" , null , null , Strings . Options . VerboseDeprecated ),
new CommandLineArgument ( "full-result" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . FullresultShort , Strings . Options . FullresultLong , "false" ),
new CommandLineArgument ( "overwrite" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . OverwriteShort , Strings . Options . OverwriteLong , "false" ),
new CommandLineArgument ( "dbpath" , CommandLineArgument . ArgumentType . Path , Strings . Options . DbpathShort , Strings . Options . DbpathLong ),
new CommandLineArgument ( "blocksize" , CommandLineArgument . ArgumentType . Size , Strings . Options . BlocksizeShort , Strings . Options . BlocksizeLong , DEFAULT_BLOCKSIZE ),
new CommandLineArgument ( "file-read-buffer-size" , CommandLineArgument . ArgumentType . Size , Strings . Options . FilereadbuffersizeShort , Strings . Options . FilereadbuffersizeLong , "0kb" , null , null , Strings . Options . FilereadbuffersizeDeprecated ),
new CommandLineArgument ( "skip-metadata" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . SkipmetadataShort , Strings . Options . SkipmetadataLong , "false" ),
new CommandLineArgument ( "restore-permissions" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RestorepermissionsShort , Strings . Options . RestorepermissionsLong , "false" ),
new CommandLineArgument ( "skip-restore-verification" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . SkiprestoreverificationShort , Strings . Options . SkiprestoreverificationLong , "false" ),
new CommandLineArgument ( "disable-filepath-cache" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablefilepathcacheShort , Strings . Options . DisablefilepathcacheLong , "true" , null , null , Strings . Options . DisablefilepathcacheDeprecated ),
new CommandLineArgument ( "changed-files" , CommandLineArgument . ArgumentType . Path , Strings . Options . ChangedfilesShort , Strings . Options . ChangedfilesLong ),
new CommandLineArgument ( "deleted-files" , CommandLineArgument . ArgumentType . Path , Strings . Options . DeletedfilesShort , Strings . Options . DeletedfilesLong ( "changed-files" )),
new CommandLineArgument ( "disable-synthetic-filelist" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablesyntheticfilelistShort , Strings . Options . DisablesyntehticfilelistLong , "false" ),
new CommandLineArgument ( "threshold" , CommandLineArgument . ArgumentType . Integer , Strings . Options . ThresholdShort , Strings . Options . ThresholdLong , DEFAULT_THRESHOLD . ToString ()),
new CommandLineArgument ( "index-file-policy" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . IndexfilepolicyShort , Strings . Options . IndexfilepolicyLong , IndexFileStrategy . Full . ToString (), null , Enum . GetNames ( typeof ( IndexFileStrategy ))),
new CommandLineArgument ( "no-backend-verification" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NobackendverificationShort , Strings . Options . NobackendverificationLong , "false" ),
new CommandLineArgument ( "backup-test-samples" , CommandLineArgument . ArgumentType . Integer , Strings . Options . BackendtestsamplesShort , Strings . Options . BackendtestsamplesLong ( "no-backend-verification" ), DEFAULT_BACKUP_TEST_SAMPLES . ToString ()),
new CommandLineArgument ( "backup-test-percentage" , CommandLineArgument . ArgumentType . Decimal , Strings . Options . BackendtestpercentageShort , Strings . Options . BackendtestpercentageLong , "0.1" ),
new CommandLineArgument ( "full-remote-verification" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . FullremoteverificationShort , Strings . Options . FullremoteverificationLong ( "no-backend-verification" ), Enum . GetName ( typeof ( RemoteTestStrategy ), RemoteTestStrategy . False ), null , Enum . GetNames ( typeof ( RemoteTestStrategy ))),
new CommandLineArgument ( "dont-replace-faulty-index-files" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ReplaceFaultyIndexFilesShort , Strings . Options . ReplaceFaultyIndexFilesLong , "false" ),
new CommandLineArgument ( "dry-run" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DryrunShort , Strings . Options . DryrunLong , "false" , new string [] { "dryrun" }),
new CommandLineArgument ( "block-hash-algorithm" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . BlockhashalgorithmShort , Strings . Options . BlockhashalgorithmLong , DEFAULT_BLOCK_HASH_ALGORITHM , null , HashFactory . GetSupportedHashes ()),
new CommandLineArgument ( "file-hash-algorithm" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . FilehashalgorithmShort , Strings . Options . FilehashalgorithmLong , DEFAULT_FILE_HASH_ALGORITHM , null , HashFactory . GetSupportedHashes ()),
new CommandLineArgument ( "no-auto-compact" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NoautocompactShort , Strings . Options . NoautocompactLong , "false" ),
new CommandLineArgument ( "small-file-size" , CommandLineArgument . ArgumentType . Size , Strings . Options . SmallfilesizeShort , Strings . Options . SmallfilesizeLong ),
new CommandLineArgument ( "small-file-max-count" , CommandLineArgument . ArgumentType . Integer , Strings . Options . SmallfilemaxcountShort , Strings . Options . SmallfilemaxcountLong , DEFAULT_SMALL_FILE_MAX_COUNT . ToString ()),
new CommandLineArgument ( "patch-with-local-blocks" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . PatchwithlocalblocksShort , Strings . Options . PatchwithlocalblocksLong , "false" , null , null , Strings . Options . PatchwithlocalblocksDeprecated ( "restore-with-local-blocks" )),
new CommandLineArgument ( "no-local-db" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NolocaldbShort , Strings . Options . NolocaldbLong , "false" ),
new CommandLineArgument ( "dont-compress-restore-paths" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DontcompressrestorepathsShort , Strings . Options . DontcompressrestorepathsLong , "false" ),
2026-01-27 15:51:30 +01:00
new CommandLineArgument ( "allow-restore-outside-target-directory" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . AllowRestoreOutsideTargetDirectoryShort , Strings . Options . AllowRestoreOutsideTargetDirectoryLong , "false" ),
2025-12-14 17:17:48 +01:00
new CommandLineArgument ( "keep-versions" , CommandLineArgument . ArgumentType . Integer , Strings . Options . KeepversionsShort , Strings . Options . KeepversionsLong , DEFAULT_KEEP_VERSIONS . ToString ()),
new CommandLineArgument ( "keep-time" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . KeeptimeShort , Strings . Options . KeeptimeLong ),
2025-12-17 22:27:38 +01:00
new CommandLineArgument ( "remote-file-lock-duration" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . RemotefilelockdurationShort , Strings . Options . RemotefilelockdurationLong ),
2025-12-14 17:17:48 +01:00
new CommandLineArgument ( "retention-policy" , CommandLineArgument . ArgumentType . String , Strings . Options . RetentionPolicyShort , Strings . Options . RetentionPolicyLong ),
new CommandLineArgument ( "upload-verification-file" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . UploadverificationfileShort , Strings . Options . UploadverificationfileLong , "false" ),
new CommandLineArgument ( "allow-passphrase-change" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . AllowpassphrasechangeShort , Strings . Options . AllowpassphrasechangeLong , "false" ),
new CommandLineArgument ( "no-local-blocks" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . NolocalblocksShort , Strings . Options . NolocalblocksLong , "false" , null , null , Strings . Options . NolocalblocksDeprecated ( "restore-with-local-blocks" )),
new CommandLineArgument ( "restore-with-local-blocks" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RestorewithlocalblocksShort , Strings . Options . RestorewithlocalblocksLong , "false" ),
new CommandLineArgument ( "full-block-verification" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . FullblockverificationShort , Strings . Options . FullblockverificationLong , "false" ),
new CommandLineArgument ( "allow-full-removal" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . AllowfullremovalShort , Strings . Options . AllowfullremovalLong , "false" ),
new CommandLineArgument ( "log-retention" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . LogretentionShort , Strings . Options . LogretentionLong , DEFAULT_LOG_RETENTION ),
new CommandLineArgument ( "repair-only-paths" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RepaironlypathsShort , Strings . Options . RepaironlypathsLong , "false" ),
new CommandLineArgument ( "repair-force-block-use" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RepaironlypathsShort , Strings . Options . RepaironlypathsLong , "false" ),
new CommandLineArgument ( "repair-ignore-outdated-database" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RepairignoreoutdateddatabaseShort , Strings . Options . RepairignoreoutdateddatabaseLong , "false" ),
new CommandLineArgument ( "force-locale" , CommandLineArgument . ArgumentType . String , Strings . Options . ForcelocaleShort , Strings . Options . ForcelocaleLong ),
new CommandLineArgument ( "force-actual-date" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ForceActualDateShort , Strings . Options . ForceActualDateLong , "false" ),
new CommandLineArgument ( "concurrency-max-threads" , CommandLineArgument . ArgumentType . Integer , Strings . Options . ConcurrencymaxthreadsShort , Strings . Options . ConcurrencymaxthreadsLong , "0" ),
new CommandLineArgument ( "concurrency-block-hashers" , CommandLineArgument . ArgumentType . Integer , Strings . Options . ConcurrencyblockhashersShort , Strings . Options . ConcurrencyblockhashersLong , DEFAULT_BLOCK_HASHERS . ToString ()),
new CommandLineArgument ( "concurrency-compressors" , CommandLineArgument . ArgumentType . Integer , Strings . Options . ConcurrencycompressorsShort , Strings . Options . ConcurrencycompressorsLong , DEFAULT_COMPRESSORS . ToString ()),
new CommandLineArgument ( "concurrency-fileprocessors" , CommandLineArgument . ArgumentType . Integer , Strings . Options . ConcurrencyfileprocessorsShort , Strings . Options . ConcurrencyfileprocessorsLong , DEFAULT_FILE_PROCESSORS . ToString ()),
new CommandLineArgument ( "auto-vacuum" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . AutoVacuumShort , Strings . Options . AutoVacuumLong , "false" ),
new CommandLineArgument ( "disable-file-scanner" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablefilescannerShort , Strings . Options . DisablefilescannerLong , "false" ),
new CommandLineArgument ( "disable-filelist-consistency-checks" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablefilelistconsistencychecksShort , Strings . Options . DisablefilelistconsistencychecksLong , "false" ),
new CommandLineArgument ( "disable-on-battery" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisableOnBatteryShort , Strings . Options . DisableOnBatteryLong , "false" ),
new CommandLineArgument ( "exclude-empty-folders" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ExcludeemptyfoldersShort , Strings . Options . ExcludeemptyfoldersLong , "false" ),
new CommandLineArgument ( "ignore-filenames" , CommandLineArgument . ArgumentType . Path , Strings . Options . IgnorefilenamesShort , Strings . Options . IgnorefilenamesLong , "CACHEDIR.TAG" ),
new CommandLineArgument ( "restore-symlink-metadata" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RestoresymlinkmetadataShort , Strings . Options . RestoresymlinkmetadataLong , "false" ),
new CommandLineArgument ( "rebuild-missing-dblock-files" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RebuildmissingdblockfilesShort , Strings . Options . RebuildmissingdblockfilesLong , "false" ),
new CommandLineArgument ( "disable-partial-dblock-recovery" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisablePartialDblockRecoveryShort , Strings . Options . DisablePartialDblockRecoveryLong , "false" ),
new CommandLineArgument ( "disable-replace-missing-metadata" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . DisableReplaceMissingMetadataShort , Strings . Options . DisableReplaceMissingMetadataLong , "false" ),
2026-01-27 21:15:50 +01:00
new CommandLineArgument ( "reduced-purge-statistics" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . ReducedPurgeStatisticsShort , Strings . Options . ReducedPurgeStatisticsLong , "false" ),
2025-12-14 17:17:48 +01:00
new CommandLineArgument ( "repair-refresh-lock-info" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RepairRefreshLockInfoShort , Strings . Options . RepairRefreshLockInfoLong , "false" ),
new CommandLineArgument ( "refresh-lock-info-complete" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RefreshLockInfoCompleteShort , Strings . Options . RefreshLockInfoCompleteLong , "false" ),
new CommandLineArgument ( "auto-compact-interval" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . AutoCompactIntervalShort , Strings . Options . AutoCompactIntervalLong , "0m" ),
new CommandLineArgument ( "auto-vacuum-interval" , CommandLineArgument . ArgumentType . Timespan , Strings . Options . AutoVacuumIntervalShort , Strings . Options . AutoVacuumIntervalLong , "0m" ),
new CommandLineArgument ( "secret-provider" , CommandLineArgument . ArgumentType . Password , Strings . Options . SecretProviderShort , Strings . Options . SecretProviderLong ( Library . AutoUpdater . PackageHelper . GetExecutableName ( AutoUpdater . PackageHelper . NamedExecutable . SecretTool ))),
new CommandLineArgument ( "secret-provider-pattern" , CommandLineArgument . ArgumentType . String , Strings . Options . SecretProviderPatternShort , Strings . Options . SecretProviderPatternLong , SecretProviderHelper . DEFAULT_PATTERN ),
new CommandLineArgument ( "secret-provider-cache" , CommandLineArgument . ArgumentType . Enumeration , Strings . Options . SecretProviderCacheShort , Strings . Options . SecretProviderCacheLong , Enum . GetName ( SecretProviderHelper . CachingLevel . None ), null , Enum . GetNames ( typeof ( SecretProviderHelper . CachingLevel ))),
new CommandLineArgument ( "cpu-intensity" , CommandLineArgument . ArgumentType . Integer , Strings . Options . CPUIntensityShort , Strings . Options . CPUIntensityLong , "10" , null , [ "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" ]),
new CommandLineArgument ( "restore-cache-max" , CommandLineArgument . ArgumentType . Size , Strings . Options . RestoreCacheMaxShort , Strings . Options . RestoreCacheMaxLong , DEFAULT_RESTORE_CACHE_MAX ),
new CommandLineArgument ( "restore-cache-evict" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreCacheEvictShort , Strings . Options . RestoreCacheEvictLong , DEFAULT_RESTORE_CACHE_EVICT . ToString ()),
new CommandLineArgument ( "restore-file-processors" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreFileprocessorsShort , Strings . Options . RestoreFileprocessorsLong , DEFAULT_RESTORE_FILE_PROCESSORS . ToString ()),
new CommandLineArgument ( "restore-legacy" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RestoreLegacyShort , Strings . Options . RestoreLegacyLong , "false" ),
new CommandLineArgument ( "restore-preallocate-size" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . RestorePreallocateSizeShort , Strings . Options . RestorePreallocateSizeLong , "false" ),
new CommandLineArgument ( "restore-volume-cache-hint" , CommandLineArgument . ArgumentType . Size , Strings . Options . RestoreVolumeCacheHintShort , Strings . Options . RestoreVolumeCacheHintLong , DEFAULT_RESTORE_VOLUME_CACHE_HINT ),
new CommandLineArgument ( "restore-volume-decompressors" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreVolumeDecompressorsShort , Strings . Options . RestoreVolumeDecompressorsLong , DEFAULT_RESTORE_VOLUME_DECOMPRESSORS . ToString ()),
new CommandLineArgument ( "restore-volume-decryptors" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreVolumeDecryptorsShort , Strings . Options . RestoreVolumeDecryptorsLong , DEFAULT_RESTORE_VOLUME_DECRYPTORS . ToString ()),
new CommandLineArgument ( "restore-volume-downloaders" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreVolumeDownloadersShort , Strings . Options . RestoreVolumeDownloadersLong , DEFAULT_RESTORE_VOLUME_DOWNLOADERS . ToString ()),
new CommandLineArgument ( "restore-channel-buffer-size" , CommandLineArgument . ArgumentType . Integer , Strings . Options . RestoreChannelBufferSizeShort , Strings . Options . RestoreChannelBufferSizeLong , DEFAULT_RESTORE_CHANNEL_BUFFER_SIZE . ToString ()),
new CommandLineArgument ( "internal-profiling" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . InternalProfilingShort , Strings . Options . InternalProfilingLong , "false" ),
new CommandLineArgument ( "ignore-update-if-version-exists" , CommandLineArgument . ArgumentType . Boolean , Strings . Options . IgnoreUpdateIfVersionExistsShort , Strings . Options . IgnoreUpdateIfVersionExistsLong , "false" ),
.. GetOSConditionalCommands ()
];
/// <summary>
/// Gets or sets the current main action of the instance
/// </summary>
public OperationMode MainAction
{
get
{
var value = m_options . GetValueOrDefault ( "main-action" );
return string . IsNullOrEmpty ( value )
? (( OperationMode )(- 1 ))
: ( OperationMode ) Enum . Parse ( typeof ( OperationMode ), value );
}
set { m_options [ "main-action" ] = value . ToString (); }
}
/// <summary>
/// Gets the size of each volume in bytes
/// </summary>
public long VolumeSize
{
get
{
var volsize = GetString ( "dblock-size" , DEFAULT_VOLUME_SIZE );
#if DEBUG
return Math . Max ( 1024 * 10 , Library . Utility . Sizeparser . ParseSize ( volsize , "mb" ));
#else
return Math . Max ( 1024 * 1024 , Library . Utility . Sizeparser . ParseSize ( volsize , "mb" ));
#endif
}
}
/// <summary>
/// Gets the maximum size of a single file
/// </summary>
public long SkipFilesLargerThan
{
get
{
var value = m_options . GetValueOrDefault ( "skip-files-larger-than" );
return string . IsNullOrWhiteSpace ( value )
? long . MaxValue
: Library . Utility . Sizeparser . ParseSize ( value , "mb" );
}
}
/// <summary>
/// A value indicating if orphan files are deleted automatically
/// </summary>
public bool AutoCleanup => GetBool ( "auto-cleanup" );
/// <summary>
/// A value indicating if we are running in unittest mode
/// </summary>
public bool UnittestMode => GetBool ( "unittest-mode" );
/// <summary>
/// Gets a list of files to add to the signature volumes
/// </summary>
public string? ControlFiles => m_options . GetValueOrDefault ( "control-files" );
/// <summary>
/// A value indicating if file hash checks are skipped
/// </summary>
public bool SkipFileHashChecks => GetBool ( "skip-file-hash-checks" );
/// <summary>
/// A value indicating if the manifest files are not read
/// </summary>
public bool DontReadManifests => GetBool ( "dont-read-manifests" );
/// <summary>
/// Gets the backup that should be restored
/// </summary>
public DateTime Time
{
get
{
var value = m_options . GetValueOrDefault ( "time" );
return string . IsNullOrEmpty ( value )
? new DateTime ( 0 , DateTimeKind . Utc )
: Library . Utility . Timeparser . ParseTimeInterval ( value , DateTime . Now );
}
}
/// <summary>
/// Gets the versions the restore or list operation is limited to
/// </summary>
public long []? Version
{
get
{
m_options . TryGetValue ( "version" , out var v );
if ( string . IsNullOrEmpty ( v ))
return null ;
var versions = v . Split ( new char [] { ',' }, StringSplitOptions . RemoveEmptyEntries );
if ( v . Length == 0 )
return null ;
var res = new List < long >();
foreach ( var n in versions )
if ( n . Contains ( '-' ))
{
//TODO: Throw errors if too many entries?
var parts = n . Split ( new char [] { '-' }, StringSplitOptions . RemoveEmptyEntries ). Select ( x => Convert . ToInt64 ( x . Trim ())). ToArray ();
for ( var i = Math . Min ( parts [ 0 ], parts [ 1 ]); i <= Math . Max ( parts [ 0 ], parts [ 1 ]); i ++)
res . Add ( i );
}
else
res . Add ( Convert . ToInt64 ( n ));
return res . ToArray ();
}
}
/// <summary>
/// A value indicating if all versions are listed
/// </summary>
public bool AllVersions => GetBool ( "all-versions" );
/// <summary>
/// A value indicating if only the largest common prefix is returned
/// </summary>
public bool ListPrefixOnly => GetBool ( "list-prefix-only" );
/// <summary>
/// A value indicating if only folder contents are returned
/// </summary>
public bool ListFolderContents => GetBool ( "list-folder-contents" );
/// <summary>
/// A value indicating that only filesets are returned
/// </summary>
public bool ListSetsOnly => GetBool ( "list-sets-only" );
/// <summary>
/// A value indicating if file time checks are skipped
/// </summary>
public bool DisableFiletimeCheck => GetBool ( "disable-filetime-check" );
/// <summary>
/// A value indicating if file time checks are skipped
/// </summary>
public bool CheckFiletimeOnly => GetBool ( "check-filetime-only" );
/// <summary>
/// A value indicating if USN numbers are used to get list of changed files
/// </summary>
//public bool DisableUSNDiffCheck { get { return GetBool("disable-usn-diff-check"); } }
/// <summary>
/// A value indicating if time tolerance is disabled
/// </summary>
public bool DisableTimeTolerance => GetBool ( "disable-time-tolerance" );
/// <summary>
/// Gets a value indicating whether a temporary folder has been specified
/// </summary>
public bool HasTempDir => m_options . ContainsKey ( "tempdir" ) && ! string . IsNullOrEmpty ( m_options [ "tempdir" ]);
/// <summary>
/// Gets the folder where temporary files are stored
/// </summary>
public string TempDir => GetString ( "tempdir" , TempFolder . SystemTempPath );
/// <summary>
/// Gets a value indicating whether the user has forced the locale
/// </summary>
public bool HasForcedLocale => m_options . ContainsKey ( "force-locale" );
/// <summary>
/// Gets the forced locale for the current user
/// </summary>
public CultureInfo ForcedLocale
{
get
{
if (! m_options . ContainsKey ( "force-locale" ))
return CultureInfo . CurrentCulture ;
var localestring = m_options [ "force-locale" ];
if ( string . IsNullOrWhiteSpace ( localestring ))
return CultureInfo . InvariantCulture ;
return new CultureInfo ( localestring );
}
}
/// <summary>
/// A value indicating if missing folders should be created automatically
/// </summary>
public bool AutocreateFolders => ! GetBool ( "disable-autocreate-folder" );
/// <summary>
/// Gets the backup prefix
/// </summary>
public string Prefix => GetString ( "prefix" , "duplicati" );
/// <summary>
/// Gets the number of old backups to keep
/// </summary>
public int KeepVersions => Math . Max ( 0 , GetInt ( "keep-versions" , DEFAULT_KEEP_VERSIONS ));
/// <summary>
/// Gets the timelimit for removal
/// </summary>
public DateTime KeepTime
{
get
{
m_options . TryGetValue ( "keep-time" , out var v );
if ( string . IsNullOrEmpty ( v ))
return new DateTime ( 0 );
var tolerance =
this . DisableTimeTolerance ?
TimeSpan . FromSeconds ( 0 ) :
TimeSpan . FromSeconds ( Math . Min ( Library . Utility . Timeparser . ParseTimeSpan ( v ). TotalSeconds / 100 , 60.0 * 60.0 ));
return Library . Utility . Timeparser . ParseTimeInterval ( v , DateTime . Now , true ) - tolerance ;
}
}
/// <summary>
/// Gets the configured object lock duration for uploaded files, if specified
/// </summary>
2025-12-17 22:27:38 +01:00
public TimeSpan ? RemoteFileLockDuration
2025-12-14 17:17:48 +01:00
{
get
{
2025-12-17 22:27:38 +01:00
m_options . TryGetValue ( "remote-file-lock-duration" , out var value );
2025-12-14 17:17:48 +01:00
if ( string . IsNullOrWhiteSpace ( value ))
return null ;
return Library . Utility . Timeparser . ParseTimeSpan ( value );
}
}
/// <summary>
/// Gets the time frames and intervals for the retention policy
/// </summary>
public List < RetentionPolicyValue > RetentionPolicy
{
get
{
var retentionPolicyConfig = new List < RetentionPolicyValue >();
m_options . TryGetValue ( "retention-policy" , out var v );
if ( string . IsNullOrEmpty ( v ))
return retentionPolicyConfig ;
var periodIntervalStrings = v . Split ( new char [] { ',' }, StringSplitOptions . RemoveEmptyEntries );
foreach ( var periodIntervalString in periodIntervalStrings )
retentionPolicyConfig . Add ( RetentionPolicyValue . CreateFromString ( periodIntervalString ));
return retentionPolicyConfig ;
}
}
/// <summary>
/// Gets the encryption passphrase
/// </summary>
public string? Passphrase => GetString ( "passphrase" , null );
/// <summary>
/// Gets the new encryption passphrase
/// </summary>
public string? NewPassphrase => GetString ( "new-passphrase" , null );
/// <summary>
/// A value indicating if backups are not encrypted
/// </summary>
public bool NoEncryption => GetBool ( "no-encryption" );
/// <summary>
/// Gets the module used for encryption
/// </summary>
public string? EncryptionModule => NoEncryption ? null : GetString ( "encryption-module" , "aes" );
/// <summary>
/// Gets the module used for compression
/// </summary>
public string CompressionModule => GetString ( "compression-module" , "zip" );
/// <summary>
/// Gets the number of time to retry transmission if it fails
/// </summary>
public int NumberOfRetries => Math . Max ( 0 , GetInt ( "number-of-retries" , DEFAULT_NUMBER_OF_RETRIES ));
/// <summary>
/// A value indicating if backups are transmitted on a separate thread
/// </summary>
public bool SynchronousUpload => GetBool ( "synchronous-upload" );
/// <summary>
/// A value indicating if system is allowed to enter sleep power states during backup/restore
/// </summary>
public bool AllowSleep => GetBool ( "allow-sleep" );
/// <summary>
/// A value indicating if system should use the low-priority IO during backup/restore
/// </summary>
public bool UseBackgroundIOPriority => GetBool ( "use-background-io-priority" );
/// <summary>
/// A value indicating if use of the streaming interface is disallowed
/// </summary>
public bool DisableStreamingTransfers => GetBool ( "disable-streaming-transfers" );
/// <summary>
/// The maximum time to allow inactivity before a connection is closed.
/// Returns <c>Timeout.Infinite</c> if disabled.
/// </summary>
public int ReadWriteTimeout
{
get
{
var ts = Library . Utility . Utility . ParseTimespanOption ( m_options , "read-write-timeout" , DEFAULT_READ_WRITE_TIMEOUT );
return ts . Ticks <= 0 ? Timeout . Infinite : ( int ) ts . TotalMilliseconds ;
}
}
/// <summary>
/// Gets the delay period to retry uploads
/// </summary>
public TimeSpan RetryDelay => Library . Utility . Utility . ParseTimespanOption ( m_options , "retry-delay" , DEFAULT_RETRY_DELAY );
/// <summary>
/// Gets whether exponential backoff is enabled
/// </summary>
public bool RetryWithExponentialBackoff => GetBool ( "retry-with-exponential-backoff" );
/// <summary>
/// Gets the max upload speed in bytes pr. second
/// </summary>
public long MaxUploadPrSecond
{
get
{
lock ( m_lock )
return GetSize ( "throttle-upload" , "kb" , "0b" );
}
set
{
lock ( m_lock )
m_options [ "throttle-upload" ] = value <= 0 ? "" : $"{value}b" ;
}
}
/// <summary>
/// Gets or sets the max download speed in bytes pr. second
/// </summary>
public long MaxDownloadPrSecond
{
get
{
lock ( m_lock )
return GetSize ( "throttle-download" , "kb" , "0b" );
}
set
{
lock ( m_lock )
m_options [ "throttle-download" ] = value <= 0 ? "" : $"{value}b" ;
}
}
/// <summary>
/// A value indicating if the throttling is disabled
/// </summary>
public bool DisableThrottle => GetBool ( "throttle-disabled" );
/// <summary>
/// The backends where the throttling is disabled
/// </summary>
public HashSet < string > ThrottleDisabledBackends
=> GetString ( "throttle-disabled-backends" , DEFAULT_THROTTLE_DISABLED_BACKENDS )?. Split ( ',' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries )?. ToHashSet ( StringComparer . OrdinalIgnoreCase ) ?? new HashSet < string >();
/// <summary>
/// A value indicating if the backup is a full backup
/// </summary>
public bool AllowFullRemoval => GetBool ( "allow-full-removal" );
/// <summary>
/// A value indicating if debug output is enabled
/// </summary>
public bool DebugOutput => GetBool ( "debug-output" );
/// <summary>
/// A value indicating if unchanged backups are uploaded
/// </summary>
public bool UploadUnchangedBackups => GetBool ( "upload-unchanged-backups" );
/// <summary>
/// Gets a list of modules that should be loaded
/// </summary>
public string [] EnableModules
=> m_options . GetValueOrDefault ( "enable-module" )?. Trim (). ToLower ( CultureInfo . InvariantCulture ). Split ( ',' ) ?? [];
/// <summary>
/// Gets a list of modules that should not be loaded
/// </summary>
public string [] DisableModules
=> m_options . GetValueOrDefault ( "disable-module" )?. Trim (). ToLower ( CultureInfo . InvariantCulture ). Split ( ',' ) ?? [];
/// <summary>
/// Gets the snapshot strategy to use
/// </summary>
public OptimizationStrategy SnapShotStrategy => GetEnum ( "snapshot-policy" , DEFAULT_SNAPSHOT_POLICY );
/// <summary>
/// Gets the snapshot strategy to use
/// </summary>
[SupportedOSPlatform("windows")]
public WindowsSnapshotProvider SnapShotProvider
=> GetEnum ( "snapshot-provider" , WindowsSnapshot . DEFAULT_WINDOWS_SNAPSHOT_PROVIDER );
/// <summary>
/// Gets the BackupRead strategy to use
/// </summary>
public OptimizationStrategy BackupReadStrategy => GetEnum ( "backupread-policy" , DEFAULT_BACKUPREAD_POLICY );
/// <summary>
/// Gets a flag indicating if advisory locking should be ignored
/// </summary>
public bool IgnoreAdvisoryLocking => GetBool ( "ignore-advisory-locking" );
/// <summary>
/// Gets the symlink strategy to use
/// </summary>
public SymlinkStrategy SymlinkPolicy
=> GetEnum ( "symlink-policy" , SymlinkStrategy . Store );
/// <summary>
/// Gets the hardlink strategy to use
/// </summary>
public HardlinkStrategy HardlinkPolicy
=> GetEnum ( "hardlink-policy" , HardlinkStrategy . All );
/// <summary>
/// Gets the update sequence number (USN) strategy to use
/// </summary>
public OptimizationStrategy UsnStrategy
=> GetEnum ( "usn-policy" , OptimizationStrategy . Off );
/// <summary>
/// Gets the number of concurrent volume uploads allowed. Zero for unlimited.
/// </summary>
public int AsynchronousConcurrentUploadLimit
=> GetInt ( "asynchronous-upload-limit" , GetInt ( "asynchronous-concurrent-upload-limit" , DEFAULT_ASYNCHRONOUS_UPLOAD_LIMIT ));
/// <summary>
/// Gets the temporary folder to use for asynchronous transfers
/// </summary>
public string AsynchronousUploadFolder => GetString ( "asynchronous-upload-folder" , TempDir );
/// <summary>
/// Gets the logfile filename
/// </summary>
public string? Logfile => m_options . GetValueOrDefault ( "log-file" );
/// <summary>
/// Gets the log-file detail level
/// </summary>
public Duplicati . Library . Logging . LogMessageType LogFileLoglevel
{
get
{
if (! m_options . TryGetValue ( "log-file-log-level" , out var value ))
value = null ;
if ( string . IsNullOrWhiteSpace ( value ))
if (! m_options . TryGetValue ( "log-level" , out value ))
value = null ;
foreach ( string s in Enum . GetNames ( typeof ( Duplicati . Library . Logging . LogMessageType )))
if ( s . Equals ( value , StringComparison . OrdinalIgnoreCase ))
return ( Duplicati . Library . Logging . LogMessageType ) Enum . Parse ( typeof ( Duplicati . Library . Logging . LogMessageType ), s );
if ( Dryrun )
return Duplicati . Library . Logging . LogMessageType . DryRun ;
else
return Duplicati . Library . Logging . LogMessageType . Warning ;
}
}
/// <summary>
/// Gets the filter used to suppress warning messages.
/// </summary>
public HashSet < string >? SuppressWarningsFilter
=> m_options . GetValueOrDefault ( "suppress-warnings" )?. Split ( ',' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries )?. ToHashSet ( StringComparer . OrdinalIgnoreCase );
/// <summary>
/// A value indicating if HTTP requests should be logged
/// </summary>
public bool LogHttpRequests => GetBool ( "log-http-requests" );
/// <summary>
/// Gets the number of bytes of socket data to include in logs, -1 disables logging
/// </summary>
public int LogSocketData => GetInt ( "log-socket-data" , - 1 );
/// <summary>
/// Gets the filter used for log-file messages.
/// </summary>
/// <value>The log file filter.</value>
public IFilter ? LogFileLogFilter
=> FilterExpression . Combine (
new FilterExpression ( m_options . GetValueOrDefault ( "log-file-log-ignore" )?. Split ( ',' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries )?. Select ( x => $"*-{x}" ), false ),
FilterExpression . ParseLogFilter ( m_options . GetValueOrDefault ( "log-file-log-filter" ))
);
/// <summary>
/// Gets the filter used for console messages.
/// </summary>
/// <value>The log file filter.</value>
public IFilter ? ConsoleLogFilter
=> FilterExpression . Combine (
new FilterExpression ( m_options . GetValueOrDefault ( "console-log-ignore" )?. Split ( ',' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries )?. Select ( x => $"*-{x}" ), false ),
FilterExpression . ParseLogFilter ( m_options . GetValueOrDefault ( "console-log-filter" ))
);
/// <summary>
/// Gets the console log detail level
/// </summary>
public Duplicati . Library . Logging . LogMessageType ConsoleLoglevel
{
get
{
if (! m_options . TryGetValue ( "console-log-level" , out var value ))
value = null ;
if ( string . IsNullOrWhiteSpace ( value ))
if (! m_options . TryGetValue ( "log-level" , out value ))
value = null ;
foreach ( string s in Enum . GetNames ( typeof ( Duplicati . Library . Logging . LogMessageType )))
if ( s . Equals ( value , StringComparison . OrdinalIgnoreCase ))
return ( Duplicati . Library . Logging . LogMessageType ) Enum . Parse ( typeof ( Duplicati . Library . Logging . LogMessageType ), s );
if ( Dryrun )
return Duplicati . Library . Logging . LogMessageType . DryRun ;
else
return Duplicati . Library . Logging . LogMessageType . Warning ;
}
}
/// <summary>
/// A value indicating if all database queries should be logged
/// </summary>
public bool ProfileAllDatabaseQueries => GetBool ( "profile-all-database-queries" );
2026-01-14 09:58:19 +01:00
/// <summary>
/// A value indicating if metadata content should be stored in the database
/// </summary>
public bool StoreMetadataContentInDatabase => GetBool ( "store-metadata-content-in-database" );
2025-12-14 17:17:48 +01:00
/// <summary>
/// Gets the attribute filter used to exclude files and folders.
/// </summary>
public System . IO . FileAttributes FileAttributeFilter
=> Library . Utility . Utility . ParseFlagsOption ( m_options , "exclude-files-attributes" , default ( System . IO . FileAttributes ));
/// <summary>
/// A value indicating if server uploads are verified by listing the folder contents
/// </summary>
public bool ListVerifyUploads => GetBool ( "list-verify-uploads" );
/// <summary>
/// A value indicating if connections cannot be re-used
/// </summary>
public bool NoConnectionReuse => GetBool ( "no-connection-reuse" );
/// <summary>
/// A value indicating if the returned value should not be truncated
/// </summary>
public bool FullResult => GetBool ( "full-result" );
/// <summary>
/// A value indicating restored files overwrite existing ones
/// </summary>
public bool Overwrite => GetBool ( "overwrite" );
/// <summary>
/// Gets the total size in bytes that the backup should use, returns -1 if there is no upper limit
/// </summary>
public long QuotaSize
{
get
{
var value = m_options . GetValueOrDefault ( "quota-size" );
return string . IsNullOrEmpty ( value ) ? - 1 : Library . Utility . Sizeparser . ParseSize ( value , "mb" );
}
}
/// <summary>
/// Gets the threshold at which a quota warning should be generated.
/// </summary>
/// <remarks>
/// This is treated as a percentage, where a warning is given when the amount of free space is less than this percentage of the backup size.
/// </remarks>
public int QuotaWarningThreshold
=> GetInt ( "quota-warning-threshold" , DEFAULT_QUOTA_WARNING_THRESHOLD );
/// <summary>
/// Gets a flag indicating that backup quota reported by the backend should be ignored
/// </summary>
/// This is necessary because in some cases the backend might report a wrong quota (especially with some Linux mounts).
public bool QuotaDisable => GetBool ( "quota-disable" );
2026-01-27 14:10:31 +01:00
/// <summary>
/// Gets the soft delete prefix
/// </summary>
public string? SoftDeletePrefix => GetString ( "soft-delete-prefix" , null );
/// <summary>
/// Gets a flag indicating if the backend rename operation should be avoided
/// </summary>
public bool PreventBackendRename => GetBool ( "prevent-backend-rename" );
2025-12-14 17:17:48 +01:00
/// <summary>
/// Gets the display name of the backup
/// </summary>
public string BackupName
{
get => GetString ( "backup-name" , DefaultBackupName );
set => m_options [ "backup-name" ] = value ;
}
/// <summary>
/// Gets the ID of the backup
/// </summary>
public string? BackupId => m_options . GetValueOrDefault ( "backup-id" );
/// <summary>
/// Gets the ID of the machine
/// </summary>
public string? MachineId => m_options . GetValueOrDefault ( "machine-id" , Library . AutoUpdater . DataFolderManager . InstallID );
/// <summary>
/// Gets the path to the database
/// </summary>
public string? Dbpath
{
get => m_options . GetValueOrDefault ( "dbpath" , null );
set => m_options [ "dbpath" ] = value ;
}
/// <summary>
/// Gets a value indicating whether a blocksize has been specified
/// </summary>
public bool HasBlocksize => ! string . IsNullOrEmpty ( m_options . GetValueOrDefault ( "blocksize" ));
/// <summary>
/// Gets the size of file-blocks
/// </summary>
public int Blocksize
{
get
{
var blocksize = GetSize ( "blocksize" , "kb" , DEFAULT_BLOCKSIZE );
if ( blocksize > int . MaxValue || blocksize < 1024 )
throw new ArgumentOutOfRangeException ( nameof ( blocksize ), string . Format ( "The blocksize cannot be less than {0}, nor larger than {1}" , 1024 , int . MaxValue ));
return ( int ) blocksize ;
}
}
/// <summary>
/// Cache for the block hash size value, to avoid creating new hash instances just to get the size
/// </summary>
private KeyValuePair < string , int > m_cachedBlockHashSize ;
/// <summary>
/// Gets the size of the blockhash in bytes.
/// </summary>
/// <value>The size of the blockhash.</value>
public int BlockhashSize
{
get
{
if ( m_cachedBlockHashSize . Key != BlockHashAlgorithm )
m_cachedBlockHashSize = new KeyValuePair < string , int >( BlockHashAlgorithm , HashFactory . HashSizeBytes ( BlockHashAlgorithm ));
return m_cachedBlockHashSize . Value ;
}
}
/// <summary>
/// Gets a flag indicating if metadata for files and folders should be ignored
/// </summary>
public bool SkipMetadata => GetBool ( "skip-metadata" );
/// <summary>
/// Gets a flag indicating if empty folders should be ignored
/// </summary>
public bool ExcludeEmptyFolders => GetBool ( "exclude-empty-folders" );
/// <summary>
/// Gets a flag indicating if backup exclusion extended attributes should be ignored
/// </summary>
public bool DisableBackupExclusionXattr =>
OperatingSystem . IsMacOS () || OperatingSystem . IsLinux ()
? GetBool ( "disable-backup-exclusion-xattr" )
: true ; // Windows does not support xattrs, so disable looking for them
/// <summary>
/// Gets a flag indicating if during restores metadata should be applied to the symlink target.
/// Setting this to true can result in errors if the target no longer exists.
/// </summary>
public bool RestoreSymlinkMetadata => GetBool ( "restore-symlink-metadata" );
/// <summary>
/// Gets a flag indicating if permissions should be restored
/// </summary>
public bool RestorePermissions => GetBool ( "restore-permissions" );
/// <summary>
/// Gets a flag indicating if file hashes are checked after a restore
/// </summary>
public bool PerformRestoredFileVerification => ! GetBool ( "skip-restore-verification" );
/// <summary>
/// Gets a flag indicating if synthetic filelist generation is disabled
/// </summary>
public bool DisableSyntheticFilelist => GetBool ( "disable-synthetic-filelist" );
/// <summary>
/// Gets the compact threshold
/// </summary>
public long Threshold => GetLong ( "threshold" , DEFAULT_THRESHOLD );
/// <summary>
/// Gets the size of small volumes
/// </summary>
public long SmallFileSize => GetSize ( "small-file-size" , "mb" , $"{this.VolumeSize / 5}b" );
/// <summary>
/// Gets the maximum number of small volumes
/// </summary>
public long SmallFileMaxCount => GetLong ( "small-file-max-count" , DEFAULT_SMALL_FILE_MAX_COUNT );
/// <summary>
/// List of files to check for changes
/// </summary>
public string []? ChangedFilelist => m_options . GetValueOrDefault ( "changed-files" )?. Split ( new char [] { System . IO . Path . PathSeparator }, StringSplitOptions . RemoveEmptyEntries );
/// <summary>
/// List of files to mark as deleted
/// </summary>
public string []? DeletedFilelist => m_options . GetValueOrDefault ( "deleted-files" )?. Split ( new char [] { System . IO . Path . PathSeparator }, StringSplitOptions . RemoveEmptyEntries );
/// <summary>
/// List of filenames that are used to exclude a folder
/// </summary>
public string []? IgnoreFilenames
{
get
{
if (! m_options . TryGetValue ( "ignore-filenames" , out var v ))
v = "CACHEDIR.TAG" ;
if ( string . IsNullOrEmpty ( v ))
return null ;
return v . Split ( new char [] { System . IO . Path . PathSeparator }, StringSplitOptions . RemoveEmptyEntries );
}
}
/// <summary>
/// Alternate restore path
/// </summary>
public string? Restorepath => m_options . GetValueOrDefault ( "restore-path" );
/// <summary>
/// Gets the index file usage method
/// </summary>
public IndexFileStrategy IndexfilePolicy => GetEnum ( "index-file-policy" , IndexFileStrategy . Full );
/// <summary>
/// Gets a flag indicating if the check for files on the remote storage should be omitted
/// </summary>
public bool NoBackendverification => GetBool ( "no-backend-verification" );
/// <summary>
/// Gets the percentage of samples to test during a backup operation
/// </summary>
public decimal BackupTestPercentage
{
get
{
m_options . TryGetValue ( "backup-test-percentage" , out var s );
if ( string . IsNullOrEmpty ( s ))
return 0.1 m ;
decimal percentage ;
try
{
percentage = decimal . Parse ( s , CultureInfo . InvariantCulture );
}
catch ( Exception ex )
{
throw new ArgumentException ( "The value provided for the backup-test-percentage option must lie between 0 and 100." , ex );
}
if (( percentage < 0 ) || ( percentage > 100 ))
{
throw new ArgumentOutOfRangeException ( nameof ( percentage ), "The value provided for the backup-test-percentage option must lie between 0 and 100." );
}
return percentage ;
}
}
/// <summary>
/// Gets the number of samples to test during a backup operation
/// </summary>
public long BackupTestSampleCount => Math . Max ( 0 , GetLong ( "backup-test-samples" , DEFAULT_BACKUP_TEST_SAMPLES ));
/// <summary>
/// Gets a flag indicating if compacting should not be done automatically
/// </summary>
public bool NoAutoCompact => GetBool ( "no-auto-compact" );
/// <summary>
/// Gets the minimum time that must elapse after last compaction before running next automatic compaction
/// </summary>
public TimeSpan AutoCompactInterval => Library . Utility . Utility . ParseTimespanOption ( m_options , "auto-compact-interval" , "0s" );
/// <summary>
/// Gets a flag indicating if missing source elements should be ignored
/// </summary>
public bool AllowMissingSource => GetBool ( "allow-missing-source" );
/// <summary>
/// Gets a flag indicating if empty source elements should cause backups to fail
/// </summary>
public bool PreventEmptySource => GetBool ( "prevent-empty-source" );
/// <summary>
/// Gets a value indicating if a verification file should be uploaded after changing the remote store
/// </summary>
public bool UploadVerificationFile => GetBool ( "upload-verification-file" );
/// <summary>
/// Gets a value indicating if a passphrase change is allowed
/// </summary>
public bool AllowPassphraseChange => GetBool ( "allow-passphrase-change" );
/// <summary>
/// Gets a flag indicating if the current operation should merely output the changes
/// </summary>
public bool Dryrun => GetBool ( "dry-run" ) || GetBool ( "dryrun" );
/// <summary>
/// Gets a value indicating if the remote verification is deep
/// </summary>
public RemoteTestStrategy FullRemoteVerification => GetEnum ( "full-remote-verification" , RemoteTestStrategy . True );
/// <summary>
/// Gets a value indicating if defective index files should be replaced
/// </summary>
public bool ReplaceFaultyIndexFiles => ! GetBool ( "dont-replace-faulty-index-files" );
/// <summary>
/// The block hash algorithm to use
/// </summary>
public string BlockHashAlgorithm => GetString ( "block-hash-algorithm" , DEFAULT_BLOCK_HASH_ALGORITHM );
/// <summary>
/// The file hash algorithm to use
/// </summary>
public string FileHashAlgorithm => GetString ( "file-hash-algorithm" , DEFAULT_FILE_HASH_ALGORITHM );
/// <summary>
/// Gets a value indicating whether local blocks usage should be used for restore.
/// </summary>
/// <value><c>true</c> if no local blocks; otherwise, <c>false</c>.</value>
public bool UseLocalBlocks => GetBool ( "restore-with-local-blocks" );
/// <summary>
/// Gets a flag indicating if the local database should not be used
/// </summary>
/// <value><c>true</c> if no local db is used; otherwise, <c>false</c>.</value>
public bool NoLocalDb => GetBool ( "no-local-db" );
/// <summary>
/// Gets a flag indicating if the local database should not be used
/// </summary>
/// <value><c>true</c> if no local db is used; otherwise, <c>false</c>.</value>
public bool DontCompressRestorePaths => GetBool ( "dont-compress-restore-paths" );
2026-01-27 15:51:30 +01:00
/// <summary>
/// Gets a value indicating whether to allow restore outside target directory.
/// </summary>
public bool AllowRestoreOutsideTargetDirectory => GetBool ( "allow-restore-outside-target-directory" );
2025-12-14 17:17:48 +01:00
/// <summary>
/// Gets a flag indicating if block hashes are checked before being applied
/// </summary>
/// <value><c>true</c> if block hashes are checked; otherwise, <c>false</c>.</value>
public bool FullBlockVerification => GetBool ( "full-block-verification" );
/// <summary>
/// Gets a flag indicating if the repair process will only restore paths
/// </summary>
/// <value><c>true</c> if only paths are restored; otherwise, <c>false</c>.</value>
public bool RepairOnlyPaths => GetBool ( "repair-only-paths" );
/// <summary>
/// Gets a flag indicating if the repair process will ignore outdated database
/// </summary>
/// <value><c>true</c> if repair process will ignore outdated database; otherwise, <c>false</c>.</value>
public bool RepairIgnoreOutdatedDatabase => GetBool ( "repair-ignore-outdated-database" );
/// <summary>
/// Gets a flag indicating if the repair process will always use blocks
/// </summary>
/// <value><c>true</c> if repair process always use blocks; otherwise, <c>false</c>.</value>
public bool RepairForceBlockUse => GetBool ( "repair-force-block-use" );
/// <summary>
/// Gets a flag indicating if the repair process should refresh lock information from the backend
/// </summary>
/// <value><c>true</c> if repair process should refresh lock information; otherwise, <c>false</c>.</value>
public bool RepairRefreshLockInfo => GetBool ( "repair-refresh-lock-info" );
/// <summary>
/// Gets a flag indicating if the repair process should refresh lock information for all volumes
/// </summary>
public bool RefreshLockInfoComplete => GetBool ( "refresh-lock-info-complete" );
/// <summary>
/// Gets a flag indicating whether the VACUUM operation should ever be run automatically.
/// </summary>
public bool AutoVacuum => GetBool ( "auto-vacuum" );
/// <summary>
/// Gets the minimum time that must elapse after last vacuum before running next automatic vacuum
/// </summary>
public TimeSpan AutoVacuumInterval => Library . Utility . Utility . ParseTimespanOption ( m_options , "auto-vacuum-interval" , "0s" );
/// <summary>
/// Gets a flag indicating if the local filescanner should be disabled
/// </summary>
/// <value><c>true</c> if the filescanner should be disabled; otherwise, <c>false</c>.</value>
public bool DisableFileScanner => GetBool ( "disable-file-scanner" );
/// <summary>
/// Gets a flag indicating if the filelist consistency checks should be disabled
/// </summary>
/// <value><c>true</c> if the filelist consistency checks should be disabled; otherwise, <c>false</c>.</value>
public bool DisableFilelistConsistencyChecks => GetBool ( "disable-filelist-consistency-checks" );
/// <summary>
/// Gets a flag indicating whether the backup should be disabled when on battery power.
/// </summary>
/// <value><c>true</c> if the backup should be disabled when on battery power; otherwise, <c>false</c>.</value>
public bool DisableOnBattery => GetBool ( "disable-on-battery" );
/// <summary>
/// Gets a value indicating if missing dblock files are attempted created
/// </summary>
public bool RebuildMissingDblockFiles => GetBool ( "rebuild-missing-dblock-files" );
/// <summary>
/// Gets a value indicating if partial dblock recovery is disabled
/// </summary>
public bool DisablePartialDblockRecovery => GetBool ( "disable-partial-dblock-recovery" );
/// <summary>
/// Gets a value indicating if missing metadata is replaced with empty content on purge-broken-files
/// </summary>
public bool DisableReplaceMissingMetadata => GetBool ( "disable-replace-missing-metadata" );
2026-01-27 21:15:50 +01:00
/// <summary>
/// Gets a value indicating if the purge-broken-files command should skip calculating the size of the removed files
/// </summary>
public bool ReducedPurgeStatistics => GetBool ( "reduced-purge-statistics" );
2025-12-14 17:17:48 +01:00
/// <summary>
/// Gets the threshold for when log data should be cleaned
/// </summary>
public DateTime LogRetention
{
get
{
var value = GetString ( "log-retention" , DEFAULT_LOG_RETENTION );
return Library . Utility . Timeparser . ParseTimeInterval ( value , DateTime . Now , true );
}
}
/// <summary>
/// Gets the number of concurrent threads
/// </summary>
public int ConcurrencyMaxThreads => GetInt ( "concurrency-max-threads" , 0 );
/// <summary>
/// Gets the number of concurrent block hashers
/// </summary>
public int ConcurrencyBlockHashers => Math . Max ( 1 , GetInt ( "concurrency-block-hashers" , DEFAULT_BLOCK_HASHERS ));
/// <summary>
/// Gets the number of concurrent block hashers
/// </summary>
public int ConcurrencyCompressors => Math . Max ( 1 , GetInt ( "concurrency-compressors" , DEFAULT_COMPRESSORS ));
/// <summary>
/// Gets the number of concurrent file processors
/// </summary>
public int ConcurrencyFileprocessors => Math . Max ( 1 , GetInt ( "concurrency-fileprocessors" , DEFAULT_FILE_PROCESSORS ));
/// <summary>
/// Gets a lookup table with compression hints, the key is the file extension with the leading period
/// </summary>
public IDictionary < string , CompressionHint > CompressionHints
{
get
{
if ( m_compressionHints == null )
{
var hints = new Dictionary < string , CompressionHint >( StringComparer . OrdinalIgnoreCase ); // Ignore file system case sensitivity, since file extensions case rarely indicates type
var file = GetString ( "compression-extension-file" , DEFAULT_COMPRESSED_EXTENSION_FILE );
if (! string . IsNullOrEmpty ( file ) && System . IO . File . Exists ( file ))
foreach ( var _line in Library . Utility . Utility . ReadFileWithDefaultEncoding ( file ). Split ( '\n' ))
{
var line = _line . Trim ();
var lix = line . IndexOf ( ' ' );
if ( lix > 0 )
line = line . Substring ( 0 , lix );
if ( line . Length >= 2 && line [ 0 ] == '.' )
hints [ line ] = CompressionHint . Noncompressible ;
}
//Don't try again, if the file does not exist
m_compressionHints = hints ;
}
return m_compressionHints ;
}
}
/// <summary>
/// Gets the CPU intensity level indicating target CPU utilization. 1 is the lowest, 10 is the highest. Default is 10.
/// </summary>
public int CPUIntensity => Math . Max ( 1 , Math . Min ( 10 , GetInt ( "cpu-intensity" , 10 )));
/// <summary>
/// Gets a compression hint from a filename
/// </summary>
/// <param name="filename">The filename to get the hint for</param>
/// <returns>The compression hint</returns>
public CompressionHint GetCompressionHintFromFilename ( string filename )
{
if (! CompressionHints . TryGetValue ( System . IO . Path . GetExtension ( filename ), out var h ))
return CompressionHint . Default ;
return h ;
}
protected readonly List < IGenericModule > m_loadedModules = new ();
/// <summary>
/// Gets a list of loaded modules, in their activation order
/// </summary>
public IEnumerable < IGenericModule > LoadedModules => m_loadedModules
. OrderByDescending ( x => ( x as IGenericPriorityModule )?. Priority ?? 0 );
/// <summary>
/// Adds a loaded module to the list of loaded modules.
/// </summary>
/// <param name="module">The module to add</param>
public void AddLoadedModule ( IGenericModule module )
{
if ( module == null )
throw new ArgumentNullException ( nameof ( module ));
m_loadedModules . Add ( module );
}
/// <summary>
/// Clears the list of loaded modules.
/// </summary>
public void ClearLoadedModules ()
{
m_loadedModules . Clear ();
}
/// <summary>
/// Helper method to extract boolean values.
/// If the option is not present, it it's value is false.
/// If the option is present it's value is true, unless the option's value is false, off or 0
/// </summary>
/// <param name="name">The name of the option to read</param>
/// <returns>The interpreted value of the option</returns>
private bool GetBool ( string name )
=> Library . Utility . Utility . ParseBoolOption ( m_options , name );
/// <summary>
/// Helper method to extract string values.
/// </summary>
/// <param name="name">The option name</param>
/// <param name="default">The default value</param>
/// <returns>The value of the option, or the default value if the option is not present or empty</returns>
[return: NotNullIfNotNull("default")]
private string? GetString ( string name , string? @default )
{
var value = m_options . GetValueOrDefault ( name );
return string . IsNullOrEmpty ( value ) ? @default : value ;
}
/// <summary>
/// Helper method to extract integer values.
/// </summary>
/// <param name="name">The option name</param>
/// <param name="default">The default value</param>
/// <returns>The value of the option, or the default value if the option is not present or empty</returns>
private int GetInt ( string name , int @default )
=> Library . Utility . Utility . ParseIntOption ( m_options , name , @default );
/// <summary>
/// Helper method to extract long values.
/// </summary>
/// <param name="name">The option name</param>
/// <param name="default">The default value</param>
/// <returns>The value of the option, or the default value if the option is not present or empty</returns>
private long GetLong ( string name , long @default )
=> Library . Utility . Utility . ParseLongOption ( m_options , name , @default );
/// <summary>
/// Helper method to extract enum values.
/// </summary>
/// <typeparam name="T">The enum type</typeparam>
/// <param name="name">The option name</param>
/// <param name="default">The default value</param>
/// <returns>The value of the option, or the default value if the option is not present or empty</returns>
private T GetEnum < T >( string name , T @default ) where T : struct , Enum
=> Library . Utility . Utility . ParseEnumOption ( m_options , name , @default );
/// <summary>
/// Helper method to extract size values.
/// </summary>
/// <param name="name">The option name</param>
/// <param name="unit">The default unit</param>
/// <param name="default">The default value</param>
/// <returns>The value of the option, or the default value if the option is not present or empty</returns>
private long GetSize ( string name , string unit , string @default )
=> Library . Utility . Utility . ParseSizeOption ( m_options , name , unit , @default );
/// <summary>
/// Gets the maximum number of data blocks to keep in the cache. If set to 0, the cache is effictively disabled, but some is still kept for bookkeeping.
/// </summary>
public long RestoreCacheMax
{
get
{
var max_cache = GetSize ( "restore-cache-max" , "mb" , DEFAULT_RESTORE_CACHE_MAX );
if ( max_cache > 0 && max_cache < Blocksize )
throw new ArgumentOutOfRangeException ( nameof ( max_cache ), string . Format ( "The maximum cache size cannot be less than the blocksize if not explicitly 0: {0} < {1}" , max_cache , Blocksize ));
return max_cache / Blocksize ;
}
}
/// <summary>
/// Gets the ratio of cache entries to evict when the cache is full
/// </summary>
public float RestoreCacheEvict
{
get
{
m_options . TryGetValue ( "restore-cache-evict" , out var s );
if ( string . IsNullOrEmpty ( s ))
return DEFAULT_RESTORE_CACHE_EVICT / 100f ;
int percentage ;
try
{
percentage = int . Parse ( s , CultureInfo . InvariantCulture );
}
catch ( Exception ex )
{
throw new ArgumentException ( "The value provided for the restore-cache-evict option must lie between 0 and 100" , ex );
}
if (( percentage < 0 ) || ( percentage > 100 ))
{
throw new ArgumentOutOfRangeException ( nameof ( percentage ), "The value provided for the restore-cache-evict option must lie between 0 and 100" );
}
return percentage / 100f ;
}
}
/// <summary>
/// Gets the number of file processors to use in the restore process
/// </summary>
public int RestoreFileProcessors => GetInt ( "restore-file-processors" , DEFAULT_RESTORE_FILE_PROCESSORS );
/// <summary>
/// Gets whether to use the legacy restore method
/// </summary>
public bool RestoreLegacy => GetBool ( "restore-legacy" );
/// <summary>
/// Gets whether to preallocate files during restore
/// </summary>
public bool RestorePreAllocate => GetBool ( "restore-pre-allocate" );
/// <summary>
/// Gets whether to handle MacOS Photo Libraries specially
/// </summary>
public MacOSPhotosHandling HandleMacOSPhotoLibrary => GetEnum ( "photos-handling" , DEFAULT_MACOS_PHOTOS_HANDLING );
/// <summary>
/// Gets the path to the MacOS Photos Library
/// </summary>
public string? MacOSPhotoLibraryPath => GetString ( "photos-library-path" , null );
// <summary>
// Gets the size of the volume cache used during restore, in MB.
// </summary>
public long RestoreVolumeCacheHint
{
get
{
m_options . TryGetValue ( "restore-volume-cache-hint" , out var s );
if ( string . IsNullOrEmpty ( s ))
return VolumeSize * 100 ; // Default to 100 times the volume size
return GetSize ( "restore-volume-cache-hint" , "mb" , $"{VolumeSize * 100}b" );
}
}
/// <summary>
/// Gets the number of volume decryptors to use in the restore process
/// </summary>
public int RestoreVolumeDecryptors => GetInt ( "restore-volume-decryptors" , DEFAULT_RESTORE_VOLUME_DECRYPTORS );
/// <summary>
/// Gets the number of volume decompressors to use in the restore process
/// </summary>
public int RestoreVolumeDecompressors => GetInt ( "restore-volume-decompressors" , DEFAULT_RESTORE_VOLUME_DECOMPRESSORS );
/// <summary>
/// Gets the number of volume downloaders to use in the restore process
/// </summary>
public int RestoreVolumeDownloaders => GetInt ( "restore-volume-downloaders" , DEFAULT_RESTORE_VOLUME_DOWNLOADERS );
/// <summary>
/// Gets the size of the buffer used for the restore channel
/// </summary>
public int RestoreChannelBufferSize => GetInt ( "restore-channel-buffer-size" , DEFAULT_RESTORE_CHANNEL_BUFFER_SIZE );
/// <summary>
/// Toggles whether internal profiling is enabled and should be logged.
/// </summary>
public bool InternalProfiling => GetBool ( "internal-profiling" );
/// <summary>
/// Ignores the update if the version already exists in the database.
/// </summary>
public bool IgnoreUpdateIfVersionExists
=> GetBool ( "ignore-update-if-version-exists" );
/// <summary>
/// Class for handling a single RetentionPolicy timeframe-interval-pair
/// </summary>
public class RetentionPolicyValue
{
public readonly TimeSpan Timeframe ;
public readonly TimeSpan Interval ;
public RetentionPolicyValue ( TimeSpan timeframe , TimeSpan interval )
{
if ( timeframe < TimeSpan . Zero )
{
throw new ArgumentOutOfRangeException ( nameof ( timeframe ), string . Format ( "The timeframe cannot be negative: '{0}'" , timeframe ));
}
if ( interval < TimeSpan . Zero )
{
throw new ArgumentOutOfRangeException ( nameof ( interval ), string . Format ( "The interval cannot be negative: '{0}'" , interval ));
}
this . Timeframe = timeframe ;
this . Interval = interval ;
}
/// <summary>
/// Returns whether this is an unlimited timeframe or not
/// </summary>
/// <returns></returns>
public Boolean IsUnlimtedTimeframe ()
{
// Timeframes equal or bigger than the maximum TimeSpan effectively represent an unlimited timeframe
return Timeframe >= TimeSpan . MaxValue ;
}
/// <summary>
/// Returns whether all versions in this timeframe should be kept or not
/// </summary>
/// <returns></returns>
public Boolean IsKeepAllVersions ()
{
/// Intervals between two versions that are equal or smaller than zero effectivly result in
/// all versions in that timeframe being kept.
return Interval <= TimeSpan . Zero ;
}
public override string ToString ()
{
return ( IsUnlimtedTimeframe () ? "Unlimited" : Timeframe . ToString ()) + " / " + ( IsKeepAllVersions () ? "Keep all" : Interval . ToString ());
}
/// <summary>
/// Parses a string representation of a timeframe-interval-pair and returns a RetentionPolicyValue object
/// </summary>
/// <returns></returns>
public static RetentionPolicyValue CreateFromString ( string rententionPolicyValueString )
{
var periodInterval = rententionPolicyValueString . Split ( ':' );
TimeSpan timeframe ;
// Timeframe "U" (= Unlimited) means: For unlimited time keep one version every X interval.
// So the timeframe has to span the maximum time possible.
if ( String . Equals ( periodInterval [ 0 ], "U" , StringComparison . OrdinalIgnoreCase ))
{
timeframe = TimeSpan . MaxValue ;
}
else
{
timeframe = Library . Utility . Timeparser . ParseTimeSpan ( periodInterval [ 0 ]);
}
TimeSpan interval ;
// Interval "U" (= Unlimited) means: For period X keep all versions.
// So the interval between two versions has to be zero.
if ( String . Equals ( periodInterval [ 1 ], "U" , StringComparison . OrdinalIgnoreCase ))
{
interval = TimeSpan . Zero ;
}
else
{
interval = Library . Utility . Timeparser . ParseTimeSpan ( periodInterval [ 1 ]);
}
return new RetentionPolicyValue ( timeframe , interval );
}
}
}
}