using System; using System.Collections.Generic; using System.Linq; using System.Text; using Duplicati.Library.Interface; namespace Duplicati.Library.Main.ForestHash { public class FhOptions : Options { private const string DEFAULT_BLOCK_HASH_LOOKUP_SIZE = "64mb"; private const string DEFAULT_METADATA_HASH_LOOKUP_SIZE = "64mb"; private const string DEFAULT_FILE_HASH_LOOKUP_SIZE = "32mb"; private const string DEFAULT_FILENAME_LOOKUP_SIZE = "64mb"; private const string DEFAULT_BLOCK_HASH_ALGORITHM = "SHA256"; private const string DEFAULT_FILE_HASH_ALGORITHM = "SHA256"; /// /// The default block size for Foresthash /// private const string DEFAULT_FH_BLOCKSIZE = "100kb"; public FhOptions(Dictionary options) : base(options) { } private static string[] GetSupportedHashes() { var r = new List(); foreach(var h in new string[] {"SHA1", "MD5", "SHA256", "SHA384", "SHA512"}) try { var p = System.Security.Cryptography.HashAlgorithm.Create(h); if (p != null) r.Add(h); } catch { } return r.ToArray(); } /// /// List of commands relating to the ForestHash module /// public static IList Commands { get { return new List(new ICommandLineArgument[] { new CommandLineArgument("fh-dbpath", CommandLineArgument.ArgumentType.Path, Strings.FhOptions.FhdbpathShort, Strings.FhOptions.FhdbpathLong), new CommandLineArgument("fh-blocksize", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhblocksizeShort, Strings.FhOptions.FhblocksizeLong, DEFAULT_FH_BLOCKSIZE), new CommandLineArgument("fh-no-metadata", CommandLineArgument.ArgumentType.Boolean, Strings.FhOptions.FhnometadataShort, Strings.FhOptions.FhnometadataLong, "false"), new CommandLineArgument("fh-blockhash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhblockhashlookupsizeShort, Strings.FhOptions.FhblockhashlookupsizeLong, DEFAULT_BLOCK_HASH_LOOKUP_SIZE), new CommandLineArgument("fh-filehash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhfilehashlookupsizeShort, Strings.FhOptions.FhfilehashlookupsizeLong, DEFAULT_FILE_HASH_LOOKUP_SIZE), new CommandLineArgument("fh-metadatahash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhmetadatahashlookupsizeShort, Strings.FhOptions.FhmetadatahashlookupsizeLong, DEFAULT_METADATA_HASH_LOOKUP_SIZE), new CommandLineArgument("fh-filepath-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhfilepathlookupsizeShort, Strings.FhOptions.FhfilepathlookupsizeLong, DEFAULT_FILENAME_LOOKUP_SIZE), new CommandLineArgument("fh-changed-fileset", CommandLineArgument.ArgumentType.Path, Strings.FhOptions.FhchangedfilesetShort, Strings.FhOptions.FhchangedfilesetLong), new CommandLineArgument("fh-deleted-fileset", CommandLineArgument.ArgumentType.Path, Strings.FhOptions.FhdeletedfilesetShort, string.Format(Strings.FhOptions.FhdeletedfilesetLong, "fh-changed-fileset")), new CommandLineArgument("fh-max-wastesize", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhmaxwastesizeShort, Strings.FhOptions.FhmaxwastesizeLong), new CommandLineArgument("fh-no-indexfiles", CommandLineArgument.ArgumentType.Boolean, Strings.FhOptions.FhnoindexfilesShort, Strings.FhOptions.FhnoindexfilesLong, "false"), new CommandLineArgument("fh-no-backendverification", CommandLineArgument.ArgumentType.Boolean, Strings.FhOptions.FhnobackendverificationShort, Strings.FhOptions.FhnobackendverificationLong, "false"), new CommandLineArgument("fh-dry-run", CommandLineArgument.ArgumentType.Boolean, Strings.FhOptions.FhdryrunShort, Strings.FhOptions.FhdryrunLong, "false"), new CommandLineArgument("fh-block-hash-algorithm", CommandLineArgument.ArgumentType.Enumeration, Strings.FhOptions.FhblockhashalgorithmShort, Strings.FhOptions.FhblockhashalgorithmLong, DEFAULT_BLOCK_HASH_ALGORITHM, null, GetSupportedHashes()), new CommandLineArgument("fh-file-hash-algorithm", CommandLineArgument.ArgumentType.Enumeration, Strings.FhOptions.FhfilehashalgorithmShort, Strings.FhOptions.FhfilehashalgorithmLong, DEFAULT_FILE_HASH_ALGORITHM, null, GetSupportedHashes()), new CommandLineArgument("fh-no-auto-compact", CommandLineArgument.ArgumentType.Boolean, Strings.FhOptions.FhnoautocompactShort, Strings.FhOptions.FhnoautocompactLong, "false"), new CommandLineArgument("fh-volume-size-tolerance", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhvolumesizetoleranceShort, Strings.FhOptions.FhvolumesizetoleranceLong), new CommandLineArgument("fh-patch-with-local-blocks", CommandLineArgument.ArgumentType.Size, Strings.FhOptions.FhpatchwithlocalblocksShort, Strings.FhOptions.FhpatchwithlocalblocksLong), #if DEBUG new CommandLineArgument("fh-no-local-blocks", CommandLineArgument.ArgumentType.Boolean, "Prevents using local blocks for restore", "", "false"), new CommandLineArgument("fh-no-local-db", CommandLineArgument.ArgumentType.Boolean, "Prevents using local database for restore", "", "false"), #endif }); } } /// /// Gets the path to the database /// public string Fhdbpath { get { string tmp; m_options.TryGetValue("fh-dbpath", out tmp); return tmp; } } /// /// Gets the size of file-blocks /// public int Fhblocksize { get { string tmp; if (!m_options.TryGetValue("fh-blocksize", out tmp)) tmp = DEFAULT_FH_BLOCKSIZE; long t = Utility.Sizeparser.ParseSize(tmp, "kb"); if (t > int.MaxValue || t < 1024) throw new ArgumentOutOfRangeException("FhBlocksize", string.Format("The blocksize cannot be less than {0}, nor larger than {1}", 1024, int.MaxValue)); return (int)t; } } /// /// Gets a flag indicating if metadata for files and folders should be ignored /// public bool FhNoMetadata { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-metadata"); } } /// /// Gets the block hash lookup size /// public long FhBlockHashLookupMemory { get { string v; m_options.TryGetValue("fh-blockhash-lookup-memory", out v); if (string.IsNullOrEmpty(v)) v = DEFAULT_BLOCK_HASH_LOOKUP_SIZE; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// Gets the file hash size /// public long FhFileHashLookupMemory { get { string v; m_options.TryGetValue("fh-filehash-lookup-memory", out v); if (string.IsNullOrEmpty(v)) v = DEFAULT_FILE_HASH_LOOKUP_SIZE; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// Gets the block hash size /// public long FhMetadataHashMemory { get { string v; m_options.TryGetValue("fh-metadatahash-lookup-memory", out v); if (string.IsNullOrEmpty(v)) v = DEFAULT_METADATA_HASH_LOOKUP_SIZE; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// Gets the file hash size /// public long FhFilePathMemory { get { string v; m_options.TryGetValue("fh-filepath-lookup-memory", out v); if (string.IsNullOrEmpty(v)) v = DEFAULT_FILENAME_LOOKUP_SIZE; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// Gets the maximum wasted remote size /// public long FhMaxWasteSize { get { string v; m_options.TryGetValue("fh-max-wastesize", out v); if (string.IsNullOrEmpty(v)) return this.VolumeSize * 2; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// Gets the volume size tolerance /// public long FhVolsizeTolerance { get { string v; m_options.TryGetValue("fh-volume-size-tolerance", out v); if (string.IsNullOrEmpty(v)) return this.VolumeSize / 100; return Utility.Sizeparser.ParseSize(v, "mb"); } } /// /// List of files to check for changes /// public string[] FhChangedFilelist { get { string v; m_options.TryGetValue("fh-changed-fileset", out v); if (string.IsNullOrEmpty(v)) return null; return v.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries); } } /// /// List of files to mark as deleted /// public string[] FhDeletedFilelist { get { string v; m_options.TryGetValue("fh-deleted-fileset", out v); if (string.IsNullOrEmpty(v)) return null; return v.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries); } } /// /// Gets a flag indicating if index files should be omitted /// public bool FhNoIndexfiles { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-indexfiles"); } } /// /// Gets a flag indicating if the check for files on the remote storage should be omitted /// public bool FhNoBackendverification { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-backendverification"); } } /// /// Gets a flag indicating if compacting should not be done automatically /// public bool FhNoAutoCompact { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-auto-compact"); } } /// /// Gets a flag indicating if the current operation should merely output the changes /// public bool FhDryrun { get { return Utility.Utility.ParseBoolOption(m_options, "fh-dry-run"); } } /// /// Gets a flag indicating if the current operation is intended to delete files older than a certain threshold /// public bool HasDeleteOlderThan { get { return m_options.ContainsKey("delete-older-than"); } } /// /// Gets a flag indicating if the current operation is intended to delete files older than a certain threshold /// public bool HasDeleteAllButN { get { return m_options.ContainsKey("delete-all-but-n") || m_options.ContainsKey("delete-all-but-n-full"); } } /// /// The block hash algorithm to use /// public string FhBlockHashAlgorithm { get { string v; m_options.TryGetValue("fh-block-hash-algorithm", out v); if (string.IsNullOrEmpty(v)) return DEFAULT_BLOCK_HASH_ALGORITHM; return v; } } /// /// The file hash algorithm to use /// public string FhFileHashAlgorithm { get { string v; m_options.TryGetValue("fh-file-hash-algorithm", out v); if (string.IsNullOrEmpty(v)) return DEFAULT_FILE_HASH_ALGORITHM; return v; } } /// /// Gets a flag indicating if the current operation is intended to delete files older than a certain threshold /// public bool FhPatchWithLocalBlocks { get { return m_options.ContainsKey("fh-patch-with-local-blocks"); } } #if DEBUG public bool NoLocalBlocks { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-local-blocks"); } } public bool NoLocalDb { get { return Utility.Utility.ParseBoolOption(m_options, "fh-no-local-db"); } } #endif } }