libarchive 0.2.1.2 → 1.0.0.0
raw patch · 13 files changed
+1955/−100 lines, 13 filesdep +composition-preludedep ~base
Dependencies added: composition-prelude
Dependency ranges changed: base
Files
- CHANGELOG.md +6/−0
- README.md +3/−2
- cabal.project.local +1/−1
- cbits/unpack.c +0/−60
- libarchive.cabal +13/−17
- src/Codec/Archive.hs +76/−11
- src/Codec/Archive/Foreign.hs +7/−9
- src/Codec/Archive/Foreign/Archive.chs +898/−0
- src/Codec/Archive/Foreign/ArchiveEntry.chs +595/−0
- src/Codec/Archive/Foreign/Common.hs +7/−0
- src/Codec/Archive/Pack.hs +138/−0
- src/Codec/Archive/Types.hs +123/−0
- src/Codec/Archive/Unpack.hs +88/−0
CHANGELOG.md view
@@ -1,5 +1,11 @@ # libarchive +## 1.0.0.0++ * Get rid of `cbits`+ * Add low-level FFI bindings+ * Add high-level functions for unpacking archives+ ## 0.2.1.2 * Stream from a file when using `unpackArchive`
README.md view
@@ -4,9 +4,10 @@ [](http://hackage.haskell.org/package/libarchive) [](https://hackage.haskell.org/package/libarchive) -This contains partial Haskell bindings around+This contains Haskell bindings to [libarchive](http://libarchive.org/). It was created as an alternative to [tar](http://hackage.haskell.org/package/tar), but it supports more archive formats. -Right now it only has support for decompressing archives.+It has a high-level Haskell API for creating and unpacking archives in addition+to the C API.
cabal.project.local view
@@ -1,2 +1,2 @@-constraints: libarchive +development documentation: true+max-backjumps: 40000
− cbits/unpack.c
@@ -1,60 +0,0 @@-#include <string.h>-#include <stdlib.h>-#include <archive.h>-#include <archive_entry.h>--void unpack_common(char* dirname, struct archive *a, struct archive_entry *entry) {-- while (archive_read_next_header(a, &entry) == ARCHIVE_OK || archive_read_next_header(a, &entry) == ARCHIVE_RETRY) {- const char* pre_path_name = archive_entry_pathname(entry);- size_t fp_length = strlen(dirname) + strlen(pre_path_name);- char* fp = malloc(fp_length + 1);- strcpy(fp, dirname);- strcat(fp, pre_path_name);- archive_entry_set_pathname(entry, fp);- archive_read_extract(a, entry, ARCHIVE_EXTRACT_TIME);- archive_entry_set_pathname(entry, pre_path_name);- free(fp);- archive_read_data_skip(a);- }- free(dirname);-- archive_read_free(a);--}--void unpack_from_file(char* dirname, char* filepath) {-- // allocate/initialize archive struct- struct archive *a;- struct archive_entry *entry;- a = archive_read_new();-- // autodetect archive format/compression- archive_read_support_format_all(a);-- // open from file- archive_read_open_filename(a, filepath, 10240);-- unpack_common(dirname, a, entry);--}---// Unpack a tar archive (stored in a bytestring) into a particular directory-void unpack_in_dir(char* dirname, void *buff, size_t size) {-- // step 1: allocate/initialize archive struct- struct archive *a;- struct archive_entry *entry;- a = archive_read_new();-- // autodetect archive format/compression- archive_read_support_format_all(a);-- // open from memory (bytestring)- archive_read_open_memory(a, buff, size);-- unpack_common(dirname, a, entry);--}
libarchive.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: libarchive-version: 0.2.1.2+version: 1.0.0.0 license: BSD3 license-file: LICENSE copyright: Copyright: (c) 2018-2019 Vanessa McHale@@ -9,12 +9,11 @@ bug-reports: https://github.com/vmchale/libarchive/issues synopsis: Haskell interface to libarchive description:- Partial Haskell bindings for [libarchive](https://www.libarchive.org/). Provides the ability to unpack archives.+ Haskell bindings for [libarchive](https://www.libarchive.org/). Provides the ability to unpack archives. category: Codec build-type: Simple extra-source-files: cabal.project.local- cbits/*.c extra-doc-files: README.md CHANGELOG.md @@ -22,30 +21,27 @@ type: git location: https://github.com/vmchale/libarchive -flag development- description:- Enable `-Werror`- default: False- manual: True- library exposed-modules: Codec.Archive+ Codec.Archive.Foreign+ Codec.Archive.Foreign.Archive+ Codec.Archive.Foreign.ArchiveEntry+ build-tools: c2hs >=0.19.1 pkgconfig-depends: libarchive -any- c-sources:- cbits/unpack.c hs-source-dirs: src other-modules:- Codec.Archive.Foreign+ Codec.Archive.Pack+ Codec.Archive.Unpack+ Codec.Archive.Foreign.Common+ Codec.Archive.Types default-language: Haskell2010 ghc-options: -Wall build-depends:- base >=4.3 && <5,+ base >=4.9 && <5, bytestring -any,- filepath -any-- if (flag(development) && impl(ghc >=8.0))- ghc-options: -Werror+ filepath -any,+ composition-prelude -any if impl(ghc >=8.0) ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates
src/Codec/Archive.hs view
@@ -1,27 +1,92 @@+-- | This module contains higher-level functions for working with archives in+-- Haskell. See "Codec.Archive.Foreign" for direct bindings to+-- libarchive. module Codec.Archive- ( unpackToDir+ ( -- * High-level functionality+ unpackToDir , unpackArchive+ , entriesToFile+ , entriesToFileZip+ , entriesToFile7Zip+ , entriesToBS+ , entriesToBS7zip+ , entriesToBSzip+ , readArchiveFile+ , readArchiveBS+ -- * Concrete (Haskell) types+ , Entry (..)+ , EntryContent (..)+ , Ownership (..)+ , Permissions+ , ModTime+ , Id+ , standardPermissions+ , executablePermissions ) where import Codec.Archive.Foreign+import Codec.Archive.Pack+import Codec.Archive.Types+import Codec.Archive.Unpack+import Control.Monad (void) import Data.ByteString (useAsCStringLen) import qualified Data.ByteString as BS import Foreign.C.String-import System.FilePath (pathSeparator)+import Foreign.Ptr (Ptr)+import System.IO.Unsafe (unsafePerformIO) +withArchiveRead :: (Ptr Archive -> IO a) -> Ptr Archive -> IO a+withArchiveRead fact a = do+ res <- fact a+ void $ archive_read_free a+ pure res++-- | Read an archive from a file. The format of the archive is automatically+-- detected.+readArchiveFile :: FilePath -> IO [Entry]+readArchiveFile fp =+ archiveFile fp >>= withArchiveRead hsEntries++-- | Read an archive contained in a 'BS.ByteString'. The format of the archive is+-- automatically detected.+readArchiveBS :: BS.ByteString -> [Entry]+readArchiveBS bs = unsafePerformIO $+ bsToArchive bs >>= withArchiveRead hsEntries+{-# NOINLINE readArchiveBS #-}++archiveFile :: FilePath -> IO (Ptr Archive)+archiveFile fp = withCString fp $ \cpath -> do+ a <- archive_read_new+ void $ archive_read_support_format_all a+ void $ archive_read_open_filename a cpath 10240+ pure a++-- | This is more efficient than+--+-- @+-- unpackToDir "llvm" =<< BS.readFile "llvm.tar"+-- @ unpackArchive :: FilePath -- ^ Filepath pointing to archive- -> FilePath -- ^ Filepath to unpack to+ -> FilePath -- ^ Dirctory to unpack in -> IO () unpackArchive tarFp dirFp = do- fp' <- newCString tarFp- dir' <- newCString (dirFp ++ [pathSeparator])- unpack_from_file dir' fp'+ a <- archiveFile tarFp+ unpackEntriesFp a dirFp+ void $ archive_read_free a +bsToArchive :: BS.ByteString -> IO (Ptr Archive)+bsToArchive bs = do+ a <- archive_read_new+ void $ archive_read_support_format_all a+ useAsCStringLen bs $+ \(charPtr, sz) ->+ void $ archive_read_open_memory a charPtr (fromIntegral sz)+ pure a+ unpackToDir :: FilePath -- ^ Directory to unpack in- -> BS.ByteString -- ^ 'ByteString' containing archive+ -> BS.ByteString -- ^ 'BS.ByteString' containing archive -> IO () unpackToDir fp bs = do- fp' <- newCString (fp ++ [pathSeparator])- useAsCStringLen bs $- \(charPtr, sz) ->- unpack_in_dir fp' charPtr (fromIntegral sz)+ a <- bsToArchive bs+ unpackEntriesFp a fp+ void $ archive_read_free a
src/Codec/Archive/Foreign.hs view
@@ -1,11 +1,9 @@-module Codec.Archive.Foreign ( unpack_in_dir- , unpack_from_file+-- | Everything here is stateful and hence takes place in the 'IO' monad.+--+-- Consult @archive.h@ or @archive_entry.h@ for documentation.+module Codec.Archive.Foreign ( module Codec.Archive.Foreign.ArchiveEntry+ , module Codec.Archive.Foreign.Archive ) where -import Data.Word (Word)-import Foreign.C.String-import Foreign.C.Types-import Foreign.Ptr--foreign import ccall unsafe unpack_in_dir :: CString -> Ptr CChar -> Word -> IO ()-foreign import ccall unsafe unpack_from_file :: CString -> CString -> IO ()+import Codec.Archive.Foreign.ArchiveEntry+import Codec.Archive.Foreign.Archive
+ src/Codec/Archive/Foreign/Archive.chs view
@@ -0,0 +1,898 @@+-- | This module corresponds to @archive.h@+module Codec.Archive.Foreign.Archive ( -- * Direct bindings (read)+ archive_read_new+ , archive_read_data_skip+ , archive_read_data+ , archive_read_data_block+ , archive_read_free+ , archive_read_extract+ , archive_read_open_filename+ , archive_read_open_filename_w+ , archive_read_support_filter_all+ , archive_read_support_filter_bzip2+ , archive_read_support_filter_compress+ , archive_read_support_filter_gzip+ , archive_read_support_filter_grzip+ , archive_read_support_filter_lrzip+ , archive_read_support_filter_lz4+ , archive_read_support_filter_lzip+ , archive_read_support_filter_lzma+ , archive_read_support_filter_lzop+ , archive_read_support_filter_none+ , archive_read_support_filter_program+ , archive_read_support_filter_program_signature+ , archive_read_support_filter_rpm+ , archive_read_support_filter_uu+ , archive_read_support_filter_xz+ , archive_read_support_format_7zip+ , archive_read_support_format_all+ , archive_read_support_format_ar+ , archive_read_add_passphrase+ , archive_read_set_passphrase_callback+ , archive_read_extract2+ , archive_read_extract_set_progress_callback+ , archive_read_extract_set_skip_file+ , archive_read_close+ , archive_read_support_format_by_code+ , archive_read_support_format_cab+ , archive_read_support_format_cpio+ , archive_read_support_format_empty+ , archive_read_support_format_gnutar+ , archive_read_support_format_iso9660+ , archive_read_support_format_lha+ , archive_read_support_format_mtree+ , archive_read_support_format_rar+ , archive_read_support_format_raw+ , archive_read_support_format_tar+ , archive_read_support_format_warc+ , archive_read_support_format_xar+ , archive_read_support_format_zip+ , archive_read_support_format_zip_streamable+ , archive_read_support_format_zip_seekable+ , archive_read_set_format+ , archive_read_append_filter+ , archive_read_append_filter_program+ , archive_read_append_filter_program_signature+ , archive_read_set_open_callback+ , archive_read_set_read_callback+ , archive_read_set_seek_callback+ , archive_read_set_skip_callback+ , archive_read_set_close_callback+ , archive_read_set_switch_callback+ , archive_read_set_callback_data+ , archive_read_set_callback_data2+ , archive_read_add_callback_data+ , archive_read_append_callback_data+ , archive_read_prepend_callback_data+ , archive_read_open1+ , archive_read_open+ , archive_read_open2+ , archive_read_open_filenames+ , archive_read_open_memory+ , archive_read_open_memory2+ , archive_read_open_fd+ , archive_read_next_header+ , archive_read_next_header2+ , archive_read_header_position+ , archiveReadHasEncryptedEntries+ , archive_read_format_capabilities+ , archive_seek_data+ , archive_read_data_into_fd+ , archive_read_set_format_option+ , archive_read_set_filter_option+ , archive_read_set_option+ , archive_read_set_options+ , archive_read_disk_new+ , archive_read_disk_set_symlink_logical+ , archive_read_disk_set_symlink_physical+ , archive_read_disk_set_symlink_hybrid+ , archive_read_disk_entry_from_file+ , archive_read_disk_gname+ , archive_read_disk_uname+ , archive_read_disk_set_standard_lookup+ , archive_read_disk_set_gname_lookup+ , archive_read_disk_set_uname_lookup+ , archive_read_disk_open+ , archive_read_disk_open_w+ , archive_read_disk_descend+ , archiveReadDiskCanDescend+ , archive_read_disk_current_filesystem+ , archiveReadDiskCurrentFilesystemIsSynthetic+ , archiveReadDiskCurrentFilesystemIsRemote+ , archive_read_disk_set_atime_restored+ , archive_read_disk_set_behavior+ , archive_read_disk_set_matching+ , archive_read_disk_set_metadata_filter_callback+ -- * Direct bindings (write)+ , archive_write_set_bytes_per_block+ , archive_write_get_bytes_per_block+ , archive_write_set_bytes_in_last_block+ , archive_write_get_bytes_in_last_block+ , archive_write_set_skip_file+ , archive_write_add_filter+ , archive_write_add_filter_by_name+ , archive_write_add_filter_b64encode+ , archive_write_add_filter_bzip2+ , archive_write_add_filter_compress+ , archive_write_add_filter_grzip+ , archive_write_add_filter_gzip+ , archive_write_add_filter_lrzip+ , archive_write_add_filter_lz4+ , archive_write_add_filter_lzip+ , archive_write_add_filter_lzma+ , archive_write_add_filter_lzop+ , archive_write_add_filter_none+ , archive_write_add_filter_program+ , archive_write_add_filter_uuencode+ , archive_write_add_filter_xz+ , archive_write_data+ , archive_write_new+ , archive_write_free+ , archive_write_set_format_pax_restricted+ , archive_write_header+ , archive_write_set_format+ , archive_write_set_format_by_name+ , archive_write_set_format_7zip+ , archive_write_set_format_ar_bsd+ , archive_write_set_format_ar_svr4+ , archive_write_set_format_cpio+ , archive_write_set_format_cpio_newc+ , archive_write_set_format_gnutar+ , archive_write_set_format_iso9660+ , archive_write_set_format_mtree+ , archive_write_set_format_mtree_classic+ , archive_write_set_format_pax+ , archive_write_set_format_raw+ , archive_write_set_format_shar+ , archive_write_set_format_shar_dump+ , archive_write_set_format_ustar+ , archive_write_set_format_v7tar+ , archive_write_set_format_warc+ , archive_write_set_format_xar+ , archive_write_set_format_zip+ , archive_write_set_format_filter_by_ext+ , archive_write_set_format_filter_by_ext_def+ , archive_write_zip_set_compression_deflate+ , archive_write_zip_set_compression_store+ , archive_write_open+ , archive_write_open_fd+ , archive_write_open_filename+ , archive_write_open_filename_w+ , archive_write_open_memory+ , archive_write_data_block+ , archive_write_finish_entry+ , archive_write_close+ , archive_write_fail+ , archive_write_set_format_option+ , archive_write_set_filter_option+ , archive_write_set_option+ , archive_write_set_options+ , archive_write_set_passphrase+ , archive_write_set_passphrase_callback+ , archive_write_disk_new+ , archive_write_disk_set_skip_file+ , archive_write_disk_set_options+ , archive_write_disk_set_standard_lookup+ , archive_write_disk_set_group_lookup+ , archive_write_disk_set_user_lookup+ , archive_write_disk_gid+ , archive_write_disk_uid+ -- * Direct bindings (archive error)+ , archive_errno+ , archive_error_string+ , archive_format_name+ , archive_format+ , archive_clear_error+ , archive_set_error+ , archive_copy_error+ , archive_file_count+ -- * Direct bindings (archive match)+ , archive_match_new+ , archive_match_free+ , archiveMatchExcluded+ , archiveMatchPathExcluded+ , archive_match_exclude_pattern+ , archive_match_exclude_pattern_w+ , archiveMatchExcludePatternFromFile+ , archiveMatchExcludePatternFromFileW+ , archive_match_include_pattern+ , archive_match_include_pattern_w+ , archiveMatchIncludePatternFromFile+ , archiveMatchIncludePatternFromFileW+ , archive_match_path_unmatched_inclusions+ , archive_match_path_unmatched_inclusions_next+ , archive_match_path_unmatched_inclusions_next_w+ , archiveMatchTimeExcluded+ , archive_match_include_time+ , archive_match_include_date+ , archive_match_include_date_w+ , archive_match_include_file_time+ , archive_match_include_file_time_w+ , archive_match_exclude_entry+ , archiveMatchOwnerExcluded+ , archive_match_include_uid+ , archive_match_include_gid+ , archive_match_include_uname+ , archive_match_include_uname_w+ , archive_match_include_gname+ , archive_match_include_gname_w+ -- * Direct bindings (version\/filter\/miscellaneous)+ , archive_version_number+ , archive_version_string+ , archive_version_details+ , archive_free+ , archive_filter_count+ , archive_filter_bytes+ , archive_filter_code+ , archive_filter_name+ -- * Version macros+ , archiveVersionNumber+ , archiveVersionOnlyString+ , archiveVersionString+ -- * Capability macros+ , archiveReadFormatCapsNone+ , archiveReadFormatCapsEncryptData+ , archiveReadFormatCapsEncryptMetadata+ -- * Header read macros+ , archiveOk+ , archiveEOF+ , archiveRetry+ , archiveWarn+ , archiveFailed+ , archiveFatal+ -- * Time matching macros+ , archiveMatchMTime+ , archiveMatchCTime+ , archiveMatchNewer+ , archiveMatchOlder+ , archiveMatchEqual+ -- * Entry flags+ , archiveExtractOwner+ , archiveExtractPerm+ , archiveExtractTime+ , archiveExtractNoOverwrite+ , archiveExtractUnlink+ , archiveExtractACL+ , archiveExtractFFlags+ , archiveExtractXattr+ , archiveExtractSecureSymlinks+ , archiveExtractSecureNoDotDot+ , archiveExtractNoAutodir+ , archiveExtractSparse+ , archiveExtractMacMetadata+ , archiveExtractNoHfsCompression+ , archiveExtractHfsCompressionForced+ , archiveExtractSecureNoAbsolutePaths+ , archiveExtractClearNoChangeFFlags+ -- * Filters+ , archiveFilterNone+ , archiveFilterGzip+ , archiveFilterBzip2+ , archiveFilterCompress+ , archiveFilterProgram+ , archiveFilterLzma+ , archiveFilterXz+ , archiveFilterUu+ , archiveFilterRpm+ , archiveFilterLzip+ , archiveFilterLrzip+ , archiveFilterLzop+ , archiveFilterGrzip+ , archiveFilterLz4+ -- * Formats+ , archiveFormatCpio+ , archiveFormatShar+ , archiveFormatTar+ , archiveFormatIso9660+ , archiveFormatZip+ , archiveFormatEmpty+ , archiveFormatAr+ , archiveFormatMtree+ , archiveFormatRaw+ , archiveFormatXar+ , archiveFormatLha+ , archiveFormatCab+ , archiveFormatRar+ , archiveFormat7zip+ , archiveFormatWarc+ -- * Read disk flags+ , archiveReadDiskRestoreATime+ , archiveReadDiskHonorNoDump+ , archiveReadDiskMacCopyFile+ , archiveReadDiskNoTraverseMounts+ , archiveReadDiskNoXattr+ -- * Abstract types+ , Archive+ -- * Haskell types+ , ArchiveEncryption (..)+ -- * Lower-level API types+ , ArchiveError+ , Flags+ , ArchiveFilter+ , ArchiveFormat+ , ArchiveCapabilities+ , ReadDiskFlags+ , TimeFlag+ -- * Callback types+ , ArchiveReadCallback+ , ArchiveSkipCallback+ , ArchiveSeekCallback+ , ArchiveWriteCallback+ , ArchiveOpenCallback+ , ArchiveCloseCallback+ , ArchiveSwitchCallback+ , ArchivePassphraseCallback+ -- * Callback constructors+ , mkReadCallback+ , mkSkipCallback+ , mkSeekCallback+ , mkWriteCallback+ , mkOpenCallback+ , mkCloseCallback+ , mkSwitchCallback+ , mkPassphraseCallback+ , mkWriteLookup+ , mkReadLookup+ , mkCleanup+ , mkMatch+ , mkFilter+ ) where++import Codec.Archive.Foreign.Common+import Control.Composition ((.*), (.**))+import Data.Bits (Bits (..))+import Data.Int (Int64)+import Codec.Archive.Types+import Foreign.C.String+import Foreign.C.Types+import Foreign.Ptr (FunPtr, Ptr)+import System.Posix.Types (Fd (..))++-- Miscellaneous+foreign import ccall archive_version_number :: CInt+foreign import ccall archive_version_string :: CString+foreign import ccall archive_version_details :: CString++-- destructors: use "dynamic" instead of "wrapper" (but we don't want that)+-- callbacks+foreign import ccall "wrapper" mkReadCallback :: ArchiveReadCallback a b -> IO (FunPtr (ArchiveReadCallback a b))+foreign import ccall "wrapper" mkSkipCallback :: ArchiveSkipCallback a -> IO (FunPtr (ArchiveSkipCallback a))+foreign import ccall "wrapper" mkSeekCallback :: ArchiveSeekCallback a -> IO (FunPtr (ArchiveSeekCallback a))+foreign import ccall "wrapper" mkWriteCallback :: ArchiveWriteCallback a b -> IO (FunPtr (ArchiveWriteCallback a b))+foreign import ccall "wrapper" mkOpenCallback :: ArchiveOpenCallback a -> IO (FunPtr (ArchiveOpenCallback a))+foreign import ccall "wrapper" mkCloseCallback :: ArchiveCloseCallback a -> IO (FunPtr (ArchiveCloseCallback a))+foreign import ccall "wrapper" mkSwitchCallback :: ArchiveSwitchCallback a b -> IO (FunPtr (ArchiveSwitchCallback a b))+foreign import ccall "wrapper" mkPassphraseCallback :: ArchivePassphraseCallback a -> IO (FunPtr (ArchivePassphraseCallback a))++foreign import ccall "wrapper" mkWriteLookup :: (Ptr a -> CString -> Int64 -> IO Int64) -> IO (FunPtr (Ptr a -> CString -> Int64 -> IO Int64))+foreign import ccall "wrapper" mkReadLookup :: (Ptr a -> Int64 -> IO CString) -> IO (FunPtr (Ptr a -> Int64 -> IO CString))+foreign import ccall "wrapper" mkCleanup :: (Ptr a -> IO ()) -> IO (FunPtr (Ptr a -> IO ()))++foreign import ccall "wrapper" mkMatch :: (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO ()) -> IO (FunPtr (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO ()))+foreign import ccall "wrapper" preMkFilter :: (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO CInt) -> IO (FunPtr (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO CInt))++mkFilter :: (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO Bool) -> IO (FunPtr (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO CInt))+mkFilter f = let f' = fmap boolToInt .** f in preMkFilter f'++boolToInt :: Integral a => Bool -> a+boolToInt False = 0+boolToInt True = 1++type ArchiveReadCallback a b = Ptr Archive -> Ptr a -> Ptr (Ptr b) -> IO CSize+type ArchiveSkipCallback a = Ptr Archive -> Ptr a -> Int64 -> IO Int64+type ArchiveSeekCallback a = Ptr Archive -> Ptr a -> Int64 -> CInt -> IO Int64+type ArchiveWriteCallback a b = Ptr Archive -> Ptr a -> Ptr b -> CSize -> IO CSize+type ArchiveOpenCallback a = Ptr Archive -> Ptr a -> IO ArchiveError+type ArchiveCloseCallback a = Ptr Archive -> Ptr a -> IO ArchiveError+type ArchiveSwitchCallback a b = Ptr Archive -> Ptr a -> Ptr b -> IO ArchiveError+type ArchivePassphraseCallback a = Ptr Archive -> Ptr a -> IO CString++-- Archive read+foreign import ccall unsafe archive_read_new :: IO (Ptr Archive)+foreign import ccall unsafe archive_read_support_filter_all :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_bzip2 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_compress :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_gzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_grzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_lrzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_lz4 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_lzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_lzma :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_lzop :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_none :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_program :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_program_signature :: Ptr Archive -> CString -> CString -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_rpm :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_uu :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_filter_xz :: Ptr Archive -> IO ArchiveError+-- foreign import ccall unsafe archive_read_support_filter_zstd :: Ptr Archive -> IO ArchiveError++foreign import ccall unsafe archive_read_support_format_7zip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_all :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_ar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_by_code :: Ptr Archive -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_cab :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_cpio :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_empty :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_gnutar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_iso9660 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_lha :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_mtree :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_rar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_raw :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_tar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_warc :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_xar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_zip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_zip_streamable :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_support_format_zip_seekable :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_set_format :: Ptr Archive -> ArchiveFormat -> IO ArchiveError+foreign import ccall unsafe archive_read_append_filter :: Ptr Archive -> ArchiveFilter -> IO ArchiveError+foreign import ccall unsafe archive_read_append_filter_program :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_append_filter_program_signature :: Ptr Archive -> CString -> Ptr a -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_set_open_callback :: Ptr Archive -> FunPtr (ArchiveOpenCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_read_callback :: Ptr Archive -> FunPtr (ArchiveOpenCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_seek_callback :: Ptr Archive -> FunPtr (ArchiveOpenCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_skip_callback :: Ptr Archive -> FunPtr (ArchiveSkipCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_close_callback :: Ptr Archive -> FunPtr (ArchiveCloseCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_switch_callback :: Ptr Archive -> FunPtr (ArchiveSwitchCallback a b) -> IO ArchiveError+foreign import ccall unsafe archive_read_set_callback_data :: Ptr Archive -> Ptr a -> IO ArchiveError+foreign import ccall unsafe archive_read_set_callback_data2 :: Ptr Archive -> Ptr a -> CUInt -> IO ArchiveError+foreign import ccall unsafe archive_read_add_callback_data :: Ptr Archive -> Ptr a -> CUInt -> IO ArchiveError+foreign import ccall unsafe archive_read_append_callback_data :: Ptr Archive -> Ptr a -> IO ArchiveError+foreign import ccall unsafe archive_read_prepend_callback_data :: Ptr Archive -> Ptr a -> IO ArchiveError+foreign import ccall unsafe archive_read_open1 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_open :: Ptr Archive -> Ptr a -> FunPtr (ArchiveOpenCallback a) -> FunPtr (ArchiveReadCallback a b) -> FunPtr (ArchiveCloseCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_open2 :: Ptr Archive -> Ptr a -> FunPtr (ArchiveOpenCallback a) -> FunPtr (ArchiveReadCallback a b) -> FunPtr (ArchiveSkipCallback a) -> FunPtr (ArchiveCloseCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_read_open_filename :: Ptr Archive -> CString -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_open_filenames :: Ptr Archive -> Ptr CString -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_open_filename_w :: Ptr Archive -> CWString -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_open_memory :: Ptr Archive -> Ptr CChar -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_open_memory2 :: Ptr Archive -> Ptr a -> CSize -> CSize -> IO ArchiveError+foreign import ccall unsafe archive_read_open_fd :: Ptr Archive -> Fd -> CSize -> IO ArchiveError+-- foreign import ccall unsafe archive_read_open_FILE +foreign import ccall unsafe archive_read_next_header :: Ptr Archive -> Ptr (Ptr ArchiveEntry) -> IO ArchiveError+foreign import ccall unsafe archive_read_next_header2 :: Ptr Archive -> Ptr ArchiveEntry -> IO ArchiveError+foreign import ccall unsafe archive_read_header_position :: Ptr Archive -> IO Int64+foreign import ccall unsafe archive_read_has_encrypted_entries :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_read_format_capabilities :: Ptr Archive -> IO ArchiveCapabilities++foreign import ccall unsafe archive_read_data :: Ptr Archive -> Ptr a -> CSize -> IO CSize+foreign import ccall unsafe archive_seek_data :: Ptr Archive -> Int64 -> CInt -> IO Int64+foreign import ccall unsafe archive_read_data_block :: Ptr Archive -> Ptr (Ptr a) -> Ptr CSize -> Ptr Int64 -> IO ArchiveError+foreign import ccall unsafe archive_read_data_skip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_data_into_fd :: Ptr Archive -> Fd -> IO ArchiveError++foreign import ccall unsafe archive_read_set_format_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_set_filter_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_set_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_set_options :: Ptr Archive -> CString -> IO ArchiveError++foreign import ccall unsafe archive_read_add_passphrase :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_set_passphrase_callback :: Ptr Archive -> Ptr a -> FunPtr (ArchivePassphraseCallback a) -> IO ArchiveError++foreign import ccall unsafe archive_read_extract :: Ptr Archive -> Ptr ArchiveEntry -> Flags -> IO ArchiveError+foreign import ccall unsafe archive_read_extract2 :: Ptr Archive -> Ptr ArchiveEntry -> Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_extract_set_progress_callback :: Ptr Archive -> (FunPtr (Ptr a -> IO ())) -> Ptr a -> IO ()+foreign import ccall unsafe archive_read_extract_set_skip_file :: Ptr Archive -> Int64 -> Int64 -> IO ()++foreign import ccall unsafe archive_read_close :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_free :: Ptr Archive -> IO ArchiveError++-- Archive write+foreign import ccall unsafe archive_write_new :: IO (Ptr Archive)+foreign import ccall unsafe archive_write_set_bytes_per_block :: Ptr Archive -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_write_get_bytes_per_block :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_write_set_bytes_in_last_block :: Ptr Archive -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_write_get_bytes_in_last_block :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_write_set_skip_file :: Ptr Archive -> Int64 -> Int64 -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter :: Ptr Archive -> ArchiveFilter -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_by_name :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_b64encode :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_bzip2 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_compress :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_grzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_gzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_lrzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_lz4 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_lzip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_lzma :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_lzop :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_none :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_program :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_uuencode :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_add_filter_xz :: Ptr Archive -> IO ArchiveError+-- foreign import ccall unsafe archive_write_add_filter_zstd :: Ptr Archive -> IO ArchiveError++foreign import ccall unsafe archive_write_set_format :: Ptr Archive -> ArchiveFormat -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_by_name :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_7zip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_ar_bsd :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_ar_svr4 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_cpio :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_cpio_newc :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_gnutar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_iso9660 :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_mtree :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_mtree_classic :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_pax :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_pax_restricted :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_raw :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_shar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_shar_dump :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_ustar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_v7tar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_warc :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_xar :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_zip :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_filter_by_ext :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_format_filter_by_ext_def :: Ptr Archive -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_zip_set_compression_deflate :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_zip_set_compression_store :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_open :: Ptr Archive -> Ptr a -> FunPtr (ArchiveOpenCallback a) -> FunPtr (ArchiveWriteCallback a b) -> FunPtr (ArchiveCloseCallback a) -> IO ArchiveError+foreign import ccall unsafe archive_write_open_fd :: Ptr Archive -> Fd -> IO ArchiveError+foreign import ccall unsafe archive_write_open_filename :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_open_filename_w :: Ptr Archive -> CWString -> IO ArchiveError+-- foreign import ccall unsafe archive_write_open_FILE+foreign import ccall unsafe archive_write_open_memory :: Ptr Archive -> Ptr a -> CSize -> Ptr CSize -> IO ArchiveError++foreign import ccall unsafe archive_write_header :: Ptr Archive -> Ptr ArchiveEntry -> IO ArchiveError+foreign import ccall unsafe archive_write_data :: Ptr Archive -> Ptr a -> CSize -> IO CSize++foreign import ccall unsafe archive_write_data_block :: Ptr Archive -> Ptr a -> CSize -> Int64 -> IO ArchiveError++foreign import ccall unsafe archive_write_finish_entry :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_close :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_fail :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_free :: Ptr Archive -> IO ArchiveError++foreign import ccall unsafe archive_write_set_format_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_filter_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_option :: Ptr Archive -> CString -> CString -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_options :: Ptr Archive -> CString -> IO ArchiveError++foreign import ccall unsafe archive_write_set_passphrase :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_write_set_passphrase_callback :: Ptr Archive -> Ptr a -> FunPtr (ArchivePassphraseCallback a) -> IO ArchiveError++foreign import ccall unsafe archive_write_disk_new :: IO (Ptr Archive)+foreign import ccall unsafe archive_write_disk_set_skip_file :: Ptr Archive -> Int64 -> Int64 -> IO ArchiveError+foreign import ccall unsafe archive_write_disk_set_options :: Ptr Archive -> Flags -> IO ArchiveError++foreign import ccall unsafe archive_write_disk_set_standard_lookup :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_write_disk_set_group_lookup :: Ptr Archive -> Ptr a -> FunPtr (Ptr a -> CString -> Int64 -> IO Int64) -> FunPtr (Ptr a -> IO ()) -> IO ArchiveError+foreign import ccall unsafe archive_write_disk_set_user_lookup :: Ptr Archive -> Ptr a -> FunPtr (Ptr a -> CString -> Int64 -> IO Int64) -> FunPtr (Ptr a -> IO ()) -> IO ArchiveError+foreign import ccall unsafe archive_write_disk_gid :: Ptr Archive -> CString -> Int64 -> IO Int64+foreign import ccall unsafe archive_write_disk_uid :: Ptr Archive -> CString -> Int64 -> IO Int64++foreign import ccall unsafe archive_read_disk_new :: IO (Ptr Archive)+foreign import ccall unsafe archive_read_disk_set_symlink_logical :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_symlink_physical :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_symlink_hybrid :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_entry_from_file :: Ptr Archive -> Ptr ArchiveEntry -> Fd -> Ptr Stat -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_gname :: Ptr Archive -> Int64 -> IO CString+foreign import ccall unsafe archive_read_disk_uname :: Ptr Archive -> Int64 -> IO CString+foreign import ccall unsafe archive_read_disk_set_standard_lookup :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_gname_lookup :: Ptr Archive -> Ptr a -> FunPtr (Ptr a -> Int64 -> IO CString) -> FunPtr (Ptr a -> IO ()) -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_uname_lookup :: Ptr Archive -> Ptr a -> FunPtr (Ptr a -> Int64 -> IO CString) -> FunPtr (Ptr a -> IO ()) -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_open :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_open_w :: Ptr Archive -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_descend :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_can_descend :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_read_disk_current_filesystem :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_read_disk_current_filesystem_is_synthetic :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_read_disk_current_filesystem_is_remote :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_read_disk_set_atime_restored :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_behavior :: Ptr Archive -> ReadDiskFlags -> IO ArchiveError++foreign import ccall unsafe archive_read_disk_set_matching :: Ptr Archive -> Ptr Archive -> FunPtr (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO ()) -> Ptr a -> IO ArchiveError+foreign import ccall unsafe archive_read_disk_set_metadata_filter_callback :: Ptr Archive -> FunPtr (Ptr Archive -> Ptr a -> Ptr ArchiveEntry -> IO CInt) -> Ptr a -> IO ArchiveError++foreign import ccall unsafe archive_free :: Ptr Archive -> IO ArchiveError++foreign import ccall unsafe archive_filter_count :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_filter_bytes :: Ptr Archive -> CInt -> Int64+foreign import ccall unsafe archive_filter_code :: Ptr Archive -> CInt -> IO Int+foreign import ccall unsafe archive_filter_name :: Ptr Archive -> CInt -> IO CString++foreign import ccall unsafe archive_errno :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_error_string :: Ptr Archive -> IO CString+foreign import ccall unsafe archive_format_name :: Ptr Archive -> IO CString+foreign import ccall unsafe archive_format :: Ptr Archive -> IO ArchiveFormat+foreign import ccall unsafe archive_clear_error :: Ptr Archive -> IO ()+foreign import ccall unsafe archive_set_error :: Ptr Archive -> CInt -> CString -> IO () -- TODO: variadic lol+foreign import ccall unsafe archive_copy_error :: Ptr Archive -> Ptr Archive -> IO ()+foreign import ccall unsafe archive_file_count :: Ptr Archive -> IO CInt++foreign import ccall unsafe archive_match_new :: Ptr Archive+foreign import ccall unsafe archive_match_free :: Ptr Archive -> IO ArchiveError+foreign import ccall unsafe archive_match_excluded :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_match_path_excluded :: Ptr Archive -> Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_match_exclude_pattern :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_exclude_pattern_w :: Ptr Archive -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_exclude_pattern_from_file :: Ptr Archive -> CString -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_match_exclude_pattern_from_file_w :: Ptr Archive -> CWString -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_match_include_pattern :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_pattern_w :: Ptr Archive -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_pattern_from_file :: Ptr Archive -> CString -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_match_include_pattern_from_file_w :: Ptr Archive -> CString -> CInt -> IO ArchiveError+foreign import ccall unsafe archive_match_path_unmatched_inclusions :: Ptr Archive -> IO CInt+foreign import ccall unsafe archive_match_path_unmatched_inclusions_next :: Ptr Archive -> Ptr CString -> IO ArchiveError+foreign import ccall unsafe archive_match_path_unmatched_inclusions_next_w :: Ptr Archive -> Ptr CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_time_excluded :: Ptr Archive -> Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_match_include_time :: Ptr Archive -> TimeFlag -> CTime -> CLong -> IO ArchiveError+foreign import ccall unsafe archive_match_include_date :: Ptr Archive -> TimeFlag -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_date_w :: Ptr Archive -> TimeFlag -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_file_time :: Ptr Archive -> TimeFlag -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_file_time_w :: Ptr Archive -> TimeFlag -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_exclude_entry :: Ptr Archive -> TimeFlag -> Ptr ArchiveEntry -> IO ArchiveError+foreign import ccall unsafe archive_match_owner_excluded :: Ptr Archive -> Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_match_include_gid :: Ptr Archive -> Id -> IO ArchiveError+foreign import ccall unsafe archive_match_include_uid :: Ptr Archive -> Id -> IO ArchiveError+foreign import ccall unsafe archive_match_include_uname :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_uname_w :: Ptr Archive -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_gname :: Ptr Archive -> CString -> IO ArchiveError+foreign import ccall unsafe archive_match_include_gname_w :: Ptr Archive -> CWString -> IO ArchiveError++#include <archive.h>++archiveVersionNumber :: Int+archiveVersionNumber = {# const ARCHIVE_VERSION_NUMBER #}++archiveVersionOnlyString :: String+archiveVersionOnlyString = {# const ARCHIVE_VERSION_ONLY_STRING #}++archiveVersionString :: String+archiveVersionString = {# const ARCHIVE_VERSION_STRING #}++-- TODO: make ArchiveError a sum type+archiveOk :: ArchiveError+archiveOk = ArchiveError {# const ARCHIVE_OK #}++archiveEOF :: ArchiveError+archiveEOF = ArchiveError {# const ARCHIVE_EOF #}++archiveRetry :: ArchiveError+archiveRetry = ArchiveError ({# const ARCHIVE_RETRY #})++archiveWarn :: ArchiveError+archiveWarn = ArchiveError ({# const ARCHIVE_WARN #})++archiveFailed :: ArchiveError+archiveFailed = ArchiveError ({# const ARCHIVE_FAILED #})++archiveFatal :: ArchiveError+archiveFatal = ArchiveError ({# const ARCHIVE_FATAL #})++-- Archive filter+archiveFilterNone :: ArchiveFilter+archiveFilterNone = ArchiveFilter {# const ARCHIVE_FILTER_NONE #}++archiveFilterGzip :: ArchiveFilter+archiveFilterGzip = ArchiveFilter {# const ARCHIVE_FILTER_GZIP #}++archiveFilterBzip2 :: ArchiveFilter+archiveFilterBzip2 = ArchiveFilter {# const ARCHIVE_FILTER_BZIP2 #}++archiveFilterCompress :: ArchiveFilter+archiveFilterCompress = ArchiveFilter {# const ARCHIVE_FILTER_COMPRESS #}++archiveFilterProgram :: ArchiveFilter+archiveFilterProgram = ArchiveFilter {# const ARCHIVE_FILTER_PROGRAM #}++archiveFilterLzma :: ArchiveFilter+archiveFilterLzma = ArchiveFilter {# const ARCHIVE_FILTER_LZMA #}++archiveFilterXz :: ArchiveFilter+archiveFilterXz = ArchiveFilter {# const ARCHIVE_FILTER_XZ #}++archiveFilterUu :: ArchiveFilter+archiveFilterUu = ArchiveFilter {# const ARCHIVE_FILTER_UU #}++archiveFilterRpm :: ArchiveFilter+archiveFilterRpm = ArchiveFilter {# const ARCHIVE_FILTER_RPM #}++archiveFilterLzip :: ArchiveFilter+archiveFilterLzip = ArchiveFilter {# const ARCHIVE_FILTER_LZIP #}++archiveFilterLrzip :: ArchiveFilter+archiveFilterLrzip = ArchiveFilter {# const ARCHIVE_FILTER_LRZIP #}++archiveFilterLzop :: ArchiveFilter+archiveFilterLzop = ArchiveFilter {# const ARCHIVE_FILTER_LZOP #}++archiveFilterGrzip :: ArchiveFilter+archiveFilterGrzip = ArchiveFilter {# const ARCHIVE_FILTER_GRZIP #}++archiveFilterLz4 :: ArchiveFilter+archiveFilterLz4 = ArchiveFilter {# const ARCHIVE_FILTER_LZ4 #}++-- Extraction flags+archiveExtractOwner :: Flags+archiveExtractOwner = Flags {# const ARCHIVE_EXTRACT_OWNER #}++archiveExtractPerm :: Flags+archiveExtractPerm = Flags {# const ARCHIVE_EXTRACT_PERM #}++archiveExtractTime :: Flags+archiveExtractTime = Flags {# const ARCHIVE_EXTRACT_TIME #}++archiveExtractNoOverwrite :: Flags+archiveExtractNoOverwrite = Flags {# const ARCHIVE_EXTRACT_NO_OVERWRITE #}++archiveExtractUnlink :: Flags+archiveExtractUnlink = Flags {# const ARCHIVE_EXTRACT_UNLINK #}++archiveExtractACL :: Flags+archiveExtractACL = Flags {# const ARCHIVE_EXTRACT_ACL #}++archiveExtractFFlags :: Flags+archiveExtractFFlags = Flags {# const ARCHIVE_EXTRACT_FFLAGS #}++archiveExtractXattr :: Flags+archiveExtractXattr = Flags {# const ARCHIVE_EXTRACT_XATTR #}++archiveExtractSecureSymlinks :: Flags+archiveExtractSecureSymlinks = Flags {# const ARCHIVE_EXTRACT_SECURE_SYMLINKS #}++archiveExtractSecureNoDotDot :: Flags+archiveExtractSecureNoDotDot = Flags {# const ARCHIVE_EXTRACT_SECURE_NODOTDOT #}++archiveExtractNoAutodir :: Flags+archiveExtractNoAutodir = Flags {# const ARCHIVE_EXTRACT_NO_AUTODIR #}++-- archiveExtractNoOverwriteNewer :: Flags+-- archiveExtractNoOverwriteNewer = Flags {# const ARCHIVE_NO_OVERWRITE_NEWER #}++archiveExtractSparse :: Flags+archiveExtractSparse = Flags {# const ARCHIVE_EXTRACT_SPARSE #}++archiveExtractMacMetadata :: Flags+archiveExtractMacMetadata = Flags {# const ARCHIVE_EXTRACT_MAC_METADATA #}++archiveExtractNoHfsCompression :: Flags+archiveExtractNoHfsCompression = Flags {# const ARCHIVE_EXTRACT_NO_HFS_COMPRESSION #}++archiveExtractHfsCompressionForced :: Flags+archiveExtractHfsCompressionForced = Flags {# const ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED #}++archiveExtractSecureNoAbsolutePaths :: Flags+archiveExtractSecureNoAbsolutePaths = Flags {# const ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS #}++archiveExtractClearNoChangeFFlags :: Flags+archiveExtractClearNoChangeFFlags = Flags {# const ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS #}++archiveFormatCpio :: ArchiveFormat+archiveFormatCpio = ArchiveFormat {# const ARCHIVE_FORMAT_CPIO #}++archiveFormatShar :: ArchiveFormat+archiveFormatShar = ArchiveFormat {# const ARCHIVE_FORMAT_SHAR #}++archiveFormatTar :: ArchiveFormat+archiveFormatTar = ArchiveFormat {# const ARCHIVE_FORMAT_TAR #}++archiveFormatIso9660 :: ArchiveFormat+archiveFormatIso9660 = ArchiveFormat {# const ARCHIVE_FORMAT_ISO9660 #}++archiveFormatZip :: ArchiveFormat+archiveFormatZip = ArchiveFormat {# const ARCHIVE_FORMAT_ZIP #}++archiveFormatEmpty :: ArchiveFormat+archiveFormatEmpty = ArchiveFormat {# const ARCHIVE_FORMAT_EMPTY #}++archiveFormatAr :: ArchiveFormat+archiveFormatAr = ArchiveFormat {# const ARCHIVE_FORMAT_AR #}++archiveFormatMtree :: ArchiveFormat+archiveFormatMtree = ArchiveFormat {# const ARCHIVE_FORMAT_MTREE #}++archiveFormatRaw :: ArchiveFormat+archiveFormatRaw = ArchiveFormat {# const ARCHIVE_FORMAT_RAW #}++archiveFormatXar :: ArchiveFormat+archiveFormatXar = ArchiveFormat {# const ARCHIVE_FORMAT_XAR #}++archiveFormatLha :: ArchiveFormat+archiveFormatLha = ArchiveFormat {# const ARCHIVE_FORMAT_LHA #}++archiveFormatCab :: ArchiveFormat+archiveFormatCab = ArchiveFormat {# const ARCHIVE_FORMAT_CAB #}++archiveFormatRar :: ArchiveFormat+archiveFormatRar = ArchiveFormat {# const ARCHIVE_FORMAT_RAR #}++archiveFormat7zip :: ArchiveFormat+archiveFormat7zip = ArchiveFormat {# const ARCHIVE_FORMAT_7ZIP #}++archiveFormatWarc :: ArchiveFormat+archiveFormatWarc = ArchiveFormat {# const ARCHIVE_FORMAT_WARC #}++archiveReadHasEncryptedEntries :: Ptr Archive -> IO ArchiveEncryption+archiveReadHasEncryptedEntries = fmap encryptionResult . archive_read_has_encrypted_entries++encryptionResult :: CInt -> ArchiveEncryption+encryptionResult 0 = NoEncryption+encryptionResult 1 = HasEncryption+encryptionResult ({# const ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED #}) = EncryptionUnsupported+encryptionResult ({# const ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW #}) = EncryptionUnknown+encryptionResult _ = error "Should not happen."++archiveReadFormatCapsNone :: ArchiveCapabilities+archiveReadFormatCapsNone = ArchiveCapabilities {# const ARCHIVE_READ_FORMAT_CAPS_NONE #}++(<<) :: Bits a => a -> Int -> a+m << n = m `shift` n++archiveReadFormatCapsEncryptData :: ArchiveCapabilities+archiveReadFormatCapsEncryptData = ArchiveCapabilities ({# const ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA #})++archiveReadFormatCapsEncryptMetadata :: ArchiveCapabilities+archiveReadFormatCapsEncryptMetadata = ArchiveCapabilities ({# const ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA #})++archiveReadDiskCanDescend :: Ptr Archive -> IO Bool+archiveReadDiskCanDescend = fmap intToBool . archive_read_disk_can_descend++archiveReadDiskCurrentFilesystemIsSynthetic :: Ptr Archive -> IO Bool+archiveReadDiskCurrentFilesystemIsSynthetic = fmap intToBool . archive_read_disk_current_filesystem_is_synthetic++archiveReadDiskCurrentFilesystemIsRemote :: Ptr Archive -> IO Bool+archiveReadDiskCurrentFilesystemIsRemote = fmap intToBool . archive_read_disk_current_filesystem_is_remote++archiveReadDiskRestoreATime :: ReadDiskFlags+archiveReadDiskRestoreATime = ReadDiskFlags {# const ARCHIVE_READDISK_RESTORE_ATIME #}++archiveReadDiskHonorNoDump :: ReadDiskFlags+archiveReadDiskHonorNoDump = ReadDiskFlags {# const ARCHIVE_READDISK_HONOR_NODUMP #}++archiveReadDiskMacCopyFile :: ReadDiskFlags+archiveReadDiskMacCopyFile = ReadDiskFlags {# const ARCHIVE_READDISK_MAC_COPYFILE #}++archiveReadDiskNoTraverseMounts :: ReadDiskFlags+archiveReadDiskNoTraverseMounts = ReadDiskFlags {# const ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS #}++archiveReadDiskNoXattr :: ReadDiskFlags+archiveReadDiskNoXattr = ReadDiskFlags {# const ARCHIVE_READDISK_NO_XATTR #}++-- archiveReadDiskNoAcl :: ReadDiskFlags+-- archiveReadDiskNoAcl = ReadDiskFlags {# const ARCHIVE_READDISK_NO_ACL #}++-- archiveReadDiskNoFFlags :: ReadDiskFlags+-- archiveReadDiskNoFFlags = ReadDiskFlags {# const ARCHIVE_READDISK_NO_FFLAGS #}++archiveMatchExcluded :: Ptr Archive -> IO Bool+archiveMatchExcluded = fmap intToBool . archive_match_excluded++archiveMatchPathExcluded :: Ptr Archive -> Ptr ArchiveEntry -> IO Bool+archiveMatchPathExcluded = fmap intToBool .* archive_match_path_excluded++archiveMatchExcludePatternFromFile :: Ptr Archive -> CString -> Bool -> IO ArchiveError+archiveMatchExcludePatternFromFile a str b = archive_match_exclude_pattern_from_file a str (boolToInt b)++archiveMatchExcludePatternFromFileW :: Ptr Archive -> CWString -> Bool -> IO ArchiveError+archiveMatchExcludePatternFromFileW a str b = archive_match_exclude_pattern_from_file_w a str (boolToInt b)++archiveMatchIncludePatternFromFile :: Ptr Archive -> CString -> Bool -> IO ArchiveError+archiveMatchIncludePatternFromFile a str b = archive_match_include_pattern_from_file a str (boolToInt b)++archiveMatchIncludePatternFromFileW :: Ptr Archive -> CString -> Bool -> IO ArchiveError+archiveMatchIncludePatternFromFileW a str b = archive_match_include_pattern_from_file_w a str (boolToInt b)++archiveMatchTimeExcluded :: Ptr Archive -> Ptr ArchiveEntry -> IO Bool+archiveMatchTimeExcluded = fmap intToBool .* archive_match_time_excluded++archiveMatchMTime :: TimeFlag+archiveMatchMTime = TimeFlag {# const ARCHIVE_MATCH_MTIME #}++archiveMatchCTime :: TimeFlag+archiveMatchCTime = TimeFlag {# const ARCHIVE_MATCH_CTIME #}++archiveMatchNewer :: TimeFlag+archiveMatchNewer = TimeFlag {# const ARCHIVE_MATCH_NEWER #}++archiveMatchOlder :: TimeFlag+archiveMatchOlder = TimeFlag {# const ARCHIVE_MATCH_OLDER #}++archiveMatchEqual :: TimeFlag+archiveMatchEqual = TimeFlag {# const ARCHIVE_MATCH_EQUAL #}++archiveMatchOwnerExcluded :: Ptr Archive -> Ptr ArchiveEntry -> IO Bool+archiveMatchOwnerExcluded = fmap intToBool .* archive_match_owner_excluded
+ src/Codec/Archive/Foreign/ArchiveEntry.chs view
@@ -0,0 +1,595 @@+-- | Functions found in @archive_entry.h@+module Codec.Archive.Foreign.ArchiveEntry ( -- * Direct bindings (entry)+ archive_entry_clear+ , archive_entry_clone+ , archive_entry_new+ , archive_entry_free+ , archive_entry_new2+ , archive_entry_atime+ , archive_entry_atime_nsec+ , archiveEntryATimeIsSet+ , archive_entry_birthtime+ , archive_entry_birthtime_nsec+ , archiveEntryBirthtimeIsSet+ , archive_entry_ctime+ , archive_entry_ctime_nsec+ , archiveEntryCTimeIsSet+ , archive_entry_dev+ , archiveEntryDevIsSet+ , archive_entry_devminor+ , archive_entry_devmajor+ , archive_entry_fflags+ , archive_entry_fflags_text+ , archive_entry_filetype+ , archive_entry_gid+ , archive_entry_gname+ , archive_entry_gname_utf8+ , archive_entry_gname_w+ , archive_entry_hardlink+ , archive_entry_hardlink_utf8+ , archive_entry_hardlink_w+ , archive_entry_ino+ , archive_entry_ino64+ , archiveEntryInoIsSet+ , archive_entry_mode+ , archive_entry_mtime+ , archive_entry_mtime_nsec+ , archiveEntryMTimeIsSet+ , archive_entry_nlink+ , archive_entry_pathname+ , archive_entry_pathname_utf8+ , archive_entry_pathname_w+ , archive_entry_perm+ , archive_entry_rdev+ , archive_entry_rdevmajor+ , archive_entry_rdevminor+ , archive_entry_sourcepath+ , archive_entry_sourcepath_w+ , archive_entry_size+ , archiveEntrySizeIsSet+ , archive_entry_strmode+ , archive_entry_symlink+ , archive_entry_symlink_w+ , archive_entry_symlink_utf8+ , archive_entry_uid+ , archive_entry_uname+ , archive_entry_uname_utf8+ , archive_entry_uname_w+ , archiveEntryIsDataEncrypted+ , archiveEntryIsMetadataEncrypted+ , archiveEntryIsEncrypted+ , archive_entry_set_atime+ , archive_entry_unset_atime+ , archive_entry_set_birthtime+ , archive_entry_unset_birthtime+ , archive_entry_set_ctime+ , archive_entry_unset_ctime+ , archive_entry_set_dev+ , archive_entry_set_devmajor+ , archive_entry_set_devminor+ , archive_entry_set_fflags+ , archive_entry_copy_fflags_text+ , archive_entry_copy_fflags_text_w+ , archive_entry_set_filetype+ , archive_entry_set_gid+ , archive_entry_set_gname+ , archive_entry_set_gname_utf8+ , archive_entry_copy_gname+ , archive_entry_copy_gname_w+ , archiveEntryUpdateGNameUtf8+ , archive_entry_set_hardlink+ , archive_entry_set_hardlink_utf8+ , archive_entry_copy_hardlink+ , archive_entry_copy_hardlink_w+ , archiveEntryUpdateHardlinkUtf8+ , archive_entry_set_ino+ , archive_entry_set_ino64+ , archive_entry_set_link+ , archive_entry_set_link_utf8+ , archive_entry_copy_link+ , archive_entry_copy_link_w+ , archiveEntryUpdateLinkUtf8+ , archive_entry_set_mode+ , archive_entry_set_mtime+ , archive_entry_unset_mtime+ , archive_entry_set_nlink+ , archive_entry_set_pathname+ , archive_entry_set_pathname_utf8+ , archive_entry_copy_pathname+ , archive_entry_copy_pathname_w+ , archiveEntryUpdatePathnameUtf8+ , archive_entry_set_perm+ , archive_entry_set_rdev+ , archive_entry_set_rdevmajor+ , archive_entry_set_rdevminor+ , archive_entry_set_size+ , archive_entry_unset_size+ , archive_entry_copy_sourcepath+ , archive_entry_copy_sourcepath_w+ , archive_entry_set_symlink+ , archive_entry_set_symlink_utf8+ , archive_entry_copy_symlink+ , archive_entry_copy_symlink_w+ , archiveEntryUpdateSymlinkUtf8+ , archive_entry_set_uid+ , archive_entry_set_uname+ , archive_entry_set_uname_utf8+ , archive_entry_copy_uname+ , archive_entry_copy_uname_w+ , archiveEntryUpdateUNameUtf8+ , archive_entry_stat+ , archive_entry_copy_stat+ , archive_entry_mac_metadata+ , archive_entry_copy_mac_metadata+ -- * ACL functions+ , archive_entry_acl_add_entry+ , archive_entry_acl_add_entry_w+ , archive_entry_acl_reset+ , archive_entry_acl_next+ , archive_entry_acl_next_w+ , archive_entry_acl_to_text+ , archive_entry_acl_to_text_w+ , archive_entry_acl_from_text+ , archive_entry_acl_from_text_w+ , archive_entry_acl_types+ , archive_entry_count+ -- * Xattr functions+ , archive_entry_xattr_clear+ , archive_entry_xattr_add_entry+ , archive_entry_xattr_count+ , archive_entry_xattr_reset+ , archive_entry_xattr_next+ -- * For sparse archives+ , archive_entry_sparse_clear+ , archive_entry_sparse_add_entry+ , archive_entry_sparse_count+ , archive_entry_sparse_reset+ , archive_entry_sparse_next+ -- * Link resolver+ , archive_entry_linkresolver_new+ , archive_entry_linkresolver_set_strategy+ , archive_entry_linkresolver_free+ , archive_entry_linkify+ , archive_entry_partial_links+ -- * ACL+ , archive_entry_acl_clear+ -- * File types+ , regular+ , symlink+ , socket+ , characterDevice+ , blockDevice+ , directory+ , fifo+ -- * ACL macros+ , archiveEntryACLExecute+ , archiveEntryACLWrite+ , archiveEntryACLRead+ , archiveEntryACLReadData+ , archiveEntryACLListData+ , archiveEntryACLWriteData+ , archiveEntryACLAddFile+ , archiveEntryACLAppendData+ , archiveEntryACLAddSubdirectory+ , archiveEntryACLReadNamedAttrs+ , archiveEntryACLWriteNamedAttrs+ , archiveEntryACLDeleteChild+ , archiveEntryACLReadAttributes+ , archiveEntryACLWriteAttributes+ , archiveEntryACLDelete+ , archiveEntryACLReadACL+ , archiveEntryACLWriteACL+ , archiveEntryACLWriteOwner+ , archiveEntryACLSynchronize+ , archiveEntryACLEntryFileInherit+ , archiveEntryACLEntryDirectoryInherit+ , archiveEntryACLEntryNoPropagateInherit+ , archiveEntryACLEntryInheritOnly+ , archiveEntryACLEntrySuccessfulAccess+ , archiveEntryACLEntryFailedAccess+ , archiveEntryACLTypeAccess+ , archiveEntryACLTypeDefault+ , archiveEntryACLTypeAllow+ , archiveEntryACLTypeDeny+ , archiveEntryACLTypeAudit+ , archiveEntryACLTypeAlarm+ , archiveEntryACLUser+ , archiveEntryACLUserObj+ , archiveEntryACLGroup+ , archiveEntryACLGroupObj+ , archiveEntryACLMask+ , archiveEntryACLOther+ , archiveEntryACLEveryone+ , archiveEntryACLStyleExtraID+ , archiveEntryACLStyleMarkDefault+ -- * Abstract types+ , ArchiveEntry+ , Stat+ , LinkResolver+ -- * Lower-level API types+ , FileType+ , EntryACL+ ) where++import Codec.Archive.Foreign.Common+import Codec.Archive.Types+import Control.Composition ((.*))+import Data.Int (Int64)+import Data.Word (Word64)+import Foreign.C.String+import Foreign.C.Types+import Foreign.Ptr (Ptr)+import System.Posix.Types (CMode (..))++#include <archive_entry.h>++-- Archive entry+foreign import ccall unsafe archive_entry_clear :: Ptr ArchiveEntry -> IO (Ptr ArchiveEntry)+foreign import ccall unsafe archive_entry_clone :: Ptr ArchiveEntry -> IO (Ptr ArchiveEntry)+foreign import ccall unsafe archive_entry_free :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_new :: IO (Ptr ArchiveEntry)+foreign import ccall unsafe archive_entry_new2 :: Ptr ArchiveEntry -> IO (Ptr ArchiveEntry)++foreign import ccall unsafe archive_entry_atime :: Ptr ArchiveEntry -> IO CTime+foreign import ccall unsafe archive_entry_atime_nsec :: Ptr ArchiveEntry -> IO CLong+foreign import ccall unsafe archive_entry_atime_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_birthtime :: Ptr ArchiveEntry -> IO CTime+foreign import ccall unsafe archive_entry_birthtime_nsec :: Ptr ArchiveEntry -> IO CLong+foreign import ccall unsafe archive_entry_birthtime_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_ctime :: Ptr ArchiveEntry -> IO CTime+foreign import ccall unsafe archive_entry_ctime_nsec :: Ptr ArchiveEntry -> IO CLong+foreign import ccall unsafe archive_entry_ctime_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_dev :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_dev_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_devmajor :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_devminor :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_filetype :: Ptr ArchiveEntry -> IO FileType+foreign import ccall unsafe archive_entry_fflags :: Ptr ArchiveEntry -> CULong -> CULong -> IO ()+foreign import ccall unsafe archive_entry_fflags_text :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_gid :: Ptr ArchiveEntry -> IO Id+foreign import ccall unsafe archive_entry_gname :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_gname_utf8 :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_gname_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_hardlink :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_hardlink_utf8 :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_hardlink_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_ino :: Ptr ArchiveEntry -> IO Int64+foreign import ccall unsafe archive_entry_ino64 :: Ptr ArchiveEntry -> IO Int64+foreign import ccall unsafe archive_entry_ino_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_mode :: Ptr ArchiveEntry -> IO CMode+foreign import ccall unsafe archive_entry_mtime :: Ptr ArchiveEntry -> IO CTime+foreign import ccall unsafe archive_entry_mtime_nsec :: Ptr ArchiveEntry -> IO CLong+foreign import ccall unsafe archive_entry_mtime_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_nlink :: Ptr ArchiveEntry -> IO CUInt+foreign import ccall unsafe archive_entry_pathname :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_pathname_utf8 :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_pathname_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_perm :: Ptr ArchiveEntry -> IO CMode+foreign import ccall unsafe archive_entry_rdev :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_rdevmajor :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_rdevminor :: Ptr ArchiveEntry -> IO Word64+foreign import ccall unsafe archive_entry_sourcepath :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_sourcepath_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_size :: Ptr ArchiveEntry -> IO Int64+foreign import ccall unsafe archive_entry_size_is_set :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_strmode :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_symlink :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_symlink_utf8 :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_symlink_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_uid :: Ptr ArchiveEntry -> IO Id+foreign import ccall unsafe archive_entry_uname :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_uname_utf8 :: Ptr ArchiveEntry -> IO CString+foreign import ccall unsafe archive_entry_uname_w :: Ptr ArchiveEntry -> IO CWString+foreign import ccall unsafe archive_entry_is_data_encrypted :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_is_metadata_encrypted :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_is_encrypted :: Ptr ArchiveEntry -> IO CInt++foreign import ccall unsafe archive_entry_set_atime :: Ptr ArchiveEntry -> CTime -> CLong -> IO ()+foreign import ccall unsafe archive_entry_unset_atime :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_set_birthtime :: Ptr ArchiveEntry -> CTime -> CLong -> IO ()+foreign import ccall unsafe archive_entry_unset_birthtime :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_set_ctime :: Ptr ArchiveEntry -> CTime -> CLong -> IO ()+foreign import ccall unsafe archive_entry_unset_ctime :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_set_dev :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_devmajor :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_devminor :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_filetype :: Ptr ArchiveEntry -> FileType -> IO ()+foreign import ccall unsafe archive_entry_set_fflags :: Ptr ArchiveEntry -> CULong -> CULong -> IO ()+foreign import ccall unsafe archive_entry_copy_fflags_text :: Ptr ArchiveEntry -> CString -> IO CString+foreign import ccall unsafe archive_entry_copy_fflags_text_w :: Ptr ArchiveEntry -> CWString -> IO CWString+foreign import ccall unsafe archive_entry_set_gid :: Ptr ArchiveEntry -> Id -> IO ()+foreign import ccall unsafe archive_entry_set_gname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_gname_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_gname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_gname_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_gname_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_set_hardlink :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_hardlink_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_hardlink :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_hardlink_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_hardlink_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_set_ino :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_ino64 :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_link :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_link_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_link :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_link_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_link_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_set_mode :: Ptr ArchiveEntry -> CMode -> IO ()+foreign import ccall unsafe archive_entry_set_mtime :: Ptr ArchiveEntry -> CTime -> CLong -> IO ()+foreign import ccall unsafe archive_entry_unset_mtime :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_set_nlink :: Ptr ArchiveEntry -> CUInt -> IO ()+foreign import ccall unsafe archive_entry_set_pathname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_pathname_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_pathname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_pathname_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_pathname_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_set_perm :: Ptr ArchiveEntry -> CMode -> IO ()+foreign import ccall unsafe archive_entry_set_rdev :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_rdevmajor :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_rdevminor :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_set_size :: Ptr ArchiveEntry -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_unset_size :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_copy_sourcepath :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_sourcepath_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_set_symlink :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_symlink_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_symlink :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_symlink_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_symlink_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_set_uid :: Ptr ArchiveEntry -> Id -> IO ()+foreign import ccall unsafe archive_entry_set_uname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_set_uname_utf8 :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_uname :: Ptr ArchiveEntry -> CString -> IO ()+foreign import ccall unsafe archive_entry_copy_uname_w :: Ptr ArchiveEntry -> CWString -> IO ()+foreign import ccall unsafe archive_entry_update_uname_utf8 :: Ptr ArchiveEntry -> CString -> IO CInt+foreign import ccall unsafe archive_entry_stat :: Ptr ArchiveEntry -> IO (Ptr Stat)+foreign import ccall unsafe archive_entry_copy_stat :: Ptr ArchiveEntry -> Ptr Stat -> IO ()+foreign import ccall unsafe archive_entry_mac_metadata :: Ptr ArchiveEntry -> Ptr CSize -> IO (Ptr a)+foreign import ccall unsafe archive_entry_copy_mac_metadata :: Ptr ArchiveEntry -> Ptr a -> CSize -> IO ()++foreign import ccall unsafe archive_entry_acl_clear :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_acl_add_entry :: Ptr ArchiveEntry -> EntryACL -> EntryACL -> EntryACL -> CInt -> CString -> IO ArchiveError+foreign import ccall unsafe archive_entry_acl_add_entry_w :: Ptr ArchiveEntry -> EntryACL -> EntryACL -> EntryACL -> CInt -> CWString -> IO ArchiveError+foreign import ccall unsafe archive_entry_acl_reset :: Ptr ArchiveEntry -> EntryACL -> IO CInt+foreign import ccall unsafe archive_entry_acl_next :: Ptr ArchiveEntry -> EntryACL -> EntryACL -> EntryACL -> EntryACL -> CInt -> Ptr CString -> IO ArchiveError+foreign import ccall unsafe archive_entry_acl_next_w :: Ptr ArchiveEntry -> EntryACL -> EntryACL -> EntryACL -> EntryACL -> CInt -> Ptr CWString -> IO ArchiveError++foreign import ccall unsafe archive_entry_acl_to_text_w :: Ptr ArchiveEntry -> CSize -> EntryACL -> IO CWString+foreign import ccall unsafe archive_entry_acl_to_text :: Ptr ArchiveEntry -> CSize -> EntryACL -> IO CString+foreign import ccall unsafe archive_entry_acl_from_text :: Ptr ArchiveEntry -> CString -> EntryACL -> IO ArchiveError+foreign import ccall unsafe archive_entry_acl_from_text_w :: Ptr ArchiveEntry -> CWString -> EntryACL -> IO ArchiveError+foreign import ccall unsafe archive_entry_acl_types :: Ptr ArchiveEntry -> IO EntryACL+foreign import ccall unsafe archive_entry_count :: Ptr ArchiveEntry -> EntryACL -> IO CInt++-- don't bother with archive_entry_acl++foreign import ccall unsafe archive_entry_xattr_clear :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_xattr_add_entry :: Ptr ArchiveEntry -> CString -> Ptr a -> CSize -> IO ()+foreign import ccall unsafe archive_entry_xattr_count :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_xattr_reset :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_xattr_next :: Ptr ArchiveEntry -> Ptr CString -> Ptr (Ptr a) -> Ptr CSize -> IO ArchiveError+-- TODO: higher level archiveEntryXattrList?++foreign import ccall unsafe archive_entry_sparse_clear :: Ptr ArchiveEntry -> IO ()+foreign import ccall unsafe archive_entry_sparse_add_entry :: Ptr ArchiveEntry -> Int64 -> Int64 -> IO ()+foreign import ccall unsafe archive_entry_sparse_count :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_sparse_reset :: Ptr ArchiveEntry -> IO CInt+foreign import ccall unsafe archive_entry_sparse_next :: Ptr ArchiveEntry -> Ptr Int64 -> Ptr Int64 -> IO ArchiveError++foreign import ccall unsafe archive_entry_linkresolver_new :: Ptr LinkResolver+foreign import ccall unsafe archive_entry_linkresolver_set_strategy :: Ptr LinkResolver -> ArchiveFormat -> IO ()+foreign import ccall unsafe archive_entry_linkresolver_free :: Ptr LinkResolver -> IO ()+foreign import ccall unsafe archive_entry_linkify :: Ptr LinkResolver -> Ptr (Ptr ArchiveEntry) -> Ptr (Ptr ArchiveEntry) -> IO ()+foreign import ccall unsafe archive_entry_partial_links :: Ptr LinkResolver -> Ptr CUInt -> IO (Ptr ArchiveEntry)++-- stupid function to work around some annoying C quirk+mode_t :: Integer -> FileType+mode_t = FileType . fromIntegral . asOctal++-- converts 0020000 to 16384 etc.+asOctal :: Integral a => a -> a+asOctal n | n < 10 = n+ | otherwise = 8 * asOctal (n `div` 10) + n `mod` 10++-- filetype+regular :: FileType+regular = {# const AE_IFREG #}++symlink :: FileType+symlink = {# const AE_IFLNK #}++socket :: FileType+socket = {# const AE_IFSOCK #}++characterDevice :: FileType+characterDevice = {# const AE_IFCHR #}++blockDevice :: FileType+blockDevice = {# const AE_IFBLK #}++directory :: FileType+directory = {# const AE_IFDIR #}++fifo :: FileType+fifo = {# const AE_IFIFO #}++archiveEntryATimeIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryATimeIsSet = fmap intToBool . archive_entry_atime_is_set++archiveEntryBirthtimeIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryBirthtimeIsSet = fmap intToBool . archive_entry_birthtime_is_set++archiveEntryCTimeIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryCTimeIsSet = fmap intToBool . archive_entry_ctime_is_set++archiveEntryDevIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryDevIsSet = fmap intToBool . archive_entry_dev_is_set++archiveEntryInoIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryInoIsSet = fmap intToBool . archive_entry_ino_is_set++archiveEntryMTimeIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntryMTimeIsSet = fmap intToBool . archive_entry_mtime_is_set++archiveEntrySizeIsSet :: Ptr ArchiveEntry -> IO Bool+archiveEntrySizeIsSet = fmap intToBool . archive_entry_size_is_set++archiveEntryIsDataEncrypted :: Ptr ArchiveEntry -> IO Bool+archiveEntryIsDataEncrypted = fmap intToBool . archive_entry_is_data_encrypted++archiveEntryIsMetadataEncrypted :: Ptr ArchiveEntry -> IO Bool+archiveEntryIsMetadataEncrypted = fmap intToBool . archive_entry_is_metadata_encrypted++archiveEntryIsEncrypted :: Ptr ArchiveEntry -> IO Bool+archiveEntryIsEncrypted = fmap intToBool . archive_entry_is_encrypted++archiveEntryUpdateGNameUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdateGNameUtf8 = fmap intToBool .* archive_entry_update_gname_utf8++archiveEntryUpdateHardlinkUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdateHardlinkUtf8 = fmap intToBool .* archive_entry_update_hardlink_utf8++archiveEntryUpdateLinkUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdateLinkUtf8 = fmap intToBool .* archive_entry_update_link_utf8++archiveEntryUpdatePathnameUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdatePathnameUtf8 = fmap intToBool .* archive_entry_update_pathname_utf8++archiveEntryUpdateSymlinkUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdateSymlinkUtf8 = fmap intToBool .* archive_entry_update_symlink_utf8++archiveEntryUpdateUNameUtf8 :: Ptr ArchiveEntry -> CString -> IO Bool+archiveEntryUpdateUNameUtf8 = fmap intToBool .* archive_entry_update_uname_utf8++archiveEntryACLExecute :: EntryACL+archiveEntryACLExecute = EntryACL {# const ARCHIVE_ENTRY_ACL_EXECUTE #}++archiveEntryACLWrite :: EntryACL+archiveEntryACLWrite = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE #}++archiveEntryACLRead :: EntryACL+archiveEntryACLRead = EntryACL {# const ARCHIVE_ENTRY_ACL_READ #}++archiveEntryACLReadData :: EntryACL+archiveEntryACLReadData = EntryACL {# const ARCHIVE_ENTRY_ACL_READ_DATA #}++archiveEntryACLListData :: EntryACL+archiveEntryACLListData = EntryACL {# const ARCHIVE_ENTRY_ACL_LIST_DIRECTORY #}++archiveEntryACLWriteData :: EntryACL+archiveEntryACLWriteData = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE_DATA #}++archiveEntryACLAddFile :: EntryACL+archiveEntryACLAddFile = EntryACL {# const ARCHIVE_ENTRY_ACL_ADD_FILE #}++archiveEntryACLAppendData :: EntryACL+archiveEntryACLAppendData = EntryACL {# const ARCHIVE_ENTRY_ACL_APPEND_DATA #}++archiveEntryACLAddSubdirectory :: EntryACL+archiveEntryACLAddSubdirectory = EntryACL {# const ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY #}++archiveEntryACLReadNamedAttrs :: EntryACL+archiveEntryACLReadNamedAttrs = EntryACL {# const ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS #}++archiveEntryACLWriteNamedAttrs :: EntryACL+archiveEntryACLWriteNamedAttrs = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS #}++archiveEntryACLDeleteChild :: EntryACL+archiveEntryACLDeleteChild = EntryACL {# const ARCHIVE_ENTRY_ACL_DELETE_CHILD #}++archiveEntryACLReadAttributes :: EntryACL+archiveEntryACLReadAttributes = EntryACL {# const ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES #}++archiveEntryACLWriteAttributes :: EntryACL+archiveEntryACLWriteAttributes = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES #}++archiveEntryACLDelete :: EntryACL+archiveEntryACLDelete = EntryACL {# const ARCHIVE_ENTRY_ACL_DELETE #}++archiveEntryACLReadACL :: EntryACL+archiveEntryACLReadACL = EntryACL {# const ARCHIVE_ENTRY_ACL_READ_ACL #}++archiveEntryACLWriteACL :: EntryACL+archiveEntryACLWriteACL = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE_ACL #}++archiveEntryACLWriteOwner :: EntryACL+archiveEntryACLWriteOwner = EntryACL {# const ARCHIVE_ENTRY_ACL_WRITE_OWNER #}++archiveEntryACLSynchronize :: EntryACL+archiveEntryACLSynchronize = EntryACL {# const ARCHIVE_ENTRY_ACL_SYNCHRONIZE #}++-- archiveEntryACLEntryInherited :: EntryACL+-- archiveEntryACLEntryInherited = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_INHERITED #}++archiveEntryACLEntryFileInherit :: EntryACL+archiveEntryACLEntryFileInherit = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT #}++archiveEntryACLEntryDirectoryInherit :: EntryACL+archiveEntryACLEntryDirectoryInherit = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT #}++archiveEntryACLEntryNoPropagateInherit :: EntryACL+archiveEntryACLEntryNoPropagateInherit = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT #}++archiveEntryACLEntryInheritOnly :: EntryACL+archiveEntryACLEntryInheritOnly = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY #}++archiveEntryACLEntrySuccessfulAccess :: EntryACL+archiveEntryACLEntrySuccessfulAccess = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS #}++archiveEntryACLEntryFailedAccess :: EntryACL+archiveEntryACLEntryFailedAccess = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS #}++archiveEntryACLTypeAccess :: EntryACL+archiveEntryACLTypeAccess = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_ACCESS #}++archiveEntryACLTypeDefault :: EntryACL+archiveEntryACLTypeDefault = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_DEFAULT #}++archiveEntryACLTypeAllow :: EntryACL+archiveEntryACLTypeAllow = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_ALLOW #}++archiveEntryACLTypeDeny :: EntryACL+archiveEntryACLTypeDeny = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_DENY #}++archiveEntryACLTypeAudit :: EntryACL+archiveEntryACLTypeAudit = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_AUDIT #}++archiveEntryACLTypeAlarm :: EntryACL+archiveEntryACLTypeAlarm = EntryACL {# const ARCHIVE_ENTRY_ACL_TYPE_ALARM #}++archiveEntryACLUser :: EntryACL+archiveEntryACLUser = EntryACL {# const ARCHIVE_ENTRY_ACL_USER #}++archiveEntryACLUserObj :: EntryACL+archiveEntryACLUserObj = EntryACL {# const ARCHIVE_ENTRY_ACL_USER_OBJ #}++archiveEntryACLGroup :: EntryACL+archiveEntryACLGroup = EntryACL {# const ARCHIVE_ENTRY_ACL_GROUP #}++archiveEntryACLGroupObj :: EntryACL+archiveEntryACLGroupObj = EntryACL {# const ARCHIVE_ENTRY_ACL_GROUP_OBJ #}++archiveEntryACLMask :: EntryACL+archiveEntryACLMask = EntryACL {# const ARCHIVE_ENTRY_ACL_MASK #}++archiveEntryACLOther :: EntryACL+archiveEntryACLOther = EntryACL {# const ARCHIVE_ENTRY_ACL_OTHER #}++archiveEntryACLEveryone :: EntryACL+archiveEntryACLEveryone = EntryACL {# const ARCHIVE_ENTRY_ACL_EVERYONE #}++archiveEntryACLStyleExtraID :: EntryACL+archiveEntryACLStyleExtraID = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID #}++archiveEntryACLStyleMarkDefault :: EntryACL+archiveEntryACLStyleMarkDefault = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT #}++-- archiveEntryACLStyleSolaris :: EntryACL+-- archiveEntryACLStyleSolaris = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_SOLARIS #}++-- archiveEntryACLStyleSeparatorComma :: EntryACL+-- archiveEntryACLStyleSeparatorComma = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA #}++-- archiveEntryACLStyleCompact :: EntryACL+-- archiveEntryACLStyleCompact = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_COMPACT #}
+ src/Codec/Archive/Foreign/Common.hs view
@@ -0,0 +1,7 @@+module Codec.Archive.Foreign.Common ( intToBool ) where++import Foreign.C.Types++-- TODO: this should check against ArchiveFatal or whatnot?+intToBool :: CInt -> Bool+intToBool = toEnum . fromIntegral
+ src/Codec/Archive/Pack.hs view
@@ -0,0 +1,138 @@+module Codec.Archive.Pack ( packEntries+ , entriesToFile+ , entriesToFileZip+ , entriesToFile7Zip+ , entriesToBS+ , entriesToBSzip+ , entriesToBS7zip+ ) where++import Codec.Archive.Foreign+import Codec.Archive.Types+import Control.Monad (void)+import Data.ByteString (packCStringLen, useAsCStringLen)+import qualified Data.ByteString as BS+import Data.Foldable (traverse_)+import Data.Semigroup (Sum (..))+import Foreign.C.String+import Foreign.Marshal.Alloc (alloca, allocaBytes)+import Foreign.Ptr (Ptr)+import Foreign.Storable (peek)+import System.IO.Unsafe (unsafePerformIO)++contentAdd :: EntryContent -> Ptr Archive -> Ptr ArchiveEntry -> IO ()+contentAdd (NormalFile contents) a entry = do+ archive_entry_set_filetype entry regular+ archive_entry_set_size entry (fromIntegral (BS.length contents))+ void $ archive_write_header a entry+ useAsCStringLen contents $ \(buff, sz) ->+ void $ archive_write_data a buff (fromIntegral sz)+contentAdd Directory a entry = do+ archive_entry_set_filetype entry directory+ void $ archive_write_header a entry+contentAdd (Symlink fp) a entry = do+ archive_entry_set_filetype entry symlink+ withCString fp $ \fpc ->+ archive_entry_set_symlink entry fpc+ void $ archive_write_header a entry++setOwnership :: Ownership -> Ptr ArchiveEntry -> IO ()+setOwnership (Ownership uname gname uid gid) entry =+ withCString uname $ \unameC ->+ withCString gname $ \gnameC ->+ sequence_+ [ archive_entry_set_uname entry unameC+ , archive_entry_set_gname entry gnameC+ , archive_entry_set_uid entry uid+ , archive_entry_set_gid entry gid+ ]++setTime :: ModTime -> Ptr ArchiveEntry -> IO ()+setTime (time', nsec) entry = archive_entry_set_mtime entry time' nsec++packEntries :: (Foldable t) => Ptr Archive -> t Entry -> IO ()+packEntries a = traverse_ (archiveEntryAdd a)++-- Get a number of bytes appropriate for creating the archive.+entriesSz :: (Foldable t, Integral a) => t Entry -> a+entriesSz = getSum . foldMap (Sum . entrySz)+ where entrySz e = 512 + 512 * (contentSz (content e) `div` 512 + 1)+ contentSz (NormalFile str) = fromIntegral $ BS.length str+ contentSz Directory = 0+ contentSz (Symlink fp) = fromIntegral $ length fp++-- | Returns a 'BS.ByteString' containing a tar archive with the 'Entry's+entriesToBS :: Foldable t => t Entry -> BS.ByteString+entriesToBS = unsafePerformIO . entriesToBSGeneral archive_write_set_format_pax_restricted+{-# NOINLINE entriesToBS #-}++-- | Returns a 'BS.ByteString' containing a @.7z@ archive with the 'Entry's+entriesToBS7zip :: Foldable t => t Entry -> BS.ByteString+entriesToBS7zip = unsafePerformIO . entriesToBSGeneral archive_write_set_format_7zip+{-# NOINLINE entriesToBS7zip #-}++-- | Returns a 'BS.ByteString' containing a zip archive with the 'Entry's+entriesToBSzip :: Foldable t => t Entry -> BS.ByteString+entriesToBSzip = unsafePerformIO . entriesToBSGeneral archive_write_set_format_zip+{-# NOINLINE entriesToBSzip #-}++entriesToBSGeneral :: (Foldable t) => (Ptr Archive -> IO ArchiveError) -> t Entry -> IO BS.ByteString+entriesToBSGeneral modifier hsEntries' = do+ a <- archive_write_new+ void $ modifier a+ alloca $ \used ->+ allocaBytes bufSize $ \buffer -> do+ void $ archive_write_open_memory a buffer bufSize used+ packEntries a hsEntries'+ void $ archive_write_close a+ usedSz <- peek used+ res <- curry packCStringLen buffer (fromIntegral usedSz)+ void $ archive_write_free a+ pure res++ where bufSize :: Integral a => a+ bufSize = entriesSz hsEntries'++-- | Write some entries to a file, creating a tar archive. This is more+-- efficient than+--+-- @+-- BS.writeFile "file.tar" (entriesToBS entries)+-- @+entriesToFile :: Foldable t => FilePath -> t Entry -> IO ()+entriesToFile = entriesToFileGeneral archive_write_set_format_pax_restricted+-- this is the recommended format; it is a tar archive++-- | Write some entries to a file, creating a zip archive.+entriesToFileZip :: Foldable t => FilePath -> t Entry -> IO ()+entriesToFileZip = entriesToFileGeneral archive_write_set_format_zip++-- | Write some entries to a file, creating a @.7z@ archive.+entriesToFile7Zip :: Foldable t => FilePath -> t Entry -> IO ()+entriesToFile7Zip = entriesToFileGeneral archive_write_set_format_7zip++entriesToFileGeneral :: Foldable t => (Ptr Archive -> IO ArchiveError) -> FilePath -> t Entry -> IO ()+entriesToFileGeneral modifier fp hsEntries' = do+ a <- archive_write_new+ void $ modifier a+ withCString fp $ \fpc ->+ void $ archive_write_open_filename a fpc+ packEntries a hsEntries'+ void $ archive_write_free a++withArchiveEntry :: (Ptr ArchiveEntry -> IO a) -> IO a+withArchiveEntry fact = do+ entry <- archive_entry_new+ res <- fact entry+ archive_entry_free entry+ pure res++archiveEntryAdd :: Ptr Archive -> Entry -> IO ()+archiveEntryAdd a (Entry fp contents perms owner mtime) =+ withArchiveEntry $ \entry -> do+ withCString fp $ \fpc ->+ archive_entry_set_pathname entry fpc+ archive_entry_set_perm entry perms+ setOwnership owner entry+ setTime mtime entry+ contentAdd contents a entry
+ src/Codec/Archive/Types.hs view
@@ -0,0 +1,123 @@+module Codec.Archive.Types ( -- * Abstract data types+ Archive+ , ArchiveEntry+ , Stat+ , LinkResolver+ -- * Concrete (Haskell) data types+ , Entry (..)+ , EntryContent (..)+ , Ownership (..)+ , ModTime+ , Id+ , Permissions+ , ArchiveEncryption (..)+ -- * Macros+ , Flags (..)+ , ArchiveError (..)+ , ArchiveFilter (..)+ , ArchiveFormat (..)+ , FileType (..)+ , ArchiveCapabilities (..)+ , ReadDiskFlags (..)+ , TimeFlag (..)+ , EntryACL (..)+ -- * Values+ , standardPermissions+ , executablePermissions+ ) where++import Data.Bits (Bits (..))+import qualified Data.ByteString as BS+import Data.Int (Int64)+import Data.Semigroup+import Foreign.C.Types (CInt, CLong, CTime)+import System.Posix.Types (CMode (..))++-- | Abstract type+data Archive++-- | Abstract type+data ArchiveEntry++data Stat++data LinkResolver++-- TODO: support everything here: http://hackage.haskell.org/package/tar/docs/Codec-Archive-Tar-Entry.html#t:EntryContent+data EntryContent = NormalFile !BS.ByteString+ | Directory+ | Symlink !FilePath++data Entry = Entry { filepath :: !FilePath+ , content :: !EntryContent+ , permissions :: !Permissions+ , ownership :: !Ownership+ , time :: !ModTime+ }++data Ownership = Ownership { userName :: !String+ , groupName :: !String+ , ownerId :: !Id+ , groupId :: !Id+ }++type Permissions = CMode+type ModTime = (CTime, CLong)++-- | A user or group ID+type Id = Int64++standardPermissions :: Permissions+standardPermissions = 0o644++executablePermissions :: Permissions+executablePermissions = 0o755++newtype ArchiveFormat = ArchiveFormat CInt++newtype FileType = FileType CMode+ deriving (Eq)++-- TODO: make this a sum type ?+newtype ArchiveError = ArchiveError CInt+ deriving (Eq)++newtype Flags = Flags CInt++newtype ReadDiskFlags = ReadDiskFlags CInt++newtype TimeFlag = TimeFlag CInt++newtype EntryACL = EntryACL CInt++newtype ArchiveFilter = ArchiveFilter CInt++newtype ArchiveCapabilities = ArchiveCapabilities CInt+ deriving (Eq)++data ArchiveEncryption = HasEncryption+ | NoEncryption+ | EncryptionUnsupported+ | EncryptionUnknown++instance Semigroup ArchiveCapabilities where+ (<>) (ArchiveCapabilities x) (ArchiveCapabilities y) = ArchiveCapabilities (x .|. y)++instance Monoid ArchiveCapabilities where+ mempty = ArchiveCapabilities 0+ mappend = (<>)++instance Semigroup ReadDiskFlags where+ (<>) (ReadDiskFlags x) (ReadDiskFlags y) = ReadDiskFlags (x .|. y)++instance Semigroup Flags where+ (<>) (Flags x) (Flags y) = Flags (x .|. y)++instance Monoid Flags where+ mempty = Flags 0+ mappend = (<>)++instance Semigroup EntryACL where+ (<>) (EntryACL x) (EntryACL y) = EntryACL (x .|. y)++-- TODO: `has` function for EntryACL
+ src/Codec/Archive/Unpack.hs view
@@ -0,0 +1,88 @@+module Codec.Archive.Unpack ( hsEntries+ , unpackEntriesFp+ ) where++import Codec.Archive.Foreign+import Codec.Archive.Types+import Control.Monad (void)+import qualified Data.ByteString as BS+import Foreign.C.String+import Foreign.Marshal.Alloc (alloca, allocaBytes)+import Foreign.Ptr (Ptr)+import Foreign.Storable (Storable (..))+import System.FilePath ((</>))++readEntry :: Ptr Archive -> Ptr ArchiveEntry -> IO Entry+readEntry a entry =+ Entry+ <$> (peekCString =<< archive_entry_pathname entry)+ <*> readContents a entry+ <*> archive_entry_perm entry+ <*> readOwnership entry+ <*> readTimes entry++getHsEntry :: Ptr Archive -> IO (Maybe Entry)+getHsEntry a = do+ entry <- getEntry a+ case entry of+ Nothing -> pure Nothing+ Just x -> Just <$> readEntry a x++hsEntries :: Ptr Archive -> IO [Entry]+hsEntries a = do+ next <- getHsEntry a+ case next of+ Nothing -> pure []+ Just x -> (x:) <$> hsEntries a++-- | Unpack an archive in a given directory+unpackEntriesFp :: Ptr Archive -> FilePath -> IO ()+unpackEntriesFp a fp = do+ res <- getEntry a+ case res of+ Nothing -> pure ()+ Just x -> do+ preFile <- archive_entry_pathname x+ file <- peekCString preFile+ let file' = fp </> file+ withCString file' $ \fileC ->+ archive_entry_set_pathname x fileC+ void $ archive_read_extract a x archiveExtractTime+ archive_entry_set_pathname x preFile+ void $ archive_read_data_skip a+ unpackEntriesFp a fp++readBS :: Ptr Archive -> Int -> IO BS.ByteString+readBS a sz =+ allocaBytes sz $ \buff ->+ archive_read_data a buff (fromIntegral sz) *>+ BS.packCStringLen (buff, sz)++readContents :: Ptr Archive -> Ptr ArchiveEntry -> IO EntryContent+readContents a entry = go =<< archive_entry_filetype entry+ where go ft | ft == regular = NormalFile <$> (readBS a =<< sz)+ | ft == symlink = Symlink <$> (peekCString =<< archive_entry_symlink entry)+ | ft == directory = pure Directory+ | otherwise = error "Unsupported filetype"+ sz = fromIntegral <$> archive_entry_size entry++readOwnership :: Ptr ArchiveEntry -> IO Ownership+readOwnership entry =+ Ownership+ <$> (peekCString =<< archive_entry_uname entry)+ <*> (peekCString =<< archive_entry_gname entry)+ <*> archive_entry_uid entry+ <*> archive_entry_gid entry++readTimes :: Ptr ArchiveEntry -> IO ModTime+readTimes entry =+ (,) <$> archive_entry_mtime entry <*> archive_entry_mtime_nsec entry++getEntry :: Ptr Archive -> IO (Maybe (Ptr ArchiveEntry))+getEntry a = alloca $ \ptr -> do+ let done res = not (res == archiveOk || res == archiveRetry)+ stop <- done <$> archive_read_next_header a ptr+ if stop+ then pure Nothing+ else Just <$> peek ptr+