diff --git a/Duplicati/CommandLine/Program.cs b/Duplicati/CommandLine/Program.cs index f7e14dc82..3b12d4f62 100644 --- a/Duplicati/CommandLine/Program.cs +++ b/Duplicati/CommandLine/Program.cs @@ -27,7 +27,7 @@ namespace Duplicati.CommandLine { private static readonly string[] COMMANDS_AS_ARGUMENTS = new string[] { "delete-all-but-n-full", "delete-all-but-n", "delete-older-than" }; - static void Main(string[] args) + static int Main(string[] args) { bool verboseErrors = false; try @@ -70,7 +70,7 @@ namespace Duplicati.CommandLine cargs.RemoveAt(0); UnitTest.RunTest(cargs.ToArray(), options); - return; + return 0; } #endif @@ -91,7 +91,7 @@ namespace Duplicati.CommandLine if (options.ContainsKey(internaloption)) { Console.WriteLine(Strings.Program.InternalOptionUsedError, internaloption); - return; + return 200; } //After checking for internal options, we set the filter option @@ -104,7 +104,7 @@ namespace Duplicati.CommandLine { case "purge-signature-cache": Library.Main.Interface.PurgeSignatureCache(options); - return; + return 0; } } @@ -116,7 +116,7 @@ namespace Duplicati.CommandLine Help.PrintUsage(cargs[1], options); - return; + return 0; } @@ -158,7 +158,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } Console.WriteLine(string.Join("\r\n", new List(Duplicati.Library.Main.Interface.ListCurrentFiles(target, options)).ToArray())); @@ -170,7 +170,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } Console.WriteLine(string.Join("\r\n", Duplicati.Library.Main.Interface.ListSourceFolders(target, options) ?? new string[0])); @@ -182,7 +182,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } List> files = Duplicati.Library.Main.Interface.ListActualSignatureFiles(cargs[0], options); @@ -248,7 +248,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } List entries = Duplicati.Library.Main.Interface.ParseFileList(cargs[0], options); @@ -281,7 +281,7 @@ namespace Duplicati.CommandLine if (!int.TryParse(target, out n) || n < 0) { Console.WriteLine(string.Format(Strings.Program.IntegerParseError, target)); - return; + return 200; } options["delete-all-but-n-full"] = n.ToString(); @@ -292,7 +292,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } if (source.Trim().ToLower() == "delete-all-but-n") @@ -309,7 +309,7 @@ namespace Duplicati.CommandLine catch (Exception ex) { Console.WriteLine(string.Format(Strings.Program.TimeParseError, target, ex.Message)); - return; + return 200; } options["delete-older-than"] = target; @@ -320,7 +320,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } Console.WriteLine(Duplicati.Library.Main.Interface.DeleteOlderThan(cargs[0], options)); @@ -332,7 +332,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } Console.WriteLine(Duplicati.Library.Main.Interface.Cleanup(cargs[0], options)); @@ -344,7 +344,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } Duplicati.Library.Main.Interface.CreateFolder(cargs[0], options); @@ -357,7 +357,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } List> results = Duplicati.Library.Main.Interface.FindLastFileVersion(cargs[0], options); @@ -372,7 +372,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 1) { PrintWrongNumberOfArguments(cargs, 1); - return; + return 200; } List> results = Duplicati.Library.Main.Interface.VerifyBackup(cargs[0], options); @@ -412,7 +412,7 @@ namespace Duplicati.CommandLine if (cargs.Count != 2) { PrintWrongNumberOfArguments(cargs, 2); - return; + return 200; } Console.WriteLine(Duplicati.Library.Main.Interface.Restore(source, target.Split(System.IO.Path.PathSeparator), options)); @@ -422,11 +422,33 @@ namespace Duplicati.CommandLine if (cargs.Count != 2) { PrintWrongNumberOfArguments(cargs, 2); - return; - } + return 200; + } - Console.WriteLine(Duplicati.Library.Main.Interface.Backup(source.Split(System.IO.Path.PathSeparator), target, options)); + string result = Duplicati.Library.Main.Interface.Backup(source.Split(System.IO.Path.PathSeparator), target, options); + Console.WriteLine(result); + + Dictionary tmp = ParseDuplicatiOutput(result); + + //Interrupted = 50 + if (tmp.ContainsKey("PartialBackup")) + return 50; + + //Completed with warnings = 2 + if (tmp.ContainsKey("NumberOfWarnings")) + return 2; + + //Success, but no upload = 1 + if (tmp.ContainsKey("BytesUploaded")) + { + long s; + if (long.TryParse(tmp["BytesUploaded"], out s) && s == 0) + return 1; + } } + + //Normal operation = 0 + return 0; } catch (Exception ex) { @@ -452,9 +474,22 @@ namespace Duplicati.CommandLine Console.Error.WriteLine(Strings.Program.UnhandledInnerException, ex.ToString()); } } + + //Error = 100 + return 100; } } + public static Dictionary ParseDuplicatiOutput(string output) + { + System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex("(?[^\\:]+)\\:(?[^\\n]*)", System.Text.RegularExpressions.RegexOptions.Singleline); + Dictionary res = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + foreach (System.Text.RegularExpressions.Match m in re.Matches(output)) + res[m.Groups["key"].Value.Trim()] = m.Groups["value"].Value.Trim(); + + return res; + } + private static void PrintWrongNumberOfArguments(List args, int expected) { Console.WriteLine(Strings.Program.WrongNumberOfCommandsError_v2, args.Count, expected, args.Count == 0 ? "" : "\"" + string.Join("\", \"", args.ToArray()) + "\""); diff --git a/Duplicati/CommandLine/help.txt b/Duplicati/CommandLine/help.txt index b6b6dca52..ec1044336 100644 --- a/Duplicati/CommandLine/help.txt +++ b/Duplicati/CommandLine/help.txt @@ -23,7 +23,7 @@ See duplicati.commandline.exe help for more information. Formats: date, time, size, encryption, compression - Advanced options: advanced, filter,