summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/base/bootloaderinstallbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/base/bootloaderinstallbase.cpp')
-rw-r--r--utils/rbutilqt/base/bootloaderinstallbase.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/utils/rbutilqt/base/bootloaderinstallbase.cpp b/utils/rbutilqt/base/bootloaderinstallbase.cpp
new file mode 100644
index 0000000000..096c601b91
--- /dev/null
+++ b/utils/rbutilqt/base/bootloaderinstallbase.cpp
@@ -0,0 +1,302 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Dominik Riebeling
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
20#include <QtCore>
21
22#include "bootloaderinstallbase.h"
23#include "utils.h"
24#include "ziputil.h"
25#include "mspackutil.h"
26#include "Logger.h"
27
28#if defined(Q_OS_MACX)
29#include <sys/param.h>
30#include <sys/ucred.h>
31#include <sys/mount.h>
32#endif
33
34
35BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void)
36{
37 return BootloaderUnknown;
38}
39
40
41BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void)
42{
43 return Capabilities();
44}
45
46
47void BootloaderInstallBase::downloadBlStart(QUrl source)
48{
49 m_http.setFile(&m_tempfile);
50 m_http.setCache(true);
51 connect(&m_http, &HttpGet::done, this, &BootloaderInstallBase::downloadBlFinish);
52 // connect the http read signal to our logProgess *signal*
53 // to immediately emit it without any helper function.
54 connect(&m_http, &HttpGet::dataReadProgress,
55 this, &BootloaderInstallBase::logProgress);
56 m_http.getFile(source);
57}
58
59
60void BootloaderInstallBase::downloadReqFinished(int id, bool error)
61{
62 LOG_INFO() << "Download Request" << id
63 << "finished, error:" << m_http.errorString();
64
65 downloadBlFinish(error);
66}
67
68
69void BootloaderInstallBase::downloadBlFinish(bool error)
70{
71 LOG_INFO() << "Downloading bootloader finished, error:"
72 << error;
73
74 // update progress bar
75 emit logProgress(100, 100);
76
77 if(m_http.httpResponse() != 200) {
78 emit logItem(tr("Download error: received HTTP error %1.")
79 .arg(m_http.errorString()), LOGERROR);
80 emit done(true);
81 return;
82 }
83 if(error) {
84 emit logItem(tr("Download error: %1")
85 .arg(m_http.errorString()), LOGERROR);
86 emit done(true);
87 return;
88 }
89 else if(m_http.isCached())
90 emit logItem(tr("Download finished (cache used)."), LOGOK);
91 else
92 emit logItem(tr("Download finished."), LOGOK);
93
94 QCoreApplication::processEvents();
95 m_blversion = m_http.timestamp();
96 emit downloadDone();
97}
98
99
100void BootloaderInstallBase::installBlfile(void)
101{
102 LOG_INFO() << "installBlFile(void)";
103}
104
105
106void BootloaderInstallBase::progressAborted(void)
107{
108 LOG_INFO() << "progressAborted(void)";
109 emit installAborted();
110}
111
112
113//! @brief backup OF file.
114//! @param to folder to write backup file to. Folder will get created.
115//! @return true on success, false on error.
116bool BootloaderInstallBase::backup(QString to)
117{
118 LOG_INFO() << "Backing up bootloader file";
119 QDir targetDir(".");
120 emit logItem(tr("Creating backup of original firmware file."), LOGINFO);
121 if(!targetDir.mkpath(to)) {
122 emit logItem(tr("Creating backup folder failed"), LOGERROR);
123 return false;
124 }
125 QString tofile = to + "/" + QFileInfo(m_blfile).fileName();
126 LOG_INFO() << "trying to backup" << m_blfile << "to" << tofile;
127 if(!QFile::copy(Utils::resolvePathCase(m_blfile), tofile)) {
128 emit logItem(tr("Creating backup copy failed."), LOGERROR);
129 return false;
130 }
131 emit logItem(tr("Backup created."), LOGOK);
132 return true;
133}
134
135
136//! @brief log installation to logfile.
137//! @param mode action to perform. 0: add to log, 1: remove from log.
138//! @return 0 on success
139int BootloaderInstallBase::logInstall(LogMode mode)
140{
141 int result = 0;
142 QString section = m_blurl.path().section('/', -1);
143 QSettings s(m_logfile, QSettings::IniFormat, this);
144 emit logItem(tr("Creating installation log"), LOGINFO);
145
146 if(mode == LogAdd) {
147 s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate));
148 LOG_INFO() << "Writing log, version:"
149 << m_blversion.toString(Qt::ISODate);
150 }
151 else {
152 s.remove("Bootloader/" + section);
153 }
154 s.sync();
155
156 emit logItem(tr("Installation log created"), LOGOK);
157
158 return result;
159}
160
161
162#if defined(Q_OS_MACX)
163void BootloaderInstallBase::waitRemount()
164{
165 m_remountTries = 600;
166 emit logItem(tr("Waiting for system to remount player"), LOGINFO);
167
168 QTimer::singleShot(100, this, SLOT(checkRemount()));
169}
170#endif
171
172
173void BootloaderInstallBase::checkRemount()
174{
175#if defined(Q_OS_MACX)
176 if(m_remountTries--) {
177 int status = 0;
178 // check if device has been remounted
179 QCoreApplication::processEvents();
180 int num;
181 struct statfs *mntinf;
182
183 num = getmntinfo(&mntinf, MNT_WAIT);
184 while(num--) {
185 if(QString(mntinf->f_mntfromname).startsWith(m_remountDevice)
186 && QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive))
187 status = 1;
188 mntinf++;
189 }
190 if(!status) {
191 // still not remounted, restart timer.
192 QTimer::singleShot(500, this, SLOT(checkRemount()));
193 LOG_INFO() << "Player not remounted yet" << m_remountDevice;
194 }
195 else {
196 emit logItem(tr("Player remounted"), LOGINFO);
197 emit remounted(true);
198 }
199 }
200 else {
201 emit logItem(tr("Timeout on remount"), LOGERROR);
202 emit remounted(false);
203 }
204#endif
205}
206
207
208//! @brief set list of possible bootloader files and pick the existing one.
209//! @param sl list of possible bootloader files.
210void BootloaderInstallBase::setBlFile(QStringList sl)
211{
212 // figue which of the possible bootloader filenames is correct.
213 for(int a = 0; a < sl.size(); a++) {
214 if(!Utils::resolvePathCase(sl.at(a)).isEmpty()) {
215 m_blfile = sl.at(a);
216 }
217 }
218 if(m_blfile.isEmpty()) {
219 m_blfile = sl.at(0);
220 }
221}
222
223
224bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile)
225{
226 bool found = false;
227 ArchiveUtil *util = nullptr;
228
229 // check if we're actually looking for a zip file. If so we must avoid
230 // trying to unzip it.
231 bool wantZip = false;
232 for (int i = 0; i < blfile.size(); i++)
233 {
234 if (blfile.at(i).endsWith(".zip"))
235 wantZip = true;
236 }
237
238 // try ZIP first
239 ZipUtil *zu = new ZipUtil(this);
240 if(zu->open(of) && !wantZip)
241 {
242 emit logItem(tr("Zip file format detected"), LOGINFO);
243 util = zu;
244 }
245 else
246 delete zu;
247
248 // if ZIP failed, try CAB
249 if(util == nullptr)
250 {
251 MsPackUtil *msu = new MsPackUtil(this);
252 if(msu->open(of))
253 {
254 emit logItem(tr("CAB file format detected"), LOGINFO);
255 util = msu;
256 }
257 else
258 delete msu;
259 }
260
261 // check if the file set is in zip format
262 if(util) {
263 QStringList contents = util->files();
264 LOG_INFO() << "archive contains:" << contents;
265 for(int i = 0; i < blfile.size(); ++i) {
266 // strip any path, we don't know the structure in the zip
267 QString f = QFileInfo(blfile.at(i)).fileName();
268 LOG_INFO() << "searching archive for" << f;
269 // contents.indexOf() works case sensitive. Since the filename
270 // casing is unknown (and might change) do this manually.
271 // FIXME: support files in folders
272 for(int j = 0; j < contents.size(); ++j) {
273 if(contents.at(j).compare(f, Qt::CaseInsensitive) == 0) {
274 found = true;
275 emit logItem(tr("Extracting firmware %1 from archive")
276 .arg(f), LOGINFO);
277 // store in class temporary file
278 m_tempof.open();
279 m_offile = m_tempof.fileName();
280 m_tempof.close();
281 if(!util->extractArchive(m_offile, contents.at(j))) {
282 emit logItem(tr("Error extracting firmware from archive"), LOGERROR);
283 found = false;
284 break;
285 }
286 break;
287 }
288 }
289 }
290 if(!found) {
291 emit logItem(tr("Could not find firmware in archive"), LOGERROR);
292 }
293 delete util;
294 }
295 else {
296 m_offile = of;
297 found = true;
298 }
299
300 return found;
301}
302