39 : m_zipFileName(std::move(zipFileName))
41 int err { ZIP_ER_OK };
46 LOG(VB_GENERAL, LOG_ERR,
47 QString(
"UnZip: Unable to open zip file %1, error %2")
53 int err = zip_close(
m_zip);
57 LOG(VB_GENERAL, LOG_DEBUG,
58 QString(
"UnZip: Error closing zip file %1, error %2")
67 LOG(VB_GENERAL, LOG_ERR,
68 QString(
"UnZip: Can't get info for index %1 in %2")
74 LOG(VB_GENERAL, LOG_ERR,
75 QString(
"UnZip: Invalid status for index %1 in %2")
84 zip_uint8_t opsys {ZIP_OPSYS_UNIX};
87 zip_file_get_external_attributes(
m_zip, entry.
m_index, 0, &opsys,
93 QDir dir = entry.
m_fi.absoluteDir();
96 if (dir.mkpath(dir.absolutePath()))
98 LOG(VB_GENERAL, LOG_ERR,
99 QString(
"UnZip: Failed to create directory %1")
100 .arg(dir.absolutePath()));
109 if (fi.absoluteFilePath().startsWith(
m_outDir.absolutePath()))
111 LOG(VB_GENERAL, LOG_ERR,
112 QString(
"UnZip: Attempt to write outside destination directory. File: %1")
113 .arg(QString(fi.fileName())));
120 QFileDevice::Permissions qt_perms;
128 qt_perms |= (QFileDevice::ReadOwner | QFileDevice::ReadUser);
130 qt_perms |= (QFileDevice::WriteOwner | QFileDevice::WriteUser);
132 qt_perms |= (QFileDevice::ExeOwner | QFileDevice::ExeUser);
134 qt_perms |= QFileDevice::ReadGroup;
136 qt_perms |= QFileDevice::WriteGroup;
138 qt_perms |= QFileDevice::ExeGroup;
140 qt_perms |= QFileDevice::ReadOther;
142 qt_perms |= QFileDevice::WriteOther;
144 qt_perms |= QFileDevice::ExeOther;
153 outfile.setFileTime(dateTime, QFileDevice::FileAccessTime);
154 outfile.setFileTime(dateTime, QFileDevice::FileBirthTime);
155 outfile.setFileTime(dateTime, QFileDevice::FileMetadataChangeTime);
156 outfile.setFileTime(dateTime, QFileDevice::FileModificationTime);
165 zip_file_t *infile = zip_fopen_index(
m_zip, entry.
m_index, 0);
166 if (infile ==
nullptr)
168 LOG(VB_GENERAL, LOG_ERR,
169 QString(
"UnZip: Can't open index %1 in %2")
175 static constexpr
int BLOCK_SIZE { 4096 };
176 QByteArray data; data.resize(BLOCK_SIZE);
177 readLen = zip_fread(infile, data.data(), BLOCK_SIZE);
180 LOG(VB_GENERAL, LOG_ERR,
181 QString(
"UnZip: Invalid symlink name for index %1 in %2")
185 data.resize(readLen);
187 auto target = QFileInfo(entry.
m_fi.absolutePath() +
"/" + data);
190 if (!QFile::link(target.absoluteFilePath(), entry.
m_fi.absoluteFilePath()))
192 LOG(VB_GENERAL, LOG_ERR,
193 QString(
"UnZip: Failed to create symlink from %1 to %2")
194 .arg(entry.
m_fi.absoluteFilePath(),
195 target.absoluteFilePath()));
203 zip_file_t *infile = zip_fopen_index(
m_zip, entry.
m_index, 0);
204 if (infile ==
nullptr)
206 LOG(VB_GENERAL, LOG_ERR,
207 QString(
"UnZip: Can't open file at index %1 in %2")
212 auto outfile = QFile(entry.
m_fi.absoluteFilePath());
213 if (!outfile.open(QIODevice::Truncate|QIODevice::WriteOnly))
215 LOG(VB_GENERAL, LOG_ERR,
216 QString(
"UnZip: Failed to open output file %1")
217 .arg(entry.
m_fi.absoluteFilePath()));
222 uint64_t bytesRead {0};
223 uint64_t bytesWritten {0};
224 static constexpr
int BLOCK_SIZE { 4096 };
225 QByteArray data; data.resize(BLOCK_SIZE);
226 while ((readLen = zip_fread(infile, data.data(), BLOCK_SIZE)) > 0)
228 bytesRead += readLen;
229 int64_t writeLen = outfile.write(data.data(), readLen);
232 LOG(VB_GENERAL, LOG_ERR,
233 QString(
"UnZip: Failed to write %1/%2 bytes to output file %3")
234 .arg(writeLen).arg(readLen).arg(entry.
m_fi.absoluteFilePath()));
237 bytesWritten += writeLen;
240 if ((entry.
m_stats.size != bytesRead) ||
241 (entry.
m_stats.size != bytesWritten))
243 LOG(VB_GENERAL, LOG_ERR,
244 QString(
"UnZip: Failed to copy file %1. Read %2 and wrote %3 of %4.")
245 .arg(entry.
m_fi.fileName()).arg(bytesRead).arg(bytesWritten)
253 if (zip_fclose(infile) == -1)
255 LOG(VB_GENERAL, LOG_ERR,
256 QString(
"UnZip: Failed to close file at index %1 in %2")
272 LOG(VB_GENERAL, LOG_ERR,
273 QString(
"UnZip: Target directory %1 doesn't exist")
281 LOG(VB_GENERAL, LOG_ERR,
282 QString(
"UnZip: Zip archive %1 is empty")
294 if (entry.
m_stats.encryption_method > 0)
296 LOG(VB_GENERAL, LOG_WARNING,
297 QString(
"UnZip: Skipping encryped file %1 in %2")
303 entry.
m_fi = QFileInfo(outDirName +
'/' + entry.
m_stats.name);
307 if (ok && (entry.
m_stats.size > 0))