public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count >= 1 && !string.Equals("help", args[0])) { Console.WriteLine("Unsupported command: {0}", args[0]); Console.WriteLine(); return 100; } Console.Write(new System.IO.StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + "." + RESOURCE_NAME)).ReadToEnd()); return 0; }
public static int RealMain(string[] _args) { try { var args = new List<string>(_args); var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(args); var options = tmpparsed.Item1; var filter = tmpparsed.Item2; if (!options.ContainsKey("auth_password") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_PASSWORD"))) options["auth_password"] = System.Environment.GetEnvironmentVariable("AUTH_PASSWORD"); if (!options.ContainsKey("auth_username") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_USERNAME"))) options["auth_username"] = System.Environment.GetEnvironmentVariable("AUTH_USERNAME"); if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"])) Library.Utility.TempFolder.SystemTempPath = options["tempdir"]; var actions = new Dictionary<string, CommandRunner>(StringComparer.InvariantCultureIgnoreCase); actions["download"] = Download.Run; actions["index"] = Index.Run; actions["list"] = List.Run; actions["restore"] = Restore.Run; actions["help"] = Help.Run; CommandRunner command; actions.TryGetValue(args.FirstOrDefault(), out command); command = command ?? actions["help"]; return command(args, options, filter); } catch(Exception ex) { Console.WriteLine("Program crashed: {0}{1}", Environment.NewLine, ex.ToString()); return 200; } }
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count != 2 && args.Count != 3) { Console.WriteLine("Invalid argument count ({0} expected 2 or 3): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args)); return 100; } var folder = Path.GetFullPath(args[1]); if (!Directory.Exists(folder)) { Console.WriteLine("Folder not found: {0}", folder); return 100; } Directory.SetCurrentDirectory(folder); if (args.Count == 2) { var times = ParseListFiles(folder); foreach(var v in times.Zip(Enumerable.Range(0, times.Length), (a,b) => new KeyValuePair<int, DateTime>(b, a.Key))) Console.WriteLine("{0}: {1}", v.Key, v.Value.ToLocalTime()); } else { var file = SelectListFile(args[2], folder); var p = Library.Main.Volumes.VolumeBase.ParseFilename(file); Library.Main.Volumes.VolumeReaderBase.UpdateOptionsFromManifest(p.CompressionModule, file, new Duplicati.Library.Main.Options(options)); foreach(var f in EnumerateFilesInDList(file, filter, options)) Console.WriteLine("{0} ({1})", f.Path, Library.Utility.Utility.FormatSizeString(f.Size)); } return 0; }
public static int RealMain(string[] _args) { try { var args = new List<string>(_args); var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(args); var options = tmpparsed.Item1; var filter = tmpparsed.Item2; if (!options.ContainsKey("auth_password") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_PASSWORD"))) options["auth_password"] = System.Environment.GetEnvironmentVariable("AUTH_PASSWORD"); if (!options.ContainsKey("auth_username") && !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_USERNAME"))) options["auth_username"] = System.Environment.GetEnvironmentVariable("AUTH_USERNAME"); if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"])) Library.Utility.TempFolder.SetSystemTempPath(options["tempdir"]); bool isHelp = args.Count == 0 || (args.Count >= 1 && string.Equals(args[0], "help", StringComparison.InvariantCultureIgnoreCase)); if (!isHelp && ((options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file")) || (options.ContainsKey("parameter-file") && !string.IsNullOrEmpty("parameter-file")) || (options.ContainsKey("parameterfile") && !string.IsNullOrEmpty("parameterfile")))) { string filename; if (options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file")) { filename = options["parameters-file"]; options.Remove("parameters-file"); } else if (options.ContainsKey("parameter-file") && !string.IsNullOrEmpty("parameter-file")) { filename = options["parameter-file"]; options.Remove("parameter-file"); } else { filename = options["parameterfile"]; options.Remove("parameterfile"); } if (!ReadOptionsFromFile(filename, ref filter, args, options)) return 100; } var actions = new Dictionary<string, CommandRunner>(StringComparer.InvariantCultureIgnoreCase); actions["download"] = Download.Run; actions["recompress"] = Recompress.Run; actions["index"] = Index.Run; actions["list"] = List.Run; actions["restore"] = Restore.Run; actions["help"] = Help.Run; CommandRunner command; actions.TryGetValue(args.FirstOrDefault() ?? "", out command); command = command ?? actions["help"]; return command(args, options, filter); } catch(Exception ex) { Console.WriteLine("Program crashed: {0}{1}", Environment.NewLine, ex.ToString()); return 200; } }
private static bool ReadOptionsFromFile(string filename, ref Library.Utility.IFilter filter, List<string> cargs, Dictionary<string, string> options) { try { List<string> fargs = new List<string>(Library.Utility.Utility.ReadFileWithDefaultEncoding(Library.Utility.Utility.ExpandEnvironmentVariables(filename)).Replace("\r\n", "\n").Replace("\r", "\n").Split(new String[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim())); var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(fargs); var opt = tmpparsed.Item1; var newfilter = tmpparsed.Item2; // If the user specifies parameters-file, all filters must be in the file. // Allowing to specify some filters on the command line could result in wrong filter ordering if (!filter.Empty && !newfilter.Empty) throw new Exception("Filters cannot be specified on the commandline if filters are also present in the parameter file"); if (!newfilter.Empty) filter = newfilter; foreach(KeyValuePair<String, String> keyvalue in opt) options[keyvalue.Key] = keyvalue.Value; cargs.AddRange( from c in fargs where !string.IsNullOrWhiteSpace(c) && !c.StartsWith("#") && !c.StartsWith("!") && !c.StartsWith("REM ", StringComparison.InvariantCultureIgnoreCase) select c ); return true; } catch (Exception e) { Console.WriteLine(@"Unable to read the parameters file ""{0}"", reason: {1}", filename, e.Message); return false; } }
public void Dispose() { foreach(var v in m_lookup.Values) try { v.Dispose(); } catch { } m_lookup = null; m_mru = null; }
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count != 2 && args.Count != 3) { Console.WriteLine("Invalid argument count ({0} expected 2 or 3): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args)); return 100; } var folder = Path.GetFullPath(args[1]); if (!Directory.Exists(folder)) { Console.WriteLine("Folder not found: {0}", folder); return 100; } Directory.SetCurrentDirectory(folder); string targetpath; options.TryGetValue("targetpath", out targetpath); string ixfile; options.TryGetValue("indexfile", out ixfile); if (string.IsNullOrWhiteSpace(ixfile)) ixfile = "index.txt"; ixfile = Path.GetFullPath(ixfile); if (!File.Exists(ixfile)) { Console.WriteLine("Index file not found, perhaps you need to run the index command?"); return 100; } Console.Write("Sorting index file ..."); Index.SortFile(ixfile, ixfile); Console.WriteLine(" done!"); string filelist; if (args.Count == 2) { var time = List.ParseListFiles(folder).First(); filelist = time.Value; Console.WriteLine("Using set 0 with timestamp {0}", time.Key.ToLocalTime()); } else { filelist = List.SelectListFile(args[2], folder); } Library.Main.Volumes.VolumeReaderBase.UpdateOptionsFromManifest(Path.GetExtension(filelist).Trim('.'), filelist, new Duplicati.Library.Main.Options(options)); string blocksize_str; options.TryGetValue("blocksize", out blocksize_str); string blockhash_str; options.TryGetValue("block-hash-algorithm", out blockhash_str); string filehash_str; options.TryGetValue("block-hash-algorithm", out filehash_str); long blocksize = string.IsNullOrWhiteSpace(blocksize_str) ? 0 : Library.Utility.Sizeparser.ParseSize(blocksize_str); if (blocksize <= 0) { Console.WriteLine("Invalid blocksize: {0}, try setting --blocksize manually"); return 100; } var blockhasher = string.IsNullOrWhiteSpace(blockhash_str) ? null : System.Security.Cryptography.HashAlgorithm.Create(blockhash_str); var filehasher = string.IsNullOrWhiteSpace(filehash_str) ? null : System.Security.Cryptography.HashAlgorithm.Create(filehash_str); if (blockhasher == null) throw new Exception(string.Format("Block hash algorithm not valid: {0}", blockhash_str)); if (filehasher == null) throw new Exception(string.Format("File hash algorithm not valid: {0}", filehash_str)); var hashesprblock = blocksize / (blockhasher.HashSize / 8); using(var mru = new CompressedFileMRUCache(options)) { Console.WriteLine("Building lookup table for file hashes"); var lookup = new HashLookupHelper(ixfile, mru, (int)blocksize, blockhasher.HashSize / 8); var filecount = 0L; string largestprefix = null; string[] largestprefixparts = null; if (!string.IsNullOrWhiteSpace(targetpath)) Console.WriteLine("Computing restore path"); foreach(var f in List.EnumerateFilesInDList(filelist, filter, options)) { if (largestprefix == null) { largestprefix = f.Path; largestprefixparts = largestprefix.Split(new char[] { Path.DirectorySeparatorChar }); } else if (largestprefix.Length > 1) { var parts = f.Path.Split(new char[] { Path.DirectorySeparatorChar }); var ni = 0; for(; ni < Math.Min(parts.Length, largestprefixparts.Length); ni++) if (!Library.Utility.Utility.ClientFilenameStringComparer.Equals(parts[ni], largestprefixparts[ni])) break; if (ni != largestprefixparts.Length) { if (ni == 0) { largestprefixparts = new string[0]; largestprefix = string.Empty; } else { Array.Resize(ref largestprefixparts, ni - 1); largestprefix = string.Join(Path.DirectorySeparatorChar.ToString(), largestprefixparts); } } } filecount++; } Console.WriteLine("Restoring {0} files to {1}", filecount, string.IsNullOrWhiteSpace(targetpath) ? "original position" : targetpath); if (Library.Utility.Utility.IsClientLinux || largestprefix.Length > 0) largestprefix = Library.Utility.Utility.AppendDirSeparator(largestprefix); if (!string.IsNullOrEmpty(largestprefix)) Console.WriteLine("Removing common prefix {0} from files", largestprefix); var i = 0L; var errors = 0L; foreach(var f in List.EnumerateFilesInDList(filelist, filter, options)) { try { var targetfile = MapToRestorePath(f.Path, largestprefix, targetpath); if (!Directory.Exists(Path.GetDirectoryName(targetfile))) Directory.CreateDirectory(Path.GetDirectoryName(targetfile)); Console.Write("{0}: {1} ({2})", i, targetfile, Library.Utility.Utility.FormatSizeString(f.Size)); using(var tf = new Library.Utility.TempFile()) { using(var sw = File.OpenWrite(tf)) { if (f.BlocklistHashes == null) { lookup.WriteHash(sw, f.Hash); } else { var blhi = 0L; foreach(var blh in f.BlocklistHashes) { Console.Write(" {0}", blhi); var blockhashoffset = blhi * hashesprblock * blocksize; try { var bi = 0; foreach(var h in lookup.ReadBlocklistHashes(blh)) { try { sw.Position = blockhashoffset + (bi * blocksize); lookup.WriteHash(sw, h); } catch(Exception ex) { Console.WriteLine("Failed to read hash: {0}{1}{2}", h, Environment.NewLine, ex.ToString()); } bi++; } } catch (Exception ex) { Console.WriteLine("Failed to read Blocklist hash: {0}{1}{2}", blh, Environment.NewLine, ex.ToString()); } blhi++; } } } string fh; using(var fs = File.OpenRead(tf)) fh = Convert.ToBase64String(filehasher.ComputeHash(fs)); if (fh == f.Hash) { Console.WriteLine(" done!"); File.Copy(tf, targetfile, true); } else { Console.Write(" - Restored file hash mismatch"); if (File.Exists(targetfile)) Console.WriteLine(" - not overwriting existing file: {0}", targetfile); else Console.WriteLine(" - restoring file in damaged condition"); } } } catch (Exception ex) { Console.WriteLine(" error: {0}", ex.ToString()); errors++; } i++; } } return 0; }
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count != 3) { Console.WriteLine("Invalid argument count ({0} expected 3): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args)); return 100; } using(var backend = Library.DynamicLoader.BackendLoader.GetBackend(args[1], options)) { if (backend == null) { Console.WriteLine("Backend not found: {0}{1}Backends supported: {2}", args[1], Environment.NewLine, string.Join(", ", Library.DynamicLoader.BackendLoader.Keys)); return 100; } var targetfolder = Path.GetFullPath(args[2]); if (!Directory.Exists(args[2])) { Console.WriteLine("Creating target folder: {0}", targetfolder); Directory.CreateDirectory(targetfolder); } Console.WriteLine("Listing files on backend: {0} ...", backend.ProtocolKey); var lst = backend.List(); Console.WriteLine("Found {0} files", lst.Count); var i = 0; var downloaded = 0; var errors = 0; var needspass = 0; string passphrase; options.TryGetValue("passphrase", out passphrase); foreach(var file in lst) { try { Console.Write("{0}: {1}", i, file.Name); var p = Duplicati.Library.Main.Volumes.VolumeBase.ParseFilename(file); if (p == null) { Console.WriteLine(" - Not a Duplicati file, ignoring"); continue; } var local = Path.Combine(targetfolder, file.Name); if (p.EncryptionModule != null) { if (string.IsNullOrWhiteSpace(passphrase)) { needspass++; Console.WriteLine(" - No passphrase supplied, skipping"); continue; } local = local.Substring(0, local.Length - p.EncryptionModule.Length - 1); } if (p.FileType != Duplicati.Library.Main.RemoteVolumeType.Blocks && p.FileType != Duplicati.Library.Main.RemoteVolumeType.Files) { Console.WriteLine(" - Filetype {0}, skipping", p.FileType); continue; } if (File.Exists(local)) { Console.WriteLine(" - Already exists, skipping"); continue; } Console.Write(" - downloading ({0})...", Library.Utility.Utility.FormatSizeString(file.Size)); using(var tf = new Library.Utility.TempFile()) { backend.Get(file.Name, tf); if (p.EncryptionModule != null) { Console.Write(" - decrypting ..."); using(var m = Library.DynamicLoader.EncryptionLoader.GetModule(p.EncryptionModule, passphrase, options)) using(var tf2 = new Library.Utility.TempFile()) { m.Decrypt(tf, tf2); File.Copy(tf2, local); } } else File.Copy(tf, local); } Console.WriteLine(" done!"); } catch(Exception ex) { Console.WriteLine(" error: {0}", ex.ToString()); errors++; } i++; } if (needspass > 0 && downloaded == 0) { Console.WriteLine("No files downloaded, try adding --passphrase to decrypt files"); return 100; } Console.WriteLine("Download complete, of {0} remote files, {1} were downloaded with {2} errors", lst.Count, downloaded, errors); if (needspass > 0) Console.WriteLine("Additonally {0} remote files were skipped because of encryption, supply --passphrase to download those"); if (errors > 0) return 200; else return 0; } }
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count != 2) { Console.WriteLine("Invalid argument count ({0} expected 2): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args)); return 100; } var folder = Path.GetFullPath(args[1]); if (!Directory.Exists(folder)) { Console.WriteLine("Folder not found: {0}", folder); return 100; } Directory.SetCurrentDirectory(folder); string ixfile; options.TryGetValue("indexfile", out ixfile); if (string.IsNullOrWhiteSpace(ixfile)) ixfile = "index.txt"; ixfile = Path.GetFullPath(ixfile); if (!File.Exists(ixfile)) { using(File.Create(ixfile)) { } } else { Console.WriteLine("Sorting existing index file"); SortFile(ixfile, ixfile); } var filecount = Directory.EnumerateFiles(folder).Count(); Console.WriteLine("Processing {0} files", filecount); var i = 0; var errors = 0; var totalblocks = 0L; var files = 0; foreach(var file in Directory.EnumerateFiles(folder)) { Console.Write("{0}: {1}", i, file); try { var p = Duplicati.Library.Main.Volumes.VolumeBase.ParseFilename(file); if (p == null) { Console.WriteLine(" - Not a Duplicati file, ignoring"); continue; } if (p.FileType != Duplicati.Library.Main.RemoteVolumeType.Blocks) { Console.WriteLine(" - Filetype {0}, skipping", p.FileType); continue; } if (!string.IsNullOrWhiteSpace(p.EncryptionModule)) { Console.WriteLine(" - Encrypted, skipping"); continue; } var filekey = Path.GetFileName(file); var blocks = 0; using(var cp = Library.DynamicLoader.CompressionLoader.GetModule(p.CompressionModule, file, options)) using(var tf = new Library.Utility.TempFile()) { using(var sw = new StreamWriter(tf)) foreach(var f in cp.ListFiles(null)) { sw.WriteLine("{0}, {1}", Library.Utility.Utility.Base64UrlToBase64Plain(f), filekey); blocks++; } files++; totalblocks += blocks; Console.Write(" {0} hashes found, sorting ...", blocks); SortFile(tf, tf); Console.WriteLine(" done!"); Console.Write("Merging {0} hashes ...", totalblocks); MergeFiles(ixfile, tf, ixfile); Console.WriteLine(" done!"); } } catch(Exception ex) { Console.WriteLine(" error: {0}", ex.ToString()); errors++; } i++; } Console.WriteLine("Processed {0} files and found {1} hashes", files, totalblocks); if (errors > 0) Console.WriteLine("Experienced {0} errors", errors); return 0; }
public static int Run(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter) { if (args.Count != 4) { Console.WriteLine("Invalid argument count ({0} expected 4): {1}{2}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args)); return 100; } string target_compr_module = args[1]; if (!Library.DynamicLoader.CompressionLoader.Keys.Contains(target_compr_module)) { Console.WriteLine("Target compression module not found: {0}{1}Modules supported: {2}", args[1], Environment.NewLine, string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys)); return 100; } var m_Options = new Options(options); using (var backend = Library.DynamicLoader.BackendLoader.GetBackend(args[2], options)) { if (backend == null) { Console.WriteLine("Backend not found: {0}{1}Backends supported: {2}", args[2], Environment.NewLine, string.Join(", ", Library.DynamicLoader.BackendLoader.Keys)); return 100; } var targetfolder = Path.GetFullPath(args[3]); if (!Directory.Exists(args[3])) { Console.WriteLine("Creating target folder: {0}", targetfolder); Directory.CreateDirectory(targetfolder); } Console.WriteLine("Listing files on backend: {0} ...", backend.ProtocolKey); var rawlist = backend.List(); Console.WriteLine("Found {0} files", rawlist.Count); var i = 0; var downloaded = 0; var errors = 0; var needspass = 0; var remotefiles = (from x in rawlist let n = VolumeBase.ParseFilename(x) where n != null && n.Prefix == m_Options.Prefix select n).ToArray(); //ToArray() ensures that we do not remote-request it multiple times if (remotefiles.Length == 0) { if (rawlist.Count == 0) Console.WriteLine("No files were found at the remote location, perhaps the target url is incorrect?"); else { var tmp = (from x in rawlist let n = VolumeBase.ParseFilename(x) where n != null select n.Prefix).ToArray(); var types = tmp.Distinct().ToArray(); if (tmp.Length == 0) Console.WriteLine("Found {0} files at the remote storage, but none that could be parsed", rawlist.Count); else if (types.Length == 1) Console.WriteLine("Found {0} parse-able files with the prefix {1}, did you forget to set the backup-prefix?", tmp.Length, types[0]); else Console.WriteLine("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup-prefix?", tmp.Length, rawlist.Count, string.Join(", ", types)); } return 100; } bool reencrypt = Library.Utility.Utility.ParseBoolOption(options, "reencrypt"); bool reupload = Library.Utility.Utility.ParseBoolOption(options, "reupload"); foreach (var entry in remotefiles) { try { Console.Write("{0}: {1}", i, entry.File.Name); var local = Path.Combine(targetfolder, entry.File.Name); if (entry.EncryptionModule != null) { if (string.IsNullOrWhiteSpace(m_Options.Passphrase)) { needspass++; Console.WriteLine(" - No passphrase supplied, skipping"); continue; } local = local.Substring(0, local.Length - entry.EncryptionModule.Length - 1); } if (entry.CompressionModule == target_compr_module) { Console.WriteLine(" - compression types are same"); continue; } string localNew; if (entry.CompressionModule != null) { localNew = local.Substring(0, local.Length - entry.CompressionModule.Length - 1) + "." + target_compr_module; if (File.Exists(localNew)) { Console.WriteLine(" - target file already exist"); continue; } } else { Console.WriteLine(" - cannot detect compression type"); continue; } if (File.Exists(local)) File.Delete(local); Console.Write(" - downloading ({0})...", Library.Utility.Utility.FormatSizeString(entry.File.Size)); DateTime originLastWriteTime; FileInfo destinationFileInfo; using (var tf = new Library.Utility.TempFile()) { backend.Get(entry.File.Name, tf); originLastWriteTime = new FileInfo(tf).LastWriteTime; downloaded++; if (entry.EncryptionModule != null) { Console.Write(" decrypting ..."); using (var m = Library.DynamicLoader.EncryptionLoader.GetModule(entry.EncryptionModule, m_Options.Passphrase, options)) using (var tf2 = new Library.Utility.TempFile()) { m.Decrypt(tf, tf2); File.Copy(tf2, local); File.Delete(tf2); } } else File.Copy(tf, local); File.Delete(tf); destinationFileInfo = new FileInfo(local); destinationFileInfo.LastWriteTime = originLastWriteTime; } if (entry.CompressionModule != null) { Console.Write(" recompressing ..."); using (var cmOld = Library.DynamicLoader.CompressionLoader.GetModule(entry.CompressionModule, local, options)) using (var cmNew = Library.DynamicLoader.CompressionLoader.GetModule(target_compr_module, localNew, options)) foreach (var cmfile in cmOld.ListFiles("")) { string cmfileNew = cmfile; if (entry.FileType == RemoteVolumeType.Index) { var cmFileVolume = Library.Main.Volumes.VolumeBase.ParseFilename(cmfileNew); if (cmFileVolume != null) { cmfileNew = cmfileNew.Replace("." + cmFileVolume.CompressionModule, "." + target_compr_module); if(!reencrypt) cmfileNew = cmfileNew.Replace("." + cmFileVolume.EncryptionModule, ""); } } using (var sourceStream = cmOld.OpenRead(cmfile)) using (var cs = cmNew.CreateFile(cmfileNew, Duplicati.Library.Interface.CompressionHint.Compressible, cmOld.GetLastWriteTime(cmfile))) Library.Utility.Utility.CopyStream(sourceStream, cs); } File.Delete(local); destinationFileInfo = new FileInfo(localNew); destinationFileInfo.LastWriteTime = originLastWriteTime; } if (reencrypt && entry.EncryptionModule != null) { Console.Write(" reencrypting ..."); using (var m = Library.DynamicLoader.EncryptionLoader.GetModule(entry.EncryptionModule, m_Options.Passphrase, options)) { m.Encrypt(localNew, localNew + "." + m.FilenameExtension); File.Delete(localNew); localNew = localNew + "." + m.FilenameExtension; } destinationFileInfo = new FileInfo(localNew); destinationFileInfo.LastWriteTime = originLastWriteTime; } if (reupload) { backend.Put((new FileInfo(localNew)).Name, localNew); backend.Delete(entry.File.Name); File.Delete(localNew); } Console.WriteLine(" done!"); } catch (Exception ex) { Console.WriteLine(" error: {0}", ex.ToString()); errors++; } i++; } if (reupload) { var remoteverificationfileexist = rawlist.Any(x => x.Name == (m_Options.Prefix + "-verification.json")); if (remoteverificationfileexist) { Console.WriteLine("Found verification file {0} - deleting", m_Options.Prefix + "-verification.json"); backend.Delete(m_Options.Prefix + "-verification.json"); } } if (needspass > 0 && downloaded == 0) { Console.WriteLine("No files downloaded, try adding --passphrase to decrypt files"); return 100; } Console.WriteLine("Download complete, of {0} remote files, {1} were downloaded with {2} errors", remotefiles.Count(), downloaded, errors); if (needspass > 0) Console.WriteLine("Additonally {0} remote files were skipped because of encryption, supply --passphrase to download those"); if (errors > 0) { Console.WriteLine("There were errors during recompress of remote backend files!"); return 200; } return 0; } }