summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/quazip/quazipnewinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/quazip/quazipnewinfo.cpp')
-rw-r--r--rbutil/rbutilqt/quazip/quazipnewinfo.cpp284
1 files changed, 251 insertions, 33 deletions
diff --git a/rbutil/rbutilqt/quazip/quazipnewinfo.cpp b/rbutil/rbutilqt/quazip/quazipnewinfo.cpp
index 17571f2fc8..02e01da9c5 100644
--- a/rbutil/rbutilqt/quazip/quazipnewinfo.cpp
+++ b/rbutil/rbutilqt/quazip/quazipnewinfo.cpp
@@ -1,53 +1,98 @@
1/* -- A kind of "standard" GPL license statement -- 1/*
2QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package 2Copyright (C) 2005-2014 Sergey A. Tachenov
3Copyright (C) 2005-2007 Sergey A. Tachenov 3
4 4This file is part of QuaZIP.
5This program is free software; you can redistribute it and/or modify it 5
6under the terms of the GNU General Public License as published by the 6QuaZIP is free software: you can redistribute it and/or modify
7Free Software Foundation; either version 2 of the License, or (at your 7it under the terms of the GNU Lesser General Public License as published by
8option) any later version. 8the Free Software Foundation, either version 2.1 of the License, or
9 9(at your option) any later version.
10This program is distributed in the hope that it will be useful, but 10
11WITHOUT ANY WARRANTY; without even the implied warranty of 11QuaZIP is distributed in the hope that it will be useful,
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 12but WITHOUT ANY WARRANTY; without even the implied warranty of
13Public License for more details. 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14GNU Lesser General Public License for more details.
15You should have received a copy of the GNU General Public License along 15
16with this program; if not, write to the Free Software Foundation, Inc., 16You should have received a copy of the GNU Lesser General Public License
1759 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18 18
19-- A kind of "standard" GPL license statement ends here -- 19See COPYING file for the full LGPL text.
20 20
21See COPYING file for GPL. 21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23You are also permitted to use QuaZIP under the terms of LGPL (see
24COPYING.LGPL). You are free to choose either license, but please note
25that QuaZIP makes use of Qt, which is not licensed under LGPL. So if
26you are using Open Source edition of Qt, you therefore MUST use GPL for
27your code based on QuaZIP, since it would be also based on Qt in this
28case. If you are Qt commercial license owner, then you are free to use
29QuaZIP as long as you respect either GPL or LGPL for QuaZIP code.
30*/ 23*/
31 24
32#include <QFileInfo> 25#include <QFileInfo>
33 26
34#include "quazipnewinfo.h" 27#include "quazipnewinfo.h"
35 28
29#include <string.h>
30
31static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
32 QFile::Permissions perm, bool isDir)
33{
34 quint32 uPerm = isDir ? 0040000 : 0100000;
35 if ((perm & QFile::ReadOwner) != 0)
36 uPerm |= 0400;
37 if ((perm & QFile::WriteOwner) != 0)
38 uPerm |= 0200;
39 if ((perm & QFile::ExeOwner) != 0)
40 uPerm |= 0100;
41 if ((perm & QFile::ReadGroup) != 0)
42 uPerm |= 0040;
43 if ((perm & QFile::WriteGroup) != 0)
44 uPerm |= 0020;
45 if ((perm & QFile::ExeGroup) != 0)
46 uPerm |= 0010;
47 if ((perm & QFile::ReadOther) != 0)
48 uPerm |= 0004;
49 if ((perm & QFile::WriteOther) != 0)
50 uPerm |= 0002;
51 if ((perm & QFile::ExeOther) != 0)
52 uPerm |= 0001;
53 info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
54}
55
56template<typename FileInfo>
57void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing)
58{
59 self.name = existing.name;
60 self.dateTime = existing.dateTime;
61 self.internalAttr = existing.internalAttr;
62 self.externalAttr = existing.externalAttr;
63 self.comment = existing.comment;
64 self.extraLocal = existing.extra;
65 self.extraGlobal = existing.extra;
66 self.uncompressedSize = existing.uncompressedSize;
67}
68
69QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing)
70{
71 QuaZipNewInfo_init(*this, existing);
72}
73
74QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing)
75{
76 QuaZipNewInfo_init(*this, existing);
77}
36 78
37QuaZipNewInfo::QuaZipNewInfo(const QString& name): 79QuaZipNewInfo::QuaZipNewInfo(const QString& name):
38 name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0) 80 name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0),
81 uncompressedSize(0)
39{ 82{
40} 83}
41 84
42QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file): 85QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
43 name(name), internalAttr(0), externalAttr(0) 86 name(name), internalAttr(0), externalAttr(0), uncompressedSize(0)
44{ 87{
45 QFileInfo info(file); 88 QFileInfo info(file);
46 QDateTime lm = info.lastModified(); 89 QDateTime lm = info.lastModified();
47 if (!info.exists()) 90 if (!info.exists()) {
48 dateTime = QDateTime::currentDateTime(); 91 dateTime = QDateTime::currentDateTime();
49 else 92 } else {
50 dateTime = lm; 93 dateTime = lm;
94 QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir());
95 }
51} 96}
52 97
53void QuaZipNewInfo::setFileDateTime(const QString& file) 98void QuaZipNewInfo::setFileDateTime(const QString& file)
@@ -57,3 +102,176 @@ void QuaZipNewInfo::setFileDateTime(const QString& file)
57 if (info.exists()) 102 if (info.exists())
58 dateTime = lm; 103 dateTime = lm;
59} 104}
105
106void QuaZipNewInfo::setFilePermissions(const QString &file)
107{
108 QFileInfo info = QFileInfo(file);
109 QFile::Permissions perm = info.permissions();
110 QuaZipNewInfo_setPermissions(this, perm, info.isDir());
111}
112
113void QuaZipNewInfo::setPermissions(QFile::Permissions permissions)
114{
115 QuaZipNewInfo_setPermissions(this, permissions, name.endsWith('/'));
116}
117
118void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName)
119{
120 QFileInfo fi(fileName);
121 if (!fi.exists()) {
122 qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist",
123 fileName.toUtf8().constData());
124 return;
125 }
126 setFileNTFSmTime(fi.lastModified());
127 setFileNTFSaTime(fi.lastRead());
128 setFileNTFScTime(fi.created());
129}
130
131static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position,
132 int fineTicks) {
133 int ntfsPos = -1, timesPos = -1;
134 unsigned ntfsLength = 0, ntfsTimesLength = 0;
135 for (int i = 0; i <= extra.size() - 4; ) {
136 unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
137 extra.at(i)))
138 | (static_cast<unsigned>(static_cast<unsigned char>(
139 extra.at(i + 1))) << 8);
140 i += 2;
141 unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
142 extra.at(i)))
143 | (static_cast<unsigned>(static_cast<unsigned char>(
144 extra.at(i + 1))) << 8);
145 i += 2;
146 if (type == QUAZIP_EXTRA_NTFS_MAGIC) {
147 ntfsPos = i - 4; // the beginning of the NTFS record
148 ntfsLength = length;
149 if (length <= 4) {
150 break; // no times in the NTFS record
151 }
152 i += 4; // reserved
153 while (i <= extra.size() - 4) {
154 unsigned tag = static_cast<unsigned>(
155 static_cast<unsigned char>(extra.at(i)))
156 | (static_cast<unsigned>(
157 static_cast<unsigned char>(extra.at(i + 1)))
158 << 8);
159 i += 2;
160 unsigned tagsize = static_cast<unsigned>(
161 static_cast<unsigned char>(extra.at(i)))
162 | (static_cast<unsigned>(
163 static_cast<unsigned char>(extra.at(i + 1)))
164 << 8);
165 i += 2;
166 if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) {
167 timesPos = i - 4; // the beginning of the NTFS times tag
168 ntfsTimesLength = tagsize;
169 break;
170 } else {
171 i += tagsize;
172 }
173 }
174 break; // I ain't going to search for yet another NTFS record!
175 } else {
176 i += length;
177 }
178 }
179 if (ntfsPos == -1) {
180 // No NTFS record, need to create one.
181 ntfsPos = extra.size();
182 ntfsLength = 32;
183 extra.resize(extra.size() + 4 + ntfsLength);
184 // the NTFS record header
185 extra[ntfsPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC);
186 extra[ntfsPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC >> 8);
187 extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian
188 extra[ntfsPos + 3] = 0;
189 // zero the record
190 memset(extra.data() + ntfsPos + 4, 0, 32);
191 timesPos = ntfsPos + 8;
192 // now set the tag data
193 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
194 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
195 >> 8);
196 // the size:
197 extra[timesPos + 2] = 24;
198 extra[timesPos + 3] = 0;
199 ntfsTimesLength = 24;
200 }
201 if (timesPos == -1) {
202 // No time tag in the NTFS record, need to add one.
203 timesPos = ntfsPos + 4 + ntfsLength;
204 extra.resize(extra.size() + 28);
205 // Now we need to move the rest of the field
206 // (possibly zero bytes, but memmove() is OK with that).
207 // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos
208 // <some data> <header> <NTFS record> <need-to-move data> <end>
209 memmove(extra.data() + timesPos + 28, extra.data() + timesPos,
210 extra.size() - 28 - timesPos);
211 ntfsLength += 28;
212 // now set the tag data
213 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
214 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
215 >> 8);
216 // the size:
217 extra[timesPos + 2] = 24;
218 extra[timesPos + 3] = 0;
219 // zero the record
220 memset(extra.data() + timesPos + 4, 0, 24);
221 ntfsTimesLength = 24;
222 }
223 if (ntfsTimesLength < 24) {
224 // Broken times field. OK, this is really unlikely, but just in case...
225 size_t timesEnd = timesPos + 4 + ntfsTimesLength;
226 extra.resize(extra.size() + (24 - ntfsTimesLength));
227 // Move it!
228 // 0 ......... timesPos .... timesPos + 4 .. timesEnd
229 // <some data> <time header> <broken times> <need-to-move data> <end>
230 memmove(extra.data() + timesEnd + (24 - ntfsTimesLength),
231 extra.data() + timesEnd,
232 extra.size() - (24 - ntfsTimesLength) - timesEnd);
233 // Now we have to increase the NTFS record and time tag lengths.
234 ntfsLength += (24 - ntfsTimesLength);
235 ntfsTimesLength = 24;
236 extra[ntfsPos + 2] = static_cast<char>(ntfsLength);
237 extra[ntfsPos + 3] = static_cast<char>(ntfsLength >> 8);
238 extra[timesPos + 2] = static_cast<char>(ntfsTimesLength);
239 extra[timesPos + 3] = static_cast<char>(ntfsTimesLength >> 8);
240 }
241 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
242#if (QT_VERSION >= 0x040700)
243 quint64 ticks = base.msecsTo(time) * 10000 + fineTicks;
244#else
245 QDateTime utc = time.toUTC();
246 quint64 ticks = (static_cast<qint64>(base.date().daysTo(utc.date()))
247 * Q_INT64_C(86400000)
248 + static_cast<qint64>(base.time().msecsTo(utc.time())))
249 * Q_INT64_C(10000) + fineTicks;
250#endif
251 extra[timesPos + 4 + position] = static_cast<char>(ticks);
252 extra[timesPos + 5 + position] = static_cast<char>(ticks >> 8);
253 extra[timesPos + 6 + position] = static_cast<char>(ticks >> 16);
254 extra[timesPos + 7 + position] = static_cast<char>(ticks >> 24);
255 extra[timesPos + 8 + position] = static_cast<char>(ticks >> 32);
256 extra[timesPos + 9 + position] = static_cast<char>(ticks >> 40);
257 extra[timesPos + 10 + position] = static_cast<char>(ticks >> 48);
258 extra[timesPos + 11 + position] = static_cast<char>(ticks >> 56);
259}
260
261void QuaZipNewInfo::setFileNTFSmTime(const QDateTime &mTime, int fineTicks)
262{
263 setNTFSTime(extraLocal, mTime, 0, fineTicks);
264 setNTFSTime(extraGlobal, mTime, 0, fineTicks);
265}
266
267void QuaZipNewInfo::setFileNTFSaTime(const QDateTime &aTime, int fineTicks)
268{
269 setNTFSTime(extraLocal, aTime, 8, fineTicks);
270 setNTFSTime(extraGlobal, aTime, 8, fineTicks);
271}
272
273void QuaZipNewInfo::setFileNTFScTime(const QDateTime &cTime, int fineTicks)
274{
275 setNTFSTime(extraLocal, cTime, 16, fineTicks);
276 setNTFSTime(extraGlobal, cTime, 16, fineTicks);
277}