def __init__(self, base_fd, pathspec=None, progress_callback=None,
               full_pathspec=None):
    """Use TSK to read the pathspec.

    Args:
      base_fd: The file like object we read this component from.
      pathspec: An optional pathspec to open directly.
      progress_callback: A callback to indicate that the open call is still
                         working but needs more time.
      full_pathspec: The full pathspec we are trying to open.
    Raises:
      IOError: If the file can not be opened.
    """
    super(TSKFile, self).__init__(base_fd, pathspec=pathspec,
                                  progress_callback=progress_callback,
                                  full_pathspec=full_pathspec)
    if self.base_fd is None:
      raise IOError("TSK driver must have a file base.")

    # If our base is another tsk driver - borrow the reference to the raw
    # device, and replace the last pathspec component with this one after
    # extending its path.
    elif isinstance(base_fd, TSKFile) and self.base_fd.IsDirectory():
      self.tsk_raw_device = self.base_fd.tsk_raw_device
      last_path = utils.JoinPath(self.pathspec.last.path, pathspec.path)

      # Replace the last component with this one.
      self.pathspec.Pop(-1)
      self.pathspec.Append(pathspec)
      self.pathspec.last.path = last_path

    # Use the base fd as a base to parse the filesystem only if its file like.
    elif not self.base_fd.IsDirectory():
      self.tsk_raw_device = self.base_fd
      self.pathspec.Append(pathspec)
    else:
      # If we get here we have a directory from a non sleuthkit driver - dont
      # know what to do with it.
      raise IOError("Unable to parse base using Sleuthkit.")

    # If we are successful in opening this path below the path casing is
    # correct.
    self.pathspec.last.path_options = rdf_paths.PathSpec.Options.CASE_LITERAL

    fd_hash = self.tsk_raw_device.pathspec.SerializeToString()

    # Cache the filesystem using the path of the raw device
    try:
      self.filesystem = vfs.DEVICE_CACHE.Get(fd_hash)
      self.fs = self.filesystem.fs
    except __HOLE__:
      self.img = MyImgInfo(fd=self.tsk_raw_device,
                           progress_callback=progress_callback)

      self.fs = pytsk3.FS_Info(self.img, 0)
      self.filesystem = CachedFilesystem(self.fs, self.img)

      vfs.DEVICE_CACHE.Put(fd_hash, self.filesystem)

    # We prefer to open the file based on the inode because that is more
    # efficient.
    if pathspec.HasField("inode"):
      self.fd = self.fs.open_meta(pathspec.inode)
      self.tsk_attribute = self.GetAttribute(
          pathspec.ntfs_type, pathspec.ntfs_id)
      if self.tsk_attribute:
        self.size = self.tsk_attribute.info.size
      else:
        self.size = self.fd.info.meta.size

    else:
      # Does the filename exist in the image?
      self.fd = self.fs.open(utils.SmartStr(self.pathspec.last.path))
      self.size = self.fd.info.meta.size
      self.pathspec.last.inode = self.fd.info.meta.addr
dataset/ETHPy150Open google/grr/grr/client/vfs_handlers/sleuthkit.py/TSKFile.__init__