summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-03-11 18:57:11 +0100
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2013-11-04 23:00:23 +0100
commit6375c47f036a4992ecb4bc3023a0fedbdc2356e0 (patch)
treee882032544d8e6adcc8ecd19d69ba69aa0e11512 /rbutil/rbutilqt
parent289acf3333cf76ffc689aff8a17340b299ce0686 (diff)
downloadrockbox-6375c47f036a4992ecb4bc3023a0fedbdc2356e0.tar.gz
rockbox-6375c47f036a4992ecb4bc3023a0fedbdc2356e0.zip
Add support for CAB archives to rbutil
Change-Id: Ia8b4953343caf8bc2b3c5a6cfd53c921c6d082b1 Reviewed-on: http://gerrit.rockbox.org/418 Reviewed-by: Dominik Riebeling <Dominik.Riebeling@gmail.com>
Diffstat (limited to 'rbutil/rbutilqt')
-rw-r--r--rbutil/rbutilqt/base/archiveutil.cpp30
-rw-r--r--rbutil/rbutilqt/base/archiveutil.h41
-rw-r--r--rbutil/rbutilqt/base/bootloaderinstallbase.cpp37
-rw-r--r--rbutil/rbutilqt/base/mspackutil.cpp163
-rw-r--r--rbutil/rbutilqt/base/mspackutil.h51
-rw-r--r--rbutil/rbutilqt/base/ziputil.cpp4
-rw-r--r--rbutil/rbutilqt/base/ziputil.h9
-rw-r--r--rbutil/rbutilqt/rbutilqt.pri29
8 files changed, 350 insertions, 14 deletions
diff --git a/rbutil/rbutilqt/base/archiveutil.cpp b/rbutil/rbutilqt/base/archiveutil.cpp
new file mode 100644
index 0000000000..d5f0a12471
--- /dev/null
+++ b/rbutil/rbutilqt/base/archiveutil.cpp
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Amaury Pouly
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <QtCore>
+#include <QDebug>
+#include "archiveutil.h"
+
+ArchiveUtil::ArchiveUtil(QObject* parent)
+ :QObject(parent)
+{
+}
+
+ArchiveUtil::~ArchiveUtil()
+{
+}
diff --git a/rbutil/rbutilqt/base/archiveutil.h b/rbutil/rbutilqt/base/archiveutil.h
new file mode 100644
index 0000000000..76616728c3
--- /dev/null
+++ b/rbutil/rbutilqt/base/archiveutil.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Amaury Pouly
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef ARCHIVEUTIL_H
+#define ARCHIVEUTIL_H
+
+#include <QtCore>
+
+class ArchiveUtil : public QObject
+{
+ Q_OBJECT
+
+ public:
+ ArchiveUtil(QObject* parent);
+ ~ArchiveUtil();
+ virtual bool close(void) = 0;
+ virtual bool extractArchive(const QString& dest, QString file = "") = 0;
+ virtual QStringList files(void) = 0;
+
+ signals:
+ void logProgress(int, int);
+ void logItem(QString, int);
+};
+#endif
+
+
diff --git a/rbutil/rbutilqt/base/bootloaderinstallbase.cpp b/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
index 6cfb2cd1c6..1a47f967b0 100644
--- a/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
+++ b/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
@@ -22,6 +22,7 @@
#include "bootloaderinstallbase.h"
#include "utils.h"
#include "ziputil.h"
+#include "mspackutil.h"
#if defined(Q_OS_MACX)
#include <sys/param.h>
@@ -215,11 +216,34 @@ void BootloaderInstallBase::setBlFile(QStringList sl)
bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
{
bool found = false;
- ZipUtil z(this);
- // check if the file set is in zip format
- if(z.open(of)) {
+ ArchiveUtil *util = 0;
+
+ // try ZIP first
+ ZipUtil *zu = new ZipUtil(this);
+ if(zu->open(of))
+ {
emit logItem(tr("Zip file format detected"), LOGINFO);
- QStringList contents = z.files();
+ util = zu;
+ }
+ else
+ delete zu;
+
+ // if ZIP failed, try CAB
+ if(util == 0)
+ {
+ MsPackUtil *msu = new MsPackUtil(this);
+ if(msu->open(of))
+ {
+ emit logItem(tr("CAB file format detected"), LOGINFO);
+ util = msu;
+ }
+ else
+ delete msu;
+ }
+
+ // check if the file set is in zip format
+ if(util) {
+ QStringList contents = util->files();
qDebug() << "[BootloaderInstallBase] archive contains:" << contents;
for(int i = 0; i < blfile.size(); ++i) {
// strip any path, we don't know the structure in the zip
@@ -237,7 +261,7 @@ bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
m_tempof.open();
m_offile = m_tempof.fileName();
m_tempof.close();
- if(!z.extractArchive(m_offile, contents.at(j))) {
+ if(!util->extractArchive(m_offile, contents.at(j))) {
emit logItem(tr("Error extracting firmware from archive"), LOGERROR);
found = false;
break;
@@ -249,12 +273,13 @@ bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
if(!found) {
emit logItem(tr("Could not find firmware in archive"), LOGERROR);
}
-
+ delete util;
}
else {
m_offile = of;
found = true;
}
+
return found;
}
diff --git a/rbutil/rbutilqt/base/mspackutil.cpp b/rbutil/rbutilqt/base/mspackutil.cpp
new file mode 100644
index 0000000000..4bc7307cd9
--- /dev/null
+++ b/rbutil/rbutilqt/base/mspackutil.cpp
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Amaury Pouly
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <QtCore>
+#include <QDebug>
+#include "mspackutil.h"
+#include "progressloggerinterface.h"
+
+MsPackUtil::MsPackUtil(QObject* parent)
+ :ArchiveUtil(parent)
+{
+ m_cabd = mspack_create_cab_decompressor(NULL);
+ m_cabinet = NULL;
+ if(!m_cabd)
+ qDebug() << "[MsPackUtil] CAB decompressor creation failed!";
+}
+
+MsPackUtil::~MsPackUtil()
+{
+ close();
+ if(m_cabd)
+ mspack_destroy_cab_decompressor(m_cabd);
+}
+
+bool MsPackUtil::open(QString& mspackfile)
+{
+ close();
+
+ if(m_cabd == NULL)
+ {
+ qDebug() << "[MsPackUtil] No CAB decompressor available: cannot open file!";
+ return false;
+ }
+ m_cabinet = m_cabd->search(m_cabd, QFile::encodeName(mspackfile).constData());
+ return m_cabinet != NULL;
+}
+
+bool MsPackUtil::close(void)
+{
+ if(m_cabd && m_cabinet)
+ m_cabd->close(m_cabd, m_cabinet);
+ m_cabinet = NULL;
+ return true;
+}
+
+bool MsPackUtil::extractArchive(const QString& dest, QString file)
+{
+ qDebug() << "[MsPackUtil] extractArchive" << dest << file;
+ if(!m_cabinet)
+ {
+ qDebug() << "[MsPackUtil] CAB file not open!";
+ return false;
+ }
+
+ // construct the filename when extracting a single file from an archive.
+ // if the given destination is a full path use it as output name,
+ // otherwise use it as path to place the file as named in the archive.
+ QString singleoutfile;
+ if(!file.isEmpty() && QFileInfo(dest).isDir())
+ singleoutfile = dest + "/" + file;
+ else if(!file.isEmpty())
+ singleoutfile = dest;
+ struct mscabd_file *f = m_cabinet->files;
+ if(f == NULL)
+ {
+ qDebug() << "[MsPackUtil] CAB doesn't contain file" << file;
+ return true;
+ }
+ bool found = false;
+ while(f)
+ {
+ QString name = QFile::decodeName(f->filename);
+ name.replace("\\", "/");
+ if(name.at(0) == '/')
+ name.remove(0, 1);
+ if(name == file || file.isEmpty())
+ {
+ QString path;
+ if(!singleoutfile.isEmpty())
+ path = singleoutfile;
+ else
+ path = dest + "/" + name;
+ // make sure the output path exists
+ if(!QDir().mkpath(QFileInfo(path).absolutePath()))
+ {
+ emit logItem(tr("Creating output path failed"), LOGERROR);
+ qDebug() << "[MsPackUtil] creating output path failed for:" << path;
+ emit logProgress(1, 1);
+ return false;
+ }
+ int ret = m_cabd->extract(m_cabd, f, QFile::encodeName(path).constData());
+ if(ret != MSPACK_ERR_OK)
+ {
+ emit logItem(tr("Error during CAB operation"), LOGERROR);
+ qDebug() << "[MsPackUtil] mspack error: " << ret << "(" << errorStringMsPack(ret) << ")";
+ emit logProgress(1, 1);
+ return false;
+ }
+ found = true;
+ }
+ f = f->next;
+ }
+ emit logProgress(1, 1);
+
+ return found;
+}
+
+QStringList MsPackUtil::files(void)
+{
+ QStringList list;
+ if(!m_cabinet)
+ {
+ qDebug() << "[MsPackUtil] CAB file not open!";
+ return list;
+ }
+ struct mscabd_file *file = m_cabinet->files;
+ while(file)
+ {
+ QString name = QFile::decodeName(file->filename);
+ name.replace("\\", "/");
+ if(name.at(0) == '/')
+ name.remove(0, 1);
+ list.append(name);
+ file = file->next;
+ }
+
+ return list;
+}
+
+QString MsPackUtil::errorStringMsPack(int error) const
+{
+ switch(error)
+ {
+ case MSPACK_ERR_OK: return "Ok";
+ case MSPACK_ERR_ARGS: return "Bad arguments";
+ case MSPACK_ERR_OPEN: return "Open error";
+ case MSPACK_ERR_READ: return "Read error";
+ case MSPACK_ERR_WRITE: return "Write error";
+ case MSPACK_ERR_SEEK: return "Seek error";
+ case MSPACK_ERR_NOMEMORY: return "Out of memory";
+ case MSPACK_ERR_SIGNATURE: return "Bad signature";
+ case MSPACK_ERR_DATAFORMAT: return "Bad data format";
+ case MSPACK_ERR_CHECKSUM: return "Checksum error";
+ case MSPACK_ERR_CRUNCH: return "Compression error";
+ case MSPACK_ERR_DECRUNCH: return "Decompression error";
+ default: return "Unknown";
+ }
+}
diff --git a/rbutil/rbutilqt/base/mspackutil.h b/rbutil/rbutilqt/base/mspackutil.h
new file mode 100644
index 0000000000..1cb4350b13
--- /dev/null
+++ b/rbutil/rbutilqt/base/mspackutil.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Amaury Pouly
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef MSPACKUTIL_H
+#define MSPACKUTIL_H
+
+#include <QtCore>
+#include "archiveutil.h"
+#include "mspack/mspack.h"
+
+class MsPackUtil : public ArchiveUtil
+{
+ Q_OBJECT
+
+ public:
+ // archive types can be ORed
+ MsPackUtil(QObject* parent);
+ ~MsPackUtil();
+ bool open(QString& mspackfile);
+ virtual bool close(void);
+ virtual bool extractArchive(const QString& dest, QString file = "");
+ virtual QStringList files(void);
+
+ signals:
+ void logProgress(int, int);
+ void logItem(QString, int);
+
+ private:
+ QString errorStringMsPack(int error) const;
+ struct mscab_decompressor* m_cabd;
+ struct mscabd_cabinet *m_cabinet;
+
+};
+#endif
+
+
diff --git a/rbutil/rbutilqt/base/ziputil.cpp b/rbutil/rbutilqt/base/ziputil.cpp
index ca921eb708..b93d5fd86a 100644
--- a/rbutil/rbutilqt/base/ziputil.cpp
+++ b/rbutil/rbutilqt/base/ziputil.cpp
@@ -26,7 +26,7 @@
#include "quazip/quazipfileinfo.h"
-ZipUtil::ZipUtil(QObject* parent) : QObject(parent)
+ZipUtil::ZipUtil(QObject* parent) : ArchiveUtil(parent)
{
m_zip = NULL;
}
@@ -74,7 +74,7 @@ bool ZipUtil::close(void)
//! single file.
//! @brief file file to extract from archive, full archive if empty.
//! @return true on success, false otherwise
-bool ZipUtil::extractArchive(QString& dest, QString file)
+bool ZipUtil::extractArchive(const QString& dest, QString file)
{
qDebug() << "[ZipUtil] extractArchive" << dest << file;
bool result = true;
diff --git a/rbutil/rbutilqt/base/ziputil.h b/rbutil/rbutilqt/base/ziputil.h
index 49a1bd3f06..25c3dce391 100644
--- a/rbutil/rbutilqt/base/ziputil.h
+++ b/rbutil/rbutilqt/base/ziputil.h
@@ -20,11 +20,12 @@
#define ZIPUTIL_H
#include <QtCore>
+#include "archiveutil.h"
#include "quazip/quazip.h"
#include "quazip/quazipfile.h"
#include "quazip/quazipfileinfo.h"
-class ZipUtil : public QObject
+class ZipUtil : public ArchiveUtil
{
Q_OBJECT
@@ -32,12 +33,12 @@ class ZipUtil : public QObject
ZipUtil(QObject* parent);
~ZipUtil();
bool open(QString& zipfile, QuaZip::Mode mode = QuaZip::mdUnzip);
- bool close(void);
- bool extractArchive(QString& dest, QString file = "");
+ virtual bool close(void);
+ virtual bool extractArchive(const QString& dest, QString file = "");
bool appendDirToArchive(QString& source, QString& basedir);
bool appendFileToArchive(QString& file, QString& basedir);
qint64 totalUncompressedSize(unsigned int clustersize = 0);
- QStringList files(void);
+ virtual QStringList files(void);
signals:
void logProgress(int, int);
diff --git a/rbutil/rbutilqt/rbutilqt.pri b/rbutil/rbutilqt/rbutilqt.pri
index 8ec961a50f..b8193d56ab 100644
--- a/rbutil/rbutilqt/rbutilqt.pri
+++ b/rbutil/rbutilqt/rbutilqt.pri
@@ -79,7 +79,14 @@ SOURCES += \
gui/comboboxviewdelegate.cpp \
gui/selectiveinstallwidget.cpp \
gui/backupdialog.cpp \
- gui/changelog.cpp
+ gui/changelog.cpp \
+ mspack/cabd.c \
+ mspack/lzxd.c \
+ mspack/mszipd.c \
+ mspack/qtmd.c \
+ mspack/system-mspack.c \
+ base/mspackutil.cpp \
+ base/archiveutil.cpp \
HEADERS += \
@@ -157,7 +164,25 @@ HEADERS += \
gui/comboboxviewdelegate.h \
gui/selectiveinstallwidget.h \
gui/backupdialog.h \
- gui/changelog.h
+ gui/changelog.h \
+ mspack/cab.h \
+ mspack/chm.h \
+ mspack/des.h \
+ mspack/hlp.h \
+ mspack/kwaj.h \
+ mspack/lit.h \
+ mspack/lzss.h \
+ mspack/lzx.h \
+ mspack/mspack.h \
+ mspack/mszip.h \
+ mspack/qtm.h \
+ mspack/readbits.h \
+ mspack/readhuff.h \
+ mspack/sha.h \
+ mspack/system-mspack.h \
+ mspack/szdd.h \
+ base/mspackutil.h \
+ base/archiveutil.h \
FORMS += \