diff --git a/ProtectionScan/Options.cs b/ProtectionScan/Options.cs deleted file mode 100644 index 1e6901e9..00000000 --- a/ProtectionScan/Options.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace ProtectionScan -{ - /// - /// Set of options for the test executable - /// - internal sealed class Options - { - #region Properties - - /// - /// Enable debug output for relevant operations - /// - public bool Debug { get; private set; } = false; - - /// - /// Set of input paths to use for operations - /// - public List InputPaths { get; private set; } = []; - - /// - /// Scan archives during protection scanning - /// - public bool ScanArchives { get; private set; } = true; - - /// - /// Scan file contents during protection scanning - /// - public bool ScanContents { get; private set; } = true; - - /// - /// Scan file paths during protection scanning - /// - public bool ScanPaths { get; private set; } = true; - - /// - /// Scan subdirectories during protection scanning - /// - public bool ScanSubdirectories { get; set; } = true; - - #endregion - - /// - /// Parse commandline arguments into an Options object - /// - public static Options? ParseOptions(string[] args) - { - // If we have invalid arguments - if (args == null || args.Length == 0) - return null; - - // Create an Options object - var options = new Options(); - - // Parse the options and paths - for (int index = 0; index < args.Length; index++) - { - string arg = args[index]; - switch (arg) - { - case "-?": - case "-h": - case "--help": - return null; - - case "-d": - case "--debug": - options.Debug = true; - break; - - case "-na": - case "--no-archives": - options.ScanArchives = false; - break; - - case "-nc": - case "--no-contents": - options.ScanContents = false; - break; - - case "-np": - case "--no-paths": - options.ScanPaths = false; - break; - - case "-ns": - case "--no-subdirs": - options.ScanSubdirectories = false; - break; - - default: - options.InputPaths.Add(arg); - break; - } - } - - // Validate we have any input paths to work on - if (options.InputPaths.Count == 0) - { - Console.WriteLine("At least one path is required!"); - return null; - } - - return options; - } - - /// - /// Display a basic help text - /// - public static void DisplayHelp() - { - Console.WriteLine("Protection Scanner"); - Console.WriteLine(); - Console.WriteLine("ProtectionScan ..."); - Console.WriteLine(); - Console.WriteLine("Options:"); - Console.WriteLine("-?, -h, --help Display this help text and quit"); - Console.WriteLine("-d, --debug Enable debug mode"); - Console.WriteLine("-nc, --no-contents Disable scanning for content checks"); - Console.WriteLine("-na, --no-archives Disable scanning archives"); - Console.WriteLine("-np, --no-paths Disable scanning for path checks"); - Console.WriteLine("-ns, --no-subdirs Disable scanning subdirectories"); - } - } -} diff --git a/ProtectionScan/Program.cs b/ProtectionScan/Program.cs index 7411c485..752fa139 100644 --- a/ProtectionScan/Program.cs +++ b/ProtectionScan/Program.cs @@ -2,11 +2,24 @@ using System.Collections.Generic; using System.IO; using BinaryObjectScanner; +using SabreTools.CommandLine; +using SabreTools.CommandLine.Inputs; namespace ProtectionScan { class Program { + #region Constants + + private const string _debugName = "debug"; + private const string _helpName = "help"; + private const string _noArchivesName = "no-archives"; + private const string _noContentsName = "no-contents"; + private const string _noPathsName = "no-paths"; + private const string _noSubdirsName = "no-subdirs"; + + #endregion + static void Main(string[] args) { #if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER @@ -18,32 +31,77 @@ namespace ProtectionScan var fileProgress = new Progress(); fileProgress.ProgressChanged += Changed; - // Get the options from the arguments - var options = Options.ParseOptions(args); + // Create the command set + var commandSet = CreateCommands(); - // If we have an invalid state - if (options == null) + // If we have no args, show the help and quit + if (args == null || args.Length == 0) { - Options.DisplayHelp(); + commandSet.OutputAllHelp(); + return; + } + + // Loop through and process the options + int firstFileIndex = 0; + for (; firstFileIndex < args.Length; firstFileIndex++) + { + string arg = args[firstFileIndex]; + + var input = commandSet.GetTopLevel(arg); + if (input == null) + break; + + input.ProcessInput(args, ref firstFileIndex); + } + + // If help was specified + if (commandSet.GetBoolean(_helpName)) + { + commandSet.OutputAllHelp(); return; } // Create scanner for all paths var scanner = new Scanner( - options.ScanArchives, - options.ScanContents, - options.ScanPaths, - options.ScanSubdirectories, - options.Debug, + !commandSet.GetBoolean(_noArchivesName), + !commandSet.GetBoolean(_noContentsName), + !commandSet.GetBoolean(_noPathsName), + !commandSet.GetBoolean(_noSubdirsName), + !commandSet.GetBoolean(_debugName), fileProgress); // Loop through the input paths - foreach (string inputPath in options.InputPaths) + for (int i = firstFileIndex; i < args.Length; i++) { - GetAndWriteProtections(scanner, inputPath); + string arg = args[i]; + GetAndWriteProtections(scanner, arg); } } + /// + /// Create the command set for the program + /// + private static CommandSet CreateCommands() + { + List header = [ + "Protection Scanner", + string.Empty, + "ProtectionScan file|directory ...", + string.Empty, + ]; + + var commandSet = new CommandSet(header); + + commandSet.Add(new FlagInput(_helpName, ["-?", "-h", "--help"], "Display this help text")); + commandSet.Add(new FlagInput(_debugName, ["-d", "--debug"], "Enable debug mode")); + commandSet.Add(new FlagInput(_noContentsName, ["-nc", "--no-contents"], "Disable scanning for content checks")); + commandSet.Add(new FlagInput(_noArchivesName, ["-na", "--no-archives"], "Disable scanning archives")); + commandSet.Add(new FlagInput(_noPathsName, ["-np", "--no-paths"], "Disable scanning for path checks")); + commandSet.Add(new FlagInput(_noSubdirsName, ["-ns", "--no-subdirs"], "Disable scanning subdirectories")); + + return commandSet; + } + /// /// Wrapper to get and log protections for a single path /// diff --git a/ProtectionScan/ProtectionScan.csproj b/ProtectionScan/ProtectionScan.csproj index 62ca3590..39e4509c 100644 --- a/ProtectionScan/ProtectionScan.csproj +++ b/ProtectionScan/ProtectionScan.csproj @@ -32,6 +32,7 @@ +