-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Reading, writing and manipulating ".tar" archive files. -- -- This library is for working with ".tar" archive files. It can -- read and write a range of common variations of archive format -- including V7, POSIX USTAR and GNU formats. -- -- It provides support for packing and unpacking portable archives. This -- makes it suitable for distribution but not backup because details like -- file ownership and exact permissions are not preserved. -- -- It also provides features for random access to archive content using -- an index. @package tar @version 0.6.2.0 -- | Random access to the content of a .tar archive. -- -- This module uses common names and so is designed to be imported -- qualified: -- --
-- import qualified Codec.Archive.Tar.Index as TarIndex --module Codec.Archive.Tar.Index -- | An index of the entries in a tar file. -- -- This index type is designed to be quite compact and suitable to store -- either on disk or in memory. data TarIndex -- | Look up a given filepath in the TarIndex. It may return a -- TarFileEntry containing the TarEntryOffset of the file -- within the tar file, or if the filepath identifies a directory then it -- returns a TarDir containing the list of files within that -- directory. -- -- Given the TarEntryOffset you can then use one of the I/O -- operations: -- --
-- entry <- Tar.hReadEntryHeader hnd -- case Tar.entryContent entry of -- Tar.NormalFile _ size -> do content <- BS.hGet hnd size -- ... ---- -- Of course you don't have to read it all in one go (as -- hReadEntry does), you can use any appropriate method to read it -- incrementally. -- -- In addition to I/O errors, this can throw a FormatError if the -- offset is wrong, or if the file is not valid tar format. -- -- There is also the lower level operation hSeekEntryOffset. hReadEntryHeader :: Handle -> TarEntryOffset -> IO Entry -- | Build a TarIndex from a sequence of tar Entries. The -- Entries are assumed to start at offset 0 within a -- file. build :: Entries e -> Either e TarIndex -- | The intermediate type used for incremental construction of a -- TarIndex. data IndexBuilder -- | The initial empty IndexBuilder. empty :: IndexBuilder -- | Add the next Entry into the IndexBuilder. addNextEntry :: Entry -> IndexBuilder -> IndexBuilder -- | Use this function if you want to skip some entries and not add them to -- the final TarIndex. skipNextEntry :: Entry -> IndexBuilder -> IndexBuilder -- | Finish accumulating Entry information and build the compact -- TarIndex lookup structure. finalise :: IndexBuilder -> TarIndex -- | Resume building an existing index -- -- A TarIndex is optimized for a highly compact and efficient -- in-memory representation. This, however, makes it read-only. If you -- have an existing TarIndex for a large file, and want to add to -- it, you can translate the TarIndex back to an -- IndexBuilder. Be aware that this is a relatively costly -- operation (linear in the size of the TarIndex), though still -- faster than starting again from scratch. -- -- This is the left inverse to finalise (modulo ordering). unfinalise :: TarIndex -> IndexBuilder -- | The TarIndex is compact in memory, and it has a similarly -- compact external representation. serialise :: TarIndex -> ByteString -- | Read the external representation back into a TarIndex. deserialise :: ByteString -> Maybe (TarIndex, ByteString) -- | This is a low level variant on hReadEntryHeader, that can be -- used to iterate through a tar file, entry by entry. -- -- It has a few differences compared to hReadEntryHeader: -- --
-- import qualified Codec.Archive.Tar as Tar -- import qualified Codec.Archive.Tar.Entry as Tar --module Codec.Archive.Tar.Entry -- | Polymorphic tar archive entry. High-level interfaces commonly work -- with GenEntry FilePath FilePath, while low-level -- ones use GenEntry TarPath LinkTarget. data GenEntry tarPath linkTarget Entry :: !tarPath -> !GenEntryContent linkTarget -> {-# UNPACK #-} !Permissions -> {-# UNPACK #-} !Ownership -> {-# UNPACK #-} !EpochTime -> !Format -> GenEntry tarPath linkTarget -- | The path of the file or directory within the archive. [entryTarPath] :: GenEntry tarPath linkTarget -> !tarPath -- | The real content of the entry. For NormalFile this includes the -- file data. An entry usually contains a NormalFile or a -- Directory. [entryContent] :: GenEntry tarPath linkTarget -> !GenEntryContent linkTarget -- | File permissions (Unix style file mode). [entryPermissions] :: GenEntry tarPath linkTarget -> {-# UNPACK #-} !Permissions -- | The user and group to which this file belongs. [entryOwnership] :: GenEntry tarPath linkTarget -> {-# UNPACK #-} !Ownership -- | The time the file was last modified. [entryTime] :: GenEntry tarPath linkTarget -> {-# UNPACK #-} !EpochTime -- | The tar format the archive is using. [entryFormat] :: GenEntry tarPath linkTarget -> !Format -- | Monomorphic tar archive entry, ready for serialization / -- deserialization. type Entry = GenEntry TarPath LinkTarget -- | Low-level function to get a native FilePath of the file or -- directory within the archive, not accounting for long names. It's -- likely that you want to apply decodeLongNames and use -- entryTarPath afterwards instead of entryPath. entryPath :: GenEntry TarPath linkTarget -> FilePath -- | Polymorphic content of a tar archive entry. High-level interfaces -- commonly work with GenEntryContent FilePath, while -- low-level ones use GenEntryContent LinkTarget. -- -- Portable archives should contain only NormalFile and -- Directory. data GenEntryContent linkTarget NormalFile :: ByteString -> {-# UNPACK #-} !FileSize -> GenEntryContent linkTarget Directory :: GenEntryContent linkTarget SymbolicLink :: !linkTarget -> GenEntryContent linkTarget HardLink :: !linkTarget -> GenEntryContent linkTarget CharacterDevice :: {-# UNPACK #-} !DevMajor -> {-# UNPACK #-} !DevMinor -> GenEntryContent linkTarget BlockDevice :: {-# UNPACK #-} !DevMajor -> {-# UNPACK #-} !DevMinor -> GenEntryContent linkTarget NamedPipe :: GenEntryContent linkTarget OtherEntryType :: {-# UNPACK #-} !TypeCode -> ByteString -> {-# UNPACK #-} !FileSize -> GenEntryContent linkTarget -- | Monomorphic content of a tar archive entry, ready for serialization / -- deserialization. type EntryContent = GenEntryContent LinkTarget -- | Ownership information for GenEntry. data Ownership Ownership :: String -> String -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Ownership -- | The owner user name. Should be set to "" if unknown. Must not -- contain non-ASCII characters. [ownerName] :: Ownership -> String -- | The owner group name. Should be set to "" if unknown. Must -- not contain non-ASCII characters. [groupName] :: Ownership -> String -- | Numeric owner user id. Should be set to 0 if unknown. [ownerId] :: Ownership -> {-# UNPACK #-} !Int -- | Numeric owner group id. Should be set to 0 if unknown. [groupId] :: Ownership -> {-# UNPACK #-} !Int -- | File size in bytes. type FileSize = Int64 -- | Permissions information for GenEntry. type Permissions = FileMode -- | The number of seconds since the UNIX epoch. type EpochTime = Int64 -- | Major device number. type DevMajor = Int -- | Minor device number. type DevMinor = Int -- | User-defined tar format expansion. type TypeCode = Char -- | There have been a number of extensions to the tar file format over the -- years. They all share the basic entry fields and put more meta-data in -- different extended headers. data Format -- | This is the classic Unix V7 tar format. It does not support owner and -- group names, just numeric Ids. It also does not support device -- numbers. V7Format :: Format -- | The "USTAR" format is an extension of the classic V7 format. It was -- later standardised by POSIX. It has some restrictions but is the most -- portable format. UstarFormat :: Format -- | The GNU tar implementation also extends the classic V7 format, though -- in a slightly different way from the USTAR format. This is the only -- format supporting long file names. GnuFormat :: Format -- | An entry with all default values except for the file name and type. It -- uses the portable USTAR/POSIX format (see UstarFormat). -- -- You can use this as a basis and override specific fields, eg: -- --
-- (emptyEntry name HardLink) { linkTarget = target }
--
simpleEntry :: tarPath -> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
-- | A tar entry for a file.
--
-- Entry fields such as file permissions and ownership have default
-- values.
--
-- You can use this as a basis and override specific fields. For example
-- if you need an executable file you could use:
--
--
-- (fileEntry name content) { fileMode = executableFileMode }
--
fileEntry :: tarPath -> ByteString -> GenEntry tarPath linkTarget
-- | A tar entry for a directory.
--
-- Entry fields such as file permissions and ownership have default
-- values.
directoryEntry :: tarPath -> GenEntry tarPath linkTarget
-- | GNU extension to store a filepath too long to fit into
-- entryTarPath as OtherEntryType 'L' with the
-- full filepath as entryContent. The next entry must contain the
-- actual data with truncated entryTarPath.
--
-- See What exactly is the GNU tar ..@LongLink "trick"?
longLinkEntry :: FilePath -> GenEntry TarPath linkTarget
-- | GNU extension to store a link target too long to fit into
-- entryTarPath as OtherEntryType 'K' with the
-- full filepath as entryContent. The next entry must contain the
-- actual data with truncated entryTarPath.
longSymLinkEntry :: FilePath -> GenEntry TarPath linkTarget
-- | rw-r--r-- for normal files
ordinaryFilePermissions :: Permissions
-- | rwxr-xr-x for executable files
executableFilePermissions :: Permissions
-- | rwxr-xr-x for directories
directoryPermissions :: Permissions
-- | Construct a tar entry based on a local file.
--
-- This sets the entry size, the data contained in the file and the
-- file's modification time. If the file is executable then that
-- information is also preserved. File ownership and detailed permissions
-- are not preserved.
--
-- -- import qualified Codec.Archive.Tar as Tar --module Codec.Archive.Tar -- | Create a new ".tar" file from a directory of files. -- -- It is equivalent to calling the standard tar program like so: -- --
-- $ tar -f tarball.tar -C base -c dir ---- -- This assumes a directory ./base/dir with files inside, eg -- ./base/dir/foo.txt. The file names inside the resulting tar -- file will be relative to dir, eg dir/foo.txt. -- -- This is a high level "all in one" operation. Since you may need -- variations on this function it is instructive to see how it is -- written. It is just: -- --
-- import qualified Data.ByteString.Lazy as BL -- -- BL.writeFile tar . Tar.write =<< Tar.pack base paths ---- -- Notes: -- -- The files and directories must not change during this operation or the -- result is not well defined. -- -- The intention of this function is to create tarballs that are portable -- between systems. It is not suitable for doing file system -- backups because file ownership and permissions are not fully -- preserved. File ownership is not preserved at all. File permissions -- are set to simple portable values: -- --
-- $ tar -x -f tarball.tar -C dir ---- -- So for example if the tarball.tar file contains -- foo/bar.txt then this will extract it to -- dir/foo/bar.txt. -- -- This is a high level "all in one" operation. Since you may need -- variations on this function it is instructive to see how it is -- written. It is just: -- --
-- import qualified Data.ByteString.Lazy as BL -- -- Tar.unpack dir . Tar.read =<< BL.readFile tar ---- -- Notes: -- -- Extracting can fail for a number of reasons. The tarball may be -- incorrectly formatted. There may be IO or permission errors. In such -- cases an exception will be thrown and extraction will not continue. -- -- Since the extraction may fail part way through it is not atomic. For -- this reason you may want to extract into an empty directory and, if -- the extraction fails, recursively delete the directory. -- -- Security: only files inside the target directory will be written. -- Tarballs containing entries that point outside of the tarball (either -- absolute paths or relative paths) will be caught and an exception will -- be thrown. extract :: FilePath -> FilePath -> IO () -- | Append new entries to a ".tar" file from a directory of -- files. -- -- This is much like create, except that all the entries are added -- to the end of an existing tar file. Or if the file does not already -- exists then it behaves the same as create. append :: FilePath -> FilePath -> [FilePath] -> IO () -- | Convert a data stream in the tar file format into an internal data -- structure. Decoding errors are reported by the Fail constructor -- of the Entries type. -- --
-- import Control.Exception (SomeException(..)) -- import Control.Applicative ((<|>)) -- -- unpackAndCheck (\x -> SomeException <$> checkEntryPortability x -- <|> SomeException <$> checkEntrySecurity x) dir entries --unpackAndCheck :: Exception e => (GenEntry FilePath FilePath -> Maybe SomeException) -> FilePath -> Entries e -> IO () -- | Polymorphic tar archive entry. High-level interfaces commonly work -- with GenEntry FilePath FilePath, while low-level -- ones use GenEntry TarPath LinkTarget. data GenEntry tarPath linkTarget -- | Monomorphic tar archive entry, ready for serialization / -- deserialization. type Entry = GenEntry TarPath LinkTarget -- | Low-level function to get a native FilePath of the file or -- directory within the archive, not accounting for long names. It's -- likely that you want to apply decodeLongNames and use -- entryTarPath afterwards instead of entryPath. entryPath :: GenEntry TarPath linkTarget -> FilePath -- | The real content of the entry. For NormalFile this includes the -- file data. An entry usually contains a NormalFile or a -- Directory. entryContent :: GenEntry tarPath linkTarget -> GenEntryContent linkTarget -- | Polymorphic content of a tar archive entry. High-level interfaces -- commonly work with GenEntryContent FilePath, while -- low-level ones use GenEntryContent LinkTarget. -- -- Portable archives should contain only NormalFile and -- Directory. data GenEntryContent linkTarget NormalFile :: ByteString -> {-# UNPACK #-} !FileSize -> GenEntryContent linkTarget Directory :: GenEntryContent linkTarget SymbolicLink :: !linkTarget -> GenEntryContent linkTarget HardLink :: !linkTarget -> GenEntryContent linkTarget CharacterDevice :: {-# UNPACK #-} !DevMajor -> {-# UNPACK #-} !DevMinor -> GenEntryContent linkTarget BlockDevice :: {-# UNPACK #-} !DevMajor -> {-# UNPACK #-} !DevMinor -> GenEntryContent linkTarget NamedPipe :: GenEntryContent linkTarget OtherEntryType :: {-# UNPACK #-} !TypeCode -> ByteString -> {-# UNPACK #-} !FileSize -> GenEntryContent linkTarget -- | Monomorphic content of a tar archive entry, ready for serialization / -- deserialization. type EntryContent = GenEntryContent LinkTarget -- | Polymorphic sequence of archive entries. High-level interfaces -- commonly work with GenEntries FilePath FilePath, -- while low-level ones use GenEntries TarPath -- LinkTarget. -- -- The point of this type as opposed to just using a list is that it -- makes the failure case explicit. We need this because the sequence of -- entries we get from reading a tarball can include errors. -- -- Converting from a list can be done with just foldr Next Done. -- Converting back into a list can be done with foldEntries -- however in that case you must be prepared to handle the Fail -- case inherent in the Entries type. -- -- The Monoid instance lets you concatenate archives or append -- entries to an archive. data GenEntries tarPath linkTarget e Next :: GenEntry tarPath linkTarget -> GenEntries tarPath linkTarget e -> GenEntries tarPath linkTarget e Done :: GenEntries tarPath linkTarget e Fail :: e -> GenEntries tarPath linkTarget e infixr 5 `Next` -- | Monomorphic sequence of archive entries, ready for serialization / -- deserialization. type Entries e = GenEntries TarPath LinkTarget e -- | This is like the standard map function on lists, but for -- Entries. It includes failure as a extra possible outcome of the -- mapping function. -- -- If your mapping function cannot fail it may be more convenient to use -- mapEntriesNoFail mapEntries :: (GenEntry tarPath linkTarget -> Either e' (GenEntry tarPath linkTarget)) -> GenEntries tarPath linkTarget e -> GenEntries tarPath linkTarget (Either e e') -- | Like mapEntries but the mapping function itself cannot fail. mapEntriesNoFail :: (GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget) -> GenEntries tarPath linkTarget e -> GenEntries tarPath linkTarget e -- | This is like the standard foldr function on lists, but for -- Entries. Compared to foldr it takes an extra function to -- account for the possibility of failure. -- -- This is used to consume a sequence of entries. For example it could be -- used to scan a tarball for problems or to collect an index of the -- contents. foldEntries :: (GenEntry tarPath linkTarget -> a -> a) -> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a -- | A foldl-like function on Entries. It either returns the final -- accumulator result, or the failure along with the intermediate -- accumulator value. foldlEntries :: (a -> GenEntry tarPath linkTarget -> a) -> a -> GenEntries tarPath linkTarget e -> Either (e, a) a -- | This is like the standard unfoldr function on lists, but for -- Entries. It includes failure as an extra possibility that the -- stepper function may return. -- -- It can be used to generate Entries from some other type. For -- example it is used internally to lazily unfold entries from a -- ByteString. unfoldEntries :: (a -> Either e (Maybe (GenEntry tarPath linkTarget, a))) -> a -> GenEntries tarPath linkTarget e -- | Translate high-level entries with POSIX FilePaths for files and -- symlinks into entries suitable for serialization by emitting -- additional OtherEntryType 'K' and -- OtherEntryType 'L' nodes. -- -- Input FilePaths must be POSIX file names, not native ones. encodeLongNames :: GenEntry FilePath FilePath -> [Entry] -- | Translate low-level entries (usually freshly deserialized) into -- high-level entries with POSIX FilePaths for files and symlinks -- by parsing and eliminating OtherEntryType 'K' and -- OtherEntryType 'L' nodes. -- -- Resolved FilePaths are still POSIX file names, not native ones. decodeLongNames :: Entries e -> GenEntries FilePath FilePath (Either e DecodeLongNamesError) -- | Errors raised by decodeLongNames. data DecodeLongNamesError -- | Two adjacent OtherEntryType 'K' nodes. TwoTypeKEntries :: DecodeLongNamesError -- | Two adjacent OtherEntryType 'L' nodes. TwoTypeLEntries :: DecodeLongNamesError -- | OtherEntryType 'K' node is not followed by a -- SymbolicLink / HardLink. NoLinkEntryAfterTypeKEntry :: DecodeLongNamesError -- | Errors that can be encountered when parsing a Tar archive. data FormatError TruncatedArchive :: FormatError ShortTrailer :: FormatError BadTrailer :: FormatError TrailingJunk :: FormatError ChecksumIncorrect :: FormatError NotTarFormat :: FormatError UnrecognisedTarFormat :: FormatError HeaderBadNumericEncoding :: FormatError