summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2012-01-15 23:20:17 +0100
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2012-01-15 23:32:15 +0100
commitb45cc0a13a20e88546cd7a536f09979edf8353a1 (patch)
tree1189e5a6381c7f4a8ac770bafbb9a21f49d5e930 /rbutil/rbutilqt
parent66c3086ae54c71413117f3de3dcfb5f0fe8b541d (diff)
downloadrockbox-b45cc0a13a20e88546cd7a536f09979edf8353a1.tar.gz
rockbox-b45cc0a13a20e88546cd7a536f09979edf8353a1.zip
Support reading OF files from zip.
Several devices require the original firmware to be able installing the bootloader. Most vendors distribute the firmware file in zip format. Extend reading the original firmware file to support reading the file from the zip directly instead of requiring the user to separately extract it. Change-Id: Ic4e89053456d8f7d6adc294f6657aceddbc354ba
Diffstat (limited to 'rbutil/rbutilqt')
-rw-r--r--rbutil/rbutilqt/base/bootloaderinstallbase.cpp41
-rw-r--r--rbutil/rbutilqt/base/bootloaderinstallbase.h4
-rw-r--r--rbutil/rbutilqt/base/ziputil.cpp28
-rw-r--r--rbutil/rbutilqt/base/ziputil.h4
-rw-r--r--rbutil/rbutilqt/rbutilqt.cpp23
5 files changed, 84 insertions, 16 deletions
diff --git a/rbutil/rbutilqt/base/bootloaderinstallbase.cpp b/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
index 750e33bef8..7941f24309 100644
--- a/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
+++ b/rbutil/rbutilqt/base/bootloaderinstallbase.cpp
@@ -31,6 +31,7 @@
#include "bootloaderinstallmpio.h"
#include "bootloaderinstallimx.h"
#include "utils.h"
+#include "ziputil.h"
#if defined(Q_OS_MACX)
#include <sys/param.h>
@@ -320,3 +321,43 @@ 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)) {
+ emit logItem(tr("Zip file format detected"), LOGINFO);
+ QStringList contents = z.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
+ QString f = QFileInfo(blfile.at(i)).fileName();
+ qDebug() << "[BootloaderInstallBase] searching archive for" << f;
+ int index = contents.indexOf(f); // FIXME: support files in folders
+ if(index >= 0) {
+ found = true;
+ emit logItem(tr("Extracting firmware %1 from archive")
+ .arg(f), LOGINFO);
+ // store in class temporary file
+ m_tempof.open();
+ m_offile = m_tempof.fileName();
+ m_tempof.close();
+ if(!z.extractArchive(m_offile, contents.at(index))) {
+ emit logItem(tr("Error extracting firmware from archive"), LOGERROR);
+ found = false;
+ break;
+ }
+ }
+ }
+ if(!found) {
+ emit logItem(tr("Could not find firmware in archive"), LOGERROR);
+ }
+
+ }
+ else {
+ m_offile = of;
+ found = true;
+ }
+ return found;
+}
diff --git a/rbutil/rbutilqt/base/bootloaderinstallbase.h b/rbutil/rbutilqt/base/bootloaderinstallbase.h
index 8198d54e76..0e970c4af6 100644
--- a/rbutil/rbutilqt/base/bootloaderinstallbase.h
+++ b/rbutil/rbutilqt/base/bootloaderinstallbase.h
@@ -60,8 +60,7 @@ class BootloaderInstallBase : public QObject
{ m_blurl = u; }
void setLogfile(QString f)
{ m_logfile = f; }
- void setOfFile(QString f)
- {m_offile = f;}
+ bool setOfFile(QString of, QStringList blfile);
//! returns a port Install Hint or empty if there is none
//! static and in the base class, so the installer classes dont need to
@@ -90,6 +89,7 @@ class BootloaderInstallBase : public QObject
QString m_logfile; //! file for installation log
QUrl m_blurl; //! bootloader download URL
QTemporaryFile m_tempfile; //! temporary file for download
+ QTemporaryFile m_tempof; //! temporary file for OF extracted from archive
QDateTime m_blversion; //! download timestamp used for version information
QString m_offile; //! path to the offile
#if defined(Q_OS_MACX)
diff --git a/rbutil/rbutilqt/base/ziputil.cpp b/rbutil/rbutilqt/base/ziputil.cpp
index 481ad4c2ae..b9218a70bc 100644
--- a/rbutil/rbutilqt/base/ziputil.cpp
+++ b/rbutil/rbutilqt/base/ziputil.cpp
@@ -70,10 +70,13 @@ bool ZipUtil::close(void)
//! @brief extract currently opened archive
-//! @brief dest path to extract archive to
+//! @brief dest path to extract archive to, can be filename when extracting a
+//! single file.
+//! @brief file file to extract from archive, full archive if empty.
//! @return true on success, false otherwise
-bool ZipUtil::extractArchive(QString& dest)
+bool ZipUtil::extractArchive(QString& dest, QString file)
{
+ qDebug() << "[ZipUtil] extractArchive" << dest << file;
bool result = true;
if(!m_zip) {
return false;
@@ -81,6 +84,16 @@ bool ZipUtil::extractArchive(QString& dest)
QuaZipFile *currentFile = new QuaZipFile(m_zip);
int entries = m_zip->getEntriesCount();
int current = 0;
+ // 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;
+ }
for(bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
{
++current;
@@ -88,7 +101,16 @@ bool ZipUtil::extractArchive(QString& dest)
if(m_zip->getCurrentFileName().split("/").last() == "")
continue;
- QString outfilename = dest + "/" + m_zip->getCurrentFileName();
+ QString outfilename;
+ if(!singleoutfile.isEmpty()
+ && QFileInfo(m_zip->getCurrentFileName()).fileName() == file) {
+ outfilename = singleoutfile;
+ }
+ else if(singleoutfile.isEmpty()) {
+ outfilename = dest + "/" + m_zip->getCurrentFileName();
+ }
+ if(outfilename.isEmpty())
+ continue;
QFile outputFile(outfilename);
// make sure the output path exists
if(!QDir().mkpath(QFileInfo(outfilename).absolutePath())) {
diff --git a/rbutil/rbutilqt/base/ziputil.h b/rbutil/rbutilqt/base/ziputil.h
index 9cbb67488a..a6b0a8ca9c 100644
--- a/rbutil/rbutilqt/base/ziputil.h
+++ b/rbutil/rbutilqt/base/ziputil.h
@@ -31,9 +31,9 @@ class ZipUtil : public QObject
public:
ZipUtil(QObject* parent);
~ZipUtil();
- bool open(QString& zipfile, QuaZip::Mode mode);
+ bool open(QString& zipfile, QuaZip::Mode mode = QuaZip::mdUnzip);
bool close(void);
- bool extractArchive(QString& dest);
+ bool extractArchive(QString& dest, QString file = "");
bool appendDirToArchive(QString& source, QString& basedir);
bool appendFileToArchive(QString& file, QString& basedir);
qint64 totalUncompressedSize(unsigned int clustersize = 0);
diff --git a/rbutil/rbutilqt/rbutilqt.cpp b/rbutil/rbutilqt/rbutilqt.cpp
index 403d13a760..958550e880 100644
--- a/rbutil/rbutilqt/rbutilqt.cpp
+++ b/rbutil/rbutilqt/rbutilqt.cpp
@@ -708,7 +708,14 @@ void RbUtilQt::installBootloader()
logger->setFinished();
return;
}
-
+
+ // the bootloader install class does NOT use any GUI stuff.
+ // All messages are passed via signals.
+ connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
+ connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
+ connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
+ connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
+
// set bootloader filename. Do this now as installed() needs it.
QStringList blfile = SystemInfo::value(SystemInfo::CurBootloaderFile).toStringList();
QStringList blfilepath;
@@ -788,16 +795,14 @@ void RbUtilQt::installBootloader()
m_error = true;
return;
}
- bl->setOfFile(offile);
+ if(!bl->setOfFile(offile, blfile)) {
+ logger->addItem(tr("Error reading firmware file"), LOGERROR);
+ logger->setFinished();
+ m_error = true;
+ return;
+ }
}
- // the bootloader install class does NOT use any GUI stuff.
- // All messages are passed via signals.
- connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
- connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
- connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
- connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
-
// start install.
if(!backupDestination.isEmpty()) {
if(!bl->backup(backupDestination)) {