sharpcompress icon indicating copy to clipboard operation
sharpcompress copied to clipboard

tar extraction doesn't preserve file permissions

Open MichaelJCompton opened this issue 8 years ago • 7 comments

v0.18.2, netcoreapp2.0 on linux/mac,

tar contains

-rw-rw-r--  ... blaa.md
-rwxrwxrwx  ... blaa.sh

result of extraction is

-rw-r--r-- ... blaa.md
-rw-r--r--  ... blaa.sh

(PreserveAttributes option to ExtractionOptions not implemented)

MichaelJCompton avatar Dec 06 '17 23:12 MichaelJCompton

Applying file permissions is kind of out of scope. The file extraction methods are just convenience.

adamhathcock avatar Dec 07 '17 13:12 adamhathcock

I don't mind extracting the files myself, but there is currently no way to get what the file permissions should be.

I think they should at least be exposed in the TarHeader so that implementors can choose to use mode/user/group if they choose.

https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Tar/Headers/TarHeader.cs#L121

pauldotknopf avatar Apr 12 '19 19:04 pauldotknopf

Sounds like a good PR to me :)

adamhathcock avatar Apr 13 '19 09:04 adamhathcock

5 years later, there seems to be code for reading the permissions but is commented out, using PreserveAttributes throws NotImplementedException. If setting permissions is out of the scope, can we please get a delegate for setting permissions, just like we have for creating symlinks? Since UNIX permissions might not apply for Windows, alternatively just make the permission properties public and let the developers handle it in the ExtractAllEntries loop

Ryhon0 avatar Apr 10 '22 21:04 Ryhon0

Sounds like a good PR to me :)

adamhathcock avatar Apr 11 '22 06:04 adamhathcock

No idea if that is the correct way to implement it. Can be tested with following code:

public static void Main()
{
	using (Stream stream = File.OpenRead("Tar.tar"))
	using (IReader reader = ReaderFactory.Open(stream))
	{
		int x = 0;
		while (reader.MoveToNextEntry())
		{
			var en = reader.Entry as TarEntry;
			Console.WriteLine($"{en.Key}\t" +
				$"{PermissionString(en.Mode)}\t" +
				$"{en.UserID}\t" +
				$"{en.GroupId}");
		}
	}
}

public static string PermissionString(long perms)
{
	const string ss = "drwxrwxrwx";
	const string ns = "----------";
	string s =  "";
	for(int i = 0; i < ss.Length; i++)
	{
		s += (perms & (1 << ss.Length - i - 1)) == 0 ? ns[i] : ss[i];
	}
	return s;
}

Ryhon0 avatar Apr 11 '22 12:04 Ryhon0

Thanks for the PR!

adamhathcock avatar Apr 11 '22 15:04 adamhathcock