-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Extract and create tar files using conduit for streaming
--   
--   Please see README.md. This is just filler to avoid warnings.
@package tar-conduit
@version 0.3.2

-- | Module contains all the types necessary for tarball processing.
module Data.Conduit.Tar.Types
data Header
Header :: !FileOffset -> !FileOffset -> !ShortByteString -> !CMode -> !UserID -> !GroupID -> !FileOffset -> !EpochTime -> !Word8 -> !ShortByteString -> !ShortByteString -> !ShortByteString -> !ShortByteString -> !DeviceID -> !DeviceID -> !ShortByteString -> Header
[headerOffset] :: Header -> !FileOffset
[headerPayloadOffset] :: Header -> !FileOffset
[headerFileNameSuffix] :: Header -> !ShortByteString
[headerFileMode] :: Header -> !CMode
[headerOwnerId] :: Header -> !UserID
[headerGroupId] :: Header -> !GroupID
[headerPayloadSize] :: Header -> !FileOffset
[headerTime] :: Header -> !EpochTime
[headerLinkIndicator] :: Header -> !Word8
[headerLinkName] :: Header -> !ShortByteString
[headerMagicVersion] :: Header -> !ShortByteString
[headerOwnerName] :: Header -> !ShortByteString
[headerGroupName] :: Header -> !ShortByteString
[headerDeviceMajor] :: Header -> !DeviceID
[headerDeviceMinor] :: Header -> !DeviceID
[headerFileNamePrefix] :: Header -> !ShortByteString
data TarChunk
ChunkHeader :: Header -> TarChunk
ChunkPayload :: !FileOffset -> !ByteString -> TarChunk
ChunkException :: TarException -> TarChunk

-- | This the the exception type that is used in this module.
--   
--   More constructors are susceptible to be added without bumping the
--   major version of this module.
data TarException
NoMoreHeaders :: TarException
UnexpectedPayload :: !FileOffset -> TarException
IncompleteHeader :: !FileOffset -> TarException
IncompletePayload :: !FileOffset -> !ByteCount -> TarException
ShortTrailer :: !FileOffset -> TarException
BadTrailer :: !FileOffset -> TarException
InvalidHeader :: !FileOffset -> TarException
BadChecksum :: !FileOffset -> TarException
FileTypeError :: !FileOffset -> !Char -> !String -> TarException
UnsupportedType :: !FileType -> TarException
data TarCreateException
FileNameTooLong :: !FileInfo -> TarCreateException
TarCreationError :: !String -> TarCreateException
data FileType
FTNormal :: FileType
FTHardLink :: !ByteString -> FileType
FTSymbolicLink :: !ByteString -> FileType
FTCharacterSpecial :: FileType
FTBlockSpecial :: FileType
FTDirectory :: FileType
FTFifo :: FileType
FTOther :: !Word8 -> FileType
data FileInfo
FileInfo :: !ByteString -> !UserID -> !ByteString -> !GroupID -> !ByteString -> !FileMode -> !FileOffset -> !FileType -> !EpochTime -> FileInfo

-- | File path.
[filePath] :: FileInfo -> !ByteString

-- | Unix user id.
[fileUserId] :: FileInfo -> !UserID

-- | Unix user name.
[fileUserName] :: FileInfo -> !ByteString

-- | Unix group id.
[fileGroupId] :: FileInfo -> !GroupID

-- | Unix group name.
[fileGroupName] :: FileInfo -> !ByteString

-- | Unix file permissions
[fileMode] :: FileInfo -> !FileMode

-- | File size
[fileSize] :: FileInfo -> !FileOffset

-- | File type. FTNormal, FTHardLink (@since 0.3.0),
--   FTSymbolicLink and FTDirectory are the only ones
--   supported for now
[fileType] :: FileInfo -> !FileType

-- | File modification timestamp
[fileModTime] :: FileInfo -> !EpochTime
type FileOffset = COff
type ByteCount = CSize
type UserID = CUid
type GroupID = CGid
type DeviceID = CDev
type EpochTime = CTime
newtype CUid
CUid :: Word32 -> CUid
newtype CGid
CGid :: Word32 -> CGid

-- | Convert FilePath into a UTF-8 encoded ByteString
encodeFilePath :: FilePath -> ByteString

-- | Convert UTF-8 encoded ByteString back into the FilePath.
decodeFilePath :: ByteString -> FilePath

