Skip to content

Commit

Permalink
Changed tools to entry points
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Jan 28, 2024
1 parent 96100dd commit 23652de
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 312 deletions.
1 change: 1 addition & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ disable=assignment-from-none,
missing-param-doc,
raise-missing-from,
raw-checker-failed,
redefined-outer-name,
super-with-arguments,
suppressed-message,
too-few-public-methods,
Expand Down
32 changes: 10 additions & 22 deletions tools/extract_data_streams.py → dfimagetools/extract_data_streams.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@
from dfimagetools.helpers import command_line


def Main():
"""The main program function.
Returns:
bool: True if successful or False if not.
"""
if __name__ == '__main__':
argument_parser = argparse.ArgumentParser(description=(
'Extracts data streams from a storage media image.'))

Expand Down Expand Up @@ -68,21 +63,21 @@ def Main():
print('')
argument_parser.print_help()
print('')
return False
sys.exit(1)

if options.artifact_filters:
if (not options.artifact_definitions and
not options.custom_artifact_definitions):
print('[ERROR] artifact filters were specified but no paths to '
'artifact definitions were provided.')
print('')
return False
sys.exit(1)

# TODO: improve this, for now this script needs at least 1 filter.
if not options.artifact_filters:
print('[ERROR] no artifact filters were specified.')
print('')
return False
sys.exit(1)

target_path = options.target
if not target_path:
Expand All @@ -95,7 +90,7 @@ def Main():
elif not os.path.isdir(target_path):
print('[ERROR] target path is not a directory.')
print('')
return False
sys.exit(1)

logging.basicConfig(
level=logging.INFO, format='[%(levelname)s] %(message)s')
Expand Down Expand Up @@ -129,7 +124,7 @@ def Main():
if not base_path_specs:
print('No supported file system found in source.')
print('')
return False
sys.exit(1)

for base_path_spec in base_path_specs:
if not options.artifact_filters:
Expand Down Expand Up @@ -176,24 +171,17 @@ def Main():
except dfvfs_errors.ScannerError as exception:
print(f'[ERROR] {exception!s}', file=sys.stderr)
print('')
return False
sys.exit(1)

except KeyboardInterrupt:
print('Aborted by user.', file=sys.stderr)
print('')
return False
sys.exit(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 False

return True


if __name__ == '__main__':
if not Main():
sys.exit(1)
else:
sys.exit(0)

sys.exit(0)
36 changes: 14 additions & 22 deletions tools/list_file_entries.py → dfimagetools/list_file_entries.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@
from dfimagetools.helpers import command_line


def Main():
"""The main program function.
Returns:
bool: True if successful or False if not.
"""
if __name__ == '__main__':
argument_parser = argparse.ArgumentParser(description=(
'Lists metadata of file entries in a storage media image.'))

Expand Down Expand Up @@ -74,22 +69,22 @@ def Main():
print('')
argument_parser.print_help()
print('')
return False
sys.exit(1)

if options.output_format != 'bodyfile':
print(f'Unsupported output format: {options.output_format:s}.')
print('')
argument_parser.print_help()
print('')
return False
sys.exit(1)

if options.artifact_filters:
if (not options.artifact_definitions and
not options.custom_artifact_definitions):
print('[ERROR] artifact filters were specified but no paths to '
'artifact definitions were provided.')
print('')
return False
sys.exit(1)

logging.basicConfig(
level=logging.INFO, format='[%(levelname)s] %(message)s')
Expand Down Expand Up @@ -123,7 +118,9 @@ def Main():
if not base_path_specs:
print('No supported file system found in source.')
print('')
return False
sys.exit(1)

bodyfile_header_printed = False

for base_path_spec in base_path_specs:
if not options.artifact_filters:
Expand Down Expand Up @@ -155,7 +152,9 @@ def Main():
else:
file_entries_generator = entry_lister.ListFileEntries([base_path_spec])

print('# extended bodyfile 3 format')
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:
Expand All @@ -166,24 +165,17 @@ def Main():
except dfvfs_errors.ScannerError as exception:
print(f'[ERROR] {exception!s}', file=sys.stderr)
print('')
return False
sys.exit(1)

except KeyboardInterrupt:
print('Aborted by user.', file=sys.stderr)
print('')
return False
sys.exit(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 False

return True


if __name__ == '__main__':
if not Main():
sys.exit(1)
else:
sys.exit(0)

sys.exit(0)
27 changes: 6 additions & 21 deletions tools/map_extents.py → dfimagetools/map_extents.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@
from dfimagetools.helpers import command_line


def Main():
"""The main program function.
Returns:
bool: True if successful or False if not.
"""
if __name__ == '__main__':
argument_parser = argparse.ArgumentParser(description=(
'Maps extents in a storage media image.'))

Expand All @@ -35,7 +30,7 @@ def Main():
print('')
argument_parser.print_help()
print('')
return False
sys.exit(1)

# TODO: add support to write extent map entry to a SQLite database

Expand All @@ -46,15 +41,14 @@ def Main():
command_line.ParseStorageMediaImageCLIArguments(options))

entry_lister = file_entry_lister.FileEntryLister(mediator=mediator)
return_value = True

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 False
sys.exit(1)

# TODO: error if not a storage media image or device

Expand Down Expand Up @@ -86,20 +80,11 @@ def Main():
f'{extent_type:s}\t{data_stream_path:s}')

