public static void Rotate(string filenameBase) { if (File.Exists(filenameBase)) { for (int i = 8; i >= 0; i--) { string fn = filenameBase + "." + i; if (File.Exists(fn)) { string fn2 = filenameBase + "." + (i + 1); if (File.Exists(fn2)) { File.Delete(fn2); } File.Move(fn, fn2); } } File.Copy(filenameBase, filenameBase + ".0"); } }
protected override async Task <ExitCode> Run() { var modListPath = (AbsolutePath)Modlist; if (modListPath.Extension != Consts.ModListExtension && modListPath.FileName != (RelativePath)"modlist.txt") { return(CLIUtils.Exit($"The file {Modlist} is not a valid modlist file!", ExitCode.BadArguments)); } if (Copy && Move) { return(CLIUtils.Exit("You can't set both copy and move flags!", ExitCode.BadArguments)); } var isModlist = modListPath.Extension == Consts.ModListExtension; var list = new List <TransferFile>(); if (isModlist) { ModList modlist; try { modlist = AInstaller.LoadFromFile(modListPath); } catch (Exception e) { return(CLIUtils.Exit($"Error while loading the Modlist!\n{e}", ExitCode.Error)); } if (modlist == null) { return(CLIUtils.Exit("The Modlist could not be loaded!", ExitCode.Error)); } CLIUtils.Log($"Modlist contains {modlist.Archives.Count} archives."); modlist.Archives.Do(a => { var inputPath = Path.Combine(Input, a.Name); var outputPath = Path.Combine(Output, a.Name); if (!File.Exists(inputPath)) { CLIUtils.Log($"File {inputPath} does not exist, skipping."); return; } CLIUtils.Log($"Adding {inputPath} to the transfer list."); list.Add(new TransferFile(inputPath, outputPath)); var metaInputPath = Path.Combine(inputPath, ".meta"); var metaOutputPath = Path.Combine(outputPath, ".meta"); if (File.Exists(metaInputPath)) { CLIUtils.Log($"Found meta file {metaInputPath}"); if (IncludeMeta) { CLIUtils.Log($"Adding {metaInputPath} to the transfer list."); list.Add(new TransferFile(metaInputPath, metaOutputPath)); } else { CLIUtils.Log($"Meta file {metaInputPath} will be ignored."); } } else { CLIUtils.Log($"Found no meta file for {inputPath}"); if (IncludeMeta) { if (string.IsNullOrWhiteSpace(a.Meta)) { CLIUtils.Log($"Meta for {a.Name} is empty, this should not be possible but whatever."); return; } CLIUtils.Log("Adding meta from archive info the transfer list"); list.Add(new TransferFile(a.Meta, metaOutputPath, true)); } else { CLIUtils.Log($"Meta will be ignored for {a.Name}"); } } }); } else { if (!Directory.Exists(Mods)) { return(CLIUtils.Exit($"Mods directory {Mods} does not exist!", ExitCode.BadArguments)); } CLIUtils.Log($"Reading modlist.txt from {Modlist}"); string[] modlist = File.ReadAllLines(Modlist); if (modlist == null || modlist.Length == 0) { return(CLIUtils.Exit($"Provided modlist.txt file at {Modlist} is empty or could not be read!", ExitCode.BadArguments)); } var mods = modlist.Where(s => s.StartsWith("+")).Select(s => s.Substring(1)).ToHashSet(); if (mods.Count == 0) { return(CLIUtils.Exit("Counted mods from modlist.txt are 0!", ExitCode.BadArguments)); } CLIUtils.Log($"Found {mods.Count} mods in modlist.txt"); var downloads = new HashSet <string>(); Directory.EnumerateDirectories(Mods, "*", SearchOption.TopDirectoryOnly) .Where(d => mods.Contains(Path.GetRelativePath(Path.GetDirectoryName(d), d))) .Do(d => { var meta = Path.Combine(d, "meta.ini"); if (!File.Exists(meta)) { CLIUtils.Log($"Mod meta file {meta} does not exist, skipping"); return; } string[] ini = File.ReadAllLines(meta); if (ini == null || ini.Length == 0) { CLIUtils.Log($"Mod meta file {meta} could not be read or is empty!"); return; } ini.Where(i => !string.IsNullOrWhiteSpace(i) && i.StartsWith("installationFile=")) .Select(i => i.Replace("installationFile=", "")) .Do(i => { CLIUtils.Log($"Found installationFile {i}"); downloads.Add(i); }); }); CLIUtils.Log($"Found {downloads.Count} installationFiles from mod metas."); Directory.EnumerateFiles(Input, "*", SearchOption.TopDirectoryOnly) .Where(f => downloads.Contains(Path.GetFileNameWithoutExtension(f))) .Do(f => { CLIUtils.Log($"Found archive {f}"); var outputPath = Path.Combine(Output, Path.GetFileName(f)); CLIUtils.Log($"Adding {f} to the transfer list"); list.Add(new TransferFile(f, outputPath)); var metaInputPath = Path.Combine(f, ".meta"); if (File.Exists(metaInputPath)) { CLIUtils.Log($"Found meta file for {f} at {metaInputPath}"); if (IncludeMeta) { var metaOutputPath = Path.Combine(outputPath, ".meta"); CLIUtils.Log($"Adding {metaInputPath} to the transfer list."); list.Add(new TransferFile(metaInputPath, metaOutputPath)); } else { CLIUtils.Log("Meta file will be ignored"); } } else { CLIUtils.Log($"Found no meta file for {f}"); } }); } CLIUtils.Log($"Transfer list contains {list.Count} items"); var success = 0; var failed = 0; var skipped = 0; list.Do(f => { if (File.Exists(f.Output)) { if (Overwrite) { CLIUtils.Log($"Output file {f.Output} already exists, it will be overwritten"); if (f.IsMeta || Move) { CLIUtils.Log($"Deleting file at {f.Output}"); try { File.Delete(f.Output); } catch (Exception e) { CLIUtils.Log($"Could not delete file {f.Output}!\n{e}"); failed++; } } } else { CLIUtils.Log($"Output file {f.Output} already exists, skipping"); skipped++; return; } } if (f.IsMeta) { CLIUtils.Log($"Writing meta data to {f.Output}"); try { File.WriteAllText(f.Output, f.Input, Encoding.UTF8); success++; } catch (Exception e) { CLIUtils.Log($"Error while writing meta data to {f.Output}!\n{e}"); failed++; } } else { if (Copy) { CLIUtils.Log($"Copying file {f.Input} to {f.Output}"); try { File.Copy(f.Input, f.Output, Overwrite ? CopyOptions.None : CopyOptions.FailIfExists, CopyMoveProgressHandler, null); success++; } catch (Exception e) { CLIUtils.Log($"Error while copying file {f.Input} to {f.Output}!\n{e}"); failed++; } } else if (Move) { CLIUtils.Log($"Moving file {f.Input} to {f.Output}"); try { File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None, CopyMoveProgressHandler, null); success++; } catch (Exception e) { CLIUtils.Log($"Error while moving file {f.Input} to {f.Output}!\n{e}"); failed++; } } } }); CLIUtils.Log($"Skipped transfers: {skipped}"); CLIUtils.Log($"Failed transfers: {failed}"); CLIUtils.Log($"Successful transfers: {success}"); return(0); }
private async Task InstallArchive(WorkQueue queue, Archive archive, string absolutePath, IGrouping <string, FromArchive> grouping) { Status($"Extracting {archive.Name}"); List <FromArchive> vFiles = grouping.Select(g => { var file = VFS.Index.FileForArchiveHashPath(g.ArchiveHashPath); g.FromFile = file; return(g); }).ToList(); var onFinish = await VFS.Stage(vFiles.Select(f => f.FromFile).Distinct()); Status($"Copying files for {archive.Name}"); void CopyFile(string from, string to, bool useMove) { if (File.Exists(to)) { var fi = new FileInfo(to); if (fi.IsReadOnly) { fi.IsReadOnly = false; } File.Delete(to); } if (File.Exists(from)) { var fi = new FileInfo(from); if (fi.IsReadOnly) { fi.IsReadOnly = false; } } if (useMove) { File.Move(from, to); } else { File.Copy(from, to); } // If we don't do this, the file will use the last-modified date of the file when it was compressed // into an archive, which isn't really what we want in the case of files installed archives File.SetLastWriteTime(to, DateTime.Now); } await vFiles.GroupBy(f => f.FromFile) .PDoIndexed(queue, (idx, group) => { Utils.Status("Installing files", idx * 100 / vFiles.Count); var firstDest = Path.Combine(OutputFolder, group.First().To); CopyFile(group.Key.StagedPath, firstDest, true); foreach (var copy in group.Skip(1)) { var nextDest = Path.Combine(OutputFolder, copy.To); CopyFile(firstDest, nextDest, false); } }); Status("Unstaging files"); onFinish(); // Now patch all the files from this archive foreach (var toPatch in grouping.OfType <PatchedFromArchive>()) { using (var patchStream = new MemoryStream()) { Status($"Patching {Path.GetFileName(toPatch.To)}"); // Read in the patch data byte[] patchData = LoadBytesFromPath(toPatch.PatchID); var toFile = Path.Combine(OutputFolder, toPatch.To); var oldData = new MemoryStream(File.ReadAllBytes(toFile)); // Remove the file we're about to patch File.Delete(toFile); // Patch it using (var outStream = File.Open(toFile, FileMode.Create)) { BSDiff.Apply(oldData, () => new MemoryStream(patchData), outStream); } Status($"Verifying Patch {Path.GetFileName(toPatch.To)}"); var resultSha = toFile.FileHash(); if (resultSha != toPatch.Hash) { throw new InvalidDataException($"Invalid Hash for {toPatch.To} after patching"); } } } }
private static void UpdateFromRepo() { Console.WriteLine(); _logger.Info( "Checking for updated maps at https://github.com/EricZimmerman/evtx/tree/master/evtx/Maps..."); Console.WriteLine(); var archivePath = Path.Combine(BaseDirectory, "____master.zip"); if (File.Exists(archivePath)) { File.Delete(archivePath); } using (var client = new WebClient()) { ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; client.DownloadFile("https://github.com/EricZimmerman/evtx/archive/master.zip", archivePath); } var fff = new FastZip(); if (Directory.Exists(Path.Combine(BaseDirectory, "Maps")) == false) { Directory.CreateDirectory(Path.Combine(BaseDirectory, "Maps")); } var directoryFilter = "Maps"; // Will prompt to overwrite if target file names already exist fff.ExtractZip(archivePath, BaseDirectory, FastZip.Overwrite.Always, null, null, directoryFilter, true); if (File.Exists(archivePath)) { File.Delete(archivePath); } var newMapPath = Path.Combine(BaseDirectory, "evtx-master", "evtx", "Maps"); var orgMapPath = Path.Combine(BaseDirectory, "Maps"); var newMaps = Directory.GetFiles(newMapPath); var newlocalMaps = new List <string>(); var updatedlocalMaps = new List <string>(); if (File.Exists(Path.Combine(orgMapPath, "Security_4624.map"))) { _logger.Warn($"Old map format found. Zipping to '!!oldMaps.zip' and cleaning up old maps"); //old maps found, so zip em first var oldZip = Path.Combine(orgMapPath, "!!oldMaps.zip"); fff.CreateZip(oldZip, orgMapPath, false, @"\.map$"); foreach (var m in Directory.GetFiles(orgMapPath, "*.map")) { File.Delete(m); } } if (File.Exists(Path.Combine(orgMapPath, "!!!!README.txt"))) { File.Delete(Path.Combine(orgMapPath, "!!!!README.txt")); } foreach (var newMap in newMaps) { var mName = Path.GetFileName(newMap); var dest = Path.Combine(orgMapPath, mName); if (File.Exists(dest) == false) { //new target newlocalMaps.Add(mName); } else { //current destination file exists, so compare to new var fiNew = new FileInfo(newMap); var fi = new FileInfo(dest); if (fiNew.GetHash(HashType.SHA1) != fi.GetHash(HashType.SHA1)) { //updated file updatedlocalMaps.Add(mName); } } File.Copy(newMap, dest, CopyOptions.None); } if (newlocalMaps.Count > 0 || updatedlocalMaps.Count > 0) { _logger.Fatal("Updates found!"); Console.WriteLine(); if (newlocalMaps.Count > 0) { _logger.Error("New maps"); foreach (var newLocalMap in newlocalMaps) { _logger.Info(Path.GetFileNameWithoutExtension(newLocalMap)); } Console.WriteLine(); } if (updatedlocalMaps.Count > 0) { _logger.Error("Updated maps"); foreach (var um in updatedlocalMaps) { _logger.Info(Path.GetFileNameWithoutExtension(um)); } Console.WriteLine(); } Console.WriteLine(); } else { Console.WriteLine(); _logger.Info("No new maps available"); Console.WriteLine(); } Directory.Delete(Path.Combine(BaseDirectory, "evtx-master"), true); }
private static void UpdateFromRepo() { Console.WriteLine(); Log.Information("Checking for updated maps at {Url}...", "https://github.com/EricZimmerman/evtx/tree/master/evtx/Maps"); Console.WriteLine(); var archivePath = Path.Combine(BaseDirectory, "____master.zip"); if (File.Exists(archivePath)) { File.Delete(archivePath); } // using (var client = new WebClient()) // { // ServicePointManager.Expect100Continue = true; // ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // client.DownloadFile("https://github.com/EricZimmerman/evtx/archive/master.zip", archivePath); // } "https://github.com/EricZimmerman/evtx/archive/master.zip".DownloadFileTo(archivePath); var fff = new FastZip(); if (Directory.Exists(Path.Combine(BaseDirectory, "Maps")) == false) { Directory.CreateDirectory(Path.Combine(BaseDirectory, "Maps")); } var directoryFilter = "Maps"; // Will prompt to overwrite if target file names already exist fff.ExtractZip(archivePath, BaseDirectory, FastZip.Overwrite.Always, null, null, directoryFilter, true); if (File.Exists(archivePath)) { File.Delete(archivePath); } var newMapPath = Path.Combine(BaseDirectory, "evtx-master", "evtx", "Maps"); var orgMapPath = Path.Combine(BaseDirectory, "Maps"); var newMaps = Directory.GetFiles(newMapPath); var newLocalMaps = new List <string>(); var updatedLocalMaps = new List <string>(); if (File.Exists(Path.Combine(orgMapPath, "Security_4624.map"))) { Log.Warning("Old map format found. Zipping to {Old} and cleaning up old maps", "!!oldMaps.zip"); //old maps found, so zip em first var oldZip = Path.Combine(orgMapPath, "!!oldMaps.zip"); fff.CreateZip(oldZip, orgMapPath, false, @"\.map$"); foreach (var m in Directory.GetFiles(orgMapPath, "*.map")) { File.Delete(m); } } if (File.Exists(Path.Combine(orgMapPath, "!!!!README.txt"))) { File.Delete(Path.Combine(orgMapPath, "!!!!README.txt")); } foreach (var newMap in newMaps) { var mName = Path.GetFileName(newMap); var dest = Path.Combine(orgMapPath, mName); if (File.Exists(dest) == false) { //new target newLocalMaps.Add(mName); } else { //current destination file exists, so compare to new var s1 = new StreamReader(newMap); var newSha = Helper.GetSha1FromStream(s1.BaseStream, 0); var s2 = new StreamReader(dest); var destSha = Helper.GetSha1FromStream(s2.BaseStream, 0); s2.Close(); s1.Close(); if (newSha != destSha) { //updated file updatedLocalMaps.Add(mName); } } #if !NET6_0 File.Copy(newMap, dest, CopyOptions.None); #else File.Copy(newMap, dest, true); #endif } if (newLocalMaps.Count > 0 || updatedLocalMaps.Count > 0) { Log.Information("Updates found!"); Console.WriteLine(); if (newLocalMaps.Count > 0) { Log.Information("New maps"); foreach (var newLocalMap in newLocalMaps) { Log.Information("{File}", Path.GetFileNameWithoutExtension(newLocalMap)); } Console.WriteLine(); } if (updatedLocalMaps.Count > 0) { Log.Information("Updated maps"); foreach (var um in updatedLocalMaps) { Log.Information("{File}", Path.GetFileNameWithoutExtension(um)); } Console.WriteLine(); } Console.WriteLine(); } else { Console.WriteLine(); Log.Information("No new maps available"); Console.WriteLine(); } Directory.Delete(Path.Combine(BaseDirectory, "evtx-master"), true); }