def _EntriesGenerator(self): """Retrieves directory entries. Since a directory can contain a vast number of entries using a generator is more memory efficient. Yields: A path specification (instance of path.OSPathSpec). Raises: AccessError: if the access to list the directory was denied. BackEndError: if the directory could not be listed. """ location = getattr(self.path_spec, u'location', None) if location is None: return # Windows will raise WindowsError, which can be caught by OSError, # if the process has not access to list the directory. The os.access() # function cannot be used since it will return true even when os.listdir() # fails. try: for directory_entry in os.listdir(location): directory_entry_location = self._file_system.JoinPath( [location, directory_entry]) yield os_path_spec.OSPathSpec( location=directory_entry_location) except OSError as exception: if exception.errno == errno.EACCES: exception_string = str(exception) if not isinstance(exception_string, py2to3.UNICODE_TYPE): exception_string = py2to3.UNICODE_TYPE(exception_string, errors=u'replace') raise errors.AccessError( u'Access to directory denied with error: {0:s}'.format( exception_string)) else: raise errors.BackEndError( u'Unable to list directory: {0:s} with error: {1:s}'. format(location, exception))
def FileEntryExistsByPathSpec(self, path_spec): """Determines if a file entry for a path specification exists. Args: path_spec: a path specification (instance of path.PathSpec). Returns: Boolean indicating if the file entry exists. """ location = getattr(path_spec, u'location', None) if location is None: return False is_device = False if platform.system() == u'Windows': # Windows does not support running os.path.exists on device files # so we use libsmdev to do the check. try: is_device = pysmdev.check_device(location) except IOError as exception: # Since pysmdev will raise IOError when it has no access to the device # we check if the exception message contains ' access denied ' and # return true. # Note that exception.message no longer works in Python 3. exception_string = str(exception) if not isinstance(exception_string, py2to3.UNICODE_TYPE): exception_string = py2to3.UNICODE_TYPE(exception_string, errors=u'replace') if u' access denied ' in exception_string: is_device = True if not is_device and not os.path.exists(location): return False return True
def FileEntryExistsByPathSpec(self, path_spec): """Determines if a file entry for a path specification exists. Args: path_spec (PathSpec): a path specification. Returns: bool: True if the file entry exists, false otherwise. """ location = getattr(path_spec, 'location', None) if location is None: return False is_device = False if platform.system() == 'Windows': # Note that os.path.exists() returns False for Windows device files so # instead use libsmdev to do the check. try: is_device = pysmdev.check_device(location) except IOError as exception: # Since pysmdev will raise IOError when it has no access to the device # we check if the exception message contains ' access denied ' and # return true. # Note that exception.message no longer works in Python 3. exception_string = str(exception) if not isinstance(exception_string, py2to3.UNICODE_TYPE): exception_string = py2to3.UNICODE_TYPE( exception_string, errors='replace') if ' access denied ' in exception_string: is_device = True # Note that os.path.exists() returns False for broken symbolic links hence # an additional check using os.path.islink() is necessary. return is_device or os.path.exists(location) or os.path.islink(location)
def _Open(self, path_spec=None, mode='rb'): """Opens the file-like object defined by path specification. Args: path_spec: optional path specification (instance of path.PathSpec). The default is None. mode: optional file access mode. The default is 'rb' read-only binary. Raises: AccessError: if the access to open the file was denied. IOError: if the file-like object could not be opened. PathSpecError: if the path specification is incorrect. ValueError: if the path specification is invalid. """ if not path_spec: raise ValueError(u'Missing path specfication.') if path_spec.HasParent(): raise errors.PathSpecError( u'Unsupported path specification with parent.') location = getattr(path_spec, u'location', None) if location is None: raise errors.PathSpecError(u'Path specification missing location.') # Windows does not support running os.stat on device files so we use # libsmdev to do an initial check. try: is_device = pysmdev.check_device(location) except IOError as exception: # Since os.stat() will not recognize Windows device file names and # will return '[Error 87] The parameter is incorrect' we check here # if pysmdev exception message contains ' access denied ' and raise # AccessError instead. # Note that exception.message no longer works in Python 3. exception_string = str(exception) if not isinstance(exception_string, py2to3.UNICODE_TYPE): exception_string = py2to3.UNICODE_TYPE(exception_string, errors=u'replace') if u' access denied ' in exception_string: raise errors.AccessError( u'Access denied to file: {0:s} with error: {1:s}'.format( location, exception_string)) is_device = False if not is_device: try: stat_info = os.stat(location) except OSError as exception: raise IOError(u'Unable to open file with error: {0:s}.'.format( exception)) # In case the libsmdev check is not able to detect the device also use # the stat information. if stat.S_ISCHR(stat_info.st_mode) or stat.S_ISBLK( stat_info.st_mode): is_device = True if is_device: self._file_object = pysmdev.handle() self._file_object.open(location, mode=mode) self._size = self._file_object.media_size else: self._file_object = open(location, mode=mode) self._size = stat_info.st_size