Source code for dfimagetools.scripts.list_file_entries

#!/usr/bin/env python3
"""Console script to list file entries."""

import argparse
import logging
import os
import sys

import artifacts

from artifacts import reader as artifacts_reader
from artifacts import registry as artifacts_registry

from dfvfs.lib import errors as dfvfs_errors

from dfimagetools import artifact_filters
from dfimagetools import bodyfile
from dfimagetools import file_entry_lister
from dfimagetools import windows_registry
from dfimagetools.helpers import command_line


[docs] def Main(): """Entry point of console script to list file entries. Returns: int: exit code that is provided to sys.exit(). """ argument_parser = argparse.ArgumentParser( description=("Lists metadata of file entries in a storage media image.") ) # TODO: add filter group argument_parser.add_argument( "--artifact_definitions", "--artifact-definitions", dest="artifact_definitions", type=str, metavar="PATH", action="store", help=( "Path to a directory or file containing the artifact definition " ".yaml files." ), ) argument_parser.add_argument( "--artifact_filters", "--artifact-filters", dest="artifact_filters", type=str, default=None, metavar="NAMES", action="store", help=("Comma separated list of names of artifact definitions to extract."), ) argument_parser.add_argument( "--custom_artifact_definitions", "--custom-artifact-definitions", dest="custom_artifact_definitions", type=str, metavar="PATH", action="store", help=( "Path to a directory or file containing custom artifact definition " ".yaml files. " ), ) # TODO: add output group argument_parser.add_argument( "--no_aliases", "--no-aliases", dest="use_aliases", action="store_false", default=True, help=( "Disable the use of partition and/or volume aliases such as " "/apfs{f449e580-e355-4e74-8880-05e46e4e3b1e} and use indices " "such as /apfs1 instead." ), ) argument_parser.add_argument( "--output_format", "--output-format", dest="output_format", action="store", metavar="FORMAT", default="bodyfile", help=("output format, default is bodyfile."), ) # TODO: add source group. command_line.AddStorageMediaImageCLIArguments(argument_parser) argument_parser.add_argument( "source", nargs="?", action="store", metavar="image.raw", default=None, help="path of the storage media image.", ) options = argument_parser.parse_args() if not options.source: print("Source value is missing.") print("") argument_parser.print_help() print("") return 1 if options.output_format != "bodyfile": print(f"Unsupported output format: {options.output_format:s}.") print("") argument_parser.print_help() print("") return 1 if options.artifact_filters: artifact_definitions = options.artifact_definitions if not artifact_definitions: artifact_definitions = os.path.join( os.path.dirname(artifacts.__file__), "data" ) if not os.path.exists(artifact_definitions): artifact_definitions = os.path.join("/", "usr", "share", "artifacts") if not os.path.exists(artifact_definitions): artifact_definitions = None if not artifact_definitions and not options.custom_artifact_definitions: print( "[ERROR] artifact filters were specified but no paths to " "artifact definitions were provided." ) print("") return 1 logging.basicConfig(level=logging.INFO, format="[%(levelname)s] %(message)s") mediator, volume_scanner_options = command_line.ParseStorageMediaImageCLIArguments( options ) if options.artifact_filters: registry = artifacts_registry.ArtifactDefinitionsRegistry() reader = artifacts_reader.YamlArtifactsReader() if artifact_definitions: if os.path.isdir(artifact_definitions): registry.ReadFromDirectory(reader, artifact_definitions) elif os.path.isfile(artifact_definitions): registry.ReadFromFile(reader, artifact_definitions) if options.custom_artifact_definitions: if os.path.isdir(options.custom_artifact_definitions): registry.ReadFromDirectory(reader, options.custom_artifact_definitions) elif os.path.isfile(options.custom_artifact_definitions): registry.ReadFromFile(reader, options.custom_artifact_definitions) entry_lister = file_entry_lister.FileEntryLister( mediator=mediator, use_aliases=options.use_aliases ) find_specs_generated = False try: base_path_specs = entry_lister.GetBasePathSpecs( options.source, options=volume_scanner_options ) if not base_path_specs: print("No supported file system found in source.") print("") return 1 bodyfile_header_printed = False for base_path_spec in base_path_specs: if not options.artifact_filters: find_specs = [] else: windows_directory = entry_lister.GetWindowsDirectory(base_path_spec) if not windows_directory: environment_variables = [] else: winregistry_collector = windows_registry.WindowsRegistryCollector( base_path_spec, windows_directory ) environment_variables = ( winregistry_collector.CollectSystemEnvironmentVariables() ) filter_generator = artifact_filters.ArtifactDefinitionFiltersGenerator( registry, environment_variables, [] ) names = options.artifact_filters.split(",") find_specs = list(filter_generator.GetFindSpecs(names)) if not find_specs: continue find_specs_generated = True if find_specs: file_entries_generator = entry_lister.ListFileEntriesWithFindSpecs( [base_path_spec], find_specs ) else: file_entries_generator = entry_lister.ListFileEntries([base_path_spec]) if not bodyfile_header_printed: print("# extended bodyfile 3 format") bodyfile_header_printed = True bodyfile_generator = bodyfile.BodyfileGenerator() for file_entry, path_segments in file_entries_generator: for bodyfile_entry in bodyfile_generator.GetEntries( file_entry, path_segments ): print(bodyfile_entry) except dfvfs_errors.ScannerError as exception: print(f"[ERROR] {exception!s}", file=sys.stderr) print("") return 1 except (KeyboardInterrupt, dfvfs_errors.UserAbort): print("Aborted by user.", file=sys.stderr) print("") return 1 if options.artifact_filters and not find_specs_generated: print( "[ERROR] an artifact filter was specified but no corresponding " "file system find specifications were generated." ) print("") return 1 return 0
if __name__ == "__main__": sys.exit(Main())