Source code for dfimagetools.scripts.list_file_entries

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""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())