Still needs to describe the filter system. git-svn-id: https://duplicati.googlecode.com/svn/trunk@129 59da171f-624f-0410-aa54-27559c288bec
338 lines
18 KiB
C#
338 lines
18 KiB
C#
#region Disclaimer / License
|
|
// Copyright (C) 2009, Kenneth Skovhede
|
|
// http://www.hexad.dk, opensource@hexad.dk
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
//
|
|
#endregion
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace Duplicati.Library.Main
|
|
{
|
|
public class Options
|
|
{
|
|
private Dictionary<string, string> m_options;
|
|
|
|
public Options(Dictionary<string, string> options)
|
|
{
|
|
m_options = options;
|
|
}
|
|
|
|
public Dictionary<string, string> RawOptions { get { return m_options; } }
|
|
|
|
public IList<Backend.ICommandLineArgument> SupportedCommands
|
|
{
|
|
get
|
|
{
|
|
return new List<Backend.ICommandLineArgument>(new Backend.ICommandLineArgument[] {
|
|
new Backend.CommandLineArgument("full", Backend.CommandLineArgument.ArgumentType.Boolean, "A flag used to force full backups", "When this flag is specified, Duplicati will make a full backup of all files, and ignore any incremental data."),
|
|
new Backend.CommandLineArgument("volsize", Backend.CommandLineArgument.ArgumentType.Size, "A size string that limits the size of the volumes", "This option can change the default volume size. Changing the size can be usefull if the backend has a limit on the size of each individual file", "5mb"),
|
|
new Backend.CommandLineArgument("totalsize", Backend.CommandLineArgument.ArgumentType.Size, "The number of bytes generated by each backup run", "This option can place an upper limit on the total size of each backup. Note that if this flag is specified the backup may not contain all files, even for a full backup."),
|
|
new Backend.CommandLineArgument("auto-cleanup", Backend.CommandLineArgument.ArgumentType.Boolean, "A flag indiciating that Duplicati should remove unused files", "If a backup is interrupted there will likely be partial files present on the backend. Using this flag, Duplicati will automatically remove such files when encountered."),
|
|
new Backend.CommandLineArgument("full-if-older-than", Backend.CommandLineArgument.ArgumentType.Timespan, "The max duration between full backups", "If the last full backup is older than the duration supplied here, Duplicati will make a full backup, otherwise an incremental"),
|
|
|
|
new Backend.CommandLineArgument("signature-control-files", Backend.CommandLineArgument.ArgumentType.Path, "A list of control files to embed in the backups", "Supply a list of files seperated with semicolons, that will be added to each backup. The Duplicati GUI program uses this to store the setup database with each backup."),
|
|
new Backend.CommandLineArgument("signature-cache-path", Backend.CommandLineArgument.ArgumentType.Path, "A path to temporary storage", "If this path is supplied, Duplicati will store all signature files here, so re-downloads can be avoided."),
|
|
new Backend.CommandLineArgument("skip-file-hash-checks", Backend.CommandLineArgument.ArgumentType.Boolean, "Set this flag to skip hash checks", "If the hash for the volume does not match, Duplicati will refuse to use the backup. Supply this flag to allow Duplicati to proceed anyway."),
|
|
new Backend.CommandLineArgument("file-to-restore", Backend.CommandLineArgument.ArgumentType.String, "A list of files to restore", "By default, duplicati will restore all files in the backup. Use this option to restore only a subset of the files"),
|
|
new Backend.CommandLineArgument("restore-time", Backend.CommandLineArgument.ArgumentType.String, "The time to restore files", "By default, Duplicati will restore files from the most recent backup, use this option to select another item. You may use relative times, like \"-2M\" for a backup from two months ago.", "now"),
|
|
|
|
new Backend.CommandLineArgument("disable-filetime-check", Backend.CommandLineArgument.ArgumentType.String, "Disable checks based on file time", "The operating system keeps track of the last time a file was written. Using this information, Duplicati can quickly determine if the file has been modified. If some application deliberately modifies this information, Duplicati won't work correctly unless this flag is set."),
|
|
new Backend.CommandLineArgument("force", Backend.CommandLineArgument.ArgumentType.String, "Force the removal of files", "When deleting old files, Duplicati will only write out what files are supposed to be deleted. Specify the \"force\" option to actually remove them."),
|
|
new Backend.CommandLineArgument("tempdir", Backend.CommandLineArgument.ArgumentType.Path, "Temporary storage folder", "Duplicati will use the system default temporary folder. This option can be used to supply an alternative folder for temporary storage."),
|
|
new Backend.CommandLineArgument("thread-priority", Backend.CommandLineArgument.ArgumentType.Enumeration, "Thread priority", "Selects another thread priority for the process. Use this to set Duplicati to be more or less CPU intensive.", "normal", null, new string[] {"high", "abovenormal", "normal", "belownormal", "low", "idle" }),
|
|
|
|
new Backend.CommandLineArgument("backup-prefix", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename prefix", "Any string used to prefix the filenames generated by Duplicati.", "duplicati"),
|
|
new Backend.CommandLineArgument("time-separator", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename timeseperator", "Per default, Duplicati will use the colon \":\" character to seperate the time fields in the filename. However, on some filesystem, notably windows, this character is not allowed. Use this option to use another character."),
|
|
new Backend.CommandLineArgument("short-filenames", Backend.CommandLineArgument.ArgumentType.Boolean, "Use short filenames", "If the filesystem does not support the long filenames that Duplicati uses, this switch will change the time to be a much more compact, but hard to read format. It will also make the default prefix \"dpl\"."),
|
|
|
|
/*new Backend.CommandLineArgument("include", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename timeseperator", "Per default, Duplicati will use the colon \":\" character to seperate the time fields in the filename. However, on some filesystem, notably windows, this character is not allowed. Use this option to use another character."),
|
|
new Backend.CommandLineArgument("exclude", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename timeseperator", "Per default, Duplicati will use the colon \":\" character to seperate the time fields in the filename. However, on some filesystem, notably windows, this character is not allowed. Use this option to use another character."),
|
|
new Backend.CommandLineArgument("include-regexp", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename timeseperator", "Per default, Duplicati will use the colon \":\" character to seperate the time fields in the filename. However, on some filesystem, notably windows, this character is not allowed. Use this option to use another character."),
|
|
new Backend.CommandLineArgument("exclude-regexp", Backend.CommandLineArgument.ArgumentType.String, "Backup volume filename timeseperator", "Per default, Duplicati will use the colon \":\" character to seperate the time fields in the filename. However, on some filesystem, notably windows, this character is not allowed. Use this option to use another character."),*/
|
|
|
|
new Backend.CommandLineArgument("passphrase", Backend.CommandLineArgument.ArgumentType.String, "Passphrase used to encrypt backups", "Supply a passphrase that Duplicati will use to encrypt the backup volumes, making the unreadable without the passphrase."),
|
|
new Backend.CommandLineArgument("gpg-encryption", Backend.CommandLineArgument.ArgumentType.Boolean, "Use GnuPG for encryption", "By default, Duplicati will use the AES encryption algorithm to encrypt the backup volumes, setting this flag makes Duplicati use the GNU Privacy Guard instead. GnuPG must be installed on the machine for this to work."),
|
|
new Backend.CommandLineArgument("gpg-program-path", Backend.CommandLineArgument.ArgumentType.Path, "The path to GnuPG", "The path to the GNU Privacy Guard program. If not supplied, Duplicati will assume that the program \"gpg\" is avalible in the system path."),
|
|
new Backend.CommandLineArgument("sign-key", Backend.CommandLineArgument.ArgumentType.String, "Sign key for GnuPG", "The GNU Privacy Guard can optionally sign volumes with a special key. This feature is not currently active in Duplicati."),
|
|
new Backend.CommandLineArgument("no-encryption", Backend.CommandLineArgument.ArgumentType.Boolean, "Disable encryption", "If you store the backups on a local disk, and prefer that they are kept unencrypted, you can turn of encryption completely by using this switch."),
|
|
|
|
|
|
});
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A value indicating if the backup is a full backup
|
|
/// </summary>
|
|
public bool Full { get { return GetBool("full"); } }
|
|
|
|
/// <summary>
|
|
/// Gets the size of each volume in bytes
|
|
/// </summary>
|
|
public long VolumeSize
|
|
{
|
|
get
|
|
{
|
|
string volsize = "5mb";
|
|
if (m_options.ContainsKey("volsize"))
|
|
volsize = m_options["volsize"];
|
|
|
|
return Math.Max(1024 * 1024, Core.Sizeparser.ParseSize(volsize, "mb"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the total size in bytes allowed for a single backup run
|
|
/// </summary>
|
|
public long MaxSize
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("totalsize") || string.IsNullOrEmpty(m_options["totalsize"]))
|
|
return long.MaxValue;
|
|
else
|
|
return Math.Max(VolumeSize, Core.Sizeparser.ParseSize(m_options["totalsize"]));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the time at which a full backup should be performed
|
|
/// </summary>
|
|
/// <param name="offsettime">The time the last full backup was created</param>
|
|
/// <returns>The time at which a full backup should be performed</returns>
|
|
public DateTime FullIfOlderThan(DateTime offsettime)
|
|
{
|
|
if (!m_options.ContainsKey("full-if-older-than") || string.IsNullOrEmpty(m_options["full-if-older-than"]))
|
|
return DateTime.Now.AddYears(1); //We assume that the check will occur in less than one year :)
|
|
else
|
|
return Core.Timeparser.ParseTimeInterval(m_options["full-if-older-than"], offsettime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// A value indicating if orphan files are deleted automatically
|
|
/// </summary>
|
|
public bool AutoCleanup { get { return GetBool("auto-cleanup"); } }
|
|
|
|
/// <summary>
|
|
/// Gets a list of files to add to the signature volumes
|
|
/// </summary>
|
|
public string SignatureControlFiles
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("signature-control-files") || string.IsNullOrEmpty(m_options["signature-control-files"]))
|
|
return null;
|
|
else
|
|
return m_options["signature-control-files"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a list of files to add to the signature volumes
|
|
/// </summary>
|
|
public string SignatureCachePath
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("signature-cache-path") || string.IsNullOrEmpty(m_options["signature-cache-path"]))
|
|
return null;
|
|
else
|
|
return m_options["signature-cache-path"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A value indicating if file hash checks are skipped
|
|
/// </summary>
|
|
public bool SkipFileHashChecks { get { return GetBool("skip-file-hash-checks"); } }
|
|
|
|
/// <summary>
|
|
/// Gets a list of files to restore
|
|
/// </summary>
|
|
public string FileToRestore
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("file-to-restore") || string.IsNullOrEmpty(m_options["file-to-restore"]))
|
|
return null;
|
|
else
|
|
return m_options["file-to-restore"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the backup that should be restored
|
|
/// </summary>
|
|
public DateTime RestoreTime
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("restore-time") || string.IsNullOrEmpty(m_options["restore-time"]))
|
|
return DateTime.Now.AddYears(1); //We assume that the check will occur in less than one year :)
|
|
else
|
|
return Core.Timeparser.ParseTimeInterval(m_options["restore-time"], DateTime.Now);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A value indicating if file time checks are skipped
|
|
/// </summary>
|
|
public bool DisableFiletimeCheck { get { return GetBool("disable-filetime-check"); } }
|
|
|
|
/// <summary>
|
|
/// A value indicating if file deletes are forced
|
|
/// </summary>
|
|
public bool Force { get { return GetBool("force"); } }
|
|
|
|
/// <summary>
|
|
/// Gets the folder where temporary files are stored
|
|
/// </summary>
|
|
public string TempDir
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("tempdir") || string.IsNullOrEmpty(m_options["tempdir"]))
|
|
return null;
|
|
else
|
|
return m_options["tempdir"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the process priority
|
|
/// </summary>
|
|
public string ThreadPriority
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("thread-priority") || string.IsNullOrEmpty(m_options["thread-priority"]))
|
|
return null;
|
|
else
|
|
return m_options["thread-priority"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A value indicating if file deletes are forced
|
|
/// </summary>
|
|
public bool UseShortFilenames { get { return GetBool("short-filenames"); } }
|
|
|
|
/// <summary>
|
|
/// Gets the backup prefix
|
|
/// </summary>
|
|
public string BackupPrefix
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("backup-prefix") || string.IsNullOrEmpty(m_options["backup-prefix"]))
|
|
return this.UseShortFilenames ? "dpl" : "duplicati";
|
|
else
|
|
return m_options["backup-prefix"];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the process priority
|
|
/// </summary>
|
|
public string TimeSeperatorChar
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("time-separator") || string.IsNullOrEmpty(m_options["time-separator"]))
|
|
return ":";
|
|
else
|
|
return m_options["time-separator"];
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the filter used to include or exclude files
|
|
/// </summary>
|
|
public Core.FilenameFilter Filter
|
|
{
|
|
get
|
|
{
|
|
if (m_options.ContainsKey("filter"))
|
|
return new Duplicati.Library.Core.FilenameFilter(Core.FilenameFilter.DecodeFilter(m_options["filter"]));
|
|
else
|
|
return new Duplicati.Library.Core.FilenameFilter(new List<KeyValuePair<bool, string>>());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a value indiciating if a filter is specified
|
|
/// </summary>
|
|
public bool HasFilter { get { return m_options.ContainsKey("filter"); } }
|
|
|
|
/// <summary>
|
|
/// Gets the number of old backups to keep
|
|
/// </summary>
|
|
public int RemoveAllButNFull
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("remove-all-but-n-full"))
|
|
throw new Exception("No count given for \"Remove All But N Full\"");
|
|
|
|
int x = int.Parse(m_options["remove-all-but-n-full"]);
|
|
if (x < 0)
|
|
throw new Exception("Invalid count for remove-all-but-n-full");
|
|
|
|
return x;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the timelimit for removal
|
|
/// </summary>
|
|
public DateTime RemoveOlderThan
|
|
{
|
|
get
|
|
{
|
|
if (!m_options.ContainsKey("remove-older-than"))
|
|
throw new Exception("No count given for \"Remove Older Than\"");
|
|
|
|
return Core.Timeparser.ParseTimeInterval(m_options["remove-older-than"], DateTime.Now, true);
|
|
}
|
|
}
|
|
|
|
private bool GetBool(string name)
|
|
{
|
|
if (!m_options.ContainsKey(name))
|
|
return false;
|
|
else
|
|
{
|
|
string v = m_options[name];
|
|
if (string.IsNullOrEmpty(v))
|
|
return true;
|
|
else
|
|
{
|
|
v = v.ToLower().Trim();
|
|
if (v == "false" || v == "no" || v == "off")
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|