Unix permissions stuff

This commit is contained in:
alqualos 2012-12-15 14:54:30 +00:00
parent e6c5782071
commit d66695a9b2
6 changed files with 110 additions and 10 deletions

View file

@ -153,8 +153,13 @@ bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
return false;
}
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir())
return true;
QuaZipFileInfo info;
if (!zip->getCurrentFileInfo(&info))
return false;
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
return QFile(fileDest).setPermissions(info.getPermissions());
}
// Apro il file risultato
QFile outFile;
@ -176,7 +181,7 @@ bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
return false;
}
return true;
return outFile.setPermissions(info.getPermissions());
}
/**

View file

@ -0,0 +1,26 @@
#include "quazipfileinfo.h"
QFile::Permissions QuaZipFileInfo::getPermissions() const
{
quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
QFile::Permissions perm = 0;
if ((uPerm & 0400) != 0)
perm |= QFile::ReadOwner;
if ((uPerm & 0200) != 0)
perm |= QFile::WriteOwner;
if ((uPerm & 0100) != 0)
perm |= QFile::ExeOwner;
if ((uPerm & 0040) != 0)
perm |= QFile::ReadGroup;
if ((uPerm & 0020) != 0)
perm |= QFile::WriteGroup;
if ((uPerm & 0010) != 0)
perm |= QFile::ExeGroup;
if ((uPerm & 0004) != 0)
perm |= QFile::ReadOther;
if ((uPerm & 0002) != 0)
perm |= QFile::WriteOther;
if ((uPerm & 0001) != 0)
perm |= QFile::ExeOther;
return perm;
}

View file

@ -26,6 +26,7 @@ quazip/(un)zip.h files for details, basically it's zlib license.
#include <QByteArray>
#include <QDateTime>
#include <QFile>
#include "quazip_global.h"
@ -61,6 +62,12 @@ struct QUAZIP_EXPORT QuaZipFileInfo {
QString comment;
/// Extra field.
QByteArray extra;
/// Get the file permissions.
/**
Returns the high 16 bits of external attributes converted to
QFile::Permissions.
*/
QFile::Permissions getPermissions() const;
};
#endif

View file

@ -25,6 +25,30 @@ quazip/(un)zip.h files for details, basically it's zlib license.
#include "quazipnewinfo.h"
static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
QFile::Permissions perm, bool isDir)
{
quint32 uPerm = isDir ? 0040000 : 0100000;
if ((perm & QFile::ReadOwner) != 0)
uPerm |= 0400;
if ((perm & QFile::WriteOwner) != 0)
uPerm |= 0200;
if ((perm & QFile::ExeOwner) != 0)
uPerm |= 0100;
if ((perm & QFile::ReadGroup) != 0)
uPerm |= 0040;
if ((perm & QFile::WriteGroup) != 0)
uPerm |= 0020;
if ((perm & QFile::ExeGroup) != 0)
uPerm |= 0010;
if ((perm & QFile::ReadOther) != 0)
uPerm |= 0004;
if ((perm & QFile::WriteOther) != 0)
uPerm |= 0002;
if ((perm & QFile::ExeOther) != 0)
uPerm |= 0001;
info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
}
QuaZipNewInfo::QuaZipNewInfo(const QString& name):
name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0)
@ -36,10 +60,12 @@ QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
{
QFileInfo info(file);
QDateTime lm = info.lastModified();
if (!info.exists())
if (!info.exists()) {
dateTime = QDateTime::currentDateTime();
else
} else {
dateTime = lm;
QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir());
}
}
void QuaZipNewInfo::setFileDateTime(const QString& file)
@ -49,3 +75,15 @@ void QuaZipNewInfo::setFileDateTime(const QString& file)
if (info.exists())
dateTime = lm;
}
void QuaZipNewInfo::setFilePermissions(const QString &file)
{
QFileInfo info = QFileInfo(file);
QFile::Permissions perm = info.permissions();
QuaZipNewInfo_setPermissions(this, perm, info.isDir());
}
void QuaZipNewInfo::setPermissions(QFile::Permissions permissions)
{
QuaZipNewInfo_setPermissions(this, permissions, name.endsWith('/'));
}

