quazip
quazip copied to clipboard
quazip don't extract file as symlink on linux
I have a zip file with symlinks but when I extracted files with quazip symlinked files looks like file with text to symlinked file so this https://github.com/stachenov/quazip/commit/0e5c7adc87e9d23aa80f512b282fbe526d1cc05b don't work on linux
I had no idea ZIP even supported symlinks. I'll look into it.
@stachenov zip -y btw so I don't get that commit :) what was the purpose ? :)
No, wait. Is that my commit? Change “haad no idea” to “totally forgot” and say again, what's your problem? Show me the shortest code that doesn't work.
@stachenov Ou sorry It is my fault :) I will need to check it one more time
@stachenov My code look like this:
QuaZip zip( filename );
QuaZipFile zipFile( &zip );
for( bool hasMore = zip.goToFirstFile(); hasMore; hasMore = zip.goToNextFile() )
{
zipFile.open( QIODevice::ReadOnly );
while( ( len = zipFile.read( buf, BUF_SIZE ) ) > 0 )
{
outputFile.write( buf, len );
}
}
Ok so how can I detect if file in zip is symlink ?
it looks like minizip continue in development here https://github.com/nmoinvaz/minizip They also have 1.2 branch
Yes, I know, but QuaZIP needs some extra modifications in minizip. It can't be used as-is.
I found that all information is in externalAttr So I have one method
void UpdateDownloader::getFileInfo( quint32 val, bool & isDir, bool & isSymlink ) const
{
quint32 unixData = val >> 16;
isDir = ( unixData & 0170000 ) == 0040000;
isSymlink = ( unixData & 0170000 ) == 0120000;
}
QuaZipFileInfo64 info;
zip.getCurrentFileInfo( &info );
bool isDir, isSymlink;
getFileInfo( info.externalAttr, isDir, isSymlink );
ispiration is from https://github.com/nmoinvaz/minizip/blob/master/mz_zip.c#L2559 so you can detect directory and symlink with this
Right, it's the same bits that are used in QuaZipNewInfo
(the commit you linked from your first post). Well, almost the same. I don't know whether it's unixData & 0170000
or unixData & 0120000
. But that's not too important right now. What's important is that it turned out that QuaZIP currently supports symlink creation in the archives, but not extraction. You can do it manually for now, and I'll add a convenience method into QuaZipFileInfo64
later.
Could you tell me if it's been fixed? or How can i to fix it.
It seems that the quazip
extract file by copy data, but doesn't handle file attributes?
QuaZip is now stuck between 0.9.x and 1.0, thanks to CMake... There's the v0.9.x
branch, however. If you figure out how to do it, feel free to send a PR to that branch, and I'll make it 0.10 or something. Or wait until I get to it myself, but I can't make any promises how soon it will be done. Thanks for reminding me about it, though.
I sort of fixed this now with e226541cedfa611dcdbb01163772e51eda2717b6, but I'm not sure what happens if someone tries to extract an archive containing symbolic links on Windows. Qt will probably end up creating shortcuts instead, which will probably won't be what the user expect because they won't be named *.lnk
and therefore won't be recognized by the OS.
Added a Windows test in 54fd26ebf78cb51347efc3835ab480c651c3539c. Looks like it works as expected, except that links are broken, but they are useless anyway. At least extraction works in general.
The only part I'm unsure of now is this:
static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
QFile::Permissions perm, bool isDir, bool isSymLink = false)
{
quint32 uPerm = isDir ? 0040000 : 0100000;
if ( isSymLink ) {
#ifdef Q_OS_WIN
uPerm = 0200000;
#else
uPerm = 0120000;
#endif
}
I couldn't find what that Windows mask means for Unix permissions. Currently this code is executed for both symbolic links and shortcuts on Qt versions up to 5.13.x, and since 5.14 it is only executed for symbolic links, which are a rare beast on Windows. This code is sort of harmless too because the worst it can do is create ZIP archives with broken links inside. But I'll keep this open for a while in case someone has an idea how to do it right.