using System.Formats.Tar; using System.IO.Compression; if (args.Length < 3) { Console.Error.WriteLine("usage: Monitor.Tar ..."); return 2; } string sourceDirectory = Path.GetFullPath(args[0]); string archivePath = Path.GetFullPath(args[1]); HashSet executables = args.Skip(2).Select(path => path.Replace('\\', '/')).ToHashSet(StringComparer.Ordinal); UnixFileMode executableMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherExecute; UnixFileMode regularMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead; Directory.CreateDirectory(Path.GetDirectoryName(archivePath)!); using FileStream fileStream = File.Create(archivePath); using GZipStream gzipStream = new(fileStream, CompressionLevel.Optimal, leaveOpen: true); using TarWriter writer = new(gzipStream, TarEntryFormat.Pax, leaveOpen: true); foreach (string filePath in Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories)) { string relativePath = Path.GetRelativePath(sourceDirectory, filePath).Replace('\\', '/'); PaxTarEntry entry = new(TarEntryType.RegularFile, relativePath) { Mode = executables.Contains(relativePath) ? executableMode : regularMode, DataStream = File.OpenRead(filePath) }; using (entry.DataStream) { writer.WriteEntry(entry); } } return 0;