예제 #1
0
    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))
예제 #2
0
    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
예제 #3
0
  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)
예제 #4
0
    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