View file

@ -51,6 +51,11 @@ struct QUAZIP_EXPORT QuaZipNewInfo {
/// File internal attributes.
quint16 internalAttr;
/// File external attributes.
/**
The highest 16 bits contain Unix file permissions and type (dir or
file). The constructor QuaZipNewInfo(const QString&, const QString&)
takes permissions from the provided file.
*/
quint32 externalAttr;
/// File comment.
/** Will be encoded using QuaZip::getCommentCodec().
@ -72,10 +77,10 @@ struct QUAZIP_EXPORT QuaZipNewInfo {
**/
QuaZipNewInfo(const QString& name);
/// Constructs QuaZipNewInfo instance.
/** Initializes name with \a name and dateTime with timestamp of the
* file named \a file. If the \a file does not exists or its timestamp
/** Initializes name with \a name. Timestamp and permissions are taken
* from the specified file. If the \a file does not exists or its timestamp
* is inaccessible (e. g. you do not have read permission for the
* directory file in), uses current date and time. Attributes are
* directory file in), uses current time and zero permissions. Other attributes are
* initialized with zeros, comment and extra field with null values.
*
* \sa setFileDateTime()
@ -97,6 +102,20 @@ struct QUAZIP_EXPORT QuaZipNewInfo {
* file is inaccessible).
**/
void setFileDateTime(const QString& file);
/// Sets the file permissions from the existing file.
/**
Takes permissions from the file and sets the high 16 bits of
external attributes. Uses QFileInfo to get permissions on all
platforms.
*/
void setFilePermissions(const QString &file);
/// Sets the file permissions.
/**
Modifies the highest 16 bits of external attributes. The type part
is set to dir if the name ends with a slash, and to regular file
otherwise.
*/
void setPermissions(QFile::Permissions permissions);
};
#endif

View file

@ -137,6 +137,7 @@ void TestJlCompress::extractFile()
QFileInfo destInfo("jlext/jlfile/" + destName), srcInfo("tmp/" +
fileToExtract);
QCOMPARE(destInfo.size(), srcInfo.size());
QCOMPARE(destInfo.permissions(), srcInfo.permissions());
curDir.remove("jlext/jlfile/" + destName);
curDir.mkdir("jlext/jlfile/" + destName);
QVERIFY(JlCompress::extractFile(zipName, fileToExtract,
@ -176,7 +177,9 @@ void TestJlCompress::extractFiles()
"jlext/jlfiles").isEmpty());
foreach (QString fileName, filesToExtract) {
QFileInfo fileInfo("jlext/jlfiles/" + fileName);
QCOMPARE(fileInfo.size(), QFileInfo("tmp/" + fileName).size());
QFileInfo extInfo("tmp/" + fileName);
QCOMPARE(fileInfo.size(), extInfo.size());
QCOMPARE(fileInfo.permissions(), extInfo.permissions());
curDir.remove("jlext/jlfiles/" + fileName);
curDir.rmpath(fileInfo.dir().path());
}
@ -216,8 +219,10 @@ void TestJlCompress::extractDir()
foreach (QString fileName, fileNames) {
QString fullName = "jlext/jldir/" + fileName;
QFileInfo fileInfo(fullName);
QFileInfo extInfo("tmp/" + fileName);
if (!fileInfo.isDir())
QCOMPARE(fileInfo.size(), QFileInfo("tmp/" + fileName).size());
QCOMPARE(fileInfo.size(), extInfo.size());
QCOMPARE(fileInfo.permissions(), extInfo.permissions());
curDir.remove(fullName);
curDir.rmpath(fileInfo.dir().path());
QString absolutePath = fileInfo.absoluteFilePath();