diff --git a/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
new file mode 100644
index 000000000..eedf3f25e
--- /dev/null
+++ b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
@@ -0,0 +1,91 @@
+
+
+
+ Debug
+ AnyCPU
+ 10.0.0
+ 2.0
+ {2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}
+ Exe
+ Duplicati.CommandLine.BackendTool
+ Duplicati.CommandLine.BackendTool
+ true
+ ..\Duplicati.snk
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+
+
+ none
+ true
+ bin\Release
+ prompt
+ 4
+ true
+
+
+
+
+
+
+
+
+
+
+
+ {1BFAE226-8364-4086-825C-BB83F6F3EE4C}
+ Duplicati.Library.Backend.CloudFiles
+
+
+ {FC9B7611-836F-4127-8B44-A7C31F506807}
+ Duplicati.Library.Backend.File
+
+
+ {F61679A9-E5DE-468A-B5A4-05F92D0143D2}
+ Duplicati.Library.Backend.FTP
+
+
+ {42C91180-11EB-4590-82EA-80FE9D4DEBEC}
+ Duplicati.Library.Backend.GoogleDocs
+
+
+ {C03F6DFD-805A-4BE0-9338-64870ADDB4A2}
+ Duplicati.Library.Backend.S3
+
+
+ {CCD76347-7DC7-4B42-B7E1-E500E624CAC3}
+ Duplicati.Library.Backend.SkyDrive
+
+
+ {FF2BF37C-E502-4C98-BEA0-701671DDFA08}
+ Duplicati.Library.Backend.SSHv2
+
+
+ {C0270709-2A40-43B5-8CF1-69581B9FA2A1}
+ Duplicati.Library.Backend.TahoeLAFS
+
+
+ {BAE27510-8B5D-44B2-B33E-372A98908041}
+ Duplicati.Library.Backend.WEBDAV
+
+
+ {0CA86ECF-5BEC-4909-B4F6-110A03B30B92}
+ Duplicati.Library.DynamicLoader
+
+
+ {C5899F45-B0FF-483C-9D38-24A9FCAAB237}
+ Duplicati.Library.Interface
+
+
+ {DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}
+ Duplicati.Library.Utility
+
+
+
\ No newline at end of file
diff --git a/Duplicati/CommandLine/BackendTool/Program.cs b/Duplicati/CommandLine/BackendTool/Program.cs
new file mode 100644
index 000000000..0d8c62a37
--- /dev/null
+++ b/Duplicati/CommandLine/BackendTool/Program.cs
@@ -0,0 +1,151 @@
+#region Disclaimer / License
+// Copyright (C) 2011, 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;
+using Duplicati.Library.Interface;
+
+namespace Duplicati.CommandLine.BackendTool
+{
+ class Program
+ {
+ static int Main(string[] _args)
+ {
+ try
+ {
+ List args = new List(_args);
+ Dictionary options = Library.Utility.CommandLineParser.ExtractOptions(args);
+
+ if (!options.ContainsKey("ftp_password") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_PASSWORD")))
+ options["ftp_password"] = System.Environment.GetEnvironmentVariable("FTP_PASSWORD");
+
+ if (!options.ContainsKey("ftp_username") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("FTP_USERNAME")))
+ options["ftp_username"] = System.Environment.GetEnvironmentVariable("FTP_USERNAME");
+
+ if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"]))
+ Library.Utility.TempFolder.SystemTempPath = options["tempdir"];
+
+
+ string command = null;
+ if (args.Count >= 2)
+ {
+ if (args[0].Equals("list", StringComparison.InvariantCultureIgnoreCase))
+ command = "list";
+ else if (args[0].Equals("get", StringComparison.InvariantCultureIgnoreCase))
+ command = "get";
+ else if (args[0].Equals("put", StringComparison.InvariantCultureIgnoreCase))
+ command = "put";
+ else if (args[0].Equals("delete", StringComparison.InvariantCultureIgnoreCase))
+ command = "delete";
+ else if (args[0].Equals("create-folder", StringComparison.InvariantCultureIgnoreCase))
+ command = "create";
+ }
+
+
+ if (args.Count >= 2 || args[0].ToLower() == "help" || args[0] == "?" || command == null)
+ {
+ if (command == null && args.Count >= 2)
+ {
+ Console.WriteLine("Unsupported command: {0}", args[0]);
+ Console.WriteLine();
+ }
+
+ Console.WriteLine("Usage: ://:@ [filename]");
+ Console.WriteLine("Example: LIST ftp://user:pass@server/folder");
+ Console.WriteLine();
+ Console.WriteLine("Supported backends: " + string.Join(",", Duplicati.Library.DynamicLoader.BackendLoader.Keys));
+ Console.WriteLine("Supported commands: GET PUT LIST DELETE CREATEFOLDER");
+
+ return 200;
+ }
+
+ using(var backend = Library.DynamicLoader.BackendLoader.GetBackend(args[1], options))
+ {
+ if (backend == null)
+ throw new Exception("Backend not supported");
+
+ if (command == "list")
+ {
+ if (args.Count != 2)
+ throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", "Name", "Dir/File", "LastChange", "Size"));
+
+ foreach(var e in backend.List())
+ Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", e.Name, e.IsFolder ? "Dir" : "File", e.LastModification, e.Size < 0 ? "" : Library.Utility.Utility.FormatSizeString(e.Size)));
+
+ return 0;
+ }
+ else if (command == "create")
+ {
+ if (args.Count != 2)
+ throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+
+ if (!(backend is IBackend_v2))
+ throw new Exception(string.Format("{0} backend does not support creating folders", backend.ProtocolKey));
+ ((IBackend_v2)backend).CreateFolder();
+
+ return 0;
+ }
+ else if (command == "delete")
+ {
+ if (args.Count < 3)
+ throw new Exception("DELETE requires a filename argument");
+ if (args.Count > 3)
+ throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ backend.Delete(args[2]);
+
+ return 0;
+ }
+ else if (command == "get")
+ {
+ if (args.Count < 3)
+ throw new Exception("GET requires a filename argument");
+ if (args.Count > 3)
+ throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ backend.Get(args[2], args[2]);
+
+ return 0;
+ }
+ else if (command == "put")
+ {
+ if (args.Count < 3)
+ throw new Exception("PUT requires a filename argument");
+ if (args.Count > 3)
+ throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ if (System.IO.File.Exists(args[2]))
+ throw new Exception("File already exists, not overwriting!");
+
+ backend.Put(args[2], args[2]);
+
+ return 0;
+ }
+
+ throw new Exception("Internal error");
+ }
+
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Command failed: " + ex.Message);
+ return 100;
+ }
+ }
+ }
+}
diff --git a/Duplicati/CommandLine/BackendTool/Properties/AssemblyInfo.cs b/Duplicati/CommandLine/BackendTool/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..4ddc0936f
--- /dev/null
+++ b/Duplicati/CommandLine/BackendTool/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// Copyright (C) 2011, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Duplicati.CommandLine.BackendTool")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+