From d540ec853e174e78c0ba4f29fe6cd5d4382af862 Mon Sep 17 00:00:00 2001 From: Dylan Simon Date: Tue, 24 Apr 2018 13:49:12 -0400 Subject: [PATCH] Expose external attributes on zipping only For #6 -- based on patch by @utdemir --- Codec/Archive/Zip/Conduit/Types.hs | 3 ++- Codec/Archive/Zip/Conduit/UnZip.hs | 1 + Codec/Archive/Zip/Conduit/Zip.hs | 2 +- cmd/zip.hs | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Codec/Archive/Zip/Conduit/Types.hs b/Codec/Archive/Zip/Conduit/Types.hs index b9d6e35..9f2b1c6 100644 --- a/Codec/Archive/Zip/Conduit/Types.hs +++ b/Codec/Archive/Zip/Conduit/Types.hs @@ -10,7 +10,7 @@ import Data.String (IsString(..)) import qualified Data.Text as T import Data.Time.LocalTime (LocalTime) import Data.Typeable (Typeable) -import Data.Word (Word64) +import Data.Word (Word32, Word64) -- |Errors thrown during zip file processing newtype ZipError = ZipError String @@ -33,6 +33,7 @@ data ZipEntry = ZipEntry { zipEntryName :: Either T.Text ByteString -- ^File name (in posix format, no leading slashes), either UTF-8 encoded text or raw bytes (CP437), with a trailing slash for directories , zipEntryTime :: LocalTime -- ^Modification time , zipEntrySize :: Maybe Word64 -- ^Size of file data (if known); checked on zipping and also used as hint to enable zip64 + , zipEntryExternalAttributes :: Maybe Word32 -- ^Host-dependent attributes, often MS-DOS directory attribute byte (only supported when zipping) } deriving (Eq, Show) -- |The data contents for a 'ZipEntry'. For empty entries (e.g., directories), use 'mempty'. diff --git a/Codec/Archive/Zip/Conduit/UnZip.hs b/Codec/Archive/Zip/Conduit/UnZip.hs index de9efed..51b47ea 100644 --- a/Codec/Archive/Zip/Conduit/UnZip.hs +++ b/Codec/Archive/Zip/Conduit/UnZip.hs @@ -221,6 +221,7 @@ unZipStream = next where { zipEntryName = if testBit gpf 11 then Left (TE.decodeUtf8 name) else Right name , zipEntryTime = time , zipEntrySize = if testBit gpf 3 then Nothing else Just extZip64USize + , zipEntryExternalAttributes = Nothing } , fileDecompress = dcomp , fileCSize = extZip64CSize diff --git a/Codec/Archive/Zip/Conduit/Zip.hs b/Codec/Archive/Zip/Conduit/Zip.hs index 8d7272e..bceea26 100644 --- a/Codec/Archive/Zip/Conduit/Zip.hs +++ b/Codec/Archive/Zip/Conduit/Zip.hs @@ -192,7 +192,7 @@ zipStream ZipOptions{..} = execStateC 0 $ do P.putWord16le 0 -- comment length P.putWord16le 0 -- disk number P.putWord16le 0 -- internal file attributes - P.putWord32le 0 -- external file attributes + P.putWord32le $ fromMaybe 0 zipEntryExternalAttributes P.putWord32le $ if o64 then maxBound32 else fromIntegral off P.putByteString name when a64 $ do diff --git a/cmd/zip.hs b/cmd/zip.hs index d46853f..9ea2789 100644 --- a/cmd/zip.hs +++ b/cmd/zip.hs @@ -48,6 +48,7 @@ generate (p:paths) = do { zipEntryName = Right $ BSC.pack $ dropWhile ('/' ==) p , zipEntryTime = utcToLocalTime utc t -- FIXME: timezone , zipEntrySize = Nothing + , zipEntryExternalAttributes = Nothing } isd <- liftIO $ doesDirectoryExist p if isd