-- | Get the FilePath.
getFileInfoPath :: FileInfo -> FilePath
instance GHC.Show.Show Data.Conduit.Tar.Types.TarCreateException
instance GHC.Show.Show Data.Conduit.Tar.Types.TarChunk
instance GHC.Show.Show Data.Conduit.Tar.Types.TarException
instance GHC.Show.Show Data.Conduit.Tar.Types.Header
instance GHC.Classes.Eq Data.Conduit.Tar.Types.FileInfo
instance GHC.Show.Show Data.Conduit.Tar.Types.FileInfo
instance GHC.Classes.Eq Data.Conduit.Tar.Types.FileType
instance GHC.Show.Show Data.Conduit.Tar.Types.FileType
instance GHC.Exception.Type.Exception Data.Conduit.Tar.Types.TarCreateException
instance GHC.Exception.Type.Exception Data.Conduit.Tar.Types.TarException

-- | This module is about stream-processing tar archives. It is currently
--   not very well tested. See the documentation of withEntries for
--   an usage sample.
module Data.Conduit.Tar

-- | Create a tar archive by suppying a stream of Left
--   FileInfos. Whenever a file type is FTNormal, it must be
--   immediately followed by its content as Right ByteString.
--   The produced ByteString is in the raw tar format and is
--   properly terminated at the end, therefore it can not be extended
--   afterwards. Returned is the total size of the bytestring as a
--   FileOffset.
tar :: MonadThrow m => ConduitM (Either FileInfo ByteString) ByteString m FileOffset

-- | Just like tar, except gives you the ability to work at a lower
--   Header level, versus more user friendly FileInfo. A
--   deeper understanding of tar format is necessary in order to work
--   directly with Headers.
tarEntries :: MonadThrow m => ConduitM (Either Header ByteString) ByteString m FileOffset

-- | Just like withFileInfo, but works directly on the stream of
--   bytes.
untar :: MonadThrow m => (FileInfo -> ConduitM ByteString o m ()) -> ConduitM ByteString o m ()

-- | Just like untar, except that each FileInfo handling
--   function can produce a finalizing action, all of which will be
--   executed after the whole tarball has been processed in the opposite
--   order. Very useful with restoreFile and restoreFileInto,
--   since they restore direcory modification timestamps only after files
--   have been fully written to disk.
untarWithFinalizers :: (MonadThrow m, MonadIO m) => (FileInfo -> ConduitM ByteString (IO ()) m ()) -> ConduitM ByteString c m ()

-- | Same as untarWithFinalizers, but will also produce a list of
--   any exceptions that might have occured during restoration process.
untarWithExceptions :: (MonadThrow m, MonadIO m) => (FileInfo -> ConduitM ByteString (IO (FileInfo, [SomeException])) m ()) -> ConduitM ByteString c m [(FileInfo, [SomeException])]

-- | Restore files onto the file system. Produces actions that will set the
--   modification time on the directories, which can be executed after the
--   pipeline has finished and all files have been written to disk.
restoreFile :: MonadResource m => FileInfo -> ConduitM ByteString (IO ()) m ()

-- | Restore all files into a folder. Absolute file paths will be turned
--   into relative to the supplied folder.
restoreFileInto :: MonadResource m => FilePath -> FileInfo -> ConduitM ByteString (IO ()) m ()

-- | Restore all files into a folder. Absolute file paths will be turned
--   into relative to the supplied folder. Yields a list with exceptions
--   instead of throwing them.
restoreFileIntoLenient :: MonadResource m => FilePath -> FileInfo -> ConduitM ByteString (IO (FileInfo, [SomeException])) m ()

-- | Restore files onto the file system, much in the same way
--   restoreFile does it, except with ability to ignore restoring
--   problematic files and report errors that occured as a list of
--   exceptions, which will be returned as a list when finilizer executed.
--   If a list is empty, it means, that no errors occured and a file only
--   had a finilizer associated with it.
restoreFileWithErrors :: MonadResource m => Bool -> FileInfo -> ConduitM ByteString (IO (FileInfo, [SomeException])) m ()

-- | Convert a stream of raw bytes into a stream of TarChunks. This
--   stream can further be passed into withFileInfo or
--   withHeaders functions.
untarChunks :: Monad m => ConduitM ByteString TarChunk m ()

-- | Process a single tar entry. See withEntries for more details.
withEntry :: MonadThrow m => (Header -> ConduitM ByteString o m r) -> ConduitM TarChunk o m r

