SharpZipLib icon indicating copy to clipboard operation
SharpZipLib copied to clipboard

Add support for restoring/setting posix file permissions

Open Hawxy opened this issue 5 years ago • 9 comments

Steps to reproduce

  1. Create a file and apply the execute permission
  2. Create a tar.gz and pass the -p flag to preserve permissions
  3. Extract the tar.gz using SharpZipLib, eg
            await using (FileStream fileStream = File.OpenRead("<---TARFILE--->"))
            {
                await using (Stream inputStream = new GZipInputStream(fileStream))
                {
                    using (TarArchive inputTarArchive = TarArchive.CreateInputTarArchive(inputStream))
                    {                     
                        inputTarArchive.ExtractContents(outputDirectory);
                    }
                }
            }

Expected behavior

The execute permission should be preserved in the output file if extracted on linux, as per extracting via the tar command.

Actual behavior

The execute permission is lost and the file defaults to 644.

Version of SharpZipLib

1.2

Obtained from

  • Package installed using NuGet

Hawxy avatar Feb 09 '20 12:02 Hawxy

This is unfortunately not possible to do in .NET Standard right now since there is no support for POSIX style permissions. That being said, there is the Mono.Posix.NETStandard nuget package, but we don't want to add it as a dependency for just this feature.

You should be able to listen to the TarArchive.ProgressMessageEvent and set the file permissions for the entry file on each call perhaps?

piksel avatar Mar 27 '20 19:03 piksel

would it be possible to do it by p/invoking the native functions directly, or is that too likely to cause issues with different platforms/implementations and such?

Numpsy avatar Mar 27 '20 22:03 Numpsy

@Numpsy +1, chmod has pretty simple prototype, so it would be easy to use on Linux/macOS in TarArchive.ExtractContents().

But it's not so obvious if you want to create an archive, because getting unix file attributes requires stat() and struct stat definitions but they are all different on Linux x64, Linux arm64, and macOS (I have checked it) and probably on other platforms also.

k15tfu avatar May 26 '20 08:05 k15tfu

@piksel Unfortunately TarArchive.ProgressMessageEvent gets called before each entry will be extracted to disk, so I can't chmod these files in 1 iteration. Probably the best I can is to TarArchive.ExtractContents to extract files first and then TarArchive.ListContents to chmod them.

k15tfu avatar May 26 '20 09:05 k15tfu

That's a bummer. I would really like to have a way to co-operate with an external library to achieve this. Perhaps we can add another Event for post extraction of a file?

Same thing for creation, it should be possible to add something like a hook for adding additional meta data for files, where the consumer could use whatever solution for getting the additional file data they want and adding it to the file entry.

piksel avatar May 27 '20 21:05 piksel

Perhaps we can add another Event for post extraction of a file?

FastZip has a 'CompletedFile' delegate that gets called after a file is done - maybe something consistent with that?

Same thing for creation, it should be possible to add something like a hook for adding additional meta data for files, where the consumer could use whatever solution for getting the additional file data they want and adding it to the file entry.

There may be several possible approaches (e.g. make the file event delegates return extra data rather than just bools, have a dedicated interface for it, extend TarArchive to use a TarEntryFactory in a similar way to ZipEntryFactory and wire it up through that). Don't know what the best approach is though.

Numpsy avatar May 28 '20 11:05 Numpsy

Any update on this ~PR~ issue? When extracting contents none of the files have execute permissions (which I need as I am writing an updater), and don't see an immediate fix. Using .NET 5 across win, linux, and mac

However when inspecting the tar gz archive itself the files all have rwe permissions

nolanblew avatar Dec 06 '21 21:12 nolanblew

This isn't a PR, and no concrete solution has been submitted. Adding the event makes it easier to apply the permissions, but there is no built in support for Unix style permissions in .NET afaik. I can look into implementing the event at least though.

piksel avatar Dec 07 '21 09:12 piksel

This is unfortunately not possible to do in .NET Standard right now since there is no support for POSIX style permissions

It is possible since NET7 https://learn.microsoft.com/en-us/dotnet/api/system.io.unixfilemode?view=net-7.0

gleblebedev avatar Oct 02 '23 22:10 gleblebedev