Skip to content

Commit e2ff4ab

Browse files
committed
Replace libzlib with libarchive for decompression
1 parent 30b2659 commit e2ff4ab

File tree

8 files changed

+135
-246
lines changed

8 files changed

+135
-246
lines changed

src/src.pro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ else: unix:!android: target.path = /usr/bin/
152152
!isEmpty(target.path): INSTALLS += target
153153

154154
unix {
155-
LIBS += -ldl -lz
156-
QMAKE_LFLAGS += -ldl -lutil -lz #-fsanitize=address
155+
LIBS += -ldl
156+
QMAKE_LFLAGS += -ldl -lutil #-fsanitize=address
157157
QMAKE_CXXFLAGS += -g #-fno-omit-frame-pointer -fsanitize=address
158158

159159
CONFIG += link_pkgconfig
160160

161-
PKGCONFIG += glibmm-2.4 giomm-2.4
161+
PKGCONFIG += glibmm-2.4 giomm-2.4 libarchive
162162

163163
USE_PULSEAUDIO {
164164
PKGCONFIG += gstreamer-1.0 gstreamer-audio-1.0

src/subprojects/AutoEqIntegration/AutoEqIntegration.pri

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ HEADERS += \
1616
$$PWD/GzipDownloader.h \
1717
$$PWD/GzipDownloaderDialog.h \
1818
$$PWD/HttpException.h \
19-
$$PWD/untar.h
19+
$$PWD/Untar.h
2020

2121
SOURCES += \
2222
$$PWD/AeqMeasurementItem.cpp \

src/subprojects/AutoEqIntegration/GzipDownloader.cpp

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "GzipDownloader.h"
22

3+
#include "Untar.h"
4+
35
bool GzipDownloader::start(QNetworkReply *reply, QDir _extractionPath)
46
{
57
if(networkReply)
@@ -66,30 +68,17 @@ void GzipDownloader::onArchiveReady()
6668
{
6769
QDir(extractionPath).mkpath(extractionPath.path());
6870

69-
auto file = gzopen(downloadedFile.fileName().toStdString().c_str(), "rb");
70-
auto temp = std::tmpfile();
71-
72-
inflate(file, temp);
73-
gzclose(file);
74-
std::rewind(temp);
75-
76-
emit unarchiveStarted();
77-
78-
bool bad_checksum;
79-
bool short_read;
80-
81-
untar(temp, extractionPath.path().toStdString().c_str(), &bad_checksum, &short_read);
82-
std::fclose(temp);
71+
QString errorMsg;
72+
int ret = Untar::extract(downloadedFile.fileName(), extractionPath.path(), errorMsg);
73+
downloadedFile.remove();
8374

84-
if(bad_checksum)
75+
if(ret > 0)
8576
{
86-
return "Bad checksum, corrupted package. Please try again.";
77+
return errorMsg;
8778
}
88-
if(short_read)
89-
{
90-
return "Short read; expected 512 bytes but received less. Please try again.";
91-
}
92-
return "";
79+
80+
return QString("");
81+
9382
})).then([this](const QString& msg)
9483
{
9584
if(msg.isEmpty())

src/subprojects/AutoEqIntegration/GzipDownloader.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include <QtConcurrent/QtConcurrent>
77

88
#include <QtPromise>
9-
#include <untar.h>
10-
#include <zlib.h>
119

1210
#define TMP_DIR "/tmp/jamesdsp/download/"
1311
#define CHUNK 16384
@@ -33,7 +31,6 @@ class GzipDownloader : public QObject
3331
signals:
3432
void downloadProgressUpdated(qint64 bytesReceived, qint64 bytesTotal);
3533
void decompressionStarted();
36-
void unarchiveStarted();
3734
void success();
3835
void errorOccurred(QString errorString);
3936

@@ -45,7 +42,7 @@ private slots:
4542
void cleanup();
4643

4744
/* Decompress from file source to file dest until stream ends or EOF. */
48-
inline void inflate(gzFile_s *source, FILE *dest)
45+
/*inline void inflate(gzFile_s *source, FILE *dest)
4946
{
5047
unsigned char buf[CHUNK];
5148
@@ -54,7 +51,7 @@ private slots:
5451
size > 0;
5552
size = gzread(source, buf, CHUNK)
5653
) std::fwrite(buf, 1, CHUNK, dest);
57-
}
54+
}*/
5855

5956
private:
6057
QDir extractionPath;

src/subprojects/AutoEqIntegration/GzipDownloaderDialog.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ GzipDownloaderDialog::GzipDownloaderDialog(QNetworkReply* _reply, QDir _targetDi
1818
connect(gzip, &GzipDownloader::errorOccurred, this, &GzipDownloaderDialog::onError);
1919
connect(gzip, &GzipDownloader::downloadProgressUpdated, this, &GzipDownloaderDialog::onDownloadProgressUpdated);
2020
connect(gzip, &GzipDownloader::decompressionStarted, this, &GzipDownloaderDialog::onDecompressionStarted);
21-
connect(gzip, &GzipDownloader::unarchiveStarted, this, &GzipDownloaderDialog::onUnarchiveStarted);
2221

2322
reply = _reply;
2423
targetDirectory = _targetDirectory;
@@ -47,7 +46,6 @@ void GzipDownloaderDialog::closeEvent(QCloseEvent *ev)
4746
disconnect(gzip, &GzipDownloader::errorOccurred, this, &GzipDownloaderDialog::onError);
4847
disconnect(gzip, &GzipDownloader::downloadProgressUpdated, this, &GzipDownloaderDialog::onDownloadProgressUpdated);
4948
disconnect(gzip, &GzipDownloader::decompressionStarted, this, &GzipDownloaderDialog::onDecompressionStarted);
50-
disconnect(gzip, &GzipDownloader::unarchiveStarted, this, &GzipDownloaderDialog::onUnarchiveStarted);
5149
gzip->deleteLater();
5250

5351
QDialog::closeEvent(ev);
@@ -85,9 +83,3 @@ void GzipDownloaderDialog::onDecompressionStarted()
8583
ui->size->setText("");
8684
ui->buttonBox->setEnabled(false);
8785
}
88-
89-
void GzipDownloaderDialog::onUnarchiveStarted()
90-
{
91-
ui->title->setText("Extracting package...");
92-
ui->size->setText("");
93-
}

src/subprojects/AutoEqIntegration/GzipDownloaderDialog.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ private slots:
2828
void onError(const QString &msg);
2929
void onDownloadProgressUpdated(qint64 recv, qint64 total);
3030
void onDecompressionStarted();
31-
void onUnarchiveStarted();
3231

3332
private:
3433
Ui::FileDownloaderDialog *ui;
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#ifndef UNTAR_H
2+
#define UNTAR_H
3+
4+
#include <sys/types.h>
5+
#include <sys/stat.h>
6+
7+
#include <QDebug>
8+
#include <QString>
9+
#include <QDir>
10+
11+
#include <archive.h>
12+
#include <archive_entry.h>
13+
#include <fcntl.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
#include <string.h>
17+
#include <unistd.h>
18+
19+
class Untar
20+
{
21+
public:
22+
static int extract(const QString& qFilename, const QDir& outputPath, QString& returnState)
23+
{
24+
const char* filename = qFilename.toUtf8().constData();
25+
26+
struct archive *a;
27+
struct archive *ext;
28+
struct archive_entry *entry;
29+
int flags;
30+
int r;
31+
32+
/* Select which attributes we want to restore. */
33+
flags = ARCHIVE_EXTRACT_TIME;
34+
35+
a = archive_read_new();
36+
archive_read_support_format_all(a);
37+
archive_read_support_filter_all(a);
38+
ext = archive_write_disk_new();
39+
archive_write_disk_set_options(ext, flags);
40+
archive_write_disk_set_standard_lookup(ext);
41+
if ((r = archive_read_open_filename(a, filename, 10240)))
42+
{
43+
returnState = archive_error_string(a);
44+
qWarning() << returnState << "\n";
45+
return (1);
46+
}
47+
for (;;) {
48+
r = archive_read_next_header(a, &entry);
49+
if (r == ARCHIVE_EOF)
50+
break;
51+
if (r < ARCHIVE_OK)
52+
qWarning() << archive_error_string(a);
53+
if (r < ARCHIVE_WARN)
54+
{
55+
returnState = archive_error_string(a);
56+
return 1;
57+
}
58+
59+
const char* currentFile = archive_entry_pathname(entry);
60+
const QString fullOutputPath = outputPath.path() + QDir::separator() + currentFile;
61+
archive_entry_set_pathname_utf8(entry, fullOutputPath.toUtf8().constData());
62+
63+
r = archive_write_header(ext, entry);
64+
if (r < ARCHIVE_OK)
65+
qWarning() << archive_error_string(ext);
66+
else if (archive_entry_size(entry) > 0) {
67+
r = copy_data(a, ext);
68+
if (r < ARCHIVE_OK)
69+
qWarning() << archive_error_string(ext);
70+
if (r < ARCHIVE_WARN)
71+
{
72+
returnState = archive_error_string(ext);
73+
return 1;
74+
}
75+
}
76+
r = archive_write_finish_entry(ext);
77+
if (r < ARCHIVE_OK)
78+
qWarning() << archive_error_string(ext);
79+
if (r < ARCHIVE_WARN)
80+
{
81+
returnState = archive_error_string(ext);
82+
return 1;
83+
}
84+
}
85+
archive_read_close(a);
86+
archive_read_free(a);
87+
archive_write_close(ext);
88+
archive_write_free(ext);
89+
return 0;
90+
}
91+
92+
private:
93+
static int
94+
copy_data(struct archive *ar, struct archive *aw)
95+
{
96+
int r;
97+
const void *buff;
98+
size_t size;
99+
int64_t offset;
100+
101+
for (;;) {
102+
r = archive_read_data_block(ar, &buff, &size, &offset);
103+
if (r == ARCHIVE_EOF)
104+
return (ARCHIVE_OK);
105+
if (r < ARCHIVE_OK) {
106+
qWarning() << "copyData(): " << archive_error_string(ar) << "\n";
107+
return (r);
108+
}
109+
r = archive_write_data_block(aw, buff, size, offset);
110+
if (r < ARCHIVE_OK) {
111+
qWarning() << "copyData(): " << archive_error_string(ar) << "\n";
112+
return (r);
113+
}
114+
}
115+
}
116+
117+
};
118+
119+
#endif // UNTAR_H

0 commit comments

Comments
 (0)