forked from len0rd/rockbox
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>
This commit is contained in:
parent
289acf3333
commit
6375c47f03
8 changed files with 350 additions and 14 deletions
30
rbutil/rbutilqt/base/archiveutil.cpp
Normal file
30
rbutil/rbutilqt/base/archiveutil.cpp
Normal file
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
41
rbutil/rbutilqt/base/archiveutil.h
Normal file
41
rbutil/rbutilqt/base/archiveutil.h
Normal file
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
163
rbutil/rbutilqt/base/mspackutil.cpp
Normal file
163
rbutil/rbutilqt/base/mspackutil.cpp
Normal file
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
51
rbutil/rbutilqt/base/mspackutil.h
Normal file
51
rbutil/rbutilqt/base/mspackutil.h
Normal file
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 += \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue