summaryrefslogtreecommitdiff
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
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>
-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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QDebug>
21#include "archiveutil.h"
22
23ArchiveUtil::ArchiveUtil(QObject* parent)
24 :QObject(parent)
25{
26}
27
28ArchiveUtil::~ArchiveUtil()
29{
30}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef ARCHIVEUTIL_H
20#define ARCHIVEUTIL_H
21
22#include <QtCore>
23
24class ArchiveUtil : public QObject
25{
26 Q_OBJECT
27
28 public:
29 ArchiveUtil(QObject* parent);
30 ~ArchiveUtil();
31 virtual bool close(void) = 0;
32 virtual bool extractArchive(const QString& dest, QString file = "") = 0;
33 virtual QStringList files(void) = 0;
34
35 signals:
36 void logProgress(int, int);
37 void logItem(QString, int);
38};
39#endif
40
41
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 @@
22#include "bootloaderinstallbase.h" 22#include "bootloaderinstallbase.h"
23#include "utils.h" 23#include "utils.h"
24#include "ziputil.h" 24#include "ziputil.h"
25#include "mspackutil.h"
25 26
26#if defined(Q_OS_MACX) 27#if defined(Q_OS_MACX)
27#include <sys/param.h> 28#include <sys/param.h>
@@ -215,11 +216,34 @@ void BootloaderInstallBase::setBlFile(QStringList sl)
215bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile) 216bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
216{ 217{
217 bool found = false; 218 bool found = false;
218 ZipUtil z(this); 219 ArchiveUtil *util = 0;
219 // check if the file set is in zip format 220
220 if(z.open(of)) { 221 // try ZIP first
222 ZipUtil *zu = new ZipUtil(this);
223 if(zu->open(of))
224 {
221 emit logItem(tr("Zip file format detected"), LOGINFO); 225 emit logItem(tr("Zip file format detected"), LOGINFO);
222 QStringList contents = z.files(); 226 util = zu;
227 }
228 else
229 delete zu;
230
231 // if ZIP failed, try CAB
232 if(util == 0)
233 {
234 MsPackUtil *msu = new MsPackUtil(this);
235 if(msu->open(of))
236 {
237 emit logItem(tr("CAB file format detected"), LOGINFO);
238 util = msu;
239 }
240 else
241 delete msu;
242 }
243
244 // check if the file set is in zip format
245 if(util) {
246 QStringList contents = util->files();
223 qDebug() << "[BootloaderInstallBase] archive contains:" << contents; 247 qDebug() << "[BootloaderInstallBase] archive contains:" << contents;
224 for(int i = 0; i < blfile.size(); ++i) { 248 for(int i = 0; i < blfile.size(); ++i) {
225 // strip any path, we don't know the structure in the zip 249 // strip any path, we don't know the structure in the zip
@@ -237,7 +261,7 @@ bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
237 m_tempof.open(); 261 m_tempof.open();
238 m_offile = m_tempof.fileName(); 262 m_offile = m_tempof.fileName();
239 m_tempof.close(); 263 m_tempof.close();
240 if(!z.extractArchive(m_offile, contents.at(j))) { 264 if(!util->extractArchive(m_offile, contents.at(j))) {
241 emit logItem(tr("Error extracting firmware from archive"), LOGERROR); 265 emit logItem(tr("Error extracting firmware from archive"), LOGERROR);
242 found = false; 266 found = false;
243 break; 267 break;
@@ -249,12 +273,13 @@ bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
249 if(!found) { 273 if(!found) {
250 emit logItem(tr("Could not find firmware in archive"), LOGERROR); 274 emit logItem(tr("Could not find firmware in archive"), LOGERROR);
251 } 275 }
252 276 delete util;
253 } 277 }
254 else { 278 else {
255 m_offile = of; 279 m_offile = of;
256 found = true; 280 found = true;
257 } 281 }
282
258 return found; 283 return found;
259} 284}
260 285
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include <QDebug>
21#include "mspackutil.h"
22#include "progressloggerinterface.h"
23
24MsPackUtil::MsPackUtil(QObject* parent)
25 :ArchiveUtil(parent)
26{
27 m_cabd = mspack_create_cab_decompressor(NULL);
28 m_cabinet = NULL;
29 if(!m_cabd)
30 qDebug() << "[MsPackUtil] CAB decompressor creation failed!";
31}
32
33MsPackUtil::~MsPackUtil()
34{
35 close();
36 if(m_cabd)
37 mspack_destroy_cab_decompressor(m_cabd);
38}
39
40bool MsPackUtil::open(QString& mspackfile)
41{
42 close();
43
44 if(m_cabd == NULL)
45 {
46 qDebug() << "[MsPackUtil] No CAB decompressor available: cannot open file!";
47 return false;
48 }
49 m_cabinet = m_cabd->search(m_cabd, QFile::encodeName(mspackfile).constData());
50 return m_cabinet != NULL;
51}
52
53bool MsPackUtil::close(void)
54{
55 if(m_cabd && m_cabinet)
56 m_cabd->close(m_cabd, m_cabinet);
57 m_cabinet = NULL;
58 return true;
59}
60
61bool MsPackUtil::extractArchive(const QString& dest, QString file)
62{
63 qDebug() << "[MsPackUtil] extractArchive" << dest << file;
64 if(!m_cabinet)
65 {
66 qDebug() << "[MsPackUtil] CAB file not open!";
67 return false;
68 }
69
70 // construct the filename when extracting a single file from an archive.
71 // if the given destination is a full path use it as output name,
72 // otherwise use it as path to place the file as named in the archive.
73 QString singleoutfile;
74 if(!file.isEmpty() && QFileInfo(dest).isDir())
75 singleoutfile = dest + "/" + file;
76 else if(!file.isEmpty())
77 singleoutfile = dest;
78 struct mscabd_file *f = m_cabinet->files;
79 if(f == NULL)
80 {
81 qDebug() << "[MsPackUtil] CAB doesn't contain file" << file;
82 return true;
83 }
84 bool found = false;
85 while(f)
86 {
87 QString name = QFile::decodeName(f->filename);
88 name.replace("\\", "/");
89 if(name.at(0) == '/')
90 name.remove(0, 1);
91 if(name == file || file.isEmpty())
92 {
93 QString path;
94 if(!singleoutfile.isEmpty())
95 path = singleoutfile;
96 else
97 path = dest + "/" + name;
98 // make sure the output path exists
99 if(!QDir().mkpath(QFileInfo(path).absolutePath()))
100 {
101 emit logItem(tr("Creating output path failed"), LOGERROR);
102 qDebug() << "[MsPackUtil] creating output path failed for:" << path;
103 emit logProgress(1, 1);
104 return false;
105 }
106 int ret = m_cabd->extract(m_cabd, f, QFile::encodeName(path).constData());
107 if(ret != MSPACK_ERR_OK)
108 {
109 emit logItem(tr("Error during CAB operation"), LOGERROR);
110 qDebug() << "[MsPackUtil] mspack error: " << ret << "(" << errorStringMsPack(ret) << ")";
111 emit logProgress(1, 1);
112 return false;
113 }
114 found = true;
115 }
116 f = f->next;
117 }
118 emit logProgress(1, 1);
119
120 return found;
121}
122
123QStringList MsPackUtil::files(void)
124{
125 QStringList list;
126 if(!m_cabinet)
127 {
128 qDebug() << "[MsPackUtil] CAB file not open!";
129 return list;
130 }
131 struct mscabd_file *file = m_cabinet->files;
132 while(file)
133 {
134 QString name = QFile::decodeName(file->filename);
135 name.replace("\\", "/");
136 if(name.at(0) == '/')
137 name.remove(0, 1);
138 list.append(name);
139 file = file->next;
140 }
141
142 return list;
143}
144
145QString MsPackUtil::errorStringMsPack(int error) const
146{
147 switch(error)
148 {
149 case MSPACK_ERR_OK: return "Ok";
150 case MSPACK_ERR_ARGS: return "Bad arguments";
151 case MSPACK_ERR_OPEN: return "Open error";
152 case MSPACK_ERR_READ: return "Read error";
153 case MSPACK_ERR_WRITE: return "Write error";
154 case MSPACK_ERR_SEEK: return "Seek error";
155 case MSPACK_ERR_NOMEMORY: return "Out of memory";
156 case MSPACK_ERR_SIGNATURE: return "Bad signature";
157 case MSPACK_ERR_DATAFORMAT: return "Bad data format";
158 case MSPACK_ERR_CHECKSUM: return "Checksum error";
159 case MSPACK_ERR_CRUNCH: return "Compression error";
160 case MSPACK_ERR_DECRUNCH: return "Decompression error";
161 default: return "Unknown";
162 }
163}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifndef MSPACKUTIL_H
20#define MSPACKUTIL_H
21
22#include <QtCore>
23#include "archiveutil.h"
24#include "mspack/mspack.h"
25
26class MsPackUtil : public ArchiveUtil
27{
28 Q_OBJECT
29
30 public:
31 // archive types can be ORed
32 MsPackUtil(QObject* parent);
33 ~MsPackUtil();
34 bool open(QString& mspackfile);
35 virtual bool close(void);
36 virtual bool extractArchive(const QString& dest, QString file = "");
37 virtual QStringList files(void);
38
39 signals:
40 void logProgress(int, int);
41 void logItem(QString, int);
42
43 private:
44 QString errorStringMsPack(int error) const;
45 struct mscab_decompressor* m_cabd;
46 struct mscabd_cabinet *m_cabinet;
47
48};
49#endif
50
51
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 @@
26#include "quazip/quazipfileinfo.h" 26#include "quazip/quazipfileinfo.h"
27 27
28 28
29ZipUtil::ZipUtil(QObject* parent) : QObject(parent) 29ZipUtil::ZipUtil(QObject* parent) : ArchiveUtil(parent)
30{ 30{
31 m_zip = NULL; 31 m_zip = NULL;
32} 32}
@@ -74,7 +74,7 @@ bool ZipUtil::close(void)
74//! single file. 74//! single file.
75//! @brief file file to extract from archive, full archive if empty. 75//! @brief file file to extract from archive, full archive if empty.
76//! @return true on success, false otherwise 76//! @return true on success, false otherwise
77bool ZipUtil::extractArchive(QString& dest, QString file) 77bool ZipUtil::extractArchive(const QString& dest, QString file)
78{ 78{
79 qDebug() << "[ZipUtil] extractArchive" << dest << file; 79 qDebug() << "[ZipUtil] extractArchive" << dest << file;
80 bool result = true; 80 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 @@
20#define ZIPUTIL_H 20#define ZIPUTIL_H
21 21
22#include <QtCore> 22#include <QtCore>
23#include "archiveutil.h"
23#include "quazip/quazip.h" 24#include "quazip/quazip.h"
24#include "quazip/quazipfile.h" 25#include "quazip/quazipfile.h"
25#include "quazip/quazipfileinfo.h" 26#include "quazip/quazipfileinfo.h"
26 27
27class ZipUtil : public QObject 28class ZipUtil : public ArchiveUtil
28{ 29{
29 Q_OBJECT 30 Q_OBJECT
30 31
@@ -32,12 +33,12 @@ class ZipUtil : public QObject
32 ZipUtil(QObject* parent); 33 ZipUtil(QObject* parent);
33 ~ZipUtil(); 34 ~ZipUtil();
34 bool open(QString& zipfile, QuaZip::Mode mode = QuaZip::mdUnzip); 35 bool open(QString& zipfile, QuaZip::Mode mode = QuaZip::mdUnzip);
35 bool close(void); 36 virtual bool close(void);
36 bool extractArchive(QString& dest, QString file = ""); 37 virtual bool extractArchive(const QString& dest, QString file = "");
37 bool appendDirToArchive(QString& source, QString& basedir); 38 bool appendDirToArchive(QString& source, QString& basedir);
38 bool appendFileToArchive(QString& file, QString& basedir); 39 bool appendFileToArchive(QString& file, QString& basedir);
39 qint64 totalUncompressedSize(unsigned int clustersize = 0); 40 qint64 totalUncompressedSize(unsigned int clustersize = 0);
40 QStringList files(void); 41 virtual QStringList files(void);
41 42
42 signals: 43 signals:
43 void logProgress(int, int); 44 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 += \
79 gui/comboboxviewdelegate.cpp \ 79 gui/comboboxviewdelegate.cpp \
80 gui/selectiveinstallwidget.cpp \ 80 gui/selectiveinstallwidget.cpp \
81 gui/backupdialog.cpp \ 81 gui/backupdialog.cpp \
82 gui/changelog.cpp 82 gui/changelog.cpp \
83 mspack/cabd.c \
84 mspack/lzxd.c \
85 mspack/mszipd.c \
86 mspack/qtmd.c \
87 mspack/system-mspack.c \
88 base/mspackutil.cpp \
89 base/archiveutil.cpp \
83 90
84 91
85HEADERS += \ 92HEADERS += \
@@ -157,7 +164,25 @@ HEADERS += \
157 gui/comboboxviewdelegate.h \ 164 gui/comboboxviewdelegate.h \
158 gui/selectiveinstallwidget.h \ 165 gui/selectiveinstallwidget.h \
159 gui/backupdialog.h \ 166 gui/backupdialog.h \
160 gui/changelog.h 167 gui/changelog.h \
168 mspack/cab.h \
169 mspack/chm.h \
170 mspack/des.h \
171 mspack/hlp.h \
172 mspack/kwaj.h \
173 mspack/lit.h \
174 mspack/lzss.h \
175 mspack/lzx.h \
176 mspack/mspack.h \
177 mspack/mszip.h \
178 mspack/qtm.h \
179 mspack/readbits.h \
180 mspack/readhuff.h \
181 mspack/sha.h \
182 mspack/system-mspack.h \
183 mspack/szdd.h \
184 base/mspackutil.h \
185 base/archiveutil.h \
161 186
162 187
163FORMS += \ 188FORMS += \