mrkkrp / zip

Efficient library for manipulating zip archives
Other
81 stars 27 forks source link

Preserving file permissions (especially executable bits)? #64

Closed saurabhnanda closed 4 years ago

saurabhnanda commented 4 years ago

I'm not sure if it's just me or if there is a bug/limitation in this library. Based off the sample code given in library docs, here's what I wrote:

do
  bs <- BS.readFile "/tmp/some-executable-binary"
  s <- Zip.mkEntrySelector "some-executable-binary"
  Zip.createArchive "/tmp/zipfile.zip" (Zip.addEntry Zip.Deflate bs s)

This creates /tmp/zipfile.zip, but when it is unzipped, some-executable-binary no longer has an executable bit set.

After that, I tried making the following change...

  s <- Zip.mkEntrySelector "/tmp/some-executable-binary"

...but it gave the following error:

*** Exception: Cannot build selector from "/tmp/bootstrap"

What am I doing wrong?

mrkkrp commented 4 years ago

Perhaps you could use setExternalFileAttrs now that #63 is merged? Make sure to use version 1.4.0 of the library.

mrkkrp commented 4 years ago

What am I doing wrong?

If you read the docs for mkEntrySelector, you'll discover that only relative paths can be used. I'm not sure what you want to achieve. Do you want to create an archive which unpacks files to absolute locations on host file system?

saurabhnanda commented 4 years ago

Perhaps you could use setExternalFileAttrs now that #63 is merged? Make sure to use version 1.4.0 of the library.

Ah - this PR was merged just yesterday! Thanks. Let me try this out and report back.

If you read the docs for mkEntrySelector, you'll discover that only relative paths can be used. I'm not sure what you want to achieve. Do you want to create an archive which unpacks files to absolute locations on host file system?

I understand the rationale for using relative paths. Since file permission weren't being preserved with the first code snippet, I assumed that mkEntrySelector might need an absolute file path to pick file permissions from.

I was looking at https://www.stackage.org/haddock/lts-12.1/zip-1.1.0/Codec-Archive-Zip.html earlier. I hope zip-1.4.0 can work with LTS-12.1

PS: Btw, hackage doesn't have docs for 1.3.0, .1.3.1, 1.3.2, and 1.4.0

saurabhnanda commented 4 years ago

At the risk of taking this thread off-topic, I tried compiling zip-1.4.0 with lts-12.1 and ran in the following error. Is there some breaking change between the versions of base or ghc that you might know about?

zip               > configure
zip               > Configuring zip-1.4.0...
zip               > build
zip               > Preprocessing library for zip-1.4.0..
zip               > Building library for zip-1.4.0..
zip               > [1 of 5] Compiling Codec.Archive.Zip.CP437
zip               > [2 of 5] Compiling Codec.Archive.Zip.Type
zip               > [3 of 5] Compiling Codec.Archive.Zip.Internal
zip               > [4 of 5] Compiling Codec.Archive.Zip
zip               > [5 of 5] Compiling Codec.Archive.Zip.Unix
zip               > 
zip               > /private/var/folders/j7/fgt692sj0wzg0lvrk86ctnxc0000gn/T/stack77859/zip-1.4.0/Codec/Archive/Zip/Unix.hs:31:24: error:
zip               >     • Couldn't match expected type ‘Word16’ with actual type ‘Word32’
zip               >     • In the second argument of ‘($)’, namely
zip               >         ‘(w `shiftR` 16) .&. 0x0fff’
zip               >       In the expression: CMode $ (w `shiftR` 16) .&. 0x0fff
zip               >       In an equation for ‘toFileMode’:
zip               >           toFileMode w = CMode $ (w `shiftR` 16) .&. 0x0fff
zip               >    |
zip               > 31 | toFileMode w = CMode $ (w `shiftR` 16) .&. 0x0fff
zip               >    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
zip               > 
zip               > /private/var/folders/j7/fgt692sj0wzg0lvrk86ctnxc0000gn/T/stack77859/zip-1.4.0/Codec/Archive/Zip/Unix.hs:42:26: error:
zip               >     • Couldn't match expected type ‘Word32’ with actual type ‘Word16’
zip               >     • In the expression: (0o100000 .|. c) `shiftL` 16
zip               >       In an equation for ‘fromFileMode’:
zip               >           fromFileMode (CMode c) = (0o100000 .|. c) `shiftL` 16
zip               >    |
zip               > 42 | fromFileMode (CMode c) = (0o100000 .|. c) `shiftL` 16
zip               >    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
zip               > 
saurabhnanda commented 4 years ago

I tried the following, which uses GHC 8.4.4, but it gave the same error:

stack build zip-1.4.0 --resolver=lts-12.26
saurabhnanda commented 4 years ago

Same error with:

saurabhnanda commented 4 years ago

For some strange reason, on my Mac OSX machine, CMode is defined as:

newtype CMode = CMode Word16    -- Defined in ‘System.Posix.Types’

And here's where the documentation says:

This module contains platform specific information about types. As such the types presented on this page reflect the platform on which the documentation was generated and may not coincide with the types on your platform.

saurabhnanda commented 4 years ago

Is there any way to make the code for toFileMode and fromFileMode platform-specific? Also, are these functions actually being used in the library anywhere?

mrkkrp commented 4 years ago

PS: Btw, hackage doesn't have docs for 1.3.0, .1.3.1, 1.3.2, and 1.4.0

Apparently Hackage doesn't have the bz2 library. I uploaded the docs manually for 1.4.0.

Good catch re CMode I'll see how to fix it perhaps later today.

saurabhnanda commented 4 years ago

@mrkkrp does packDirRecur preserve file permissions as much as possible?

saurabhnanda commented 4 years ago

@mrkkrp or is the library user supposed to handle the preservation of file permissions via the second argument to the function, i.e.

(FilePath -> ZipArchive EntrySelector)
-- ^ How to get EntrySelector from a path relative to the root of the directory we pack

If this is the case, is there a convenience function within the library to help with this common use-case?