Source code for dfvfs.lib.ewf_helper

# -*- coding: utf-8 -*-
"""Helper functions for EWF image support."""

from dfvfs.lib import errors
from dfvfs.path import factory as path_spec_factory


[docs] def EWFGlobPathSpec(file_system, path_spec): """Globs for path specifications according to the EWF naming schema. Args: file_system (FileSystem): file system. path_spec (PathSpec): path specification. Returns: list[PathSpec]: path specifications that match the glob. Raises: PathSpecError: if the path specification is invalid. RuntimeError: if the maximum number of supported segment files is reached. """ if not path_spec.HasParent(): raise errors.PathSpecError( 'Unsupported path specification without parent.') parent_path_spec = path_spec.parent parent_location = getattr(parent_path_spec, 'location', None) if not parent_location: raise errors.PathSpecError( 'Unsupported parent path specification without location.') parent_location, _, segment_extension = parent_location.rpartition('.') segment_extension_start = segment_extension[0] segment_extension_length = len(segment_extension) if (segment_extension_length not in [3, 4] or not segment_extension.endswith('01') or ( segment_extension_length == 3 and segment_extension_start not in ['E', 'e', 's']) or ( segment_extension_length == 4 and not segment_extension.startswith('Ex'))): raise errors.PathSpecError(( f'Unsupported parent path specification invalid segment file ' f'extension: {segment_extension:s}')) segment_number = 1 segment_files = [] while True: segment_location = f'{parent_location:s}.{segment_extension:s}' # Note that we don't want to set the keyword arguments when not used # because the path specification base class will check for unused # keyword arguments and raise. kwargs = path_spec_factory.Factory.GetProperties(parent_path_spec) kwargs['location'] = segment_location if parent_path_spec.parent is not None: kwargs['parent'] = parent_path_spec.parent segment_path_spec = path_spec_factory.Factory.NewPathSpec( parent_path_spec.type_indicator, **kwargs) if not file_system.FileEntryExistsByPathSpec(segment_path_spec): break segment_files.append(segment_path_spec) segment_number += 1 if segment_number <= 99: if segment_extension_length == 3: segment_extension = f'{segment_extension_start:s}{segment_number:02d}' elif segment_extension_length == 4: segment_extension = f'{segment_extension_start:s}x{segment_number:02d}' else: segment_index = segment_number - 100 if segment_extension_start in ['e', 's']: letter_offset = ord('a') else: letter_offset = ord('A') segment_index, remainder = divmod(segment_index, 26) third_letter = chr(letter_offset + remainder) segment_index, remainder = divmod(segment_index, 26) second_letter = chr(letter_offset + remainder) first_letter = chr(ord(segment_extension_start) + segment_index) if first_letter in ['[', '{']: raise RuntimeError('Unsupported number of segment files.') if segment_extension_length == 3: segment_extension = f'{first_letter:s}{second_letter:s}{third_letter:s}' elif segment_extension_length == 4: segment_extension = ( f'{first_letter:s}x{second_letter:s}{third_letter:s}') return segment_files