Encryption now works, at least with AES encryption.
Most Duplicity commandline switches are now supported. git-svn-id: https://duplicati.googlecode.com/svn/trunk@53 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
@@ -5,11 +5,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Main", "Duplicati
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.CommandLine", "Duplicati\CommandLine\Duplicati.CommandLine.csproj", "{81765A64-3661-4E3E-B850-2F6F87A51F74}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackendInterface", "Duplicati\Backend\BackendInterface\BackendInterface.csproj", "{994F3D0A-E91E-4EEE-80EE-064485E09909}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Backend.BackendInterface", "Duplicati\Backend\BackendInterface\Duplicati.Backend.BackendInterface.csproj", "{994F3D0A-E91E-4EEE-80EE-064485E09909}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackendLoader", "Duplicati\Backend\BackendLoader\BackendLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Backend.BackendLoader", "Duplicati\Backend\BackendLoader\Duplicati.Backend.BackendLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File", "Duplicati\Backend\File\File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Backend.File", "Duplicati\Backend\File\Duplicati.Backend.File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Core", "Duplicati\Core\Duplicati.Core.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
|
||||
EndProject
|
||||
@@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.SharpRSync", "Dup
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Logging", "Duplicati\Logging\Duplicati.Logging.csproj", "{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Encryption", "Duplicati\Encryption\Duplicati.Encryption.csproj", "{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SubversionScc) = preSolution
|
||||
Svn-Managed = True
|
||||
@@ -65,6 +67,10 @@ Global
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -100,6 +100,9 @@ namespace Duplicati.Backend
|
||||
|
||||
string scheme = new Uri(url).Scheme.ToLower();
|
||||
|
||||
if (m_backends == null)
|
||||
LoadBackends();
|
||||
|
||||
if (m_backends.ContainsKey(scheme))
|
||||
return (IBackendInterface)Activator.CreateInstance(m_backends[scheme], url, options);
|
||||
else
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BackendInterface\BackendInterface.csproj">
|
||||
<ProjectReference Include="..\BackendInterface\Duplicati.Backend.BackendInterface.csproj">
|
||||
<Project>{994F3D0A-E91E-4EEE-80EE-064485E09909}</Project>
|
||||
<Name>BackendInterface</Name>
|
||||
<Name>Duplicati.Backend.BackendInterface</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
@@ -1,69 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A0819A66-A2EF-48B1-BA69-14140C6C230E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Duplicati.Backend</RootNamespace>
|
||||
<AssemblyName>DuplicatiBackend</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BackendInterface\BackendInterface.csproj">
|
||||
<Project>{994F3D0A-E91E-4EEE-80EE-064485E09909}</Project>
|
||||
<Name>BackendInterface</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\BackendLoader\BackendLoader.csproj">
|
||||
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
|
||||
<Name>BackendLoader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\File\File.csproj">
|
||||
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
|
||||
<Name>File</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\FTP\FTP.csproj">
|
||||
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
|
||||
<Name>FTP</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SSH\SSH.csproj">
|
||||
<Project>{6BA21DCB-1701-4936-B177-3B6D4DE3474E}</Project>
|
||||
<Name>SSH</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DuplicatiBackend", "DuplicatiBackend.csproj", "{A0819A66-A2EF-48B1-BA69-14140C6C230E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackendInterface", "..\BackendInterface\BackendInterface.csproj", "{994F3D0A-E91E-4EEE-80EE-064485E09909}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FTP", "..\FTP\FTP.csproj", "{F61679A9-E5DE-468A-B5A4-05F92D0143D2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackendLoader", "..\BackendLoader\BackendLoader.csproj", "{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SSH", "..\SSH\SSH.csproj", "{6BA21DCB-1701-4936-B177-3B6D4DE3474E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File", "..\File\File.csproj", "{FC9B7611-836F-4127-8B44-A7C31F506807}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A0819A66-A2EF-48B1-BA69-14140C6C230E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A0819A66-A2EF-48B1-BA69-14140C6C230E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A0819A66-A2EF-48B1-BA69-14140C6C230E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A0819A66-A2EF-48B1-BA69-14140C6C230E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,186 +0,0 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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.Backend
|
||||
{
|
||||
|
||||
class Program
|
||||
{
|
||||
const string HELPMESSAGE =
|
||||
"Invalid number of arguments.\r\n\r\n" +
|
||||
"Usage: DuplicatiBackend <operation> <url> [options]\r\n\r\n" +
|
||||
"Operations:\r\n" +
|
||||
"\tHELP \t: Return this message\r\n" +
|
||||
"\tBACKENDS \t: List the avalible backends\r\n" +
|
||||
"\tLIST \t: Return a list of files at the given url\r\n" +
|
||||
"\tGET \t: Write the file at the given url to stdout\r\n" +
|
||||
"\tPUT \t: Write the contents of stdin to the given url\r\n" +
|
||||
"\tDELETE \t: Delete the file at the given url\r\n" +
|
||||
"\r\n\r\n" +
|
||||
"Options:\r\n" +
|
||||
"\t--file=<filename> \t: For GET, use filename rather than stdin\r\n" +
|
||||
" \t: For PUT, use filename rather than stdout\r\n" +
|
||||
" \t: For LIST, use filename rather than stdout\r\n";
|
||||
|
||||
static int Main(string[] args)
|
||||
{
|
||||
List<string> largs = new List<string>(args);
|
||||
|
||||
Dictionary<string, string> options = ExtractOptions(largs);
|
||||
|
||||
if (largs.Count < 1)
|
||||
{
|
||||
Console.WriteLine(HELPMESSAGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
string operation = args[0].ToUpper();
|
||||
if (operation == "HELP")
|
||||
{
|
||||
Console.WriteLine(HELPMESSAGE);
|
||||
return 0;
|
||||
}
|
||||
else if (operation == "BACKENDS")
|
||||
{
|
||||
Console.WriteLine("Registered backends:\r\n");
|
||||
foreach (string b in BackendLoader.Backends)
|
||||
Console.WriteLine(b + "\t: " + BackendLoader.GetBackend(b).DisplayName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (largs.Count != 2)
|
||||
{
|
||||
Console.WriteLine(HELPMESSAGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
string url = largs[1];
|
||||
IBackendInterface backend = null;
|
||||
try
|
||||
{
|
||||
backend = new BackendLoader(url);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("Failed to load backend: {0}", ex.Message));
|
||||
return -1;
|
||||
}
|
||||
|
||||
string file = options.ContainsKey("file") ? options["file"] : null;
|
||||
|
||||
System.IO.Stream s = null;
|
||||
|
||||
try
|
||||
{
|
||||
switch (operation.Trim().ToUpper())
|
||||
{
|
||||
case "LIST":
|
||||
if (file == null)
|
||||
s = Console.OpenStandardOutput();
|
||||
else
|
||||
s = new System.IO.FileStream(file, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None);
|
||||
|
||||
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(s))
|
||||
foreach (FileEntry fe in backend.List(url, options))
|
||||
sw.WriteLine(fe.Name);
|
||||
|
||||
break;
|
||||
case "PUT":
|
||||
if (file == null)
|
||||
s = Console.OpenStandardInput();
|
||||
else
|
||||
s = new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
|
||||
|
||||
backend.Put(url, options, s);
|
||||
break;
|
||||
case "GET":
|
||||
if (file == null)
|
||||
s = Console.OpenStandardOutput();
|
||||
else
|
||||
s = new System.IO.FileStream(file, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None);
|
||||
Utility.CopyStream(backend.Get(url, options), s, true);
|
||||
break;
|
||||
case "DELETE":
|
||||
backend.Delete(url, options);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine(HELPMESSAGE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("Failed: {0}", ex.Message));
|
||||
return -1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (file != null && s != null)
|
||||
{
|
||||
try { s.Close(); }
|
||||
catch { }
|
||||
|
||||
try { s.Dispose(); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> ExtractOptions(List<string> args)
|
||||
{
|
||||
Dictionary<string, string> options = new Dictionary<string, string>();
|
||||
|
||||
for (int i = 0; i < args.Count; i++)
|
||||
{
|
||||
if (args[i].StartsWith("--"))
|
||||
{
|
||||
string key = null;
|
||||
string value = null;
|
||||
if (args[i].IndexOf("=") > 0)
|
||||
{
|
||||
key = args[i].Substring(0, args[i].IndexOf("="));
|
||||
value = args[i].Substring(args[i].IndexOf("=") + 1);
|
||||
}
|
||||
else
|
||||
key = args[i];
|
||||
|
||||
//Skip the leading --
|
||||
key = key.Substring(2);
|
||||
if (!string.IsNullOrEmpty(value) && value.Length > 1 && value.StartsWith("\"") && value.EndsWith("\""))
|
||||
value = value.Substring(1, value.Length - 2);
|
||||
options[key] = value;
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DuplicatiBackend")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("HexaD")]
|
||||
[assembly: AssemblyProduct("DuplicatiBackend")]
|
||||
[assembly: AssemblyCopyright("Copyright © HexaD 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3c3285d4-1f1c-4673-80fa-7b76bab4b909")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+2
-2
@@ -41,9 +41,9 @@
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\BackendInterface\BackendInterface.csproj">
|
||||
<ProjectReference Include="..\BackendInterface\Duplicati.Backend.BackendInterface.csproj">
|
||||
<Project>{994F3D0A-E91E-4EEE-80EE-064485E09909}</Project>
|
||||
<Name>BackendInterface</Name>
|
||||
<Name>Duplicati.Backend.BackendInterface</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
@@ -48,8 +48,8 @@ namespace Duplicati.CommandLine
|
||||
if (!string.IsNullOrEmpty(value) && value.Length > 1 && value.StartsWith("\"") && value.EndsWith("\""))
|
||||
value = value.Substring(1, value.Length - 2);
|
||||
|
||||
//This is a bit ugly, but we want to preserve the order of "include" and "exclude"
|
||||
options.Add(key, value);
|
||||
//Last argument overwrites the current
|
||||
options[key] = value;
|
||||
|
||||
args.RemoveAt(i);
|
||||
i--;
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
<Compile Include="UnitTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Backend\File\File.csproj">
|
||||
<ProjectReference Include="..\Backend\File\Duplicati.Backend.File.csproj">
|
||||
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
|
||||
<Name>File</Name>
|
||||
<Name>Duplicati.Backend.File</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Compression\Duplicati.Compression.csproj">
|
||||
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
|
||||
|
||||
@@ -39,15 +39,113 @@ namespace Duplicati.CommandLine
|
||||
cargs.Add(Core.FilenameFilter.EncodeAsFilter(Core.FilenameFilter.ParseCommandLine(cargs, true)));
|
||||
Dictionary<string, string> options = CommandLineParser.ExtractOptions(cargs);
|
||||
|
||||
//TODO: Print usage window
|
||||
if (cargs.Count < 2)
|
||||
throw new Exception("Not enough parameters");
|
||||
|
||||
string source = cargs[0];
|
||||
string target = cargs[1];
|
||||
|
||||
if (source.Trim().ToLower() == "restore" && cargs.Count == 3)
|
||||
{
|
||||
source = target;
|
||||
target = cargs[2];
|
||||
options["restore"] = null;
|
||||
}
|
||||
|
||||
if (!options.ContainsKey("passphrase"))
|
||||
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("PASSPHRASE")))
|
||||
options["passphrase"] = System.Environment.GetEnvironmentVariable("PASSPHRASE");
|
||||
|
||||
if (source.Trim().ToLower() == "list")
|
||||
Console.WriteLine(string.Join("\r\n", Duplicati.Main.Interface.List(target, options)));
|
||||
else if (source.IndexOf("://") > 0)
|
||||
else if (source.IndexOf("://") > 0 || options.ContainsKey("restore"))
|
||||
{
|
||||
if (!options.ContainsKey("passphrase") && !options.ContainsKey("no-encryption"))
|
||||
{
|
||||
string pwd = ReadPassphraseFromConsole(false);
|
||||
if (pwd == null)
|
||||
return;
|
||||
else
|
||||
options["passphrase"] = pwd;
|
||||
}
|
||||
|
||||
Duplicati.Main.Interface.Restore(source, target, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!options.ContainsKey("passphrase") && !options.ContainsKey("no-encryption"))
|
||||
{
|
||||
string pwd = ReadPassphraseFromConsole(true);
|
||||
if (pwd == null)
|
||||
return;
|
||||
else
|
||||
options["passphrase"] = pwd;
|
||||
}
|
||||
|
||||
Duplicati.Main.Interface.Backup(source, target, options);
|
||||
}
|
||||
}
|
||||
|
||||
private static string ReadPassphraseFromConsole(bool confirm)
|
||||
{
|
||||
Console.Write("\nEnter passphrase: ");
|
||||
StringBuilder password = new StringBuilder();
|
||||
|
||||
while (true)
|
||||
{
|
||||
ConsoleKeyInfo k = Console.ReadKey(true);
|
||||
if (k.Key == ConsoleKey.Enter)
|
||||
break;
|
||||
|
||||
if (k.Key == ConsoleKey.Escape)
|
||||
return null;
|
||||
|
||||
password.Append(k.KeyChar);
|
||||
|
||||
//Unix/Linux user know that there is no feedback, Win user gets scared :)
|
||||
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
Console.Write("*");
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
if (confirm)
|
||||
{
|
||||
Console.Write("\nConfirm passphrase: ");
|
||||
StringBuilder password2 = new StringBuilder();
|
||||
|
||||
while (true)
|
||||
{
|
||||
ConsoleKeyInfo k = Console.ReadKey(true);
|
||||
if (k.Key == ConsoleKey.Enter)
|
||||
break;
|
||||
|
||||
if (k.Key == ConsoleKey.Escape)
|
||||
return null;
|
||||
|
||||
password2.Append(k.KeyChar);
|
||||
|
||||
//Unix/Linux user know that there is no feedback, Win user gets scared :)
|
||||
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
Console.Write("*");
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
if (password.ToString() != password2.ToString())
|
||||
{
|
||||
Console.WriteLine("The passwords do not match");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (password.ToString().Length == 0)
|
||||
{
|
||||
Console.WriteLine("Empty passwords are not allowed");
|
||||
return null;
|
||||
}
|
||||
|
||||
return password.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//
|
||||
#endregion
|
||||
|
||||
#if DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@@ -43,6 +46,8 @@ namespace Duplicati.CommandLine
|
||||
{
|
||||
Dictionary<string, string> options = new Dictionary<string, string>();
|
||||
options["time-separator"] = "'";
|
||||
options["passphrase"] = "secret password!";
|
||||
|
||||
Console.WriteLine("Backing up the full copy: " + folders[0]);
|
||||
using (new Logging.Timer("Full backup of " + folders[0]))
|
||||
Duplicati.Main.Interface.Backup(folders[0], "file://" + tf, options);
|
||||
@@ -166,3 +171,5 @@ namespace Duplicati.CommandLine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -41,15 +41,18 @@ namespace Duplicati.Core
|
||||
/// <returns>A parsed ordered set of filters</returns>
|
||||
public static List<KeyValuePair<bool, string>> ParseCommandLine(List<string> commandline, bool remove)
|
||||
{
|
||||
//TODO: Support the options --include-filelist, --include-globbin-filelist, --include-regexp-filelist
|
||||
//and the exclude variants (all work on the lines in a file)
|
||||
|
||||
List<KeyValuePair<bool, string>> lst = new List<KeyValuePair<bool, string>>();
|
||||
Regex includeOrExclude = new Regex(@"(?<prefix>(\-\-include\=)|(\-\-exclude\=)|(\-\-regexp\-include\=)|(\-\-regexp\-exclude\=))(?<content>.+)", RegexOptions.IgnoreCase);
|
||||
Regex includeOrExclude = new Regex(@"(?<prefix>(\-\-include\=)|(\-\-exclude\=)|(\-\-include\-regexp\=)|(\-\-exclude\-regexp\=))(?<content>.+)", RegexOptions.IgnoreCase);
|
||||
for (int i = 0; i < commandline.Count; i++ )
|
||||
{
|
||||
string s = commandline[i];
|
||||
Match m = includeOrExclude.Match(s.ToLower());
|
||||
if (m.Success)
|
||||
{
|
||||
bool include = m.Groups["prefix"].Value.ToLower() == "--include=" || m.Groups["prefix"].Value.ToLower() == "--regexp-include=";
|
||||
bool include = m.Groups["prefix"].Value.ToLower() == "--include=" || m.Groups["prefix"].Value.ToLower() == "--include-regexp=";
|
||||
string cmd = m.Groups["content"].Value;
|
||||
if (!m.Groups["prefix"].Value.ToLower().StartsWith("--regexp"))
|
||||
cmd = ConvertGlobbingToRegExp(cmd);
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Duplicati.Core
|
||||
private string m_path;
|
||||
|
||||
public TempFile()
|
||||
: this(System.IO.Path.GetTempFileName())
|
||||
: this(System.IO.Path.Combine(TempFolder.SystemTempPath, System.IO.Path.GetRandomFileName()))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ namespace Duplicati.Core
|
||||
{
|
||||
m_path = path;
|
||||
if (!System.IO.File.Exists(m_path))
|
||||
System.IO.File.Create(m_path);
|
||||
using (System.IO.File.Create(m_path))
|
||||
{ /*Dispose it immediately*/ }
|
||||
}
|
||||
|
||||
public static implicit operator string(TempFile path)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Duplicati.Core
|
||||
private string m_folder;
|
||||
|
||||
public TempFolder()
|
||||
: this(System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName()))
|
||||
: this(System.IO.Path.Combine(SystemTempPath, System.IO.Path.GetRandomFileName()))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,5 +67,22 @@ namespace Duplicati.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static string m_system_temp_dir = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the global temporary path used to store temporary files.
|
||||
/// Set to null to use the system default.
|
||||
/// </summary>
|
||||
public static string SystemTempPath
|
||||
{
|
||||
get { return m_system_temp_dir == null ? System.IO.Path.GetTempPath() : m_system_temp_dir; }
|
||||
set
|
||||
{
|
||||
if (!System.IO.Directory.Exists(value))
|
||||
throw new Exception("Temporary folder does not exist: " + value);
|
||||
m_system_temp_dir = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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;
|
||||
@@ -62,8 +81,11 @@ namespace Duplicati.Encryption
|
||||
throw new Exception("Useless encryption detected");
|
||||
|
||||
System.Security.Cryptography.ICryptoTransform ct = m_instance.CreateEncryptor();
|
||||
using (System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(input, ct, System.Security.Cryptography.CryptoStreamMode.Write))
|
||||
Core.Utility.CopyStream(cs, output);
|
||||
using (System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(output, ct, System.Security.Cryptography.CryptoStreamMode.Write))
|
||||
{
|
||||
Core.Utility.CopyStream(input, cs);
|
||||
cs.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Decrypt(System.IO.Stream input, System.IO.Stream output)
|
||||
|
||||
@@ -34,12 +34,21 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AESEncryption.cs" />
|
||||
<Compile Include="EncryptedBackendWrapper.cs" />
|
||||
<Compile Include="EncryptionBase.cs" />
|
||||
<Compile Include="IEncryption.cs" />
|
||||
<Compile Include="GPGEncryption.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Backend\BackendInterface\Duplicati.Backend.BackendInterface.csproj">
|
||||
<Project>{994F3D0A-E91E-4EEE-80EE-064485E09909}</Project>
|
||||
<Name>Duplicati.Backend.BackendInterface</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Backend\BackendLoader\Duplicati.Backend.BackendLoader.csproj">
|
||||
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
|
||||
<Name>Duplicati.Backend.BackendLoader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Core\Duplicati.Core.csproj">
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Core</Name>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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.Encryption
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that wraps a backend and transparently encrypts and decrypts data to and from the backend
|
||||
/// </summary>
|
||||
public class EncryptedBackendWrapper : Backend.IBackendInterface
|
||||
{
|
||||
private Backend.IBackendInterface m_realbackend;
|
||||
private IEncryption m_encryptionEngine;
|
||||
|
||||
public EncryptedBackendWrapper(string target, Dictionary<string, string> options)
|
||||
: this(Backend.BackendLoader.GetBackend(target, options), options)
|
||||
{
|
||||
}
|
||||
|
||||
public EncryptedBackendWrapper(Backend.IBackendInterface backend, Dictionary<string, string> options)
|
||||
{
|
||||
if (!options.ContainsKey("passphrase") || string.IsNullOrEmpty(options["passphrase"]))
|
||||
throw new Exception("No passphrase set");
|
||||
|
||||
string passphrase = options["passphrase"];
|
||||
|
||||
m_realbackend = backend;
|
||||
if (options.ContainsKey("gpg-encryption"))
|
||||
m_encryptionEngine = new GPGEncryption(passphrase, options.ContainsKey("sign-key") ? options["sign-key"] : null);
|
||||
else
|
||||
m_encryptionEngine = new AESEncryption(passphrase);
|
||||
}
|
||||
|
||||
#region IBackendInterface Members
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get { return m_realbackend.DisplayName; }
|
||||
}
|
||||
|
||||
public string ProtocolKey
|
||||
{
|
||||
get { return m_realbackend.ProtocolKey; }
|
||||
}
|
||||
|
||||
public List<Duplicati.Backend.FileEntry> List()
|
||||
{
|
||||
return m_realbackend.List();
|
||||
}
|
||||
|
||||
public void Put(string remotename, string filename)
|
||||
{
|
||||
remotename += (m_encryptionEngine is AESEncryption ? ".aes" : ".gpg");
|
||||
using (Core.TempFile tf = new Duplicati.Core.TempFile())
|
||||
{
|
||||
m_encryptionEngine.Encrypt(filename, tf);
|
||||
m_realbackend.Put(remotename, tf);
|
||||
}
|
||||
}
|
||||
|
||||
public void Get(string remotename, string filename)
|
||||
{
|
||||
using (Core.TempFile tf = new Duplicati.Core.TempFile())
|
||||
{
|
||||
m_realbackend.Get(remotename, tf);
|
||||
m_encryptionEngine.Decrypt(tf, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(string remotename)
|
||||
{
|
||||
m_realbackend.Delete(remotename);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static Backend.IBackendInterface WrapWithEncryption(Backend.IBackendInterface backend, Dictionary<string, string> options)
|
||||
{
|
||||
if (options.ContainsKey("no-encryption"))
|
||||
return backend;
|
||||
else
|
||||
return new EncryptedBackendWrapper(backend, options);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,22 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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;
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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;
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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;
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
using System.Reflection;
|
||||
#region Disclaimer / License
|
||||
// Copyright (C) 2008, 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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
<Compile Include="RSyncDir.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Backend\BackendInterface\BackendInterface.csproj">
|
||||
<ProjectReference Include="..\Backend\BackendInterface\Duplicati.Backend.BackendInterface.csproj">
|
||||
<Project>{994F3D0A-E91E-4EEE-80EE-064485E09909}</Project>
|
||||
<Name>BackendInterface</Name>
|
||||
<Name>Duplicati.Backend.BackendInterface</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Backend\BackendLoader\BackendLoader.csproj">
|
||||
<ProjectReference Include="..\Backend\BackendLoader\Duplicati.Backend.BackendLoader.csproj">
|
||||
<Project>{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}</Project>
|
||||
<Name>BackendLoader</Name>
|
||||
<Name>Duplicati.Backend.BackendLoader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Compression\Duplicati.Compression.csproj">
|
||||
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
|
||||
@@ -57,6 +57,10 @@
|
||||
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
|
||||
<Name>Duplicati.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Encryption\Duplicati.Encryption.csproj">
|
||||
<Project>{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}</Project>
|
||||
<Name>Duplicati.Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Duplicati.Logging.csproj">
|
||||
<Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
|
||||
<Name>Duplicati.Logging</Name>
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Duplicati.Main
|
||||
private bool m_useShortFilenames;
|
||||
private string m_timeSeperator;
|
||||
|
||||
private const long TICKS_PR_SECOND = 10000000;
|
||||
|
||||
public FilenameStrategy(Dictionary<string, string> options)
|
||||
{
|
||||
//--short-filenames
|
||||
@@ -68,34 +70,38 @@ namespace Duplicati.Main
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: Finish this
|
||||
byte[] tmp = new byte[4 + 2 + 2 + 2 + 2 + 2];
|
||||
return prefix + "-" + t + (full ? "F" : "I") + "";
|
||||
return prefix + "-" + t + (full ? "F" : "I") + (time.Ticks / TICKS_PR_SECOND).ToString("X");
|
||||
}
|
||||
}
|
||||
|
||||
public BackupEntry DecodeFilename(string prefix, Duplicati.Backend.FileEntry fe)
|
||||
{
|
||||
//TODO: Implement short filenames
|
||||
string shortregexp = @"(?<prefix>%filename%)\-(?<type>(C|S|M)(?<inc>(F|I))(?<time>([A-F]|[a-f]|[0-9])+)\.(?<extension>.+)";
|
||||
string regexp = @"(?<prefix>%filename%)\-(?<inc>(full|inc))\-(?<type>(content|signature|manifest))\.(?<time>\d{2}\-\d{2}\-\d{4}.\d{2}\%timesep%\d{2}\%timesep%\d{2})\.(?<extension>.+)";
|
||||
regexp = regexp.Replace("%filename%", prefix).Replace("%timesep%", m_timeSeperator);
|
||||
|
||||
Match m = Regex.Match(fe.Name, regexp);
|
||||
if (!m.Success)
|
||||
m = Regex.Match(fe.Name, shortregexp);
|
||||
if (!m.Success)
|
||||
return null;
|
||||
|
||||
BackupEntry.EntryType type;
|
||||
if (m.Groups["type"].Value == "manifest")
|
||||
if (m.Groups["type"].Value == "manifest" || m.Groups["type"].Value == "M")
|
||||
type = BackupEntry.EntryType.Manifest;
|
||||
else if (m.Groups["type"].Value == "content")
|
||||
else if (m.Groups["type"].Value == "content" || m.Groups["type"].Value == "C")
|
||||
type = BackupEntry.EntryType.Content;
|
||||
else if (m.Groups["type"].Value == "signature")
|
||||
else if (m.Groups["type"].Value == "signature" || m.Groups["type"].Value == "S")
|
||||
type = BackupEntry.EntryType.Signature;
|
||||
else
|
||||
return null;
|
||||
|
||||
bool isFull = m.Groups["inc"].Value == "full";
|
||||
DateTime time = DateTime.Parse(m.Groups["time"].Value.Replace(m_timeSeperator, ":"));
|
||||
bool isFull = m.Groups["inc"].Value == "full" || m.Groups["inc"].Value == "F";
|
||||
DateTime time;
|
||||
if (m.Groups["inc"].Value == "F") //Short format
|
||||
time = new DateTime(long.Parse(m.Groups["time"].Value, System.Globalization.NumberStyles.HexNumber) * TICKS_PR_SECOND);
|
||||
else
|
||||
time = DateTime.Parse(m.Groups["time"].Value.Replace(m_timeSeperator, ":"));
|
||||
|
||||
return new BackupEntry(fe, time, type, isFull);
|
||||
}
|
||||
|
||||
@@ -27,13 +27,15 @@ namespace Duplicati.Main
|
||||
{
|
||||
public static void Backup(string source, string target, Dictionary<string, string> options)
|
||||
{
|
||||
SetupCommonOptions(options);
|
||||
|
||||
using (new Logging.Timer("Backup from " + source + " to " + target))
|
||||
{
|
||||
FilenameStrategy fns = new FilenameStrategy(options);
|
||||
Core.FilenameFilter filter = new Duplicati.Core.FilenameFilter(options);
|
||||
bool full = options.ContainsKey("full");
|
||||
|
||||
Backend.IBackendInterface backend = new Backend.BackendLoader(target, options);
|
||||
Backend.IBackendInterface backend = new Encryption.EncryptedBackendWrapper(target, options);
|
||||
List<BackupEntry> prev = ParseFileList(target, options);
|
||||
|
||||
if (prev.Count == 0)
|
||||
@@ -101,8 +103,9 @@ namespace Duplicati.Main
|
||||
{
|
||||
using (Compression.Compression signature = new Duplicati.Compression.Compression(dir.m_targetfolder, sigzip))
|
||||
{
|
||||
foreach(string s in folders)
|
||||
signature.AddFolder(s);
|
||||
if (folders != null)
|
||||
foreach(string s in folders)
|
||||
signature.AddFolder(s);
|
||||
|
||||
folders = null;
|
||||
|
||||
@@ -154,11 +157,13 @@ namespace Duplicati.Main
|
||||
|
||||
public static void Restore(string source, string target, Dictionary<string, string> options)
|
||||
{
|
||||
SetupCommonOptions(options);
|
||||
|
||||
using (new Logging.Timer("Restore from " + source + " to " + target))
|
||||
{
|
||||
string specificfile = options.ContainsKey("file-to-restore") ? options["file-to-restore"] : "";
|
||||
string specifictime = options.ContainsKey("restore-time") ? options["restore-time"] : "now";
|
||||
Backend.IBackendInterface backend = new Backend.BackendLoader(source, options);
|
||||
Backend.IBackendInterface backend = new Encryption.EncryptedBackendWrapper(source, options);
|
||||
|
||||
if (string.IsNullOrEmpty(specifictime))
|
||||
specifictime = "now";
|
||||
@@ -239,6 +244,8 @@ namespace Duplicati.Main
|
||||
|
||||
public static string[] List(string source, Dictionary<string, string> options)
|
||||
{
|
||||
SetupCommonOptions(options);
|
||||
|
||||
List<string> res = new List<string>();
|
||||
Duplicati.Backend.IBackendInterface i = new Duplicati.Backend.BackendLoader(source, options);
|
||||
foreach (Duplicati.Backend.FileEntry fe in i.List())
|
||||
@@ -249,6 +256,8 @@ namespace Duplicati.Main
|
||||
|
||||
public static List<BackupEntry> ParseFileList(string source, Dictionary<string, string> options)
|
||||
{
|
||||
SetupCommonOptions(options);
|
||||
|
||||
using (new Logging.Timer("Getting and sorting filelist from " + source))
|
||||
{
|
||||
FilenameStrategy fns = new FilenameStrategy(options);
|
||||
@@ -325,5 +334,11 @@ namespace Duplicati.Main
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void SetupCommonOptions(Dictionary<string, string> options)
|
||||
{
|
||||
if (options.ContainsKey("tempdir"))
|
||||
Core.TempFolder.SystemTempPath = options["tempdir"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user