-- | This function handles each entry of the tar archive according to the
--   behaviour of the function passed as first argument.
--   
--   Here is a full example function, that reads a compressed tar archive
--   and for each entry that is a simple file, it prints its file path and
--   SHA256 digest. Note that this function can throw exceptions!
--   
--   
--   import qualified Crypto.Hash.Conduit as CH
--   import qualified Data.Conduit.Tar    as CT
--   
--   import Conduit
--   import Crypto.Hash (Digest, SHA256)
--   import Control.Monad (when)
--   import Data.Conduit.Zlib (ungzip)
--   import Data.ByteString (ByteString)
--   
--   filedigests :: FilePath -> IO ()
--   filedigests fp = runConduitRes (  sourceFileBS fp          -- read the raw file
--                                  .| ungzip                   -- gunzip
--                                  .| CT.untarChunks           -- decode the tar archive
--                                  .| CT.withEntries hashentry -- process each file
--                                  .| printC                   -- print the results
--                                  )
--       where
--           hashentry :: Monad m => CT.Header -> Conduit ByteString m (FilePath, Digest SHA256)
--           hashentry hdr = when (CT.headerFileType hdr == CT.FTNormal) $ do
--               hash <- CH.sinkHash
--               yield (CT.headerFilePath hdr, hash)
--   
--   
--   The hashentry function handles a single entry, based on its
--   first Header argument. In this example, a Consumer is
--   used to process the whole entry.
--   
--   Note that the benefits of stream processing are easily lost when
--   working with a Consumer. For example, the following
--   implementation would have used an unbounded amount of memory:
--   
--   
--   hashentry hdr = when (CT.headerFileType hdr == CT.FTNormal) $ do
--       content <- mconcat <$> sinkList
--       yield (CT.headerFilePath hdr, hash content)
--   
withEntries :: MonadThrow m => (Header -> ConduitM ByteString o m ()) -> ConduitM TarChunk o m ()

-- | Extract a tarball, similarly to withEntries, but instead of
--   dealing directly with tar format, this conduit allows you to work
--   directly on file abstractions FileInfo. For now support is
--   minimal:
--   
--   
--   
- Old v7 tar format.
--   
- ustar: POSIX 1003.1-1988 format
--   
- and only some portions of GNU format:
--   
- Larger values for fileUserId, fileGroupId,
--   fileSize and fileModTime.
--   
- L type - long file names, but only up to 4096 chars to
--   prevent DoS attack
--   
- other types are simply discarded
--   
--   
--   Note - Here is a really good reference for specifics of
--   different tar formats:
--   https://github.com/libarchive/libarchive/wiki/ManPageTar5
withFileInfo :: MonadThrow m => (FileInfo -> ConduitM ByteString o m ()) -> ConduitM TarChunk o m ()

-- | Get Header file type.
headerFileType :: Header -> FileType

-- | Construct a FilePath from headerFileNamePrefix and
--   headerFileNameSuffix.
headerFilePath :: Header -> FilePath

-- | Recursively tar all of the files and directories. There will be no
--   conversion between relative and absolute paths, so just like with GNU
--   tar cli tool, it may be necessary to
--   setCurrentDirectory in order to get the paths relative. Using
--   filePathConduit directly, while modifying the filePath,
--   would be another approach to handling the file paths.
tarFilePath :: (MonadThrow m, MonadResource m) => ConduitM FilePath ByteString m FileOffset

-- | Turn a stream of file paths into a stream of FileInfo and file
--   content. All paths will be decended into recursively.
filePathConduit :: (MonadThrow m, MonadResource m) => ConduitM FilePath (Either FileInfo ByteString) m ()

-- | Uses tarFilePath to create a tarball, that will recursively
--   include the supplied list of all the files and directories
createTarball :: FilePath -> [FilePath] -> IO ()

-- | Take a list of files and paths, recursively tar them and write output
--   into supplied handle.
writeTarball :: Handle -> [FilePath] -> IO ()

-- | Extract a tarball while using restoreFileInfo for writing
--   files onto the file system. Restoration process is cross platform and
--   should work concistently both on Windows and Posix systems.
extractTarball :: FilePath -> Maybe FilePath -> IO ()

-- | Same as extractTarball, but ignores possible extraction errors.
--   It can still throw a TarException if the tarball is corrupt or
--   malformed.
extractTarballLenient :: FilePath -> Maybe FilePath -> IO [(FileInfo, [SomeException])]
