diff --git a/launcher/archive/ArchiveReader.cpp b/launcher/archive/ArchiveReader.cpp index 638d4b6d5..a866b49c5 100644 --- a/launcher/archive/ArchiveReader.cpp +++ b/launcher/archive/ArchiveReader.cpp @@ -84,7 +84,7 @@ auto ArchiveReader::goToFile(QString filename) -> std::unique_ptr archive_read_support_format_all(a); archive_read_support_filter_all(a); auto fileName = m_archivePath.toUtf8(); - if (archive_read_open_filename(a, fileName.constData(), 10240) != ARCHIVE_OK) { + if (archive_read_open_filename(a, fileName.constData(), m_blockSize) != ARCHIVE_OK) { qCritical() << "Failed to open archive file:" << m_archivePath << "-" << archive_error_string(a); return nullptr; } @@ -158,8 +158,7 @@ bool ArchiveReader::parse(std::function doStuff) archive_read_support_format_all(a); archive_read_support_filter_all(a); auto fileName = m_archivePath.toUtf8(); - const auto blockSize = 10240; - if (archive_read_open_filename(a, fileName.constData(), blockSize) != ARCHIVE_OK) { + if (archive_read_open_filename(a, fileName.constData(), m_blockSize) != ARCHIVE_OK) { qCritical() << "Failed to open archive file:" << m_archivePath << "-" << f->error(); return false; } diff --git a/launcher/archive/ArchiveReader.h b/launcher/archive/ArchiveReader.h index 56455de63..379006278 100644 --- a/launcher/archive/ArchiveReader.h +++ b/launcher/archive/ArchiveReader.h @@ -65,6 +65,7 @@ class ArchiveReader { private: QString m_archivePath; + size_t m_blockSize = 10240; QStringList m_fileNames = {}; }; diff --git a/launcher/archive/ArchiveWriter.cpp b/launcher/archive/ArchiveWriter.cpp index f69ee3f74..87cead69c 100644 --- a/launcher/archive/ArchiveWriter.cpp +++ b/launcher/archive/ArchiveWriter.cpp @@ -105,21 +105,23 @@ bool ArchiveWriter::addFile(const QString& fileName, const QString& fileDest) if (stat(cpath, &st) != 0) { qCritical() << "Failed to stat file:" << fileInfo.filePath(); } + // This should handle the copying of most attributes archive_entry_copy_stat(entry, &st); - archive_entry_set_perm(entry, fileInfo.permissions()); + // However: + // "The [filetype] constants used by stat(2) may have different numeric values from the corresponding [libarchive constants]." + // - `archive_entry_stat(3)` if (fileInfo.isSymLink()) { + archive_entry_set_filetype(entry, AE_IFLNK); + + // We also need to manually copy some attributes from the link itself, as `stat` above operates on its target auto target = fileInfo.symLinkTarget().toUtf8(); archive_entry_set_symlink(entry, target.constData()); - - if (archive_write_header(m_archive, entry) != ARCHIVE_OK) { - qCritical() << "Failed to write symlink header for:" << fileDest << "-" << archive_error_string(m_archive); - return false; - } - return true; - } - - if (!fileInfo.isFile() && !fileInfo.isDir()) { + archive_entry_set_size(entry, 0); + archive_entry_set_perm(entry, fileInfo.permissions()); + } else if (fileInfo.isFile()) { + archive_entry_set_filetype(entry, AE_IFREG); + } else { qCritical() << "Unsupported file type:" << fileInfo.filePath(); return false; } @@ -129,7 +131,7 @@ bool ArchiveWriter::addFile(const QString& fileName, const QString& fileDest) return false; } - if (fileInfo.isFile()) { + if (fileInfo.isFile() && !fileInfo.isSymLink()) { QFile file(fileInfo.absoluteFilePath()); if (!file.open(QIODevice::ReadOnly)) { qCritical() << "Failed to open file: " << fileInfo.filePath(); @@ -153,6 +155,7 @@ bool ArchiveWriter::addFile(const QString& fileName, const QString& fileDest) } } } + return true; }