except errors.ScannerError as exception:
return_value = False

print(f'[ERROR] {exception!s}', file=sys.stderr)
sys.exit(1)

except KeyboardInterrupt:
return_value = False

print('Aborted by user.', file=sys.stderr)

return return_value


if __name__ == '__main__':
if not Main():
sys.exit(1)
else:
sys.exit(0)

sys.exit(0)
76 changes: 75 additions & 1 deletion dfimagetools/recursive_hasher.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Helper to recursively calculate a message digest hash of data streams."""
"""Script to recursively calculate a message digest hash of data streams."""

import argparse
import hashlib
import logging
import sys

from dfvfs.lib import errors as dfvfs_errors

from dfimagetools import definitions
from dfimagetools import file_entry_lister
from dfimagetools.helpers import command_line


class RecursiveHasher(object):
Expand Down Expand Up @@ -108,3 +114,71 @@ def CalculateHashesFileEntry(self, file_entry, path_segments):

display_path = self._GetDisplayPath(path_segments, data_stream.name)
yield display_path, hash_value


if __name__ == '__main__':
argument_parser = argparse.ArgumentParser(description=(
'Calculates a message digest hash for every file in a directory or '
'storage media image.'))

# 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.'))

# 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('')
sys.exit(1)

logging.basicConfig(
level=logging.INFO, format='[%(levelname)s] %(message)s')

mediator, volume_scanner_options = (
command_line.ParseStorageMediaImageCLIArguments(options))

entry_lister = file_entry_lister.FileEntryLister(
mediator=mediator, use_aliases=options.use_aliases)

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('')
sys.exit(1)

hasher = RecursiveHasher()
for base_path_spec in base_path_specs:
file_entries_generator = entry_lister.ListFileEntries([base_path_spec])

for file_entry, path_segments in file_entries_generator:
for display_path, hash_value in hasher.CalculateHashesFileEntry(
file_entry, path_segments):
print('{0:s}\t{1:s}'.format(hash_value or 'N/A', display_path))

except dfvfs_errors.ScannerError as exception:
print(f'[ERROR] {exception!s}', file=sys.stderr)
print('')
sys.exit(1)

except KeyboardInterrupt:
print('Aborted by user.', file=sys.stderr)
print('')
sys.exit(1)

sys.exit(0)
Loading

0 comments on commit 23652de

Please sign in to comment.