1 /*
2 unetbootin.cpp from UNetbootin <http://unetbootin.sourceforge.net>
3 Copyright (C) 2007-2008 Geza Kovacs <geza0kovacs@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at <http://www.gnu.org/licenses/> for more details.
8 */
9
10 #include "unetbootin.h"
11
12 #include <QMessageBox>
13 #include <QFileDialog>
14 #include <QProgressDialog>
15 #include <QDebug>
16
17 static const QList<QRegExp> ignoredtypesbothRL = QList<QRegExp>()
18 << QRegExp("isolinux.bin$", Qt::CaseInsensitive)
19 << QRegExp("isolinux.cfg$", Qt::CaseInsensitive)
20 << QRegExp("memtest$", Qt::CaseInsensitive)
21 << QRegExp("memtest.bin$", Qt::CaseInsensitive)
22 << QRegExp("memtest86$", Qt::CaseInsensitive)
23 << QRegExp("memtest86.bin$", Qt::CaseInsensitive)
24 << QRegExp("memtest+$", Qt::CaseInsensitive)
25 << QRegExp("memtest+.bin$", Qt::CaseInsensitive)
26 << QRegExp("memtest86+$", Qt::CaseInsensitive)
27 << QRegExp("memtest86+.bin$", Qt::CaseInsensitive)
28 << QRegExp("memtestplus$", Qt::CaseInsensitive)
29 << QRegExp("memtestplus.bin$", Qt::CaseInsensitive)
30 << QRegExp("memtest86plus$", Qt::CaseInsensitive)
31 << QRegExp("memtest86plus.bin$", Qt::CaseInsensitive)
32 << QRegExp("mt86plus$", Qt::CaseInsensitive)
33 << QRegExp("mt86+$", Qt::CaseInsensitive)
34 << QRegExp("mt86.bin$", Qt::CaseInsensitive)
35 << QRegExp("mt86plus.bin$", Qt::CaseInsensitive)
36 << QRegExp("mt86+.bin$", Qt::CaseInsensitive)
37 << QRegExp("system.map$", Qt::CaseInsensitive)
38 << QRegExp(".efimg$", Qt::CaseInsensitive)
39 << QRegExp(".html$", Qt::CaseInsensitive)
40 << QRegExp(".jpg$", Qt::CaseInsensitive)
41 << QRegExp(".png$", Qt::CaseInsensitive)
42 << QRegExp(".pdf$", Qt::CaseInsensitive)
43 << QRegExp(".pcx$", Qt::CaseInsensitive)
44 << QRegExp(".rle$", Qt::CaseInsensitive)
45 << QRegExp(".fnt$", Qt::CaseInsensitive)
46 << QRegExp(".psd$", Qt::CaseInsensitive)
47 << QRegExp(".xcf$", Qt::CaseInsensitive)
48 << QRegExp(".bmp$", Qt::CaseInsensitive)
49 << QRegExp(".svg$", Qt::CaseInsensitive)
50 << QRegExp(".md5$", Qt::CaseInsensitive)
51 << QRegExp(".md5sum$", Qt::CaseInsensitive)
52 << QRegExp(".sha1$", Qt::CaseInsensitive)
53 << QRegExp(".sha1sum$", Qt::CaseInsensitive)
54 << QRegExp(".c32$", Qt::CaseInsensitive)
55 << QRegExp(".sig$", Qt::CaseInsensitive)
56 << QRegExp(".msg$", Qt::CaseInsensitive)
57 << QRegExp(".cat$", Qt::CaseInsensitive)
58 << QRegExp(".txt$", Qt::CaseInsensitive)
59 << QRegExp(".tar$", Qt::CaseInsensitive)
60 << QRegExp(".exe$", Qt::CaseInsensitive)
61 << QRegExp(".deb$", Qt::CaseInsensitive)
62 << QRegExp(".udeb$", Qt::CaseInsensitive)
63 << QRegExp("system.map", Qt::CaseInsensitive);
64
65 static const QList<QRegExp> ignoredtypeskernelRL = QList<QRegExp>()
66 << QRegExp("initrd.gz$", Qt::CaseInsensitive)
67 << QRegExp("initrd.img$", Qt::CaseInsensitive);
68
69 static const QList<QRegExp> ignoredtypesinitrdRL = QList<QRegExp>()
70 << QRegExp("bzImage$", Qt::CaseInsensitive);
71
72 static const QString SALT_DETECTED = "*SaLT*";
73
run()74 void callexternappT::run()
75 {
76 #ifdef Q_OS_WIN32
77 SHELLEXECUTEINFO ShExecInfo = {0};
78 ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
79 ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
80 ShExecInfo.hwnd = NULL;
81 if (QSysInfo::WindowsVersion == QSysInfo::WV_NT || QSysInfo::WindowsVersion == QSysInfo::WV_2000 || QSysInfo::WindowsVersion == QSysInfo::WV_XP || QSysInfo::WindowsVersion == QSysInfo::WV_2003 )
82 {
83 ShExecInfo.lpVerb = NULL;
84 }
85 else
86 {
87 ShExecInfo.lpVerb = L"runas";
88 }
89 ShExecInfo.lpFile = LPWSTR(execFile.utf16());
90 ShExecInfo.lpParameters = LPWSTR(execParm.utf16());
91 ShExecInfo.lpDirectory = NULL;
92 ShExecInfo.nShow = SW_HIDE;
93 ShExecInfo.hInstApp = NULL;
94 ShellExecuteEx(&ShExecInfo);
95 WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
96 retnValu = "";
97 #endif
98 #ifdef Q_OS_UNIX
99 QProcess lnexternapp;
100 lnexternapp.start("\"" + execFile + "\" " + execParm);
101 lnexternapp.waitForFinished(-1);
102 retnValu = QString(lnexternapp.readAll());
103 #endif
104 }
105
run()106 void callexternappWriteToStdinT::run()
107 {
108 QProcess lnexternapp;
109 lnexternapp.start("\"" + execFile + "\" " + execParm);
110 lnexternapp.write(writeToStdin.toLatin1().data());
111 lnexternapp.closeWriteChannel();
112 lnexternapp.waitForFinished(-1);
113 retnValu = QString(lnexternapp.readAll());
114 }
115
run()116 void copyfileT::run()
117 {
118 QFile srcF(source);
119 srcF.open(QIODevice::ReadOnly);
120 QFile dstF(destination);
121 dstF.open(QIODevice::WriteOnly);
122 qint64 maxbytes = srcF.size();
123 qint64 dlbytes = 0;
124 char *buf = new char[262144];
125 while (!srcF.atEnd())
126 {
127 qint64 bytesread = srcF.read(buf, 262144);
128 dstF.write(buf, bytesread);
129 dlbytes += bytesread;
130 emit datacopied64(dlbytes, maxbytes);
131 #ifdef Q_OS_UNIX
132 unetbootin::callexternapp("sync", "");
133 #endif
134 }
135 delete[] buf;
136 srcF.close();
137 dstF.close();
138 emit finished();
139 }
140
randtmpfile(QString rfpath,QString rfextn)141 randtmpfile::randtmpfile(QString rfpath, QString rfextn)
142 {
143 QString basefn = getrandfilename(rfpath, rfextn);
144 this->setFileName(basefn);
145 }
146
getrandfilename(QString rfpath,QString rfextn)147 QString randtmpfile::getrandfilename(QString rfpath, QString rfextn)
148 {
149 qsrand((unsigned int)time(0));
150 QString basefn = QString("%1un%2.%3").arg(rfpath).arg(qrand() % 999999).arg(rfextn);
151 while (QFile::exists(basefn))
152 {
153 basefn = QString("%1%2.%3").arg(rfpath).arg(qrand() % 999999).arg(rfextn);
154 }
155 return basefn;
156 }
157 /*
158 void nDirListStor::sAppendSelfUrlInfoList(QUrlInfo curDirUrl)
159 {
160 if (curDirUrl.isValid() && curDirUrl.isReadable() && curDirUrl.isFile() && curDirUrl.size() > nMinFileSizeBytes && curDirUrl.size() < nMaxFileSizeBytes)
161 {
162 nDirFileListSL.append(curDirUrl.name());
163 }
164 else if (this->searchsymlinks && curDirUrl.isReadable() && curDirUrl.isSymLink())
165 {
166 nDirFileListSL.append(curDirUrl.name());
167 }
168 }
169 */
unetbootin(QWidget * parent)170 unetbootin::unetbootin(QWidget *parent)
171 : QWidget(parent)
172 {
173 setupUi(this);
174 }
175
ubninitialize(QList<QPair<QString,QString>> oppairs)176 bool unetbootin::ubninitialize(QList<QPair<QString, QString> > oppairs)
177 {
178 skipExtraction = false;
179 redundanttopleveldir = false;
180 isarch64 = false;
181 islivecd = false;
182 isnetinstall = false;
183 ishdmedia = false;
184 overwriteall = false;
185 searchsymlinks = false;
186 ignoreoutofspace = false;
187 downloadFailed = false;
188 exitOnCompletion = false;
189 testingDownload = false;
190 issalt = false;
191 persistenceSpaceMB = 0;
192 logFile = 0;
193 logStream = 0;
194 #ifdef Q_OS_MAC
195 ignoreoutofspace = true;
196 #endif
197 dontgeneratesyslinuxcfg = false;
198 #ifdef Q_OS_UNIX
199 isext2 = false;
200 #endif
201 secondlayer->setEnabled(false);
202 secondlayer->hide();
203 firstlayer->setEnabled(true);
204 firstlayer->show();
205 this->setWindowTitle(UNETBOOTINB " 702");
206 overwriteall = false;
207 #ifndef Q_OS_MAC
208 typeselect->addItem(tr("Hard Disk"));
209 #endif
210 typeselect->addItem(tr("USB Drive"));
211 diskimagetypeselect->addItem(tr("ISO"));
212 diskimagetypeselect->addItem(tr("Floppy"));
213 bool hideCustom = true;
214 #ifdef NOEXTERN
215 optionslayer->setEnabled(false);
216 optionslayer->hide();
217 radioFloppy->setEnabled(false);
218 radioFloppy->hide();
219 radioManual->setEnabled(false);
220 radioManual->hide();
221 intromessage->resize(intromessage->width(), intromessage->height() + 135);
222 #endif
223 #ifdef NOFLOPPY
224 if (diskimagetypeselect->findText(tr("Floppy")) != -1)
225 diskimagetypeselect->removeItem(diskimagetypeselect->findText(tr("Floppy")));
226 #endif
227 #ifdef NOISO
228 if (diskimagetypeselect->findText(tr("ISO")) != -1)
229 diskimagetypeselect->removeItem(diskimagetypeselect->findText(tr("ISO")));
230 #endif
231 #include "distrovercust.cpp"
232 #ifdef STDUNETBOOTIN
233 optionslayer->setEnabled(true);
234 optionslayer->show();
235 #include "distrover.cpp"
236 #endif
237 #include "customdistselect.cpp"
238 #ifdef Q_OS_MAC
239 resourceDir = QDir(QApplication::applicationDirPath());
240 resourceDir.cdUp();
241 resourceDir.cd("Resources");
242 syslinuxcommand = resourceDir.absoluteFilePath("syslinux-mac");
243 sevzcommand = resourceDir.absoluteFilePath("7z-mac");
244 mke2fscommand = resourceDir.absoluteFilePath("mke2fs");
245 fdiskcommand = locatecommand("fdisk", tr("either"), "util-linux");
246 #endif
247 #ifdef Q_OS_LINUX
248 if (QFile::exists("/sbin/fdisk"))
249 fdiskcommand = "/sbin/fdisk";
250 else
251 fdiskcommand = locatecommand("fdisk", tr("either"), "util-linux");
252 if (QFile::exists("/bin/df"))
253 dfcommand = "/bin/df";
254 else
255 dfcommand = locatecommand("df", tr("either"), "util-linux");
256 if (QFile::exists("/sbin/sfdisk"))
257 sfdiskcommand = "/sbin/sfdisk";
258 else
259 sfdiskcommand = locatecommand("sfdisk", tr("either"), "silent");
260 if (QFile::exists("/lib/udev/vol_id"))
261 volidcommand = "/lib/udev/vol_id";
262 else
263 volidcommand = locatecommand("vol_id", tr("either"), "silent");
264 if (volidcommand.isEmpty())
265 {
266 if (QFile::exists("/sbin/blkid"))
267 blkidcommand = "/sbin/blkid";
268 else
269 blkidcommand = locatecommand("blkid", tr("either"), "e2fsprogs");
270 }
271 else
272 blkidcommand = "/sbin/blkid";
273 if (QFile::exists("/sbin/mke2fs"))
274 mke2fscommand = "/sbin/mke2fs";
275 else
276 mke2fscommand = locatecommand("mke2fs", tr("LiveUSB persistence"), "e2fsprogs");
277 if (QFile::exists("/sbin/e2label"))
278 e2labelcommand = "/sbin/e2label";
279 else
280 e2labelcommand = locatecommand("e2label", "Arch Linux", "e2fsprogs");
281 if (QFile::exists("/usr/bin/mlabel"))
282 mlabelcommand = "/usr/bin/mlabel";
283 else
284 mlabelcommand = locatecommand("mlabel", "Arch Linux", "mtools");
285 syslinuxcommand = "/usr/bin/ubnsylnx";
286 extlinuxcommand = "/usr/bin/ubnexlnx";
287 #ifdef NOSTATIC
288 if (QFile::exists("/usr/bin/syslinux"))
289 syslinuxcommand = "/usr/bin/syslinux";
290 else
291 syslinuxcommand = locatecommand("syslinux", tr("FAT32-formatted USB drive"), "syslinux");
292 if (QFile::exists("/usr/bin/extlinux"))
293 extlinuxcommand = "/usr/bin/extlinux";
294 else
295 extlinuxcommand = locatecommand("extlinux", tr("EXT2-formatted USB drive"), "extlinux");
296 #endif
297 sevzcommand = locatecommand("7z", tr("either"), "p7zip-full");
298 #endif // Q_OS_LINUX
299 #ifdef Q_OS_FREEBSD
300 syslinuxcommand = locatecommand("syslinux", tr("FAT32-formatted USB drive"), "syslinux");
301 sevzcommand = locatecommand("7z", tr("either"), "p7zip");
302 mke2fscommand = locatecommand("mke2fs", tr("LiveUSB persistence"), "e2fsprogs");
303 #endif // Q_OS_FREEBSD
304 ubntmpf = QDir::toNativeSeparators(QString("%1/").arg(QDir::tempPath()));
305 #ifdef Q_OS_UNIX
306 if (ubntmpf.isEmpty() || ubntmpf == "/")
307 {
308 ubntmpf = "/tmp/";
309 }
310 #endif
311 if (typeselect->findText(tr("USB Drive")) != -1)
312 typeselect->setCurrentIndex(typeselect->findText(tr("USB Drive")));
313 #ifdef HDDINSTALL
314 if (typeselect->findText(tr("Hard Disk")) != -1)
315 typeselect->setCurrentIndex(typeselect->findText(tr("Hard Disk")));
316 #endif
317 for (QList<QPair<QString, QString> >::const_iterator i = oppairs.constBegin(); i < oppairs.constEnd(); ++i)
318 {
319 QString pfirst(i->first);
320 QString psecond(i->second);
321 if (pfirst.contains("method", Qt::CaseInsensitive))
322 {
323 if (psecond.contains("distribution", Qt::CaseInsensitive))
324 this->radioDistro->setChecked(true);
325 else if (psecond.contains("diskimage", Qt::CaseInsensitive))
326 this->radioFloppy->setChecked(true);
327 else if (psecond.contains("custom", Qt::CaseInsensitive))
328 this->radioManual->setChecked(true);
329 }
330 else if (pfirst.contains("distribution", Qt::CaseInsensitive))
331 {
332 int distidx = this->distroselect->findText(psecond, Qt::MatchFixedString);
333 if (distidx != -1)
334 this->distroselect->setCurrentIndex(distidx);
335 }
336 else if (pfirst.contains("version", Qt::CaseInsensitive))
337 {
338 QStringList verlist = this->distroselect->itemData(this->distroselect->currentIndex()).value<QStringList>();
339 for (int j = 2; j < verlist.size(); ++j)
340 {
341 if (verlist[j].contains(psecond, Qt::CaseInsensitive))
342 {
343 this->dverselect->setCurrentIndex(j-2);
344 break;
345 }
346 }
347 }
348 else if (pfirst.contains("isofile", Qt::CaseInsensitive))
349 {
350 this->diskimagetypeselect->setCurrentIndex(diskimagetypeselect->findText(tr("ISO")));
351 this->FloppyPath->setText(psecond);
352 this->radioFloppy->setChecked(true);
353 }
354 else if (pfirst.contains("imgfile", Qt::CaseInsensitive))
355 {
356 this->diskimagetypeselect->setCurrentIndex(diskimagetypeselect->findText(tr("Floppy")));
357 this->FloppyPath->setText(psecond);
358 this->radioFloppy->setChecked(true);
359 }
360 else if (pfirst.contains("kernelfile", Qt::CaseInsensitive))
361 {
362 this->KernelPath->setText(psecond);
363 }
364 else if (pfirst.contains("initrdfile", Qt::CaseInsensitive))
365 {
366 this->InitrdPath->setText(psecond);
367 }
368 else if (pfirst.contains("cfgfile", Qt::CaseInsensitive))
369 {
370 QString cfgoptstxt = getcfgkernargs(psecond, "", QStringList(), QStringList());
371 if (cfgoptstxt.isEmpty())
372 {
373 cfgoptstxt = getgrubcfgargs(psecond);
374 }
375 this->OptionEnter->setText(cfgoptstxt);
376 }
377 else if (pfirst.contains("kernelopts", Qt::CaseInsensitive))
378 {
379 this->OptionEnter->setText(psecond);
380 }
381 else if (pfirst.contains("installtype", Qt::CaseInsensitive))
382 {
383 if (psecond.contains("Hard", Qt::CaseInsensitive) || psecond.contains("HDD", Qt::CaseInsensitive))
384 this->typeselect->setCurrentIndex(this->typeselect->findText(tr("Hard Disk")));
385 else
386 this->typeselect->setCurrentIndex(this->typeselect->findText(tr("USB Drive")));
387 }
388 else if (pfirst.contains("targetdrive", Qt::CaseInsensitive))
389 {
390 #ifdef Q_OS_WIN32
391 if (!psecond.endsWith('\\'))
392 {
393 psecond = psecond + '\\';
394 }
395 #endif
396 int driveidx = this->driveselect->findText(psecond, Qt::MatchFixedString);
397 if (driveidx != -1)
398 {
399 this->driveselect->setCurrentIndex(driveidx);
400 }
401 else
402 {
403 this->driveselect->addItem(psecond);
404 this->driveselect->setCurrentIndex(this->driveselect->findText(psecond, Qt::MatchFixedString));
405 }
406 }
407 else if (pfirst.contains("showcustom", Qt::CaseInsensitive))
408 {
409 if (psecond.contains('y', Qt::CaseInsensitive))
410 {
411 hideCustom = false;
412 }
413 }
414 else if (pfirst.contains("nodistro", Qt::CaseInsensitive))
415 {
416 if (psecond.contains('y', Qt::CaseInsensitive))
417 {
418 radioDistro->setEnabled(false);
419 radioDistro->hide();
420 distroselect->setEnabled(false);
421 distroselect->hide();
422 dverselect->setEnabled(false);
423 dverselect->hide();
424 intromessage->move(intromessage->x(), intromessage->y()-20);
425 intromessage->resize(intromessage->width(), intromessage->height() + 20);
426 }
427 }
428 else if (pfirst.contains("message", Qt::CaseInsensitive))
429 {
430 intromessage->setText(psecond);
431 }
432 else if (pfirst.contains("persistentspace", Qt::CaseInsensitive))
433 {
434 bool isInt = false;
435 int numMBpersistentSpace = psecond.toInt(&isInt, 10);
436 if (isInt)
437 this->persistencevalue->setValue(numMBpersistentSpace);
438 }
439 else if (pfirst.contains("testingdownload", Qt::CaseInsensitive))
440 {
441 if (psecond.contains('y', Qt::CaseInsensitive))
442 {
443 testingDownload = true;
444 exitOnCompletion = true;
445 }
446 }
447 else if (pfirst.contains("exitoncompletion", Qt::CaseInsensitive))
448 {
449 if (psecond.contains('y', Qt::CaseInsensitive))
450 {
451 exitOnCompletion = true;
452 }
453 }
454 else if (pfirst.contains("skipextraction", Qt::CaseInsensitive))
455 {
456 if (psecond.contains('y', Qt::CaseInsensitive))
457 {
458 skipExtraction = true;
459 }
460 }
461 else if (pfirst.contains("autoinstall", Qt::CaseInsensitive))
462 {
463 if (psecond.contains('y', Qt::CaseInsensitive))
464 {
465 exitOnCompletion = true;
466 overwriteall = true;
467 return true;
468 }
469 }
470 else if (pfirst.contains("action", Qt::CaseInsensitive))
471 {
472 if (psecond.contains("listdistros", Qt::CaseInsensitive))
473 {
474 QTextStream out(stdout);
475 for (int i = 1; i < this->distroselect->count(); ++i)
476 {
477 out << this->distroselect->itemText(i) << endl;
478 }
479 out.flush();
480 QApplication::exit();
481 exit(0);
482 }
483 else if (psecond.contains("listversions", Qt::CaseInsensitive))
484 {
485 QTextStream out(stdout);
486 for (int i = 0; i < this->dverselect->count(); ++i)
487 {
488 out << this->dverselect->itemText(i) << endl;
489 }
490 out.flush();
491 QApplication::exit();
492 exit(0);
493 }
494 }
495 }
496 if (hideCustom)
497 {
498 radioManual->setEnabled(false);
499 radioManual->hide();
500 labelkernel->setEnabled(false);
501 labelkernel->hide();
502 labelinitrd->setEnabled(false);
503 labelinitrd->hide();
504 labeloption->setEnabled(false);
505 labeloption->hide();
506 KernelFileSelector->setEnabled(false);
507 KernelFileSelector->hide();
508 InitrdFileSelector->setEnabled(false);
509 InitrdFileSelector->hide();
510 CfgFileSelector->setEnabled(false);
511 CfgFileSelector->hide();
512 OptionEnter->setEnabled(false);
513 OptionEnter->hide();
514 KernelPath->setEnabled(false);
515 KernelPath->hide();
516 InitrdPath->setEnabled(false);
517 InitrdPath->hide();
518 KernelFileSelector->setEnabled(false);
519 KernelFileSelector->hide();
520 InitrdFileSelector->setEnabled(false);
521 InitrdFileSelector->hide();
522 radioLayout->removeItem(verticalSpacer);
523 }
524 return false;
525 }
526
on_distroselect_currentIndexChanged(int distroselectIndex)527 void unetbootin::on_distroselect_currentIndexChanged(int distroselectIndex)
528 {
529 dverselect->clear();
530 if (distroselectIndex == -1)
531 return;
532 QStringList dverL = distroselect->itemData(distroselectIndex).value<QStringList>();
533 for (int i = 2; i < dverL.size(); ++i)
534 {
535 if (!dverL.at(i).contains("someotherversion") && !dverL.at(i).isEmpty())
536 dverselect->addItem(dverL.at(i));
537 }
538 if (dverselect->findText(dverL.at(0)) != -1)
539 dverselect->setCurrentIndex(dverselect->findText(dverL.at(0)));
540 intromessage->setText(dverL.at(1));
541 radioDistro->setChecked(true);
542 }
543
refreshdriveslist()544 void unetbootin::refreshdriveslist()
545 {
546 driveselect->clear();
547 QStringList driveslist = listcurdrives();
548 for (int i = 0; i < driveslist.size(); ++i)
549 {
550 driveselect->addItem(driveslist.at(i));
551 }
552 }
553
listcurdrives()554 QStringList unetbootin::listcurdrives()
555 {
556 return listsanedrives();
557 }
558
559 #ifdef Q_OS_MAC
is_external_drive_macos(const QString & drivename)560 bool unetbootin::is_external_drive_macos(const QString &drivename)
561 {
562 // drivename: disk3s1
563 QString device_info = callexternapp("diskutil", "info " + drivename);
564 if (device_info.contains("External"))
565 {
566 return true;
567 }
568 // stw "diskutil info" output changed; now look for line "Internal: No"
569 QStringList infoLines = device_info.split("\n").filter("Internal");
570 for (int i = 0; i < infoLines.size(); i++) {
571 if (infoLines.at(i).contains("No"))
572 return true;
573 }
574
575 return false;
576 }
577 #endif
578
matchinglist(QRegExp regex,QString text)579 QStringList unetbootin::matchinglist(QRegExp regex, QString text)
580 {
581 QStringList matchinglist;
582 int pos = 0;
583
584 while ((pos = regex.indexIn(text, pos)) != -1) {
585 matchinglist << regex.cap(1);
586 pos += regex.matchedLength();
587 }
588
589 return matchinglist;
590 }
591
listsanedrives()592 QStringList unetbootin::listsanedrives()
593 {
594 QStringList fulldrivelist;
595 if (typeselect->currentText() == tr("Hard Disk"))
596 {
597 fulldrivelist.append(QDir::toNativeSeparators(QDir::rootPath()).toUpper());
598 }
599 else if (typeselect->currentText() == tr("USB Drive"))
600 {
601 #ifdef Q_OS_WIN32
602 QFileInfoList extdrivesList = QDir::drives();
603 for (int i = 0; i < extdrivesList.size(); ++i)
604 {
605 if (QDir::toNativeSeparators(extdrivesList.at(i).path().toUpper()) != QDir::toNativeSeparators(QDir::rootPath().toUpper()) && !QDir::toNativeSeparators(extdrivesList.at(i).path().toUpper()).contains("A:") && !QDir::toNativeSeparators(extdrivesList.at(i).path().toUpper()).contains("B:"))
606 {
607 if (GetDriveType(LPWSTR(extdrivesList.at(i).path().toUpper().utf16())) == 2)
608 {
609 fulldrivelist.append(QDir::toNativeSeparators(extdrivesList.at(i).path().toUpper()));
610 }
611 }
612 }
613 #endif
614 #ifdef Q_OS_LINUX
615 QDir devlstdir("/dev/disk/by-id/");
616 QFileInfoList usbfileinfoL = devlstdir.entryInfoList(QDir::NoDotAndDotDot|QDir::Files);
617 for (int i = 0; i < usbfileinfoL.size(); ++i)
618 {
619 // if (usbfileinfoL.at(i).contains(QRegExp("^usb-\\S{1,}-part\\d{1,}$")))
620 // {
621 // fulldrivelist.append(usbfileinfoL.at(i).canonicalFilePath());
622 // }
623 if (usbfileinfoL.at(i).fileName().contains(QRegExp("^usb-\\S{1,}$")) ||
624 usbfileinfoL.at(i).fileName().contains(QRegExp("^mmc-\\S{1,}$")))
625 {
626 if (!volidcommand.isEmpty())
627 {
628 if (QString(callexternapp(volidcommand, QString("-t %2").arg(usbfileinfoL.at(i).canonicalFilePath()))).contains(QRegExp("(vfat|ext2|ext3|ext4)")))
629 fulldrivelist.append(usbfileinfoL.at(i).canonicalFilePath());
630 }
631 else
632 {
633 QString tstrblk = QString(callexternapp(blkidcommand, QString("-s TYPE %2").arg(usbfileinfoL.at(i).canonicalFilePath())));
634 if (tstrblk.contains('='))
635 {
636 if (tstrblk.section('=', -1, -1).remove('"').contains(QRegExp("(vfat|ext2|ext3|ext4)")))
637 fulldrivelist.append(usbfileinfoL.at(i).canonicalFilePath());
638 }
639 }
640 }
641 }
642 /*
643 QString fdisklusbdevsS = callexternapp(fdiskcommand, "-l");
644 QStringList usbdevsL = QString(fdisklusbdevsS).split("\n").filter(QRegExp("\\.{0,}FAT|Disk\\.{0,}")).join("\n").split(" ").join("\n").split("\t").join("\n").split("\n").filter("/dev/");
645 for (int i = 0; i < usbdevsL.size(); ++i)
646 {
647 if (usbdevsL.at(i).contains(":"))
648 {
649 if (!QString(callexternapp(volidcommand, QString("-t %2").arg(QString(usbdevsL.at(i)).remove(":")))).contains("vfat"))
650 continue;
651 }
652 fulldrivelist.append(QString(usbdevsL.at(i)).remove(":"));
653 }
654 */
655 #endif
656 #ifdef Q_OS_FREEBSD
657 #ifdef __DragonFly__
658 struct vfsconf fsconf;
659 #else
660 struct xvfsconf fsconf;
661 #endif
662 struct statfs *fslist;
663
664 /*
665 * Make sure that MSDOSFS is configured with the kernel.
666 * As a nice side effect, this would allow to compare a
667 * number (assigned by VFS) instead of "msdosfs" string
668 * when iterating over mounted filesystems.
669 */
670 if (getvfsbyname("msdosfs", &fsconf) == -1)
671 goto out;
672
673 /*
674 * Quick sanity check of the number of active mountpoints
675 * using the filesystem (we need mounted storage to work).
676 */
677 if (fsconf.vfc_refcount < 1)
678 goto out;
679
680 int numfs = getmntinfo(&fslist, MNT_NOWAIT);
681 if (numfs < 1)
682 goto out;
683
684 QRegExp pendrives_sdcards("^/dev/(da|mmcsd)\\d+");
685
686 for (int i = 0; i < numfs; ++i)
687 {
688 /*
689 * We're interested in MSDOSFS (FAT) filesystems
690 * that are mounted off removable storage (e.g.,
691 * USB memsticks, SD cards). Assume that device
692 * names for those are /dev/da* and /dev/mmcsd*.
693 * (Perhaps not entirely accurate assumption.)
694 */
695 if ((int)fslist[i].f_type == fsconf.vfc_typenum &&
696 QString(fslist[i].f_mntfromname)
697 .contains(pendrives_sdcards))
698 {
699 /*
700 * Unlike other implementations above, we
701 * append tuples of device name *and* the
702 * mount point, so we do not have to find
703 * mount point separately later.
704 */
705 fulldrivelist.append(QString("%1:%2")
706 .arg(fslist[i].f_mntfromname)
707 .arg(fslist[i].f_mntonname));
708 }
709 }
710 #endif
711 #ifdef Q_OS_MAC
712 QString systemprofilertext = callexternapp("system_profiler", "SPStorageDataType");
713 QRegExp filesystemregex("File System: (.+)\\n");
714 QRegExp drivenameregex("BSD Name: (.+)\\n");
715 filesystemregex.setMinimal(true);
716 drivenameregex.setMinimal(true);
717
718 QStringList filesystemlist = matchinglist(filesystemregex, systemprofilertext);
719 QStringList drivenamelist = matchinglist(drivenameregex, systemprofilertext);
720
721 QRegExp fatfilesystems("FAT|Microsoft");
722
723 for (int i = 0; i < filesystemlist.size(); ++i)
724 {
725 if ((fatfilesystems.indexIn(filesystemlist.at(i),0) != -1) && is_external_drive_macos(drivenamelist.at(i))) {
726 fulldrivelist.append("/dev/"+drivenamelist.at(i));
727 }
728 }
729 #endif
730 }
731 out:
732 return fulldrivelist;
733 }
734
735
listalldrives()736 QStringList unetbootin::listalldrives()
737 {
738 QStringList fulldrivelist;
739 #ifdef Q_OS_WIN32
740 QFileInfoList extdrivesList = QDir::drives();
741 for (int i = 0; i < extdrivesList.size(); ++i)
742 {
743 fulldrivelist.append(QDir::toNativeSeparators(extdrivesList.at(i).path().toUpper()));
744 }
745 #endif
746 #ifdef Q_OS_LINUX
747 QString fdisklusbdevsS = callexternapp(fdiskcommand, "-l");
748 QString dflusbdevsS = callexternapp(dfcommand, "");
749 fulldrivelist = QString(dflusbdevsS).split(" ").join("\n").split("\t").join("\n").split("\n").filter("/dev/");
750 QStringList fulldrivelist2 = QString(fdisklusbdevsS).split(" ").join("\n").split("\t").join("\n").split("\n").filter("/dev/").replaceInStrings(":", "");
751 for (int i = 0; i < fulldrivelist2.size(); ++i)
752 {
753 if (!fulldrivelist.contains(fulldrivelist2.at(i)))
754 fulldrivelist.append(fulldrivelist2.at(i));
755 }
756 #endif
757 #ifdef Q_OS_MAC
758 return listsanedrives();
759 #endif
760 return fulldrivelist;
761 }
762
on_typeselect_currentIndexChanged(int)763 void unetbootin::on_typeselect_currentIndexChanged(int)
764 {
765 refreshdriveslist();
766 }
767
on_dverselect_currentIndexChanged(int)768 void unetbootin::on_dverselect_currentIndexChanged(int)
769 {
770 radioDistro->setChecked(true);
771 }
772
on_diskimagetypeselect_currentIndexChanged(int)773 void unetbootin::on_diskimagetypeselect_currentIndexChanged(int)
774 {
775 radioFloppy->setChecked(true);
776 }
777
on_FloppyFileSelector_clicked()778 void unetbootin::on_FloppyFileSelector_clicked()
779 {
780 QString nameFloppy = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Open Disk Image File"), QDir::homePath(), tr("All Files") + " (*);;" + tr("ISO") + " (*.iso);;" + tr("Floppy") + " (*.img)", 0
781 #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
782 , QFileDialog::ReadOnly
783 #endif
784 ));
785 if (QFileInfo(nameFloppy).completeSuffix().contains("iso", Qt::CaseInsensitive))
786 {
787 if (diskimagetypeselect->findText(tr("ISO")) != -1)
788 diskimagetypeselect->setCurrentIndex(diskimagetypeselect->findText(tr("ISO")));
789 }
790 if (QFileInfo(nameFloppy).completeSuffix().contains("img", Qt::CaseInsensitive) || QFileInfo(nameFloppy).completeSuffix().contains("flp", Qt::CaseInsensitive))
791 {
792 if (diskimagetypeselect->findText(tr("Floppy")) != -1)
793 diskimagetypeselect->setCurrentIndex(diskimagetypeselect->findText(tr("Floppy")));
794 }
795 FloppyPath->clear();
796 FloppyPath->insert(nameFloppy);
797 radioFloppy->setChecked(true);
798 }
799
on_KernelFileSelector_clicked()800 void unetbootin::on_KernelFileSelector_clicked()
801 {
802 QString nameKernel = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Open Kernel File"), QDir::homePath(), tr("All Files (*)"), 0
803 #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
804 , QFileDialog::ReadOnly
805 #endif
806 ));
807 KernelPath->clear();
808 KernelPath->insert(nameKernel);
809 radioManual->setChecked(true);
810 }
811
on_InitrdFileSelector_clicked()812 void unetbootin::on_InitrdFileSelector_clicked()
813 {
814 QString nameInitrd = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Open Initrd File"), QDir::homePath(), tr("All Files (*)"), 0
815 #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
816 , QFileDialog::ReadOnly
817 #endif
818 ));
819 InitrdPath->clear();
820 InitrdPath->insert(nameInitrd);
821 radioManual->setChecked(true);
822 }
823
on_CfgFileSelector_clicked()824 void unetbootin::on_CfgFileSelector_clicked()
825 {
826 QString nameCfg = QFileDialog::getOpenFileName(this, tr("Open Bootloader Config File"), QDir::homePath(), tr("All Files (*)"), 0
827 #if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
828 , QFileDialog::ReadOnly
829 #endif
830 );
831 OptionEnter->clear();
832 QString cfgoptstxt = getcfgkernargs(nameCfg, "", QStringList(), QStringList());
833 if (cfgoptstxt.isEmpty())
834 {
835 cfgoptstxt = getgrubcfgargs(nameCfg);
836 }
837 OptionEnter->insert(cfgoptstxt);
838 radioManual->setChecked(true);
839 }
840
on_cancelbutton_clicked()841 void unetbootin::on_cancelbutton_clicked()
842 {
843 close();
844 }
845
on_okbutton_clicked()846 void unetbootin::on_okbutton_clicked()
847 {
848 if (typeselect->currentIndex() == typeselect->findText(tr("USB Drive")) && driveselect->currentText().isEmpty() && !testingDownload)
849 {
850 QMessageBox unotenoughinputmsgb;
851 unotenoughinputmsgb.setIcon(QMessageBox::Information);
852 unotenoughinputmsgb.setWindowTitle(tr("Insert a USB flash drive"));
853 unotenoughinputmsgb.setText(tr("No USB flash drives were found. If you have already inserted a USB drive, try reformatting it as FAT32."));
854 unotenoughinputmsgb.setStandardButtons(QMessageBox::Ok);
855 switch (unotenoughinputmsgb.exec())
856 {
857 case QMessageBox::Ok:
858 break;
859 default:
860 break;
861 }
862 refreshdriveslist(); // stw give it a chance to detect a new drive
863 }
864 #ifdef Q_OS_MAC
865 if (locatemountpoint(driveselect->currentText()) == "NOT MOUNTED" && !testingDownload)
866 callexternapp("diskutil", "mount "+driveselect->currentText());
867 #endif
868 #ifdef Q_OS_LINUX
869 else if (typeselect->currentIndex() == typeselect->findText(tr("USB Drive")) && locatemountpoint(driveselect->currentText()) == "NOT MOUNTED")
870 {
871 QMessageBox merrordevnotmountedmsgbx;
872 merrordevnotmountedmsgbx.setIcon(QMessageBox::Warning);
873 merrordevnotmountedmsgbx.setWindowTitle(QString(tr("%1 not mounted")).arg(driveselect->currentText()));
874 merrordevnotmountedmsgbx.setText(QString(tr("You must first mount the USB drive %1 to a mountpoint. Most distributions will do this automatically after you remove and reinsert the USB drive.")).arg(driveselect->currentText()));
875 merrordevnotmountedmsgbx.setStandardButtons(QMessageBox::Ok);
876 switch (merrordevnotmountedmsgbx.exec())
877 {
878 case QMessageBox::Ok:
879 break;
880 default:
881 break;
882 }
883 }
884 #endif
885 else if (radioDistro->isChecked() && distroselect->currentIndex() == distroselect->findText(unetbootin::tr("== Select Distribution ==")))
886 {
887 QMessageBox dnotenoughinputmsgb;
888 dnotenoughinputmsgb.setIcon(QMessageBox::Information);
889 dnotenoughinputmsgb.setWindowTitle(tr("Select a distro"));
890 dnotenoughinputmsgb.setText(tr("You must select a distribution to load."));
891 dnotenoughinputmsgb.setStandardButtons(QMessageBox::Ok);
892 switch (dnotenoughinputmsgb.exec())
893 {
894 case QMessageBox::Ok:
895 break;
896 default:
897 break;
898 }
899 }
900 else if (radioFloppy->isChecked() && FloppyPath->text().isEmpty())
901 {
902 QMessageBox fnotenoughinputmsgb;
903 fnotenoughinputmsgb.setIcon(QMessageBox::Information);
904 fnotenoughinputmsgb.setWindowTitle(tr("Select a disk image file"));
905 fnotenoughinputmsgb.setText(tr("You must select a disk image file to load."));
906 fnotenoughinputmsgb.setStandardButtons(QMessageBox::Ok);
907 switch (fnotenoughinputmsgb.exec())
908 {
909 case QMessageBox::Ok:
910 break;
911 default:
912 break;
913 }
914 }
915 else if (radioManual->isChecked() && KernelPath->text().isEmpty())
916 {
917 QMessageBox knotenoughinputmsgb;
918 knotenoughinputmsgb.setIcon(QMessageBox::Information);
919 knotenoughinputmsgb.setWindowTitle(tr("Select a kernel and/or initrd file"));
920 knotenoughinputmsgb.setText(tr("You must select a kernel and/or initrd file to load."));
921 knotenoughinputmsgb.setStandardButtons(QMessageBox::Ok);
922 switch (knotenoughinputmsgb.exec())
923 {
924 case QMessageBox::Ok:
925 break;
926 default:
927 break;
928 }
929 }
930 else if (radioFloppy->isChecked() && !QFile::exists(FloppyPath->text()) && !FloppyPath->text().startsWith("http://") && !FloppyPath->text().startsWith("ftp://"))
931 {
932 QMessageBox ffnotexistsmsgb;
933 ffnotexistsmsgb.setIcon(QMessageBox::Information);
934 ffnotexistsmsgb.setWindowTitle(tr("Diskimage file not found"));
935 ffnotexistsmsgb.setText(tr("The specified diskimage file %1 does not exist.").arg(FloppyPath->text()));
936 ffnotexistsmsgb.setStandardButtons(QMessageBox::Ok);
937 switch (ffnotexistsmsgb.exec())
938 {
939 case QMessageBox::Ok:
940 break;
941 default:
942 break;
943 }
944 }
945 else if (radioManual->isChecked() && !QFile::exists(KernelPath->text()) && !KernelPath->text().startsWith("http://") && !KernelPath->text().startsWith("ftp://"))
946 {
947 QMessageBox kfnotexistsmsgb;
948 kfnotexistsmsgb.setIcon(QMessageBox::Information);
949 kfnotexistsmsgb.setWindowTitle(tr("Kernel file not found"));
950 kfnotexistsmsgb.setText(tr("The specified kernel file %1 does not exist.").arg(KernelPath->text()));
951 kfnotexistsmsgb.setStandardButtons(QMessageBox::Ok);
952 switch (kfnotexistsmsgb.exec())
953 {
954 case QMessageBox::Ok:
955 break;
956 default:
957 break;
958 }
959 }
960 else if (radioManual->isChecked() && InitrdPath->text().trimmed() != "" && !QFile::exists(InitrdPath->text()) && !InitrdPath->text().startsWith("http://") && !InitrdPath->text().startsWith("ftp://"))
961 {
962 QMessageBox ifnotexistsmsgb;
963 ifnotexistsmsgb.setIcon(QMessageBox::Information);
964 ifnotexistsmsgb.setWindowTitle(tr("Initrd file not found"));
965 ifnotexistsmsgb.setText(tr("The specified initrd file %1 does not exist.").arg(InitrdPath->text()));
966 ifnotexistsmsgb.setStandardButtons(QMessageBox::Ok);
967 switch (ifnotexistsmsgb.exec())
968 {
969 case QMessageBox::Ok:
970 break;
971 default:
972 break;
973 }
974 }
975 else
976 {
977 runinst();
978 }
979 }
980
on_fexitbutton_clicked()981 void unetbootin::on_fexitbutton_clicked()
982 {
983 close();
984 }
985
displayfisize(quint64 fisize)986 QString unetbootin::displayfisize(quint64 fisize)
987 {
988 if (fisize < 10000)
989 {
990 return QString("%1 B").arg(fisize);
991 }
992 else if (fisize < 10240000)
993 {
994 return QString("%1 KB").arg(fisize / 1024);
995 }
996 else
997 {
998 return QString("%1 MB").arg(fisize / 1048576);
999 }
1000 }
1001
listarchiveconts(QString archivefile)1002 QPair<QPair<QStringList, QList<quint64> >, QStringList> unetbootin::listarchiveconts(QString archivefile)
1003 {
1004 #ifdef Q_OS_WIN32
1005 if (sevzcommand.isEmpty())
1006 {
1007 installsvzip();
1008 }
1009 randtmpfile tmplsF(ubntmpf, "ufl");
1010 callexternapp(getenv("COMSPEC"), QString("/c \"\"%1\" -bd -slt l \"%2\" > \"%3\"\"").arg(sevzcommand).arg(QFileInfo(archivefile).absoluteFilePath()).arg(QFileInfo(tmplsF).absoluteFilePath()));
1011 tmplsF.open(QIODevice::ReadOnly | QIODevice::Text);
1012 QTextStream tmplsS(&tmplsF);
1013 #endif
1014 #ifdef Q_OS_UNIX
1015 QString sevzlcommandout = callexternapp(sevzcommand, QString("-bd -slt l \"%1\"").arg(QFileInfo(archivefile).absoluteFilePath()));
1016 QTextStream tmplsS(&sevzlcommandout);
1017 #endif
1018 QString tmplsL;
1019 QStringList tmplsSLF;
1020 QStringList tmplsSLD;
1021 QList<quint64> tmplsSLFS;
1022 QString tmplsN;
1023 QString tmplsFS;
1024 while (!tmplsS.atEnd())
1025 {
1026 tmplsL = tmplsS.readLine();
1027 if (tmplsL.contains("Path = "))
1028 {
1029 if (tmplsL.contains("Path = [BOOT]"))
1030 continue;
1031 if (tmplsL == QString("Path = %1").arg(QFileInfo(archivefile).absoluteFilePath()))
1032 continue;
1033 if (tmplsL == QString("Path = %1").arg(QDir::toNativeSeparators(QFileInfo(archivefile).absoluteFilePath())))
1034 continue;
1035 tmplsN = tmplsS.readLine();
1036 if (tmplsN.contains("Folder = 1") || tmplsN.contains("Folder = +"))
1037 {
1038 tmplsSLD.append(tmplsL.remove("Path = "));
1039 }
1040 else
1041 {
1042 tmplsSLF.append(tmplsL.remove("Path = "));
1043 tmplsFS = QString(tmplsS.readLine()).remove("Size = ").trimmed();
1044 tmplsSLFS.append(tmplsFS.toULongLong());
1045 }
1046 }
1047 }
1048 #ifdef Q_OS_WIN32
1049 tmplsF.close();
1050 rmFile(tmplsF);
1051 #endif
1052 return qMakePair(qMakePair(tmplsSLF, tmplsSLFS), tmplsSLD);
1053 }
1054
overwritefileprompt(QString ovwfileloc)1055 bool unetbootin::overwritefileprompt(QString ovwfileloc)
1056 {
1057 if (overwriteall)
1058 {
1059 rmFile(ovwfileloc);
1060 return true;
1061 }
1062 QMessageBox overwritefilemsgbx;
1063 overwritefilemsgbx.setIcon(QMessageBox::Warning);
1064 overwritefilemsgbx.setWindowTitle(QString(tr("%1 exists, overwrite?")).arg(ovwfileloc));
1065 overwritefilemsgbx.setText(QString(tr("The file %1 already exists. Press 'Yes to All' to overwrite it and not be prompted again, 'Yes' to overwrite files on an individual basis, and 'No' to retain your existing version. If in doubt, press 'Yes to All'.")).arg(ovwfileloc));
1066 overwritefilemsgbx.setStandardButtons(QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No);
1067 switch (overwritefilemsgbx.exec())
1068 {
1069 case QMessageBox::Yes:
1070 {
1071 rmFile(ovwfileloc);
1072 return true;
1073 }
1074 case QMessageBox::YesToAll:
1075 {
1076 rmFile(ovwfileloc);
1077 overwriteall = true;
1078 return true;
1079 }
1080 case QMessageBox::No:
1081 return false;
1082 default:
1083 return false;
1084 }
1085 }
1086
ignoreoutofspaceprompt(QString destindir)1087 bool unetbootin::ignoreoutofspaceprompt(QString destindir)
1088 {
1089 QMessageBox overwritefilemsgbx;
1090 overwritefilemsgbx.setIcon(QMessageBox::Warning);
1091 overwritefilemsgbx.setWindowTitle(QString(tr("%1 is out of space, abort installation?")).arg(destindir));
1092 overwritefilemsgbx.setText(QString(tr("The directory %1 is out of space. Press 'Yes' to abort installation, 'No' to ignore this error and attempt to continue installation, and 'No to All' to ignore all out-of-space errors.")).arg(destindir));
1093 overwritefilemsgbx.setStandardButtons(QMessageBox::Yes | QMessageBox::NoToAll | QMessageBox::No);
1094 switch (overwritefilemsgbx.exec())
1095 {
1096 case QMessageBox::Yes:
1097 {
1098 QApplication::quit();
1099 return false;
1100 }
1101 case QMessageBox::No:
1102 {
1103 return true;
1104 }
1105 case QMessageBox::NoToAll:
1106 {
1107 this->ignoreoutofspace = true;
1108 return true;
1109 }
1110 default:
1111 return true;
1112 }
1113 }
1114
extractfile(QString filepath,QString destinfileL,QString archivefile)1115 bool unetbootin::extractfile(QString filepath, QString destinfileL, QString archivefile)
1116 {
1117 #ifdef Q_OS_UNIX
1118 if (installType != tr("USB Drive") && filepath.contains("boot/grub")) // don't nuke grub config
1119 return false;
1120 #endif
1121 QString destindir = QFileInfo(destinfileL).dir().absolutePath();
1122 QString destinfilename = QString("%1/%2").arg(destindir).arg(QFileInfo(destinfileL).fileName());
1123 QString filepathfilename = QString("%1/%2").arg(destindir).arg(QFileInfo(filepath).fileName());
1124 if (QFile::exists(filepathfilename))
1125 {
1126 if (!overwritefileprompt(filepathfilename))
1127 return false;
1128 }
1129 if (QFile::exists(destinfilename))
1130 {
1131 if (!overwritefileprompt(destinfilename))
1132 return false;
1133 }
1134 #ifdef Q_OS_WIN32
1135 if (sevzcommand.isEmpty())
1136 {
1137 installsvzip();
1138 }
1139 #endif
1140 callexternapp(sevzcommand, QString("-bd -aos -o\"%1\" e \"%2\" \"%3\"").arg(QDir::toNativeSeparators(destindir), QDir::toNativeSeparators(archivefile), QDir::toNativeSeparators(filepath)));
1141 int retv;
1142 if (QFileInfo(filepathfilename).absoluteFilePath() == QFileInfo(destinfilename).absoluteFilePath())
1143 {
1144 retv = true;
1145 }
1146 else
1147 {
1148 retv = QFile::rename(filepathfilename, destinfilename);
1149 }
1150 this->checkifoutofspace(destindir);
1151 return retv;
1152 }
1153
checkifoutofspace(QString destindir)1154 bool unetbootin::checkifoutofspace(QString destindir)
1155 {
1156 if (ignoreoutofspace == true)
1157 return false;
1158 bool outofspace = false;
1159 #ifdef Q_OS_UNIX
1160 struct statfs diskstatS;
1161 if (!statfs(QString(destindir+"/.").toLatin1(), &diskstatS))
1162 {
1163 /*
1164 * Refuse to work if available disk space is less than 1MB
1165 * (1024KB). Even this seems very low, but original value
1166 * of 1024 bytes was simply ridiculous.
1167 */
1168 if (diskstatS.f_bsize / 1024 * diskstatS.f_bavail < 1024)
1169 outofspace = true;
1170 }
1171 #endif
1172 #ifdef Q_OS_WIN32
1173 ULARGE_INTEGER FreeBytesAvailable;
1174 ULARGE_INTEGER TotalNumberOfBytes;
1175 ULARGE_INTEGER TotalNumberOfFreeBytes;
1176 if (GetDiskFreeSpaceExA(destindir.toUtf8(), &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
1177 {
1178 if (FreeBytesAvailable.QuadPart < 1024)
1179 outofspace = true;
1180 }
1181 #endif
1182 if (outofspace == true)
1183 {
1184 return !ignoreoutofspaceprompt(destindir);
1185 }
1186 return false;
1187 }
1188
locatekernel(QString archivefile,QPair<QStringList,QList<quint64>> archivefileconts)1189 QString unetbootin::locatekernel(QString archivefile, QPair<QStringList, QList<quint64> > archivefileconts)
1190 {
1191 pdesc1->setText(tr("Locating kernel file in %1").arg(archivefile));
1192 if (issalt) {
1193 // The grub2 boot loader is return,
1194 // it is prepended with a Linux header,
1195 // so that syslinux can chainload to it.
1196 // The embeded configuration file will find the correct prefix using the .live file at the root of the USB key.
1197 return "boot/grub2-linux.img";
1198 }
1199 else
1200 {
1201 QStringList kernelnames = QStringList() << "vmlinuz" << "vmlinux" << "bzImage" << "kernel" << "sabayon" << "gentoo" << "linux26" << "linux24" << "bsd" << "unix" << "linux" << "rescue" << "xpud" << "bzI" << "kexec" << "vmlinuz.efi";
1202 QStringList tnarchivefileconts;
1203 QStringList narchivefileconts;
1204 QString curarcitm;
1205 for (int i = 0; i < archivefileconts.second.size(); ++i)
1206 {
1207 // curarcitm = archivefileconts.first.at(i).right(archivefileconts.first.at(i).size() - archivefileconts.first.at(i).lastIndexOf(QDir::toNativeSeparators("/")) - 1);
1208 // if (curarcitm.contains("isolinux", Qt::CaseInsensitive) || curarcitm.contains("memtest", Qt::CaseInsensitive) || curarcitm.contains("system.map", Qt::CaseInsensitive) || curarcitm.contains(".efimg", Qt::CaseInsensitive) || curarcitm.contains(".jpg", Qt::CaseInsensitive) || curarcitm.contains(".png", Qt::CaseInsensitive) || curarcitm.contains(".pdf", Qt::CaseInsensitive) || curarcitm.contains(".txt", Qt::CaseInsensitive) || curarcitm.contains(".pcx", Qt::CaseInsensitive) || curarcitm.contains(".rle", Qt::CaseInsensitive) || curarcitm.contains(".fnt", Qt::CaseInsensitive) || curarcitm.contains(".msg", Qt::CaseInsensitive) || curarcitm.contains(".cat", Qt::CaseInsensitive) || curarcitm.contains(".tar", Qt::CaseInsensitive) || curarcitm.contains(".psd", Qt::CaseInsensitive) || curarcitm.contains(".xcf", Qt::CaseInsensitive) || curarcitm.contains(".bmp", Qt::CaseInsensitive) || curarcitm.contains(".svg", Qt::CaseInsensitive))
1209 // {
1210 // continue;
1211 // }
1212 // if (filteroutlist(curarcitm, ignoredtypesbothRL+ignoredtypeskernelRL).isEmpty())
1213 // {
1214 // continue;
1215 // }
1216 if (archivefileconts.second.at(i) > 614400 && archivefileconts.second.at(i) < 20971520) // between 600 KB and 20 MB
1217 {
1218 tnarchivefileconts.append(archivefileconts.first.at(i));
1219 }
1220 }
1221 narchivefileconts = filteroutlistL(tnarchivefileconts, ignoredtypesbothRL+ignoredtypeskernelRL);
1222 for (int i = 0; i < kernelnames.size(); ++i)
1223 {
1224 for (int j = 0; j < narchivefileconts.size(); ++j)
1225 {
1226 if (narchivefileconts.at(j).right(narchivefileconts.at(j).size() - narchivefileconts.at(j).lastIndexOf(QDir::toNativeSeparators("/")) - 1).contains(kernelnames.at(i), Qt::CaseInsensitive))
1227 {
1228 return narchivefileconts.at(j);
1229 }
1230 }
1231 }
1232 pdesc1->setText("");
1233 return "";
1234 }
1235 }
1236
extractkernel(QString archivefile,QString kernoutputfile,QPair<QStringList,QList<quint64>> archivefileconts)1237 bool unetbootin::extractkernel(QString archivefile, QString kernoutputfile, QPair<QStringList, QList<quint64> > archivefileconts)
1238 {
1239 QString kfloc = locatekernel(archivefile, archivefileconts);
1240 if (kfloc == "")
1241 return false;
1242 pdesc1->setText(tr("Copying kernel file from %1").arg(kfloc));
1243 return extractfile(kfloc, kernoutputfile, archivefile);
1244 }
1245
locateinitrd(QString archivefile,QPair<QStringList,QList<quint64>> archivefileconts)1246 QString unetbootin::locateinitrd(QString archivefile, QPair<QStringList, QList<quint64> > archivefileconts)
1247 {
1248 pdesc1->setText(tr("Locating initrd file in %1").arg(archivefile));
1249 QStringList kernelnames = QStringList() << "initrd.img.gz" << "initrd.lz" << "initrd.igz" << "initrd.gz" << "initrd.xz" << "initrd.lzma" << "initrd.img" << "initramfs.gz" << "initramfs.img" << "initrd" << "initramfs" << "minirt" << "miniroot" << "sabayon.igz" << "gentoo.igz" << "archlive.img" << "rootfs.gz" << ".igz" << ".cgz" << ".img" << "rootfs" << "fs.gz" << "root.gz" << ".gz" << "initram" << "initr" << "init" << "ram" << ".lz" << ".lzma" << ".xz";
1250 QStringList tnarchivefileconts;
1251 QStringList narchivefileconts;
1252 QString curarcitm;
1253 for (int i = 0; i < archivefileconts.second.size(); ++i)
1254 {
1255 curarcitm = archivefileconts.first.at(i).right(archivefileconts.first.at(i).size() - archivefileconts.first.at(i).lastIndexOf(QDir::toNativeSeparators("/")) - 1);
1256 // if (curarcitm.contains("isolinux", Qt::CaseInsensitive) || curarcitm.contains("memtest", Qt::CaseInsensitive) || curarcitm.contains("system.map", Qt::CaseInsensitive) || curarcitm.contains(".efimg", Qt::CaseInsensitive) || curarcitm.contains(".jpg", Qt::CaseInsensitive) || curarcitm.contains(".png", Qt::CaseInsensitive) || curarcitm.contains(".pdf", Qt::CaseInsensitive) || curarcitm.contains(".txt", Qt::CaseInsensitive) || curarcitm.contains(".pcx", Qt::CaseInsensitive) || curarcitm.contains(".rle", Qt::CaseInsensitive) || curarcitm.contains(".fnt", Qt::CaseInsensitive) || curarcitm.contains(".msg", Qt::CaseInsensitive) || curarcitm.contains(".cat", Qt::CaseInsensitive) || curarcitm.contains(".tar", Qt::CaseInsensitive) || curarcitm.contains(".psd", Qt::CaseInsensitive) || curarcitm.contains(".xcf", Qt::CaseInsensitive) || curarcitm.contains(".bmp", Qt::CaseInsensitive) || curarcitm.contains(".svg", Qt::CaseInsensitive))
1257 // {
1258 // continue;
1259 // }
1260 // if (filteroutlist(curarcitm, ignoredtypesbothRL+ignoredtypesinitrdRL).isEmpty())
1261 // {
1262 // continue;
1263 // }
1264 if (archivefileconts.second.at(i) >= 128000 && archivefileconts.second.at(i) < 314572800) // between 128 KB and 300 MB
1265 {
1266 tnarchivefileconts.append(archivefileconts.first.at(i));
1267 }
1268 }
1269 narchivefileconts = filteroutlistL(tnarchivefileconts, ignoredtypesbothRL+ignoredtypesinitrdRL);
1270 for (int i = 0; i < kernelnames.size(); ++i)
1271 {
1272 for (int j = 0; j < narchivefileconts.size(); ++j)
1273 {
1274 if (narchivefileconts.at(j).right(narchivefileconts.at(j).size() - narchivefileconts.at(j).lastIndexOf(QDir::toNativeSeparators("/")) - 1).contains(kernelnames.at(i), Qt::CaseInsensitive))
1275 {
1276 return narchivefileconts.at(j);
1277 }
1278 }
1279 }
1280 pdesc1->setText("");
1281 return "";
1282 }
1283
extractinitrd(QString archivefile,QString kernoutputfile,QPair<QStringList,QList<quint64>> archivefileconts)1284 bool unetbootin::extractinitrd(QString archivefile, QString kernoutputfile, QPair<QStringList, QList<quint64> > archivefileconts)
1285 {
1286 QString kfloc = locateinitrd(archivefile, archivefileconts);
1287 if (kfloc == "")
1288 return false;
1289 pdesc1->setText(tr("Copying initrd file from %1").arg(kfloc));
1290 return extractfile(kfloc, kernoutputfile, archivefile);
1291 }
1292
extractcfg(QString archivefile,QStringList archivefileconts)1293 QString unetbootin::extractcfg(QString archivefile, QStringList archivefileconts)
1294 {
1295 pdesc1->setText(tr("Extracting bootloader configuration"));
1296 QString saltpcfg;
1297 QString grubpcfg;
1298 QString syslinuxpcfg;
1299 QStringList saltdetectfiles = QStringList() << "boot/grub2-linux.img" << "boot/grub/salt.env";
1300 QStringList grubcfgtypes = QStringList() << "menu.lst" << "grub.conf";
1301 QStringList mlstfoundfiles;
1302 int saltDetected = 0; // must be equals to saltdetectfiles.size() to be considered as detected
1303 for (int i = 0; i < saltdetectfiles.size(); ++i)
1304 {
1305 mlstfoundfiles = archivefileconts.filter(saltdetectfiles.at(i), Qt::CaseInsensitive);
1306 if (!mlstfoundfiles.isEmpty())
1307 {
1308 saltDetected++;
1309 }
1310 }
1311 if (saltDetected == saltdetectfiles.size()) {
1312 saltpcfg = SALT_DETECTED; // not a real config, but used to inform that SaLT has been detected.
1313 }
1314 else
1315 {
1316 for (int i = 0; i < grubcfgtypes.size(); ++i)
1317 {
1318 mlstfoundfiles = archivefileconts.filter(grubcfgtypes.at(i), Qt::CaseInsensitive);
1319 if (!mlstfoundfiles.isEmpty())
1320 {
1321 for (int j = 0; j < mlstfoundfiles.size(); ++j)
1322 {
1323 randtmpfile mlstftf(ubntmpf, "lst");
1324 extractfile(archivefileconts.filter(grubcfgtypes.at(i), Qt::CaseInsensitive).at(j), mlstftf.fileName(), archivefile);
1325 grubpcfg = getgrubcfgargs(mlstftf.fileName()).trimmed();
1326 rmFile(mlstftf);
1327 if (!grubpcfg.isEmpty())
1328 break;
1329 }
1330 }
1331 if (!grubpcfg.isEmpty())
1332 break;
1333 }
1334 QStringList syslinuxcfgtypes = QStringList() << "syslinux.cfg" << "isolinux.cfg" << "extlinux.cfg" << "pxelinux.cfg" << "grubenv" << "menu_en.cfg" << "en.cfg" << "extlinux.conf" << "grub.cfg" << ".cfg";
1335 QStringList lcfgfoundfiles;
1336 for (int i = 0; i < syslinuxcfgtypes.size(); ++i)
1337 {
1338 lcfgfoundfiles = archivefileconts.filter(syslinuxcfgtypes.at(i), Qt::CaseInsensitive);
1339 if (!lcfgfoundfiles.isEmpty())
1340 {
1341 for (int j = 0; j < lcfgfoundfiles.size(); ++j)
1342 {
1343 randtmpfile ccfgftf(ubntmpf, "cfg");
1344 extractfile(archivefileconts.filter(syslinuxcfgtypes.at(i), Qt::CaseInsensitive).at(j), ccfgftf.fileName(), archivefile);
1345 if (lcfgfoundfiles.at(j).contains("grubenv"))
1346 loadgrub2env(ccfgftf.fileName());
1347 else if (lcfgfoundfiles.at(j).contains("grub"))
1348 syslinuxpcfg = getgrub2cfgargs(ccfgftf.fileName(), archivefile, archivefileconts, QStringList() << lcfgfoundfiles.at(j)).trimmed();
1349 else
1350 syslinuxpcfg = getcfgkernargs(ccfgftf.fileName(), archivefile, archivefileconts, QStringList() << lcfgfoundfiles.at(j)).trimmed();
1351 rmFile(ccfgftf);
1352 if (!syslinuxpcfg.isEmpty())
1353 break;
1354 }
1355 }
1356 if (!syslinuxpcfg.isEmpty())
1357 break;
1358 }
1359 }
1360 if (!saltpcfg.isEmpty()) {
1361 return saltpcfg;
1362 }
1363 else if (syslinuxpcfg.isEmpty())
1364 {
1365 return grubpcfg;
1366 }
1367 else
1368 {
1369 return syslinuxpcfg;
1370 }
1371 }
1372
extractcfgL(QString archivefile,QStringList archivefileconts)1373 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::extractcfgL(QString archivefile, QStringList archivefileconts)
1374 {
1375 pdesc1->setText(tr("Extracting bootloader configuration"));
1376 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > grubpcfgPL;
1377 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > syslinuxpcfgPL;
1378 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > combinedcfgPL;
1379 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > filteredcfgPL;
1380 QStringList grubcfgtypes = QStringList() << "menu.lst" << "grub.conf";
1381 QStringList mlstfoundfiles;
1382 for (int i = 0; i < grubcfgtypes.size(); ++i)
1383 {
1384 mlstfoundfiles = archivefileconts.filter(grubcfgtypes.at(i), Qt::CaseInsensitive);
1385 if (!mlstfoundfiles.isEmpty())
1386 {
1387 for (int j = 0; j < mlstfoundfiles.size(); ++j)
1388 {
1389 randtmpfile mlstftf(ubntmpf, "lst");
1390 extractfile(archivefileconts.filter(grubcfgtypes.at(i), Qt::CaseInsensitive).at(j), mlstftf.fileName(), archivefile);
1391 grubpcfgPL = getgrubcfgargsL(mlstftf.fileName());
1392 rmFile(mlstftf);
1393 combinedcfgPL.first.first += grubpcfgPL.first.first;
1394 combinedcfgPL.first.second += grubpcfgPL.first.second;
1395 combinedcfgPL.second.first += grubpcfgPL.second.first;
1396 combinedcfgPL.second.second += grubpcfgPL.second.second;
1397 // if (!grubpcfg.isEmpty())
1398 // break;
1399 }
1400 }
1401 // if (!grubpcfg.isEmpty())
1402 // break;
1403 }
1404 QStringList syslinuxcfgtypes = QStringList() << "syslinux.cfg" << "isolinux.cfg" << "extlinux.cfg" << "pxelinux.cfg" << "grubenv" << "extlinux.conf" << "grub.cfg";
1405 QStringList lcfgfoundfiles;
1406 for (int i = 0; i < syslinuxcfgtypes.size(); ++i)
1407 {
1408 lcfgfoundfiles = archivefileconts.filter(syslinuxcfgtypes.at(i), Qt::CaseInsensitive);
1409 if (!lcfgfoundfiles.isEmpty())
1410 {
1411 for (int j = 0; j < lcfgfoundfiles.size(); ++j)
1412 {
1413 randtmpfile ccfgftf(ubntmpf, "cfg");
1414 extractfile(archivefileconts.filter(syslinuxcfgtypes.at(i), Qt::CaseInsensitive).at(j), ccfgftf.fileName(), archivefile);
1415 if (lcfgfoundfiles.at(j).contains("grubenv"))
1416 loadgrub2env(ccfgftf.fileName());
1417 else if (lcfgfoundfiles.at(j).contains("grub"))
1418 syslinuxpcfgPL = getgrub2cfgargsL(ccfgftf.fileName(), archivefile, archivefileconts, QStringList() << lcfgfoundfiles.at(j));
1419 else
1420 syslinuxpcfgPL = getcfgkernargsL(ccfgftf.fileName(), archivefile, archivefileconts, QStringList() << lcfgfoundfiles.at(j));
1421 rmFile(ccfgftf);
1422 combinedcfgPL.first.first += syslinuxpcfgPL.first.first;
1423 combinedcfgPL.first.second += syslinuxpcfgPL.first.second;
1424 combinedcfgPL.second.first += syslinuxpcfgPL.second.first;
1425 combinedcfgPL.second.second += syslinuxpcfgPL.second.second;
1426 // if (!syslinuxpcfg.isEmpty())
1427 // break;
1428 }
1429 }
1430 // if (!syslinuxpcfg.isEmpty())
1431 // break;
1432 }
1433 /*
1434 if (syslinuxpcfg.isEmpty())
1435 {
1436 return grubpcfg;
1437 }
1438 else
1439 {
1440 return syslinuxpcfg;
1441 }
1442 */
1443 #ifdef NOINITRD
1444 for (int i = 0; i < combinedcfgPL.first.second.size(); ++i)
1445 {
1446 combinedcfgPL.first.second[i] = "";
1447 }
1448 for (int i = 0; i < combinedcfgPL.second.second.size(); ++i)
1449 {
1450 combinedcfgPL.second.second[i] = "";
1451 }
1452 #endif
1453 for (int i = 0; i < combinedcfgPL.first.first.size(); ++i)
1454 {
1455 bool isduplicate = false;
1456 for (int j = 0; j < filteredcfgPL.second.first.size(); ++j)
1457 {
1458 if (filteredcfgPL.second.first.at(j) == combinedcfgPL.second.first.at(i)) // duplicate title
1459 {
1460 isduplicate = true;
1461 break;
1462 }
1463 }
1464 if (isduplicate)
1465 continue;
1466 if (combinedcfgPL.first.first.at(i) == kernelLoc && combinedcfgPL.first.second.at(i) == initrdLoc && combinedcfgPL.second.first.at(i).contains("Untitled Entry") && combinedcfgPL.second.second.at(i).isEmpty())
1467 continue;
1468 // else if (filteredcfgPL.second.first.contains(combinedcfgPL.second.first.at(i)))
1469 // continue;
1470 else
1471 {
1472 if (combinedcfgPL.first.first.at(i).isEmpty())
1473 filteredcfgPL.first.first.append(kernelLoc);
1474 else
1475 {
1476 QString indvkrnloc = getfullarchivepath(combinedcfgPL.first.first.at(i), archivefileconts);
1477 if (indvkrnloc.isEmpty())
1478 filteredcfgPL.first.first.append(kernelLoc);
1479 else
1480 filteredcfgPL.first.first.append(indvkrnloc);
1481 }
1482 // filteredcfgPL.first.first.append(combinedcfgPL.first.first.at(i));
1483 if (combinedcfgPL.first.second.at(i).isEmpty())
1484 filteredcfgPL.first.second.append(kernelLoc);
1485 else
1486 {
1487 QString indvitrloc = getfullarchivepath(combinedcfgPL.first.second.at(i), archivefileconts);
1488 if (indvitrloc.isEmpty())
1489 {
1490 filteredcfgPL.first.second.append(initrdLoc);
1491 }
1492 else
1493 filteredcfgPL.first.second.append(indvitrloc);
1494 }
1495 // filteredcfgPL.first.second.append(combinedcfgPL.first.second.at(i));
1496 filteredcfgPL.second.first.append(combinedcfgPL.second.first.at(i));
1497 filteredcfgPL.second.second.append(combinedcfgPL.second.second.at(i));
1498 }
1499 }
1500 if (redundanttopleveldir && !redundantrootdirname.isEmpty())
1501 {
1502 for (int i = 0; i < filteredcfgPL.first.second.size(); ++i)
1503 {
1504 if (filteredcfgPL.first.second.at(i).startsWith(redundantrootdirname))
1505 {
1506 filteredcfgPL.first.second[i] = filteredcfgPL.first.second[i].mid(redundantrootdirname.length());
1507 }
1508 if (filteredcfgPL.first.second.at(i).startsWith("/" + redundantrootdirname))
1509 {
1510 filteredcfgPL.first.second[i] = filteredcfgPL.first.second[i].mid(redundantrootdirname.length() + 1);
1511 }
1512 }
1513 }
1514 return filteredcfgPL;
1515 }
1516
getfullarchivepath(QString relativefilepath,QStringList archivefile)1517 QString unetbootin::getfullarchivepath(QString relativefilepath, QStringList archivefile)
1518 {
1519 QStringList pfoundmatches;
1520 relativefilepath = QDir::fromNativeSeparators(relativefilepath);
1521 if (relativefilepath.endsWith('/'))
1522 relativefilepath = relativefilepath.left(relativefilepath.size()-1);
1523 if (!relativefilepath.startsWith('/'))
1524 relativefilepath = QString("/%1").arg(relativefilepath);
1525 // if (!relativefilepath.endsWith('/'))
1526 // relativefilepath = QString("%1/").arg(relativefilepath);
1527 for (int i = 0; i < archivefile.size(); ++i)
1528 {
1529 QString curarchiveitem = QDir::fromNativeSeparators(archivefile.at(i));
1530 if (curarchiveitem.endsWith('/'))
1531 curarchiveitem = curarchiveitem.left(curarchiveitem.size()-1);
1532 if (!curarchiveitem.startsWith('/'))
1533 curarchiveitem = QString("/%1").arg(curarchiveitem);
1534 // if (!curarchiveitem.endsWith('/'))
1535 // curarchiveitem = QString("%1/").arg(curarchiveitem);
1536 if (curarchiveitem.contains(QRegExp(relativefilepath+"$", Qt::CaseInsensitive)))
1537 pfoundmatches.append(curarchiveitem);
1538 }
1539 if (pfoundmatches.isEmpty())
1540 return "";
1541 else
1542 {
1543 return filteroutlist(pfoundmatches, ignoredtypesbothRL);
1544 }
1545 }
1546
filteroutlist(QString listofdata,QList<QRegExp> listofmatches)1547 QString unetbootin::filteroutlist(QString listofdata, QList<QRegExp> listofmatches)
1548 {
1549 if (listofdata.isEmpty())
1550 return "";
1551 return filteroutlist(QStringList() << listofdata, listofmatches);
1552 }
1553
filteroutlist(QStringList listofdata,QList<QRegExp> listofmatches)1554 QString unetbootin::filteroutlist(QStringList listofdata, QList<QRegExp> listofmatches)
1555 {
1556 if (listofdata.isEmpty())
1557 return "";
1558 QStringList fldatalist = filteroutlistL(listofdata, listofmatches);
1559 if (!fldatalist.isEmpty())
1560 return fldatalist.at(0);
1561 else
1562 return "";
1563 }
1564
filteroutlistL(QStringList listofdata,QList<QRegExp> listofmatches)1565 QStringList unetbootin::filteroutlistL(QStringList listofdata, QList<QRegExp> listofmatches)
1566 {
1567 if (listofdata.isEmpty())
1568 return QStringList();
1569 if (listofmatches.isEmpty())
1570 return listofdata;
1571 if (listofdata.size() == 1)
1572 return listofdata;
1573 QStringList newlistofdata;
1574 for (int i = 0; i < listofdata.size(); ++i)
1575 {
1576 if (!listofdata.at(i).contains(listofmatches.at(0)))
1577 newlistofdata.append(listofdata.at(i));
1578 }
1579 // QStringList newlistofdata = QStringList(listofdata).filter(listofmatches.at(0));
1580 listofmatches.removeAt(0);
1581 if (newlistofdata.isEmpty())
1582 {
1583 return filteroutlistL(listofdata, listofmatches);
1584 }
1585 else
1586 {
1587 return filteroutlistL(newlistofdata, listofmatches);
1588 }
1589 }
1590
extractiso(QString isofile)1591 void unetbootin::extractiso(QString isofile)
1592 {
1593 if (!sdesc2->text().contains(trcurrent))
1594 {
1595 sdesc1->setText(QString(sdesc1->text()).remove("<b>").replace(trcurrent+"</b>", trdone));
1596 sdesc2->setText(QString("<b>%1 %2</b>").arg(sdesc2->text()).arg(trcurrent));
1597 }
1598 tprogress->setValue(0);
1599 QPair<QPair<QStringList, QList<quint64> >, QStringList> listfilesizedirpair = listarchiveconts(isofile);
1600 if (listfilesizedirpair.first.first.size() == 1)
1601 {
1602 QString subarchivename = listfilesizedirpair.first.first.at(0);
1603 randtmpfile tmpoutsubarchive(ubntmpf, subarchivename.right(3));
1604 pdesc1->setText(tr("<b>Extracting compressed iso:</b> %1").arg(subarchivename));
1605 extractfile(subarchivename, tmpoutsubarchive.fileName(), isofile);
1606 return extractiso(tmpoutsubarchive.fileName());
1607 }
1608 if (listfilesizedirpair.first.first.contains(QDir::toNativeSeparators("rescue/KRD.VERSION"), Qt::CaseInsensitive))
1609 {
1610 return extractiso_krd10(isofile);
1611 }
1612 QFileInfo isofileFI(isofile);
1613 qint64 isofileSize = isofileFI.size();
1614 if (listfilesizedirpair.first.first.size() < 10 && isofileSize > 12)
1615 {
1616 bool foundiso = false;
1617 quint64 isofileSizeOneFourth = isofileSize / 4;
1618 quint64 isofileSizeThreeFourth = isofileSizeOneFourth * 3;
1619 for (int i = 0; i < listfilesizedirpair.first.first.size() && i < listfilesizedirpair.first.second.size(); ++i)
1620 {
1621 if (listfilesizedirpair.first.first.at(i).contains(QRegExp(".iso$", Qt::CaseInsensitive)))
1622 {
1623 if (foundiso)
1624 break;
1625 foundiso = true;
1626 if (listfilesizedirpair.first.second.at(i) > isofileSizeThreeFourth)
1627 {
1628 QString subarchivename = listfilesizedirpair.first.first.at(i);
1629 randtmpfile tmpoutsubarchive(ubntmpf, subarchivename.right(3));
1630 pdesc1->setText(tr("<b>Extracting compressed iso:</b> %1").arg(subarchivename));
1631 extractfile(subarchivename, tmpoutsubarchive.fileName(), isofile);
1632 return extractiso(tmpoutsubarchive.fileName());
1633 }
1634 }
1635 }
1636 }
1637 QStringList filepathnames = listfilesizedirpair.first.first;
1638 QStringList directorypathnames;
1639 if (listfilesizedirpair.second.size() > 0)
1640 {
1641 redundanttopleveldir = true;
1642 redundantrootdirname = listfilesizedirpair.second.at(0);
1643 for (int i = 0; i < listfilesizedirpair.second.size(); ++i)
1644 {
1645 if (listfilesizedirpair.second.at(i).size() < redundantrootdirname.size())
1646 redundantrootdirname = listfilesizedirpair.second.at(i);
1647 }
1648 if (redundantrootdirname == "boot" ||
1649 redundantrootdirname == "syslinux" ||
1650 redundantrootdirname == "grub" ||
1651 redundantrootdirname == "isolinux" ||
1652 redundantrootdirname == "extlinux" ||
1653 redundantrootdirname == "pxelinux")
1654 redundanttopleveldir = false;
1655 for (int i = 0; i < listfilesizedirpair.second.size(); ++i) // redundant toplevel path in dirs
1656 {
1657 if (!listfilesizedirpair.second.at(i).startsWith(redundantrootdirname))
1658 redundanttopleveldir = false;
1659 }
1660 if (redundanttopleveldir)
1661 {
1662 for (int i = 0; i < listfilesizedirpair.first.first.size(); ++i) // redundant toplevel path in files
1663 {
1664 if (!listfilesizedirpair.first.first.at(i).startsWith(redundantrootdirname))
1665 redundanttopleveldir = false;
1666 }
1667 }
1668 if (redundanttopleveldir)
1669 {
1670 int rmnumcharsrootdir = redundantrootdirname.size();
1671 for (int i = 0; i < listfilesizedirpair.second.size(); ++i)
1672 {
1673 QString tmpdirectpath = listfilesizedirpair.second[i];
1674 tmpdirectpath.remove(0, rmnumcharsrootdir);
1675 if (tmpdirectpath.startsWith("/") || tmpdirectpath.startsWith(QDir::toNativeSeparators("/")))
1676 {
1677 tmpdirectpath.remove(0, 1);
1678 }
1679 if (!tmpdirectpath.isEmpty())
1680 {
1681 directorypathnames.append(tmpdirectpath);
1682 }
1683 }
1684 for (int i = 0; i < listfilesizedirpair.first.first.size(); ++i)
1685 {
1686 filepathnames[i].remove(0, rmnumcharsrootdir);
1687 if (filepathnames[i].startsWith("/") || filepathnames[i].startsWith(QDir::toNativeSeparators("/")))
1688 {
1689 filepathnames[i].remove(0, 1);
1690 }
1691 }
1692 }
1693 else
1694 {
1695 directorypathnames = listfilesizedirpair.second;
1696 }
1697 }
1698 if (installType == tr("USB Drive"))
1699 {
1700 QStringList syslinuxfilepaths = QStringList() << "boot/syslinux/syslinux.cfg" << "syslinux/syslinux.cfg" << "syslinux.cfg" << "isolinux.cfg" << "extlinux.conf";
1701 if (QString(QDir::toNativeSeparators("/")) != QString("/"))
1702 {
1703 syslinuxfilepaths << QString("boot%1syslinux%1syslinux.cfg").arg(QDir::toNativeSeparators("/")) << QString("syslinux%1syslinux.cfg").arg(QDir::toNativeSeparators("/"));
1704 }
1705 for (int j = 0; j < syslinuxfilepaths.size(); ++j)
1706 {
1707 rmFile(QString("%1%2").arg(targetPath).arg(syslinuxfilepaths.at(j)));
1708 for (int i = 0; i < filepathnames.size(); ++i)
1709 {
1710 if (filepathnames.at(i) == syslinuxfilepaths.at(j))
1711 {
1712 dontgeneratesyslinuxcfg = true;
1713 locatedsyslinuxcfgfiles.append(syslinuxfilepaths.at(j));
1714 }
1715 }
1716 }
1717 }
1718 if (!dontgeneratesyslinuxcfg)
1719 {
1720 kernelOpts = extractcfg(isofile, listfilesizedirpair.first.first);
1721 issalt = (kernelOpts == SALT_DETECTED);
1722 if (issalt)
1723 {
1724 QStringList mlstfoundfiles = listfilesizedirpair.second.filter(QRegExp("/modules$", Qt::CaseInsensitive));
1725 if (!mlstfoundfiles.isEmpty())
1726 {
1727 QString match = mlstfoundfiles.at(0);
1728 saltRootDir = match.replace(QRegExp("(.*)/modules"), "\\1");
1729 }
1730 kernelLine = "linux";
1731 kernelOpts = "";
1732 initrdLoc = "";
1733 initrdOpts = "";
1734 initrdLine = "";
1735 slinitrdLine = "";
1736 }
1737 else
1738 {
1739 extraoptionsPL = extractcfgL(isofile, listfilesizedirpair.first.first);
1740 }
1741
1742 #ifndef NOEXTRACTKERNEL
1743 extractkernel(isofile, QString("%1ubnkern").arg(targetPath), listfilesizedirpair.first);
1744 #endif
1745 #ifndef NOEXTRACTINITRD
1746 if (!issalt)
1747 {
1748 extractinitrd(isofile, QString("%1ubninit").arg(targetPath), listfilesizedirpair.first);
1749 }
1750 #endif
1751 }
1752 QStringList createdpaths = makepathtree(targetDrive, directorypathnames);
1753 QFile ubnpathlF(QDir::toNativeSeparators(QString("%1ubnpathl.txt").arg(targetPath)));
1754 if (ubnpathlF.exists())
1755 {
1756 rmFile(ubnpathlF);
1757 }
1758 ubnpathlF.open(QIODevice::WriteOnly | QIODevice::Text);
1759 QTextStream ubnpathlS(&ubnpathlF);
1760 for (int i = createdpaths.size() - 1; i > -1; i--)
1761 {
1762 ubnpathlS << createdpaths.at(i) << endl;
1763 }
1764 ubnpathlF.close();
1765 QStringList extractedfiles;
1766 if (!skipExtraction)
1767 extractedfiles = extractallfiles(isofile, targetDrive, listfilesizedirpair.first, filepathnames);
1768 QFile ubnfilelF(QDir::toNativeSeparators(QString("%1ubnfilel.txt").arg(targetPath)));
1769 if (ubnfilelF.exists())
1770 {
1771 rmFile(ubnfilelF);
1772 }
1773 ubnfilelF.open(QIODevice::WriteOnly | QIODevice::Text);
1774 QTextStream ubnfilelS(&ubnfilelF);
1775 for (int i = 0; i < extractedfiles.size(); ++i)
1776 {
1777 ubnfilelS << extractedfiles.at(i) << endl;
1778 }
1779 ubnfilelF.close();
1780 #ifdef XPUD
1781 rmFile(QString("%1boot.cat").arg(targetPath));
1782 rmFile(QString("%1isolinux.bin").arg(targetPath));
1783 rmFile(QString("%1syslinux.cfg").arg(targetPath));
1784 QFile::rename(QString("%1isolinux.cfg").arg(targetPath), QString("%1syslinux.cfg").arg(targetPath));
1785 if (installType == tr("USB Drive"))
1786 {
1787 rmFile(QString("%1ubnfilel.txt").arg(targetPath));
1788 rmFile(QString("%1ubnpathl.txt").arg(targetPath));
1789 }
1790 #endif
1791 }
1792
extractiso_krd10(QString isofile)1793 void unetbootin::extractiso_krd10(QString isofile)
1794 {
1795 if (!sdesc2->text().contains(trcurrent))
1796 {
1797 sdesc1->setText(QString(sdesc1->text()).remove("<b>").replace(trcurrent+"</b>", trdone));
1798 sdesc2->setText(QString("<b>%1 %2</b>").arg(sdesc2->text()).arg(trdone));
1799 }
1800 tprogress->setValue(0);
1801 QPair<QPair<QStringList, QList<quint64> >, QStringList> listfilesizedirpair = listarchiveconts(isofile);
1802 kernelLoc = QDir::fromNativeSeparators(locatekernel(isofile, listfilesizedirpair.first));
1803 if (!kernelLoc.startsWith("/")) kernelLoc.prepend("/");
1804 initrdLoc = QDir::fromNativeSeparators(locateinitrd(isofile, listfilesizedirpair.first));
1805 if (!initrdLoc.startsWith("/")) initrdLoc.prepend("/");
1806 kernelOpts = extractcfg(isofile, listfilesizedirpair.first.first);
1807 extraoptionsPL.first.first.clear();
1808 extraoptionsPL.first.second.clear();
1809 extraoptionsPL.second.first.clear();
1810 extraoptionsPL.second.second.clear();
1811 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > tmpoptionsL = extractcfgL(isofile, listfilesizedirpair.first.first);
1812 for (int i = 0; i < tmpoptionsL.second.second.size(); ++i)
1813 {
1814 if (!tmpoptionsL.second.second.at(i).isEmpty())
1815 {
1816 extraoptionsPL.first.first.append(tmpoptionsL.first.first.at(i));
1817 extraoptionsPL.first.second.append(tmpoptionsL.first.second.at(i));
1818 extraoptionsPL.second.first.append(tmpoptionsL.second.first.at(i));
1819 extraoptionsPL.second.second.append(tmpoptionsL.second.second.at(i));
1820 }
1821 }
1822 QPair<QStringList, QList<quint64> > bootfiles;
1823 for (int i = 0; i < listfilesizedirpair.first.first.size(); ++i)
1824 {
1825 if (listfilesizedirpair.first.first.at(i).startsWith("boot", Qt::CaseInsensitive))
1826 {
1827 bootfiles.first.append(listfilesizedirpair.first.first.at(i));
1828 bootfiles.second.append(listfilesizedirpair.first.second.at(i));
1829 }
1830 }
1831 QStringList bootpaths;
1832 for (int i = 0; i < listfilesizedirpair.second.size(); ++i)
1833 {
1834 if (listfilesizedirpair.second.at(i).startsWith("boot", Qt::CaseInsensitive))
1835 {
1836 bootpaths.append(listfilesizedirpair.second.at(i));
1837 }
1838 }
1839 if (!bootpaths.contains("rescue"))
1840 bootpaths.append("rescue");
1841 QStringList createdpaths = makepathtree(targetDrive, bootpaths);
1842 QFile ubnpathlF(QDir::toNativeSeparators(QString("%1ubnpathl.txt").arg(targetPath)));
1843 if (ubnpathlF.exists())
1844 {
1845 rmFile(ubnpathlF);
1846 }
1847 ubnpathlF.open(QIODevice::WriteOnly | QIODevice::Text);
1848 QTextStream ubnpathlS(&ubnpathlF);
1849 for (int i = createdpaths.size() - 1; i > -1; i--)
1850 {
1851 ubnpathlS << createdpaths.at(i) << endl;
1852 }
1853 ubnpathlF.close();
1854 QStringList extractedfiles = extractallfiles(isofile, targetDrive, bootfiles, listfilesizedirpair.first.first);
1855 if (QFile::exists(QString("%1liveusb").arg(targetDrive)))
1856 overwritefileprompt(QString("%1liveusb").arg(targetDrive));
1857 else
1858 extractedfiles.append(QString("%1liveusb").arg(targetDrive));
1859 QFile(QString("%1liveusb").arg(targetDrive)).open(QIODevice::WriteOnly);
1860 pdesc1->setText(QString("Copying %1 to %2").arg(isofile).arg(QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/"))));
1861 if (QFile::exists(QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/"))))
1862 overwritefileprompt(QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/")));
1863 else
1864 extractedfiles.append(QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/")));
1865 //QFile::copy(isofile, QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/")));
1866 copyfilegui(isofile, QString("%1rescue%2rescue.iso").arg(targetDrive).arg(QDir::toNativeSeparators("/")));
1867 QFile ubnfilelF(QDir::toNativeSeparators(QString("%1ubnfilel.txt").arg(targetPath)));
1868 if (ubnfilelF.exists())
1869 {
1870 rmFile(ubnfilelF);
1871 }
1872 ubnfilelF.open(QIODevice::WriteOnly | QIODevice::Text);
1873 QTextStream ubnfilelS(&ubnfilelF);
1874 for (int i = 0; i < extractedfiles.size(); ++i)
1875 {
1876 ubnfilelS << extractedfiles.at(i) << endl;
1877 }
1878 ubnfilelF.close();
1879 }
1880
copyfilegui(QString src,QString dst)1881 void unetbootin::copyfilegui(QString src, QString dst)
1882 {
1883 pdesc5->setText("");
1884 pdesc4->setText(tr("Copying file, please wait..."));
1885 pdesc3->setText(tr("<b>Source:</b> <a href=\"%1\">%1</a>").arg(src));
1886 pdesc2->setText(tr("<b>Destination:</b> %1").arg(dst));
1887 pdesc1->setText(tr("<b>Copied:</b> 0 bytes"));
1888 QEventLoop cpfw;
1889 copyfileT cpft;
1890 cpft.source = src;
1891 cpft.destination = dst;
1892 connect(&cpft, SIGNAL(datacopied64(qint64,qint64)), this, SLOT(cpprogressupdate64(qint64,qint64)));
1893 connect(&cpft, SIGNAL(finished()), &cpfw, SLOT(quit()));
1894 cpft.start();
1895 cpfw.exec();
1896 pdesc4->setText("");
1897 pdesc3->setText("");
1898 pdesc2->setText("");
1899 pdesc1->setText("");
1900 tprogress->setValue(0);
1901 }
1902
makepathtree(QString dirmkpathw,QStringList pathlist)1903 QStringList unetbootin::makepathtree(QString dirmkpathw, QStringList pathlist)
1904 {
1905 QStringList createdpaths;
1906 QDir dir(dirmkpathw);
1907 for (int i = 0; i < pathlist.size(); ++i)
1908 {
1909 if (dir.mkdir(pathlist.at(i)))
1910 {
1911 createdpaths.append(pathlist.at(i));
1912 }
1913 }
1914 return createdpaths;
1915 }
1916
extractallfiles(QString archivefile,QString dirxfilesto,QPair<QStringList,QList<quint64>> filesizelist,QStringList outputfilelist)1917 QStringList unetbootin::extractallfiles(QString archivefile, QString dirxfilesto, QPair<QStringList, QList<quint64> > filesizelist, QStringList outputfilelist)
1918 {
1919 QStringList filelist = filesizelist.first;
1920 QStringList extractedfiles;
1921 QProgressDialog xprogress;
1922 tprogress->setMaximum(filelist.size());
1923 tprogress->setMinimum(0);
1924 tprogress->setValue(0);
1925 pdesc5->setText(tr("Extracting files, please wait..."));
1926 pdesc4->setText(tr("<b>Archive:</b> %1").arg(archivefile));
1927 pdesc3->setText(tr("<b>Source:</b>"));
1928 pdesc2->setText(tr("<b>Destination:</b>"));
1929 pdesc1->setText(tr("<b>Extracted:</b> 0 of %1 files").arg(filelist.size()));
1930 for (int i = 0; i < filelist.size(); ++i)
1931 {
1932 pdesc3->setText(tr("<b>Source:</b> %1 (%2)").arg(filelist.at(i)).arg(displayfisize(filesizelist.second.at(i))));
1933 pdesc2->setText(tr("<b>Destination:</b> %1%2").arg(dirxfilesto).arg(outputfilelist.at(i)));
1934 pdesc1->setText(tr("<b>Extracted:</b> %1 of %2 files").arg(i).arg(filelist.size()));
1935 tprogress->setValue(i);
1936 if (extractfile(filelist.at(i), QString("%1%2").arg(dirxfilesto).arg(outputfilelist.at(i)), archivefile))
1937 {
1938 extractedfiles.append(filelist.at(i));
1939 }
1940 }
1941 pdesc5->setText("");
1942 pdesc4->setText("");
1943 pdesc3->setText("");
1944 pdesc2->setText("");
1945 pdesc1->setText("");
1946 tprogress->setValue(0);
1947 return extractedfiles;
1948 }
1949
getgrubcfgargs(QString cfgfile)1950 QString unetbootin::getgrubcfgargs(QString cfgfile)
1951 {
1952 QFile cfgfileF(cfgfile);
1953 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
1954 QTextStream cfgfileS(&cfgfileF);
1955 QString cfgfileCL;
1956 while (!cfgfileS.atEnd())
1957 {
1958 cfgfileCL = cfgfileS.readLine().trimmed();
1959 if (cfgfileCL.contains("#"))
1960 {
1961 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
1962 }
1963 if (cfgfileCL.contains(QRegExp("^kernel\\s{1,}\\S{1,}\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
1964 {
1965 return fixkernelbootoptions(QString(cfgfileCL).remove(QRegExp("^kernel\\s{1,}\\S{1,}\\s{1,}", Qt::CaseInsensitive)));
1966 }
1967 }
1968 return "";
1969 }
1970
getgrubcfgargsL(QString cfgfile)1971 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::getgrubcfgargsL(QString cfgfile)
1972 {
1973 QPair<QStringList, QStringList> kernelandinitrd;
1974 QPair<QStringList, QStringList> titleandparams;
1975 int curindex = 0;
1976 bool kernelpassed = false;
1977 QFile cfgfileF(cfgfile);
1978 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
1979 QTextStream cfgfileS(&cfgfileF);
1980 QString cfgfileCL;
1981 kernelandinitrd.first.append(kernelLoc);
1982 kernelandinitrd.second.append(initrdLoc);
1983 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
1984 titleandparams.second.append("");
1985 while (!cfgfileS.atEnd())
1986 {
1987 cfgfileCL = cfgfileS.readLine().trimmed();
1988 if (cfgfileCL.contains("#"))
1989 {
1990 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
1991 }
1992 if (cfgfileCL.contains(QRegExp("^title\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
1993 {
1994 if (kernelpassed)
1995 {
1996 ++curindex;
1997 kernelandinitrd.first.append(kernelLoc);
1998 kernelandinitrd.second.append(initrdLoc);
1999 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2000 titleandparams.second.append("");
2001 kernelpassed = false;
2002 }
2003 titleandparams.first[curindex] = QString(cfgfileCL).remove("title", Qt::CaseInsensitive).trimmed();
2004 continue;
2005 }
2006 if (cfgfileCL.contains(QRegExp("^initrd\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2007 {
2008 kernelandinitrd.second[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^initrd", Qt::CaseInsensitive)).trimmed());
2009 // if (kernelandinitrd.second.at(curindex).isEmpty())
2010 // kernelandinitrd.second[curindex] = initrdLoc;
2011 continue;
2012 }
2013 // if (cfgfileCL.contains(QRegExp("^module\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2014 // {
2015 // kernelandinitrd.second[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^module", Qt::CaseInsensitive)).trimmed());
2016 // if (kernelandinitrd.second.at(curindex).isEmpty())
2017 // kernelandinitrd.second[curindex] = initrdLoc;
2018 // }
2019 if (cfgfileCL.contains(QRegExp("^kernel\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2020 {
2021 if (kernelpassed)
2022 {
2023 ++curindex;
2024 kernelandinitrd.first.append(kernelLoc);
2025 kernelandinitrd.second.append(initrdLoc);
2026 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2027 titleandparams.second.append("");
2028 // kernelpassed = false;
2029 }
2030 if (cfgfileCL.contains(QRegExp("^kernel\\s{1,}\\S{1,}\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2031 {
2032 titleandparams.second[curindex] = fixkernelbootoptions(QString(cfgfileCL).remove(QRegExp("^kernel\\s{1,}\\S{1,}\\s{1,}", Qt::CaseInsensitive)));
2033 }
2034 kernelandinitrd.first[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^kernel", Qt::CaseInsensitive)).trimmed());
2035 // if (kernelandinitrd.first.at(curindex).isEmpty())
2036 // kernelandinitrd.first[curindex] = kernelLoc;
2037 kernelpassed = true;
2038 continue;
2039 }
2040 }
2041 return qMakePair(kernelandinitrd, titleandparams);
2042 }
2043
getFirstTextBlock(QString fulltext)2044 QString unetbootin::getFirstTextBlock(QString fulltext)
2045 {
2046 QStringList textblockL = fulltext.split(QRegExp("\\s{1,}")).filter(QRegExp("\\S{1,}"));
2047 if (textblockL.isEmpty())
2048 return "";
2049 else
2050 {
2051 return textblockL.at(0);
2052 }
2053 }
2054
loadgrub2env(QString cfgfile)2055 void unetbootin::loadgrub2env(QString cfgfile)
2056 {
2057 QFile cfgfileF(cfgfile);
2058 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
2059 QTextStream cfgfileS(&cfgfileF);
2060 QString cfgfileCL;
2061 while (!cfgfileS.atEnd())
2062 {
2063 cfgfileCL = cfgfileS.readLine().trimmed();
2064 if (cfgfileCL.contains("#"))
2065 {
2066 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
2067 }
2068 if (cfgfileCL.contains("${"))
2069 {
2070 for (QMap<QString, QString>::const_iterator i = grub2vars.begin(); i != grub2vars.end(); ++i)
2071 {
2072 if (cfgfileCL.contains(QString("${%1}").arg(i.key())))
2073 cfgfileCL.replace(QString("${%1}").arg(i.key()), i.value());
2074 }
2075 }
2076 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\".{1,}\"")))
2077 {
2078 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}\"(.{1,})\"");
2079 setrg.indexIn(cfgfileCL);
2080 QStringList captxt = setrg.capturedTexts();
2081 if (captxt.size() >= 2)
2082 {
2083 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2084 continue;
2085 }
2086 }
2087 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\\S{1,}")))
2088 {
2089 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}(\\S{1,})");
2090 setrg.indexIn(cfgfileCL);
2091 QStringList captxt = setrg.capturedTexts();
2092 if (captxt.size() >= 2)
2093 {
2094 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2095 continue;
2096 }
2097 }
2098 if (cfgfileCL.count("=") == 1)
2099 {
2100 QStringList splp = cfgfileCL.split("=");
2101 if (splp.size() == 2)
2102 {
2103 grub2vars[splp.at(0).trimmed()] = QString(splp.at(1)).remove("\"").trimmed();
2104 }
2105 }
2106 }
2107 }
2108
getgrub2cfgargs(QString cfgfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2109 QString unetbootin::getgrub2cfgargs(QString cfgfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2110 {
2111 QFile cfgfileF(cfgfile);
2112 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
2113 QTextStream cfgfileS(&cfgfileF);
2114 QString cfgfileCL;
2115 QString includesfile;
2116 QString searchincfrs;
2117 while (!cfgfileS.atEnd())
2118 {
2119 cfgfileCL = cfgfileS.readLine().trimmed();
2120 if (cfgfileCL.contains("#"))
2121 {
2122 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
2123 }
2124 if (cfgfileCL.contains("${"))
2125 {
2126 for (QMap<QString, QString>::const_iterator i = grub2vars.begin(); i != grub2vars.end(); ++i)
2127 {
2128 if (cfgfileCL.contains(QString("${%1}").arg(i.key())))
2129 cfgfileCL.replace(QString("${%1}").arg(i.key()), i.value());
2130 }
2131 }
2132 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\".{1,}\"")))
2133 {
2134 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}\"(.{1,})\"");
2135 setrg.indexIn(cfgfileCL);
2136 QStringList captxt = setrg.capturedTexts();
2137 if (captxt.size() >= 2)
2138 {
2139 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2140 continue;
2141 }
2142 }
2143 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\\S{1,}")))
2144 {
2145 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}(\\S{1,})");
2146 setrg.indexIn(cfgfileCL);
2147 QStringList captxt = setrg.capturedTexts();
2148 if (captxt.size() >= 2)
2149 {
2150 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2151 continue;
2152 }
2153 }
2154 if (!archivefileconts.isEmpty() && QRegExp("^configfile\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2155 {
2156 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^configfile\\s{1,}", Qt::CaseInsensitive))).trimmed();
2157 searchincfrs = searchforgrub2includesfile(includesfile, archivefile, archivefileconts, visitedincludes).trimmed();
2158 if (!searchincfrs.isEmpty())
2159 return searchincfrs;
2160 }
2161 if (!archivefileconts.isEmpty() && QRegExp("^source\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2162 {
2163 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^source\\s{1,}", Qt::CaseInsensitive))).trimmed();
2164 searchincfrs = searchforgrub2includesfile(includesfile, archivefile, archivefileconts, visitedincludes).trimmed();
2165 if (!searchincfrs.isEmpty())
2166 return searchincfrs;
2167 }
2168 if (cfgfileCL.contains(QRegExp("^linux\\s{1,}\\S{1,}\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2169 {
2170 return fixkernelbootoptions(QString(cfgfileCL).remove(QRegExp("^linux\\s{1,}\\S{1,}\\s{1,}", Qt::CaseInsensitive))).remove(QRegExp("initrd=\\S{0,}")).trimmed();
2171 }
2172 }
2173 return "";
2174 }
2175
getgrub2cfgargsL(QString cfgfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2176 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::getgrub2cfgargsL(QString cfgfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2177 {
2178 QPair<QStringList, QStringList> kernelandinitrd;
2179 QPair<QStringList, QStringList> titleandparams;
2180 int curindex = 0;
2181 bool kernelpassed = false;
2182 QFile cfgfileF(cfgfile);
2183 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
2184 QTextStream cfgfileS(&cfgfileF);
2185 QString cfgfileCL;
2186 kernelandinitrd.first.append(kernelLoc);
2187 kernelandinitrd.second.append(initrdLoc);
2188 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2189 titleandparams.second.append("");
2190 QString includesfile;
2191 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > searchincfrs;
2192 while (!cfgfileS.atEnd())
2193 {
2194 cfgfileCL = cfgfileS.readLine().trimmed();
2195 if (cfgfileCL.contains("#"))
2196 {
2197 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
2198 }
2199 if (cfgfileCL.contains("${"))
2200 {
2201 for (QMap<QString, QString>::const_iterator i = grub2vars.begin(); i != grub2vars.end(); ++i)
2202 {
2203 if (cfgfileCL.contains(QString("${%1}").arg(i.key())))
2204 cfgfileCL.replace(QString("${%1}").arg(i.key()), i.value());
2205 }
2206 }
2207 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\".{1,}\"")))
2208 {
2209 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}\"(.{1,})\"");
2210 setrg.indexIn(cfgfileCL);
2211 QStringList captxt = setrg.capturedTexts();
2212 if (captxt.size() >= 2)
2213 {
2214 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2215 continue;
2216 }
2217 }
2218 if (cfgfileCL.contains(QRegExp("^set\\s{1,}\\S{1,}\\s{0,}=\\s{0,}\\S{1,}")))
2219 {
2220 QRegExp setrg("^set\\s{1,}(\\S{1,})\\s{0,}=\\s{0,}(\\S{1,})");
2221 setrg.indexIn(cfgfileCL);
2222 QStringList captxt = setrg.capturedTexts();
2223 if (captxt.size() >= 2)
2224 {
2225 grub2vars[captxt.at(captxt.size()-2)] = captxt.at(captxt.size()-1);
2226 continue;
2227 }
2228 }
2229 if (!archivefileconts.isEmpty() && QRegExp("^configfile\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2230 {
2231 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^configfile\\s{1,}", Qt::CaseInsensitive))).trimmed();
2232 searchincfrs = searchforgrub2includesfileL(includesfile, archivefile, archivefileconts, visitedincludes);
2233 if (!searchincfrs.first.first.isEmpty())
2234 {
2235 kernelandinitrd.first += searchincfrs.first.first;
2236 kernelandinitrd.second += searchincfrs.first.second;
2237 titleandparams.first += searchincfrs.second.first;
2238 titleandparams.second += searchincfrs.second.second;
2239 }
2240 continue;
2241 }
2242 if (!archivefileconts.isEmpty() && QRegExp("^source\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2243 {
2244 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^source\\s{1,}", Qt::CaseInsensitive))).trimmed();
2245 searchincfrs = searchforgrub2includesfileL(includesfile, archivefile, archivefileconts, visitedincludes);
2246 if (!searchincfrs.first.first.isEmpty())
2247 {
2248 kernelandinitrd.first += searchincfrs.first.first;
2249 kernelandinitrd.second += searchincfrs.first.second;
2250 titleandparams.first += searchincfrs.second.first;
2251 titleandparams.second += searchincfrs.second.second;
2252 }
2253 continue;
2254 }
2255 if (cfgfileCL.contains(QRegExp("^menuentry\\s{1,}\".{1,}\"", Qt::CaseInsensitive)))
2256 {
2257 if (kernelpassed)
2258 {
2259 ++curindex;
2260 kernelandinitrd.first.append(kernelLoc);
2261 kernelandinitrd.second.append(initrdLoc);
2262 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2263 titleandparams.second.append("");
2264 kernelpassed = false;
2265 }
2266 titleandparams.first[curindex] = QString(cfgfileCL).remove("menuentry", Qt::CaseInsensitive).remove("\"").remove("{").remove("}").trimmed();
2267 continue;
2268 }
2269 if (cfgfileCL.contains(QRegExp("^initrd\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2270 {
2271 kernelandinitrd.second[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^initrd", Qt::CaseInsensitive)).trimmed());
2272 // if (kernelandinitrd.second.at(curindex).isEmpty())
2273 // kernelandinitrd.second[curindex] = initrdLoc;
2274 continue;
2275 }
2276 // if (cfgfileCL.contains(QRegExp("^module\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2277 // {
2278 // kernelandinitrd.second[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^module", Qt::CaseInsensitive)).trimmed());
2279 // if (kernelandinitrd.second.at(curindex).isEmpty())
2280 // kernelandinitrd.second[curindex] = initrdLoc;
2281 // }
2282 if (cfgfileCL.contains(QRegExp("^linux\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2283 {
2284 if (kernelpassed)
2285 {
2286 ++curindex;
2287 kernelandinitrd.first.append(kernelLoc);
2288 kernelandinitrd.second.append(initrdLoc);
2289 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2290 titleandparams.second.append("");
2291 // kernelpassed = false;
2292 }
2293 if (cfgfileCL.contains(QRegExp("^linux\\s{1,}\\S{1,}\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2294 {
2295 titleandparams.second[curindex] = fixkernelbootoptions(QString(cfgfileCL).remove(QRegExp("^linux\\s{1,}\\S{1,}\\s{1,}", Qt::CaseInsensitive))).remove(QRegExp("initrd=\\S{0,}")).trimmed();
2296 }
2297 kernelandinitrd.first[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^linux", Qt::CaseInsensitive)).trimmed());
2298 // if (kernelandinitrd.first.at(curindex).isEmpty())
2299 // kernelandinitrd.first[curindex] = kernelLoc;
2300 kernelpassed = true;
2301 continue;
2302 }
2303 }
2304 return qMakePair(kernelandinitrd, titleandparams);
2305 }
2306
getcfgkernargs(QString cfgfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2307 QString unetbootin::getcfgkernargs(QString cfgfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2308 {
2309 QFile cfgfileF(cfgfile);
2310 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
2311 QTextStream cfgfileS(&cfgfileF);
2312 QString cfgfileCL;
2313 QString includesfile;
2314 QString searchincfrs;
2315 while (!cfgfileS.atEnd())
2316 {
2317 cfgfileCL = cfgfileS.readLine().trimmed();
2318 if (cfgfileCL.contains("#"))
2319 {
2320 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
2321 }
2322 if (!archivefileconts.isEmpty() && QRegExp("^include\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2323 {
2324 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^include\\s{1,}", Qt::CaseInsensitive))).trimmed();
2325 searchincfrs = searchforincludesfile(includesfile, archivefile, archivefileconts, visitedincludes).trimmed();
2326 if (!searchincfrs.isEmpty())
2327 return searchincfrs;
2328 }
2329 if (!archivefileconts.isEmpty() && QRegExp("^append\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2330 {
2331 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^append\\s{1,}", Qt::CaseInsensitive))).trimmed();
2332 searchincfrs = searchforincludesfile(includesfile, archivefile, archivefileconts, visitedincludes).trimmed();
2333 if (!searchincfrs.isEmpty())
2334 return searchincfrs;
2335 }
2336 else if (cfgfileCL.contains(QRegExp("^\\s{0,}append\\s{1,}", Qt::CaseInsensitive)))
2337 {
2338 return fixkernelbootoptions(QString(cfgfileCL).remove(QRegExp("\\s{0,}append\\s{1,}", Qt::CaseInsensitive)).remove(QRegExp("\\s{0,1}initrd=\\S{0,}", Qt::CaseInsensitive)));
2339 }
2340 }
2341 return "";
2342 }
2343
getcfgkernargsL(QString cfgfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2344 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::getcfgkernargsL(QString cfgfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2345 {
2346 /*
2347 QString cfgfiledir;
2348 if (cfgfile.contains(QDir::toNativeSeparators("/")))
2349 cfgfiledir = QDir::fromNativeSeparators(QString(cfgfile).left(cfgfile.lastIndexOf(QDir::toNativeSeparators("/")) + 1));
2350 if (!cfgfiledir.isEmpty())
2351 {
2352 if (!cfgfiledir.startsWith('/'))
2353 cfgfiledir = QString("/%1").arg(cfgfiledir);
2354 if (!cfgfiledir.endsWith('/'))
2355 cfgfiledir = QString("%1/").arg(cfgfiledir);
2356 }
2357 */
2358 QPair<QStringList, QStringList> kernelandinitrd;
2359 QPair<QStringList, QStringList> titleandparams;
2360 int curindex = 0;
2361 bool kernelpassed = false;
2362 QFile cfgfileF(cfgfile);
2363 cfgfileF.open(QIODevice::ReadOnly | QIODevice::Text);
2364 QTextStream cfgfileS(&cfgfileF);
2365 QString cfgfileCL;
2366 kernelandinitrd.first.append(kernelLoc);
2367 kernelandinitrd.second.append(initrdLoc);
2368 titleandparams.first.append(QString("Untitled Entry Grub %1").arg(curindex));
2369 titleandparams.second.append("");
2370 QString includesfile;
2371 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > searchincfrs;
2372 while (!cfgfileS.atEnd())
2373 {
2374 cfgfileCL = cfgfileS.readLine().trimmed();
2375 if (cfgfileCL.contains("#"))
2376 {
2377 cfgfileCL = cfgfileCL.left(cfgfileCL.indexOf("#")).trimmed();
2378 }
2379 if (!archivefileconts.isEmpty() && QRegExp("^include\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2380 {
2381 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^include\\s{1,}", Qt::CaseInsensitive))).trimmed();
2382 searchincfrs = searchforincludesfileL(includesfile, archivefile, archivefileconts, visitedincludes);
2383 if (!searchincfrs.first.first.isEmpty())
2384 {
2385 kernelandinitrd.first += searchincfrs.first.first;
2386 kernelandinitrd.second += searchincfrs.first.second;
2387 titleandparams.first += searchincfrs.second.first;
2388 titleandparams.second += searchincfrs.second.second;
2389 }
2390 continue;
2391 }
2392 if (!archivefileconts.isEmpty() && QRegExp("^append\\s{1,}\\S{1,}.cfg$", Qt::CaseInsensitive).exactMatch(cfgfileCL))
2393 {
2394 includesfile = QDir::toNativeSeparators(QString(cfgfileCL).remove(QRegExp("^append\\s{1,}", Qt::CaseInsensitive))).trimmed();
2395 searchincfrs = searchforincludesfileL(includesfile, archivefile, archivefileconts, visitedincludes);
2396 if (!searchincfrs.first.first.isEmpty())
2397 {
2398 kernelandinitrd.first += searchincfrs.first.first;
2399 kernelandinitrd.second += searchincfrs.first.second;
2400 titleandparams.first += searchincfrs.second.first;
2401 titleandparams.second += searchincfrs.second.second;
2402 }
2403 continue;
2404 }
2405 if (cfgfileCL.contains(QRegExp("^menu label\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2406 {
2407 titleandparams.first[curindex] = QString(cfgfileCL).remove(QRegExp("^menu label", Qt::CaseInsensitive)).trimmed();
2408 continue;
2409 }
2410 if (cfgfileCL.contains(QRegExp("^append\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2411 {
2412 QString appendoptsL = QString(cfgfileCL).remove(QRegExp("^append", Qt::CaseInsensitive)).trimmed();
2413 if (appendoptsL.contains(QRegExp("initrd=\\S{0,}", Qt::CaseInsensitive)))
2414 {
2415 kernelandinitrd.second[curindex] = getFirstTextBlock(QString(appendoptsL).remove(QRegExp(".{0,}initrd=", Qt::CaseInsensitive)));
2416 appendoptsL = QString(appendoptsL).remove(QRegExp("initrd=\\S{0,}", Qt::CaseInsensitive));
2417 // if (kernelandinitrd.second.at(curindex).isEmpty())
2418 // kernelandinitrd.second[curindex] = initrdLoc;
2419 // else if (!kernelandinitrd.second.at(curindex).contains('/'))
2420 // kernelandinitrd.second[curindex] = QString("%1%2").arg(cfgfiledir, kernelandinitrd.second.at(curindex));
2421 }
2422 titleandparams.second[curindex] = fixkernelbootoptions(appendoptsL);
2423 continue;
2424 }
2425 if (cfgfileCL.contains(QRegExp("^label\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2426 {
2427 if (kernelpassed)
2428 {
2429 ++curindex;
2430 kernelandinitrd.first.append(kernelLoc);
2431 kernelandinitrd.second.append(initrdLoc);
2432 titleandparams.first.append(QString("Untitled Entry Syslinux %1").arg(curindex));
2433 titleandparams.second.append("");
2434 kernelpassed = false;
2435 }
2436 titleandparams.first[curindex] = QString(cfgfileCL).remove(QRegExp("^label", Qt::CaseInsensitive)).trimmed();
2437 continue;
2438 }
2439 if (cfgfileCL.contains(QRegExp("^kernel\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2440 {
2441 if (kernelpassed)
2442 {
2443 ++curindex;
2444 kernelandinitrd.first.append(kernelLoc);
2445 kernelandinitrd.second.append(initrdLoc);
2446 titleandparams.first.append(QString("Untitled Entry Syslinux %1").arg(curindex));
2447 titleandparams.second.append("");
2448 // kernelpassed = false;
2449 }
2450 kernelandinitrd.first[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^kernel", Qt::CaseInsensitive)).trimmed());
2451 // if (kernelandinitrd.first.at(curindex).isEmpty())
2452 // kernelandinitrd.first[curindex] = kernelLoc;
2453 // else if (!kernelandinitrd.first.at(curindex).contains('/'))
2454 // kernelandinitrd.first[curindex] = QString("%1%2").arg(cfgfiledir, kernelandinitrd.first.at(curindex));
2455 kernelpassed = true;
2456 continue;
2457 }
2458 if (cfgfileCL.contains(QRegExp("^initrd\\s{1,}\\S{1,}", Qt::CaseInsensitive)))
2459 {
2460 if (kernelandinitrd.second[curindex] == initrdLoc) {
2461 kernelandinitrd.second[curindex] = getFirstTextBlock(QString(cfgfileCL).remove(QRegExp("^initrd", Qt::CaseInsensitive)).trimmed());
2462 }
2463 continue;
2464 }
2465 }
2466 return qMakePair(kernelandinitrd, titleandparams);
2467 }
2468
searchforincludesfile(QString includesfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2469 QString unetbootin::searchforincludesfile(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2470 {
2471 if (includesfile.startsWith(QDir::toNativeSeparators("/")))
2472 {
2473 includesfile = includesfile.right(includesfile.size() - 1).trimmed();
2474 }
2475 QStringList includesfileL;
2476 for (int i = 0; i < archivefileconts.size(); ++i)
2477 {
2478 QString curentry = archivefileconts.at(i);
2479 if (curentry.endsWith("/") || curentry.endsWith(QDir::toNativeSeparators("/")))
2480 {
2481 curentry = curentry.left(curentry.size() - 1).trimmed();
2482 }
2483 if (curentry.contains("/"))
2484 {
2485 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf("/"));
2486 }
2487 else if (curentry.contains(QDir::toNativeSeparators("/")))
2488 {
2489 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf(QDir::toNativeSeparators("/")));
2490 }
2491 if (includesfile.compare(curentry, Qt::CaseInsensitive) == 0)
2492 {
2493 includesfileL.append(archivefileconts.at(i));
2494 }
2495 }
2496 if (includesfileL.isEmpty())
2497 {
2498 includesfileL = archivefileconts.filter(includesfile, Qt::CaseInsensitive);
2499 }
2500 if (!includesfileL.isEmpty())
2501 {
2502 for (int i = 0; i < includesfileL.size(); ++i)
2503 {
2504 if (visitedincludes.contains(includesfileL.at(i)))
2505 continue;
2506 randtmpfile tmpoutputcfgf(ubntmpf, "cfg");
2507 extractfile(includesfileL.at(i), tmpoutputcfgf.fileName(), archivefile);
2508 QStringList nextinclude = visitedincludes;
2509 nextinclude.append(includesfileL.at(i));
2510 QString extractcfgtmp = getcfgkernargs(tmpoutputcfgf.fileName(), archivefile, archivefileconts, nextinclude).trimmed();
2511 rmFile(tmpoutputcfgf);
2512 if (!extractcfgtmp.isEmpty())
2513 {
2514 return extractcfgtmp;
2515 }
2516 }
2517 }
2518 return "";
2519 }
2520
searchforincludesfileL(QString includesfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2521 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::searchforincludesfileL(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2522 {
2523 if (includesfile.startsWith(QDir::toNativeSeparators("/")))
2524 {
2525 includesfile = includesfile.right(includesfile.size() - 1).trimmed();
2526 }
2527 QStringList includesfileL;
2528 for (int i = 0; i < archivefileconts.size(); ++i)
2529 {
2530 QString curentry = archivefileconts.at(i);
2531 if (curentry.endsWith("/") || curentry.endsWith(QDir::toNativeSeparators("/")))
2532 {
2533 curentry = curentry.left(curentry.size() - 1).trimmed();
2534 }
2535 if (curentry.contains("/"))
2536 {
2537 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf("/"));
2538 }
2539 else if (curentry.contains(QDir::toNativeSeparators("/")))
2540 {
2541 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf(QDir::toNativeSeparators("/")));
2542 }
2543 if (includesfile.compare(curentry, Qt::CaseInsensitive) == 0)
2544 {
2545 includesfileL.append(archivefileconts.at(i));
2546 }
2547 }
2548 if (includesfileL.isEmpty())
2549 {
2550 includesfileL = archivefileconts.filter(includesfile, Qt::CaseInsensitive);
2551 }
2552 if (!includesfileL.isEmpty())
2553 {
2554 for (int i = 0; i < includesfileL.size(); ++i)
2555 {
2556 if (visitedincludes.contains(includesfileL.at(i)))
2557 continue;
2558 randtmpfile tmpoutputcfgf(ubntmpf, "cfg");
2559 extractfile(includesfileL.at(i), tmpoutputcfgf.fileName(), archivefile);
2560 QStringList nextinclude = visitedincludes;
2561 nextinclude.append(includesfileL.at(i));
2562 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > extractcfgtmp = getcfgkernargsL(tmpoutputcfgf.fileName(), archivefile, archivefileconts, nextinclude);
2563 rmFile(tmpoutputcfgf);
2564 if (!extractcfgtmp.first.first.isEmpty())
2565 {
2566 return extractcfgtmp;
2567 }
2568 }
2569 }
2570 return QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> >();
2571 }
2572
searchforgrub2includesfile(QString includesfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2573 QString unetbootin::searchforgrub2includesfile(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2574 {
2575 if (includesfile.startsWith(QDir::toNativeSeparators("/")))
2576 {
2577 includesfile = includesfile.right(includesfile.size() - 1).trimmed();
2578 }
2579 QStringList includesfileL;
2580 for (int i = 0; i < archivefileconts.size(); ++i)
2581 {
2582 QString curentry = archivefileconts.at(i);
2583 if (curentry.endsWith("/") || curentry.endsWith(QDir::toNativeSeparators("/")))
2584 {
2585 curentry = curentry.left(curentry.size() - 1).trimmed();
2586 }
2587 if (curentry.contains("/"))
2588 {
2589 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf("/"));
2590 }
2591 else if (curentry.contains(QDir::toNativeSeparators("/")))
2592 {
2593 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf(QDir::toNativeSeparators("/")));
2594 }
2595 if (includesfile.compare(curentry, Qt::CaseInsensitive) == 0)
2596 {
2597 includesfileL.append(archivefileconts.at(i));
2598 }
2599 }
2600 if (includesfileL.isEmpty())
2601 {
2602 includesfileL = archivefileconts.filter(includesfile, Qt::CaseInsensitive);
2603 }
2604 if (!includesfileL.isEmpty())
2605 {
2606 for (int i = 0; i < includesfileL.size(); ++i)
2607 {
2608 if (visitedincludes.contains(includesfileL.at(i)))
2609 continue;
2610 randtmpfile tmpoutputcfgf(ubntmpf, "cfg");
2611 extractfile(includesfileL.at(i), tmpoutputcfgf.fileName(), archivefile);
2612 QStringList nextinclude = visitedincludes;
2613 nextinclude.append(includesfileL.at(i));
2614 QString extractcfgtmp = getgrub2cfgargs(tmpoutputcfgf.fileName(), archivefile, archivefileconts, nextinclude).trimmed();
2615 rmFile(tmpoutputcfgf);
2616 if (!extractcfgtmp.isEmpty())
2617 {
2618 return extractcfgtmp;
2619 }
2620 }
2621 }
2622 return "";
2623 }
2624
searchforgrub2includesfileL(QString includesfile,QString archivefile,QStringList archivefileconts,QStringList visitedincludes)2625 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > unetbootin::searchforgrub2includesfileL(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes)
2626 {
2627 if (includesfile.startsWith(QDir::toNativeSeparators("/")))
2628 {
2629 includesfile = includesfile.right(includesfile.size() - 1).trimmed();
2630 }
2631 QStringList includesfileL;
2632 for (int i = 0; i < archivefileconts.size(); ++i)
2633 {
2634 QString curentry = archivefileconts.at(i);
2635 if (curentry.endsWith("/") || curentry.endsWith(QDir::toNativeSeparators("/")))
2636 {
2637 curentry = curentry.left(curentry.size() - 1).trimmed();
2638 }
2639 if (curentry.contains("/"))
2640 {
2641 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf("/"));
2642 }
2643 else if (curentry.contains(QDir::toNativeSeparators("/")))
2644 {
2645 curentry = curentry.right(curentry.size() - 1 - curentry.indexOf(QDir::toNativeSeparators("/")));
2646 }
2647 if (includesfile.compare(curentry, Qt::CaseInsensitive) == 0)
2648 {
2649 includesfileL.append(archivefileconts.at(i));
2650 }
2651 }
2652 if (includesfileL.isEmpty())
2653 {
2654 includesfileL = archivefileconts.filter(includesfile, Qt::CaseInsensitive);
2655 }
2656 if (!includesfileL.isEmpty())
2657 {
2658 for (int i = 0; i < includesfileL.size(); ++i)
2659 {
2660 if (visitedincludes.contains(includesfileL.at(i)))
2661 continue;
2662 randtmpfile tmpoutputcfgf(ubntmpf, "cfg");
2663 extractfile(includesfileL.at(i), tmpoutputcfgf.fileName(), archivefile);
2664 QStringList nextinclude = visitedincludes;
2665 nextinclude.append(includesfileL.at(i));
2666 QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > extractcfgtmp = getgrub2cfgargsL(tmpoutputcfgf.fileName(), archivefile, archivefileconts, nextinclude);
2667 rmFile(tmpoutputcfgf);
2668 if (!extractcfgtmp.first.first.isEmpty())
2669 {
2670 return extractcfgtmp;
2671 }
2672 }
2673 }
2674 return QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> >();
2675 }
2676
downloadfile(QString fileurl,QString targetfile,qint64 minsize=524288)2677 void unetbootin::downloadfile(QString fileurl, QString targetfile, qint64 minsize=524288)
2678 {
2679 if (fileurl.isEmpty())
2680 {
2681 showDownloadFailedScreen(fileurl);
2682 return;
2683 }
2684 if (QFile::exists(targetfile))
2685 {
2686 rmFile(targetfile);
2687 }
2688 QNetworkAccessManager manager;
2689 QNetworkRequest dlurl(fileurl);
2690 QNetworkReply * networkReply = manager.get(dlurl);
2691
2692 QEventLoop dlewait;
2693 pdesc5->setText("");
2694 pdesc4->setText(tr("Downloading files, please wait..."));
2695 pdesc3->setText(tr("<b>Source:</b> <a href=\"%1\">%1</a>").arg(fileurl));
2696 pdesc2->setText(tr("<b>Destination:</b> %1").arg(targetfile));
2697 pdesc1->setText(tr("<b>Downloaded:</b> 0 bytes"));
2698
2699 QUrl redirectUrl;
2700 bool downloadFailed = false;
2701 QNetworkReply::NetworkError errorCode;
2702
2703 connect(networkReply, &QNetworkReply::finished, &dlewait, &QEventLoop::quit);
2704 connect(networkReply, &QNetworkReply::downloadProgress, this, &unetbootin::dlprogressupdate64);
2705 connect(networkReply, &QNetworkReply::redirected, [&](const QUrl &url){ redirectUrl = url; });
2706 connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
2707 [&](QNetworkReply::NetworkError code){ downloadFailed = true; errorCode = code; });
2708
2709 QFile dloutfile;
2710 if (installType == tr("USB Drive"))
2711 {
2712 dloutfile.setFileName(randtmpfile::getrandfilename(ubntmpf, "tmp"));
2713 }
2714 else
2715 {
2716 dloutfile.setFileName(targetfile);
2717 }
2718 dloutfile.open(QIODevice::WriteOnly);
2719
2720 connect(networkReply, &QNetworkReply::downloadProgress, [&](qint64, qint64){
2721 dloutfile.write(networkReply->readAll());
2722 });
2723
2724 dlewait.exec();
2725
2726 if (!redirectUrl.isEmpty())
2727 {
2728 networkReply->deleteLater();
2729 downloadfile(redirectUrl.toString(), targetfile, minsize);
2730 return;
2731 }
2732
2733 if (downloadFailed)
2734 {
2735 qDebug() << "Failed to download URL: " << fileurl;
2736 qDebug() << "Error code: " << errorCode;
2737 qDebug() << "Error string: " << networkReply->errorString();
2738 networkReply->deleteLater();
2739 showDownloadFailedScreen(fileurl);
2740 return;
2741 }
2742
2743 dloutfile.write(networkReply->readAll());
2744 networkReply->deleteLater();
2745 dloutfile.close();
2746 if (installType == tr("USB Drive"))
2747 {
2748 dloutfile.rename(targetfile);
2749 }
2750
2751 if (QFile(targetfile).size() < minsize)
2752 {
2753 // download failed
2754 showDownloadFailedScreen(fileurl);
2755 return;
2756 }
2757 pdesc4->setText("");
2758 pdesc3->setText("");
2759 pdesc2->setText("");
2760 pdesc1->setText("");
2761 tprogress->setValue(0);
2762 if (testingDownload)
2763 {
2764 // Note that this only tests that the first download succeeds
2765 QTextStream out(stdout);
2766 out << "exitstatus:downloadcomplete" << endl << flush;
2767 QApplication::exit();
2768 exit(0);
2769 }
2770 }
2771
showDownloadFailedScreen(const QString & fileurl)2772 void unetbootin::showDownloadFailedScreen(const QString &fileurl)
2773 {
2774 progresslayer->setEnabled(false);
2775 progresslayer->hide();
2776 rebootlayer->setEnabled(true);
2777 rebootlayer->show();
2778 rebootmsgtext->setText(tr("Download of %1 %2 from %3 failed. Please try downloading the ISO file from the website directly and supply it via the diskimage option.").arg(nameDistro).arg(nameVersion).arg(fileurl));
2779 this->downloadFailed = true;
2780 if (exitOnCompletion)
2781 {
2782 QTextStream out(stdout);
2783 out << "exitstatus:downloadfailed" << endl << flush;
2784 QApplication::exit();
2785 exit(0);
2786 }
2787 }
2788
dlprogressupdate64(qint64 dlbytes,qint64 maxbytes)2789 void unetbootin::dlprogressupdate64(qint64 dlbytes, qint64 maxbytes)
2790 {
2791 QTime time = QTime::currentTime();
2792 static int oldsec = 0;
2793 // refresh the progress bar every second
2794 if(oldsec != time.second())
2795 {
2796 oldsec = time.second();
2797 tprogress->setValue(10000 * dlbytes / maxbytes);
2798 tprogress->setMaximum(10000);
2799 // display the downloaded size with suffix
2800 pdesc1->setText(tr("<b>Downloaded:</b> %1 of %2").arg(displayfisize(dlbytes)).arg(displayfisize(maxbytes)));
2801 }
2802 }
2803
cpprogressupdate64(qint64 dlbytes,qint64 maxbytes)2804 void unetbootin::cpprogressupdate64(qint64 dlbytes, qint64 maxbytes)
2805 {
2806 QTime time = QTime::currentTime();
2807 static int oldsec = 0;
2808 // refresh the progress bar every second
2809 if(oldsec != time.second())
2810 {
2811 oldsec = time.second();
2812 tprogress->setValue(10000 * dlbytes / maxbytes);
2813 tprogress->setMaximum(10000);
2814 // display the downloaded size with suffix
2815 pdesc1->setText(tr("<b>Copied:</b> %1 of %2").arg(displayfisize(dlbytes)).arg(displayfisize(maxbytes)));
2816 }
2817 }
2818
downloadpagecontents(QUrl pageurl)2819 QString unetbootin::downloadpagecontents(QUrl pageurl)
2820 {
2821 QNetworkAccessManager manager;
2822 QNetworkRequest dlurl(pageurl);
2823 QNetworkReply * networkReply = manager.get(dlurl);
2824 QEventLoop pgwait;
2825 QUrl redirectUrl;
2826 connect(networkReply, &QNetworkReply::finished, &pgwait, &QEventLoop::quit);
2827 connect(networkReply, &QNetworkReply::redirected, [&redirectUrl](const QUrl &url){ redirectUrl = url; });
2828
2829 pgwait.exec();
2830
2831 if (!redirectUrl.isEmpty())
2832 {
2833 networkReply->deleteLater();
2834 return downloadpagecontents(redirectUrl);
2835 }
2836
2837 QString result = networkReply->readAll();
2838 networkReply->close();
2839 networkReply->deleteLater();
2840 return result;
2841 }
2842
lstFtpDirFiles(QString ldfDirStringUrl,qint64 ldfMinSize,qint64 ldfMaxSize)2843 QStringList unetbootin::lstFtpDirFiles(QString ldfDirStringUrl, qint64 ldfMinSize, qint64 ldfMaxSize)
2844 {
2845 qDebug() << "lstFtpDirFiles called for " << ldfDirStringUrl;
2846 return {};
2847 /*
2848 QUrl ldfDirUrl(ldfDirStringUrl);
2849 QFtp ldfFtp;
2850 QEventLoop ldfWait;
2851 nDirListStor nDirListStorL;
2852 nDirListStorL.nMinFileSizeBytes = ldfMinSize;
2853 nDirListStorL.nMaxFileSizeBytes = ldfMaxSize;
2854 nDirListStorL.searchsymlinks = this->searchsymlinks;
2855 connect(&ldfFtp, SIGNAL(done(bool)), &ldfWait, SLOT(quit()));
2856 connect(&ldfFtp, SIGNAL(listInfo(QUrlInfo)), &nDirListStorL, SLOT(sAppendSelfUrlInfoList(QUrlInfo)));
2857 ldfFtp.connectToHost(ldfDirUrl.host());
2858 ldfFtp.login();
2859 ldfFtp.list(ldfDirUrl.path());
2860 ldfWait.exec();
2861 ldfFtp.close();
2862 return nDirListStorL.nDirFileListSL;*/
2863 }
2864
lstHttpDirFiles(QString ldfDirStringUrl)2865 QStringList unetbootin::lstHttpDirFiles(QString ldfDirStringUrl)
2866 {
2867 QStringList relativefilelinksL;
2868 QStringList relativelinksLPreFilter =
2869 downloadpagecontents(QUrl(ldfDirStringUrl))
2870 .replace(">", ">\n")
2871 .replace("<", "\n<")
2872 .split("\n");
2873 QStringList relativelinksLPart1 =
2874 relativelinksLPreFilter
2875 .filter(QRegExp("<a href=\"(?!\\?)\\S{1,}\">", Qt::CaseInsensitive))
2876 .replaceInStrings(QRegExp("<a href=\"", Qt::CaseInsensitive), "")
2877 .replaceInStrings("\">", "");
2878 QStringList relativelinksLPart2 =
2879 relativelinksLPreFilter
2880 .filter(QRegExp("<a href=\'(?!\\?)\\S{1,}\'>", Qt::CaseInsensitive))
2881 .replaceInStrings(QRegExp("<a href=\'", Qt::CaseInsensitive), "")
2882 .replaceInStrings("\'>", "");
2883 QStringList relativelinksL = relativelinksLPart1 << relativelinksLPart2;
2884 for (int i = 0; i < relativelinksL.size(); ++i)
2885 {
2886 if (!relativelinksL.at(i).endsWith('/'))
2887 relativefilelinksL.append(relativelinksL.at(i));
2888 }
2889 return relativefilelinksL;
2890 }
2891
lstNetDirFiles(QString ldfDirStringUrl,qint64 ldfMinSize,qint64 ldfMaxSize)2892 QStringList unetbootin::lstNetDirFiles(QString ldfDirStringUrl, qint64 ldfMinSize, qint64 ldfMaxSize)
2893 {
2894 if (!ldfDirStringUrl.endsWith('/'))
2895 ldfDirStringUrl += '/';
2896 if (ldfDirStringUrl.startsWith("ftp"))
2897 {
2898 return lstFtpDirFiles(ldfDirStringUrl, ldfMinSize, ldfMaxSize);
2899 }
2900 else
2901 {
2902 return lstHttpDirFiles(ldfDirStringUrl);
2903 }
2904 }
2905
weightedFilterNetDir(QString ldfDirStringUrl,qint64 ldfMinSize,qint64 ldfMaxSize,QList<QRegExp> ldfFileMatchExp)2906 QPair<QString, int> unetbootin::weightedFilterNetDir(QString ldfDirStringUrl, qint64 ldfMinSize, qint64 ldfMaxSize, QList<QRegExp> ldfFileMatchExp)
2907 {
2908 if (!ldfDirStringUrl.endsWith('/'))
2909 ldfDirStringUrl += '/';
2910 pdesc1->setText(tr("Searching in <a href=\"%1\">%1</a>").arg(ldfDirStringUrl));
2911 QPair<QString, int> relativeFileUrl = filterBestMatch(lstNetDirFiles(ldfDirStringUrl, ldfMinSize, ldfMaxSize), ldfFileMatchExp);
2912 if (relativeFileUrl.first.startsWith('/'))
2913 ldfDirStringUrl = ldfDirStringUrl.left(ldfDirStringUrl.indexOf('/', 8));
2914 pdesc2->setText(tr("%1/%2 matches in <a href=\"%3\">%3</a>").arg(relativeFileUrl.second).arg(ldfFileMatchExp.size()).arg(ldfDirStringUrl));
2915 return qMakePair(ldfDirStringUrl+relativeFileUrl.first, relativeFileUrl.second);
2916 }
2917
fileFilterNetDir(QStringList ldfDirStringUrlList,qint64 ldfMinSize,qint64 ldfMaxSize,QList<QRegExp> ldfFileMatchExp)2918 QString unetbootin::fileFilterNetDir(QStringList ldfDirStringUrlList, qint64 ldfMinSize, qint64 ldfMaxSize, QList<QRegExp> ldfFileMatchExp)
2919 {
2920 QPair<QString, int> curRemoteFileUrlSP;
2921 int hRegxMatch = 0;
2922 QString hRegxMatchString;
2923 for (int i = 0; i < ldfDirStringUrlList.size(); ++i)
2924 {
2925 curRemoteFileUrlSP = weightedFilterNetDir(ldfDirStringUrlList.at(i), ldfMinSize, ldfMaxSize, ldfFileMatchExp);
2926 if (curRemoteFileUrlSP.second == ldfFileMatchExp.size())
2927 return curRemoteFileUrlSP.first;
2928 if (curRemoteFileUrlSP.second > hRegxMatch)
2929 {
2930 hRegxMatch = curRemoteFileUrlSP.second;
2931 hRegxMatchString = curRemoteFileUrlSP.first;
2932 }
2933 }
2934 return hRegxMatchString;
2935 }
2936
filterBestMatch(QStringList ufStringList,QList<QRegExp> filterExpList)2937 QPair<QString, int> unetbootin::filterBestMatch(QStringList ufStringList, QList<QRegExp> filterExpList)
2938 {
2939 QString hRegxMatchString, hRegxMatchStringEnd;
2940 int hRegxMatch = 0;
2941 for (int i = 0; i < ufStringList.size(); ++i)
2942 {
2943 int regxmatches = 0;
2944 hRegxMatchStringEnd = ufStringList.at(i).right(ufStringList.at(i).size() - ufStringList.at(i).lastIndexOf('/') - 1);
2945 for (int j = 0; j < filterExpList.size(); ++j)
2946 {
2947 if (hRegxMatchStringEnd.contains(filterExpList.at(j)))
2948 ++regxmatches;
2949 }
2950 if (regxmatches >= hRegxMatch)
2951 {
2952 hRegxMatchString = ufStringList.at(i);
2953 hRegxMatch = regxmatches;
2954 }
2955 }
2956 return qMakePair(hRegxMatchString, hRegxMatch);
2957 }
2958
2959
callexternapp(QString xexecFile,QString xexecParm)2960 QString unetbootin::callexternapp(QString xexecFile, QString xexecParm)
2961 {
2962 QEventLoop cxaw;
2963 callexternappT cxat;
2964 connect(&cxat, SIGNAL(finished()), &cxaw, SLOT(quit()));
2965 cxat.execFile = xexecFile;
2966 cxat.execParm = xexecParm;
2967 cxat.start();
2968 cxaw.exec();
2969 return cxat.retnValu;
2970 }
2971
callexternappWriteToStdin(QString xexecFile,QString xexecParm,QString xwriteToStdin)2972 QString unetbootin::callexternappWriteToStdin(QString xexecFile, QString xexecParm, QString xwriteToStdin)
2973 {
2974 QEventLoop cxaw;
2975 callexternappWriteToStdinT cxat;
2976 connect(&cxat, SIGNAL(finished()), &cxaw, SLOT(quit()));
2977 cxat.execFile = xexecFile;
2978 cxat.execParm = xexecParm;
2979 cxat.writeToStdin = xwriteToStdin;
2980 cxat.start();
2981 cxaw.exec();
2982 return cxat.retnValu;
2983 }
2984
getdevluid(QString voldrive)2985 QString unetbootin::getdevluid(QString voldrive)
2986 {
2987 #ifdef Q_OS_MAC
2988 QString diskutilinfo = callexternapp("diskutil", "info " + voldrive);
2989 QString uuidS = getuuid(voldrive, diskutilinfo);
2990 if (uuidS == "None")
2991 {
2992 return QString("LABEL=%1").arg(getlabel(voldrive, diskutilinfo));
2993 }
2994 else
2995 {
2996 return QString("UUID=%1").arg(uuidS);
2997 }
2998 #endif
2999 #ifndef Q_OS_MAC
3000 QString uuidS = getuuid(voldrive);
3001 if (uuidS == "None")
3002 {
3003 return QString("LABEL=%1").arg(getlabel(voldrive));
3004 }
3005 else
3006 {
3007 return QString("UUID=%1").arg(uuidS);
3008 }
3009 #endif
3010 }
3011
3012 #ifdef Q_OS_MAC
getlabel(QString voldrive,QString diskutilinfo)3013 QString unetbootin::getlabel(QString voldrive, QString diskutilinfo)
3014 {
3015 QStringList diskutiloutput = diskutilinfo.split("\n");
3016 QStringList labelLines = diskutiloutput.filter("Volume Name");
3017 if (labelLines.size() == 0)
3018 return "None";
3019 QStringList labelAtEnd = labelLines.at(0).split(":");
3020 if (labelAtEnd.size() < 2)
3021 return "None";
3022 return labelAtEnd.at(labelAtEnd.size()-1).trimmed();
3023 }
3024 #endif
3025
getlabel(QString voldrive)3026 QString unetbootin::getlabel(QString voldrive)
3027 {
3028 #ifdef Q_OS_MAC
3029 return getlabel(voldrive, callexternapp("diskutil", "info " + voldrive));
3030 #endif
3031 #ifdef Q_OS_WIN32
3032 voldrive.append("\\");
3033 wchar_t vollabel[50];
3034 GetVolumeInformation(LPWSTR(voldrive.utf16()), vollabel, 50, NULL, NULL, NULL, NULL, NULL);
3035 QString vollabelS = QString::fromWCharArray(vollabel);
3036 if (vollabelS.isEmpty())
3037 {
3038 return "None";
3039 }
3040 else
3041 {
3042 return vollabelS;
3043 }
3044 #endif
3045 #ifdef Q_OS_LINUX
3046 QString volidpS = "";
3047 if (!volidcommand.isEmpty())
3048 volidpS = QString(callexternapp(volidcommand, QString("-l %1").arg(voldrive))).remove("\r").remove("\n").trimmed();
3049 else
3050 {
3051 QString tstrblk = QString(callexternapp(blkidcommand, QString("-s LABEL %1").arg(voldrive)));
3052 if (tstrblk.contains('='))
3053 volidpS = tstrblk.section('=', -1, -1).remove('"').remove("\r").remove("\n").trimmed();
3054 }
3055 if (volidpS.isEmpty())
3056 {
3057 return "None";
3058 }
3059 else
3060 {
3061 return volidpS;
3062 }
3063 #endif
3064 }
3065
3066 #ifdef Q_OS_MAC
getuuid(QString voldrive,QString diskutilinfo)3067 QString unetbootin::getuuid(QString voldrive, QString diskutilinfo)
3068 {
3069 QStringList diskutiloutput = diskutilinfo.split("\n");
3070 QStringList uuidList = diskutiloutput.filter("UUID"); // TODO untested
3071 if (uuidList.size() > 0)
3072 {
3073 uuidList = uuidList.at(0).split(" ");
3074 return uuidList.at(uuidList.size()-1).trimmed();
3075 }
3076 // otherwise FAT32 or FAT16; return serial number
3077 bool isFat32 = diskutiloutput.filter("FAT32").size() > 0;
3078 if (!isFat32)
3079 {
3080 if (diskutiloutput.filter("FAT16").size() == 0 && diskutiloutput.filter("FAT12").size() == 0)
3081 return "None";
3082 }
3083 callexternapp("diskutil", "umount "+targetDev);
3084 QFile rawDevice(voldrive);
3085 rawDevice.open(QIODevice::ReadOnly);
3086 if (isFat32)
3087 {
3088 rawDevice.seek(67);
3089 }
3090 else // FAT16 or FAT12
3091 {
3092 rawDevice.seek(39);
3093 }
3094 unsigned char pserial[4];
3095 rawDevice.read((char*)pserial, 4);
3096 QString serialNumber = QString::number(pserial[3], 16).rightJustified(2, '0')+QString::number(pserial[2], 16).rightJustified(2, '0')+"-"+QString::number(pserial[1], 16).rightJustified(2, '0')+QString::number(pserial[0], 16).rightJustified(2, '0');
3097 rawDevice.close();
3098 callexternapp("diskutil", "mount "+targetDev);
3099 return serialNumber.toUpper();
3100 }
3101
3102 #endif
3103
getuuid(QString voldrive)3104 QString unetbootin::getuuid(QString voldrive)
3105 {
3106 #ifdef Q_OS_MAC
3107 return getuuid(voldrive, callexternapp("diskutil", "info " + voldrive));
3108 #endif
3109 #ifdef Q_OS_WIN32
3110 voldrive.append("\\");
3111 DWORD volserialnum = 0;
3112 GetVolumeInformation(LPWSTR(voldrive.utf16()), NULL, NULL, &volserialnum, NULL, NULL, NULL, NULL);
3113 if (!(volserialnum >= 1))
3114 {
3115 return "None";
3116 }
3117 QString tvolsernum = QString::number(volserialnum, 16).toUpper();
3118 if (tvolsernum.size() == 8)
3119 {
3120 return QString("%1-%2").arg(tvolsernum.left(4), tvolsernum.right(4));
3121 }
3122 else
3123 {
3124 return tvolsernum;
3125 }
3126 #endif
3127 #ifdef Q_OS_LINUX
3128 QString volidpS = "";
3129 if (!volidcommand.isEmpty())
3130 volidpS = QString(callexternapp(volidcommand, QString("-u %1").arg(voldrive))).remove("\r").remove("\n").trimmed();
3131 else
3132 {
3133 QString tstrblk = QString(callexternapp(blkidcommand, QString("-s UUID %1").arg(voldrive)));
3134 if (tstrblk.contains('='))
3135 volidpS = tstrblk.section('=', -1, -1).remove('"').remove("\r").remove("\n").trimmed();
3136 }
3137 if (volidpS.isEmpty())
3138 {
3139 return "None";
3140 }
3141 else
3142 {
3143 return volidpS;
3144 }
3145 #endif
3146 }
3147
3148 #ifdef Q_OS_UNIX
3149
locatecommand(QString commandtolocate,QString reqforinstallmode,QString packagename)3150 QString unetbootin::locatecommand(QString commandtolocate, QString reqforinstallmode, QString packagename)
3151 {
3152 QString commandbinpath = callexternapp("which", commandtolocate).trimmed();
3153 if (!commandbinpath.isEmpty() && QFile::exists(commandbinpath))
3154 return commandbinpath;
3155 if (packagename == "silent")
3156 return "";
3157 // QString commandbinpath = callexternapp("whereis", commandtolocate);
3158 // QStringList commandbinpathL = commandbinpath.split(" ").join("\n").split("\t").join("\n").split("\n");
3159 // for (int i = 0; i < commandbinpathL.size(); ++i)
3160 // {
3161 // if (commandbinpathL.at(i).contains("bin/"))
3162 // {
3163 // return commandbinpathL.at(i);
3164 // }
3165 // }
3166 QMessageBox errorcmdnotfoundmsgbx;
3167 errorcmdnotfoundmsgbx.setIcon(QMessageBox::Warning);
3168 errorcmdnotfoundmsgbx.setWindowTitle(QString(tr("%1 not found")).arg(commandtolocate));
3169 errorcmdnotfoundmsgbx.setText(QString(tr("%1 not found. This is required for %2 install mode.\nInstall the \"%3\" package or your distribution's equivalent.")).arg(commandtolocate, reqforinstallmode, packagename));
3170 errorcmdnotfoundmsgbx.setStandardButtons(QMessageBox::Ok);
3171 switch (errorcmdnotfoundmsgbx.exec())
3172 {
3173 case QMessageBox::Ok:
3174 break;
3175 default:
3176 break;
3177 }
3178 return commandtolocate;
3179 }
3180
locatedevicenode(QString mountpoint)3181 QString unetbootin::locatedevicenode(QString mountpoint)
3182 {
3183 QStringList rawdeviceL = QString(callexternapp("mount", "")).replace("\t", " ").split("\n").filter("/dev/").filter(QString(" %1 ").arg(mountpoint));
3184 if (rawdeviceL.isEmpty())
3185 {
3186 return "NOT FOUND";
3187 }
3188 else
3189 {
3190 return QFileInfo(rawdeviceL.at(0).split(" ").at(0)).canonicalFilePath();
3191 }
3192 }
3193
locatemountpoint(QString devicenode)3194 QString unetbootin::locatemountpoint(QString devicenode)
3195 {
3196 QStringList procmountsL = callexternapp("mount", "").split("\n");
3197 for (int i = 0; i < procmountsL.size(); ++i)
3198 {
3199 QString mountinfo = procmountsL.at(i).split("\t").join(" ");
3200 QStringList deviceAndRest = mountinfo.split(" on ");
3201 if (deviceAndRest.size() < 2)
3202 continue;
3203 if (deviceAndRest.at(0).trimmed() != devicenode)
3204 continue;
3205 QStringList mountpointAndOptions = deviceAndRest.at(1).split(" (").join(" type ").split(" type ");
3206 if (mountpointAndOptions.size() < 1)
3207 continue;
3208 QString mountpoint = mountpointAndOptions.at(0).trimmed();
3209 if (QDir(mountpoint).exists())
3210 return mountpoint;
3211 }
3212 return "NOT MOUNTED";
3213 }
3214
getGrubNotation(QString devicenode)3215 QString unetbootin::getGrubNotation(QString devicenode)
3216 {
3217 return QString("(hd%1,%2)").arg(getDiskNumber(devicenode)).arg(getPartitionNumber(devicenode));
3218 }
3219
getGrub2Notation(QString devicenode)3220 QString unetbootin::getGrub2Notation(QString devicenode)
3221 {
3222 return QString("(hd%1,%2)").arg(getDiskNumber(devicenode)).arg(getPartitionNumber(devicenode)+1);
3223 }
3224
letterToNumber(QChar lettertoconvert)3225 int unetbootin::letterToNumber(QChar lettertoconvert)
3226 {
3227 if (lettertoconvert.isLower())
3228 {
3229 return static_cast<int>(lettertoconvert.toLatin1() - 'a');
3230 }
3231 if (lettertoconvert.isUpper())
3232 {
3233 return static_cast<int>(lettertoconvert.toLatin1() - 'A');
3234 }
3235 else
3236 {
3237 return 999;
3238 }
3239 }
3240
getDiskNumber(QString devicenode)3241 int unetbootin::getDiskNumber(QString devicenode)
3242 {
3243 QChar disknumchar(devicenode.at(devicenode.size() - 2));
3244 if (disknumchar.isLetter())
3245 {
3246 return letterToNumber(disknumchar);
3247 }
3248 else
3249 {
3250 return disknumchar.digitValue() - 1;
3251 }
3252 }
3253
getPartitionNumber(QString devicenode)3254 int unetbootin::getPartitionNumber(QString devicenode)
3255 {
3256 QChar partitionchar(devicenode.at(devicenode.size() - 1));
3257 if (partitionchar.isLetter())
3258 {
3259 return letterToNumber(partitionchar);
3260 }
3261 else
3262 {
3263 return partitionchar.digitValue() - 1;
3264 }
3265 }
3266
3267 #endif
3268
3269 #ifdef Q_OS_WIN32
3270
installsvzip()3271 void unetbootin::installsvzip()
3272 {
3273 if (QFile::exists(QString("%1\\7z.dll").arg(ubntmpf)))
3274 {
3275 rmFile(QString("%1\\7z.dll").arg(ubntmpf));
3276 }
3277 instIndvfl("sevnz.dll", QString("%1\\7z.dll").arg(ubntmpf));
3278 if (QFile::exists(QString("%1sevnz.exe").arg(ubntmpf)))
3279 {
3280 rmFile(QString("%1sevnz.exe").arg(ubntmpf));
3281 }
3282 instIndvfl("sevnz.exe", QString("%1sevnz.exe").arg(ubntmpf));
3283 sevzcommand = QString("%1sevnz.exe").arg(ubntmpf);
3284 }
3285
configsysEdit()3286 void unetbootin::configsysEdit()
3287 {
3288 SetFileAttributesA(QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive)).toUtf8(), FILE_ATTRIBUTE_NORMAL);
3289 QFile::copy(QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive)), QString("%1config.sys").arg(targetPath));
3290 QFile::copy(QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive)), QString("%1confignw.txt").arg(targetPath));
3291 QFile confignwFile(QString("%1confignw.txt").arg(targetPath));
3292 QFile configsysFile(QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive)));
3293 confignwFile.open(QIODevice::ReadWrite | QIODevice::Text);
3294 configsysFile.open(QIODevice::ReadOnly | QIODevice::Text);
3295 QTextStream confignwOut(&confignwFile);
3296 QTextStream configsysOut(&configsysFile);
3297 QString configsysText = QString("[menu]\n"
3298 "menucolor=15,0\n"
3299 "menuitem=windows,Windows\n"
3300 "menuitem=grub,"UNETBOOTINB"\n"
3301 "menudefault=windows,30\n"
3302 "[grub]\n"
3303 "device=ubnldr.exe\n"
3304 "[windows]\n%1").arg(configsysOut.readAll());
3305 confignwOut << configsysText << endl;
3306 if (!QFile::copy(QString("%1confignw.txt").arg(targetPath), QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive))))
3307 {
3308 rmFile(configsysFile);
3309 QFile::copy(QString("%1confignw.txt").arg(targetPath), QDir::toNativeSeparators(QString("%1config.sys").arg(targetDrive)));
3310 }
3311 }
3312
bootiniEdit()3313 void unetbootin::bootiniEdit()
3314 {
3315 SetFileAttributesW(LPWSTR(QDir::toNativeSeparators(QString("%1boot.ini").arg(targetDrive)).utf16()), FILE_ATTRIBUTE_NORMAL);
3316 QFile::copy(QDir::toNativeSeparators(QString("%1boot.ini").arg(targetDrive)), QString("%1boot.ini").arg(targetPath));
3317 QFile::copy(QDir::toNativeSeparators(QString("%1bootnw.ini").arg(targetDrive)), QString("%1bootnw.txt").arg(targetPath));
3318 QFile bootnwFile(QString("%1bootnw.txt").arg(targetPath));
3319 QFile bootiniFile(QDir::toNativeSeparators(QString("%1boot.ini").arg(targetDrive)));
3320 bootnwFile.open(QIODevice::ReadWrite | QIODevice::Text);
3321 bootiniFile.open(QIODevice::ReadOnly | QIODevice::Text);
3322 QTextStream bootnwOut(&bootnwFile);
3323 QTextStream bootiniOut(&bootiniFile);
3324 QStringList bootiniCurTextL;
3325 bool btimustreplacetimeout = true;
3326 QRegExp btichkistimeout("\\s{0,}timeout.{0,}", Qt::CaseInsensitive);
3327 QString bootiniCurLine;
3328 while (!bootiniOut.atEnd())
3329 {
3330 bootiniCurLine = bootiniOut.readLine();
3331 if (btimustreplacetimeout && btichkistimeout.exactMatch(bootiniCurLine))
3332 {
3333 bootiniCurTextL.append("timeout=15");
3334 btimustreplacetimeout = false;
3335 }
3336 else
3337 {
3338 bootiniCurTextL.append(bootiniCurLine);
3339 }
3340 }
3341 QString bootiniCurText = bootiniCurTextL.join("\n");
3342 QString bootiniText = QString("%1\n%2=\""UNETBOOTINB"\"").arg(bootiniCurText).arg(QDir::toNativeSeparators(QString("%1ubnldr.mbr").arg(targetDrive)));
3343 bootnwOut << bootiniText << endl;
3344 if (!QFile::copy(QString("%1bootnw.txt").arg(targetPath), QDir::toNativeSeparators(QString("%1boot.ini").arg(targetDrive))))
3345 {
3346 rmFile(bootiniFile);
3347 QFile::copy(QString("%1bootnw.txt").arg(targetPath), QDir::toNativeSeparators(QString("%1boot.ini").arg(targetDrive)));
3348 }
3349 }
3350
vistabcdEdit()3351 void unetbootin::vistabcdEdit()
3352 {
3353 bool warch64 = false;
3354 if (!QProcess::systemEnvironment().filter("ProgramW6432").isEmpty())
3355 warch64 = true;
3356 instIndvfl("emtxfile.exe", QString("%1emtxfile.exe").arg(targetPath));
3357 QFile vbcdEditF1(QString("%1vbcdedit.bat").arg(targetPath));
3358 vbcdEditF1.open(QIODevice::ReadWrite | QIODevice::Text);
3359 QTextStream vbcdEditS1(&vbcdEditF1);
3360 vbcdEditS1 << QString("bcdedit /create /d \""UNETBOOTINB"\" /application bootsector > %1tmpbcdid").arg(targetPath) << endl;
3361 vbcdEditF1.close();
3362 if (!warch64)
3363 callexternapp(QString("%1vbcdedit.bat").arg(targetPath), "");
3364 QFile vbcdTmpInF(QString("%1tmpbcdid").arg(targetPath));
3365 vbcdTmpInF.open(QIODevice::ReadOnly | QIODevice::Text);
3366 QTextStream vbcdTmpInS(&vbcdTmpInF);
3367 QString qstmpvbcdin = vbcdTmpInS.readAll();
3368 vbcdTmpInF.close();
3369 QString vbcdIdTL;
3370 QStringList vbcdIdTLSL;
3371 if (!warch64)
3372 {
3373 vbcdIdTLSL = qstmpvbcdin.replace("{", "\n").replace("}", "\n").split("\n").filter("-");
3374 if (!vbcdIdTLSL.isEmpty())
3375 vbcdIdTL = vbcdIdTLSL.at(0);
3376 }
3377 else
3378 {
3379 callexternapp(QString("%1emtxfile.exe").arg(targetPath), QString("%1vbcdedit.bat runas").arg(targetPath));
3380 vbcdTmpInF.open(QIODevice::ReadOnly | QIODevice::Text);
3381 QTextStream vbcdTmpInS2(&vbcdTmpInF);
3382 vbcdIdTLSL = vbcdTmpInS2.readAll().replace("{", "\n").replace("}", "\n").split("\n").filter("-");
3383 if (!vbcdIdTLSL.isEmpty())
3384 vbcdIdTL = vbcdIdTLSL.at(0);
3385 vbcdTmpInF.close();
3386 }
3387 QSettings vdtistor("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
3388 vdtistor.setValue("WArch64", warch64);
3389 QFile vbcdEditF2(QString("%1vbcdedt2.bat").arg(targetPath));
3390 vbcdEditF2.open(QIODevice::ReadWrite | QIODevice::Text);
3391 QTextStream vbcdEditS2(&vbcdEditF2);
3392 vbcdEditS2 << QString("bcdedit /set {%1} device boot\n"
3393 "bcdedit /set {%1} path \\ubnldr.mbr\n"
3394 "bcdedit /set {%1} device partition=%2\n"
3395 "bcdedit /displayorder {%1} /addlast\n"
3396 "bcdedit /timeout 30").arg(vbcdIdTL).arg(targetDev) << endl;
3397 vbcdEditF2.close();
3398 if (warch64)
3399 {
3400 callexternapp(QString("%1emtxfile.exe").arg(targetPath), QString("%1vbcdedt2.bat runas").arg(targetPath));
3401 }
3402 else
3403 {
3404 callexternapp(QString("%1vbcdedt2.bat").arg(targetPath), "");
3405 }
3406 QFile vbcdundoF(QString("%1vbcdundo.bat").arg(targetPath));
3407 vbcdundoF.open(QIODevice::ReadWrite | QIODevice::Text);
3408 QTextStream vbcdundoS(&vbcdundoF);
3409 vbcdundoS << QString("bcdedit /delete {%1}").arg(vbcdIdTL) << endl;
3410 vbcdundoF.close();
3411 }
3412
3413 #endif
3414
instIndvfl(QString srcfName,QString dstfName)3415 void unetbootin::instIndvfl(QString srcfName, QString dstfName)
3416 {
3417 QFile srcF(QString(":/%1").arg(srcfName));
3418 #ifdef NOSTATIC
3419 if (srcfName == "memdisk")
3420 srcF.setFileName(QFile::exists("/usr/share/syslinux/memdisk") ? "/usr/share/syslinux/memdisk" : "/usr/lib/syslinux/memdisk");
3421 else if (srcfName == "menu.c32")
3422 {
3423 #ifdef Q_OS_LINUX
3424 srcF.setFileName(QFile::exists("/usr/share/syslinux/menu.c32") ? "/usr/share/syslinux/menu.c32" : "/usr/lib/syslinux/menu.c32");
3425 if (QFile::exists("/usr/lib/syslinux/modules/bios/menu.c32"))
3426 srcF.setFileName("/usr/lib/syslinux/modules/bios/menu.c32");
3427 #endif
3428 #ifdef Q_OS_FREEBSD
3429 srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/menu/menu.c32");
3430 #endif
3431 }
3432 else if (srcfName == "libutil.c32")
3433 {
3434 #ifdef Q_OS_LINUX
3435 srcF.setFileName(QFile::exists("/usr/share/syslinux/libutil.c32") ? "/usr/share/syslinux/libutil.c32" : "/usr/lib/syslinux/libutil.c32");
3436 if (QFile::exists("/usr/lib/syslinux/modules/bios/libutil.c32"))
3437 srcF.setFileName("/usr/lib/syslinux/modules/bios/libutil.c32");
3438 #endif
3439 #ifdef Q_OS_FREEBSD
3440 srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/libutil/libutil.c32");
3441 #endif
3442 }
3443 else if (srcfName == "libcom32.c32")
3444 {
3445 #ifdef Q_OS_LINUX
3446 srcF.setFileName(QFile::exists("/usr/share/syslinux/libcom32.c32") ? "/usr/share/syslinux/libcom32.c32" : "/usr/lib/syslinux/libcom32.c32");
3447 if (QFile::exists("/usr/lib/syslinux/modules/bios/libcom32.c32"))
3448 srcF.setFileName("/usr/lib/syslinux/modules/bios/libcom32.c32");
3449 #endif
3450 #ifdef Q_OS_FREEBSD
3451 srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/lib/libcom32.c32");
3452 #endif
3453 }
3454 else if (srcfName == "mbr.bin")
3455 {
3456 srcF.setFileName(QFile::exists("/usr/share/syslinux/mbr.bin") ? "/usr/share/syslinux/mbr.bin" : "/usr/lib/syslinux/mbr.bin");
3457 if (QFile::exists("/usr/lib/syslinux/mbr/mbr.bin"))
3458 srcF.setFileName("/usr/lib/syslinux/mbr/mbr.bin");
3459 }
3460 else if (srcfName == "ubnsylnx")
3461 srcF.setFileName("/usr/bin/syslinux");
3462 // else
3463 // srcF.setFileName(QString("/usr/lib/unetbootin/%1").arg(srcfName));
3464 #endif
3465 if (!srcF.exists())
3466 {
3467 return;
3468 }
3469 if (QFile::exists(dstfName))
3470 {
3471 if (!overwritefileprompt(dstfName))
3472 return;
3473 }
3474 QFile dstF(dstfName);
3475 dstF.open(QIODevice::WriteOnly);
3476 srcF.open(QIODevice::ReadOnly);
3477 dstF.write(srcF.readAll());
3478 dstF.close();
3479 srcF.close();
3480 }
3481
instTempfl(QString srcfName,QString dstfType)3482 QString unetbootin::instTempfl(QString srcfName, QString dstfType)
3483 {
3484 QString dstfName = randtmpfile::getrandfilename(ubntmpf, dstfType);
3485 instIndvfl(srcfName, dstfName);
3486 return dstfName;
3487 }
3488
runinst()3489 void unetbootin::runinst()
3490 {
3491 this->trcurrent = tr("(Current)");
3492 this->trdone = tr("(Done)");
3493 firstlayer->setEnabled(false);
3494 firstlayer->hide();
3495 secondlayer->setEnabled(true);
3496 secondlayer->show();
3497 rebootlayer->setEnabled(false);
3498 rebootlayer->hide();
3499 progresslayer->setEnabled(true);
3500 progresslayer->show();
3501 sdesc1->setText(QString("<b>%1 %2</b>").arg(sdesc1->text()).arg(trcurrent));
3502 tprogress->setValue(0);
3503 installType = typeselect->currentText();
3504 targetDrive = driveselect->currentText();
3505 persistenceSpaceMB = this->persistencevalue->value();
3506 QString ginstallDir;
3507 QString installDir;
3508 QString isotmpf = randtmpfile::getrandfilename(ubntmpf, "iso");
3509 #ifdef Q_OS_WIN32
3510 if (installType == tr("Hard Disk"))
3511 {
3512 ginstallDir = "unetbtin/";
3513 }
3514 if (installType == tr("USB Drive"))
3515 {
3516 ginstallDir = "";
3517 }
3518 installDir = ginstallDir;
3519 targetDev = QString("%1").arg(targetDrive).remove("\\");
3520 rawtargetDev = targetDev;
3521 #endif
3522 #ifdef Q_OS_UNIX
3523 if (installType == tr("Hard Disk"))
3524 {
3525 QString devnboot = locatedevicenode("/boot");
3526 if (devnboot == "NOT FOUND")
3527 {
3528 ginstallDir = "boot/";
3529 installDir = ginstallDir;
3530 targetDev = locatedevicenode("/");
3531 }
3532 else
3533 {
3534 ginstallDir = "";
3535 installDir = "boot/";
3536 targetDev = devnboot;
3537 }
3538 devluid = getdevluid(targetDev);
3539 }
3540 if (installType == tr("USB Drive"))
3541 {
3542 #ifdef Q_OS_LINUX
3543 targetDev = driveselect->currentText();
3544 devluid = getdevluid(targetDev);
3545 ginstallDir = "";
3546 installDir = ginstallDir;
3547 targetDrive = QString("%1/").arg(locatemountpoint(targetDev));
3548 #endif
3549 #ifdef Q_OS_FREEBSD
3550 QStringList driveinfo = driveselect->currentText().split(":");
3551 if (driveinfo.size() < 2) {
3552 QTextStream out(stdout);
3553 out << "/!\\ Target drive must be passed as "
3554 "<device-name>:<mount-point>" << endl << flush;
3555 QApplication::exit();
3556 exit(1);
3557 }
3558 targetDev = driveinfo.at(0);
3559 installDir = ginstallDir = "";
3560 targetDrive = QString("%1/").arg(driveinfo.at(1));
3561 #endif
3562 }
3563 #ifdef Q_OS_LINUX
3564 if (targetDev.contains(QRegExp("p\\d$")))
3565 rawtargetDev = QString(targetDev).remove(QRegExp("p\\d$"));
3566 else
3567 rawtargetDev = QString(targetDev).remove(QRegExp("\\d$"));
3568 #endif
3569 #ifdef Q_OS_UNIX
3570 rawtargetDev = QString(targetDev).remove(QRegExp("s\\d$"));
3571 #endif
3572 #endif
3573 #ifndef Q_OS_UNIX
3574 devluid = getdevluid(targetDev);
3575 #endif
3576 kernelLine = "kernel";
3577 kernelLoc = QString("/%1ubnkern").arg(ginstallDir);
3578 initrdLine = "initrd";
3579 slinitrdLine = "initrd=";
3580 initrdLoc = QString("/%1ubninit").arg(ginstallDir);
3581 #ifdef NOINITRD
3582 initrdLoc = "";
3583 initrdOpts = "";
3584 initrdLine = "";
3585 slinitrdLine = "";
3586 #endif
3587 #ifdef NODEFAULTKERNEL
3588 kernelLoc = "";
3589 #endif
3590 targetPath = QDir::toNativeSeparators(QString("%1%2").arg(targetDrive).arg(installDir));
3591 QDir dir;
3592 if (!dir.exists(targetPath))
3593 {
3594 dir.mkpath(targetPath);
3595 }
3596 if (QFile::exists(QString("%1ubnkern").arg(targetPath)))
3597 {
3598 overwritefileprompt(QString("%1ubnkern").arg(targetPath));
3599 }
3600 if (QFile::exists(QString("%1ubninit").arg(targetPath)))
3601 {
3602 overwritefileprompt(QString("%1ubninit").arg(targetPath));
3603 }
3604 if (radioFloppy->isChecked())
3605 {
3606 if (diskimagetypeselect->currentIndex() == diskimagetypeselect->findText(tr("Floppy")))
3607 {
3608 instIndvfl("memdisk", QString("%1ubnkern").arg(targetPath));
3609 if (!FloppyPath->text().startsWith("http://") && !FloppyPath->text().startsWith("ftp://"))
3610 QFile::copy(FloppyPath->text(), QString("%1ubninit").arg(targetPath));
3611 else
3612 downloadfile(FloppyPath->text(), QString("%1ubninit").arg(targetPath));
3613 }
3614 if (diskimagetypeselect->currentIndex() == diskimagetypeselect->findText(tr("ISO")))
3615 {
3616 if (!FloppyPath->text().startsWith("http://") && !FloppyPath->text().startsWith("ftp://"))
3617 extractiso(FloppyPath->text());
3618 else
3619 {
3620 downloadfile(FloppyPath->text(), isotmpf);
3621 extractiso(isotmpf);
3622 }
3623 if (QFile::exists(QString("%1sevnz.exe").arg(ubntmpf)))
3624 {
3625 rmFile(QString("%1sevnz.exe").arg(ubntmpf));
3626 }
3627 if (QFile::exists(QString("%1\\7z.dll").arg(ubntmpf)))
3628 {
3629 rmFile(QString("%1\\7z.dll").arg(ubntmpf));
3630 }
3631 }
3632 }
3633 else if (radioManual->isChecked())
3634 {
3635 if (!KernelPath->text().startsWith("http://") && !KernelPath->text().startsWith("ftp://"))
3636 QFile::copy(KernelPath->text(), QString("%1ubnkern").arg(targetPath));
3637 else
3638 downloadfile(KernelPath->text(), QString("%1ubnkern").arg(targetPath));
3639 if (!InitrdPath->text().startsWith("http://") && !InitrdPath->text().startsWith("ftp://"))
3640 QFile::copy(InitrdPath->text(), QString("%1ubninit").arg(targetPath));
3641 else
3642 downloadfile(InitrdPath->text(), QString("%1ubninit").arg(targetPath));
3643 kernelOpts = OptionEnter->text();
3644 }
3645 else if (radioDistro->isChecked())
3646 {
3647 nameDistro = distroselect->currentText();
3648 nameVersion = dverselect->currentText();
3649 if (nameVersion.contains("_Live"))
3650 {
3651 nameVersion.remove("_Live");
3652 islivecd = true;
3653 }
3654 else
3655 {
3656 islivecd = false;
3657 }
3658 if (nameVersion.contains("_NetInstall"))
3659 {
3660 nameVersion.remove("_NetInstall");
3661 isnetinstall = true;
3662 }
3663 if (nameVersion.contains("_HdMedia"))
3664 {
3665 nameVersion.remove("_HdMedia");
3666 ishdmedia = true;
3667 }
3668 if (nameVersion.contains("_x64"))
3669 {
3670 nameVersion.remove("_x64");
3671 isarch64 = true;
3672 }
3673 else
3674 {
3675 isarch64 = false;
3676 }
3677 QString cpuarch;
3678 QString relname = nameVersion.toLower();
3679 #include "customdistrolst.cpp"
3680 if (QFile::exists(QString("%1sevnz.exe").arg(ubntmpf)))
3681 {
3682 rmFile(QString("%1sevnz.exe").arg(ubntmpf));
3683 }
3684 if (QFile::exists(QString("%1\\7z.dll").arg(ubntmpf)))
3685 {
3686 rmFile(QString("%1\\7z.dll").arg(ubntmpf));
3687 }
3688 if (downloadFailed)
3689 {
3690 return;
3691 }
3692 }
3693 if (!sdesc1->text().contains(trdone))
3694 {
3695 sdesc1->setText(QString(sdesc1->text()).remove("<b>").replace(trcurrent+"</b>", trdone));
3696 }
3697 if (sdesc2->text().contains(trcurrent))
3698 {
3699 sdesc2->setText(QString(sdesc2->text()).remove("<b>").replace(trcurrent+"</b>", trdone));
3700 }
3701 else
3702 {
3703 sdesc2->setText(QString("%1 %2").arg(sdesc2->text()).arg(trdone));
3704 }
3705 sdesc3->setText(QString("<b>%1 %2</b>").arg(sdesc3->text()).arg(trcurrent));
3706 tprogress->setValue(0);
3707 if (this->persistenceSpaceMB > 0 && !issalt)
3708 {
3709 this->kernelOpts += " persistent";
3710 for (int i = 0; i < this->extraoptionsPL.second.second.size(); ++i)
3711 {
3712 this->extraoptionsPL.second.second[i] += " persistent";
3713 }
3714 }
3715 instDetType();
3716 }
3717
instDetType()3718 void unetbootin::instDetType()
3719 {
3720 if (installType == tr("Hard Disk"))
3721 {
3722 runinsthdd();
3723 }
3724 if (installType == tr("USB Drive"))
3725 {
3726 runinstusb();
3727 }
3728 }
3729
3730 #ifdef Q_OS_UNIX
3731
writegrub2cfg()3732 void unetbootin::writegrub2cfg()
3733 {
3734 QFile menulst;
3735 menulst.setFileName("/boot/grub/grub.cfg");
3736 if (QFile::exists(QString("%1.bak").arg(menulst.fileName())))
3737 rmFile(QString("%1.bak").arg(menulst.fileName()));
3738 QFile::copy(menulst.fileName(), QString("%1.bak").arg(menulst.fileName()));
3739 QFile bkmenulst(QString("%1.bak").arg(menulst.fileName()));
3740 bkmenulst.open(QIODevice::ReadOnly | QIODevice::Text);
3741 QTextStream bkmenulstout(&bkmenulst);
3742 menulst.open(QIODevice::WriteOnly | QIODevice::Text);
3743 QTextStream menulstout(&menulst);
3744 QRegExp mlstchkistimeout("\\s{0,}set\\s{1,}timeout=\\d{1,}.{0,}", Qt::CaseInsensitive);
3745 QStringList ecurmenulstTextL;
3746 bool mlstmustreplacetimeout = true;
3747 QString menulstCurLine;
3748 while (!bkmenulstout.atEnd())
3749 {
3750 menulstCurLine = bkmenulstout.readLine();
3751 if (mlstmustreplacetimeout && mlstchkistimeout.exactMatch(menulstCurLine))
3752 {
3753 ecurmenulstTextL.append("set timeout=15");
3754 mlstmustreplacetimeout = false;
3755 }
3756 else
3757 {
3758 ecurmenulstTextL.append(menulstCurLine);
3759 }
3760 }
3761 QString ecurmenulstText = ecurmenulstTextL.join("\n");
3762 QString menulstxt = QString(
3763 "%9\n\n"
3764 #ifndef NODEFAULTBOOT
3765 "\nmenuentry \"" UNETBOOTINB"\" {\n"
3766 "\tset root=%8\n"
3767 "\t%1 %2 %3 %4\n"
3768 "\t%5 %6 %7\n"
3769 "}\n"
3770 #endif
3771 ).arg(kernelLine.replace("kernel", "linux")).arg(kernelParam).arg(kernelLoc).arg(kernelOpts).arg(initrdLine).arg(initrdLoc).arg(initrdOpts)
3772 .arg(getGrub2Notation(targetDev)).arg(ecurmenulstText)
3773 ;
3774 if (!extraoptionsPL.first.first.isEmpty())
3775 {
3776 for (int i = 0; i < extraoptionsPL.first.first.size(); ++i)
3777 {
3778 menulstxt.append(QString("\nmenuentry \"%1\" {\n"
3779 "\tset root=%5\n"
3780 "\tlinux %2 %4\n"
3781 "\tinitrd %3\n"
3782 "}\n").arg(QString(extraoptionsPL.second.first.at(i)).remove("^")).arg(extraoptionsPL.first.first.at(i)).arg(extraoptionsPL.first.second.at(i)).arg(extraoptionsPL.second.second.at(i))
3783 .arg(getGrubNotation(targetDev))
3784 );
3785 }
3786 }
3787 menulstout << menulstxt << endl;
3788 menulst.close();
3789 }
3790
3791 #endif
3792
runinsthdd()3793 void unetbootin::runinsthdd()
3794 {
3795 this->tprogress->setValue(this->tprogress->maximum()/3);
3796 #ifdef Q_OS_UNIX
3797 if (QFile::exists("/boot/grub/grub.cfg")) // has grub2
3798 {
3799 pdesc1->setText(tr("Configuring grub2 on %1").arg(targetDev));
3800 writegrub2cfg();
3801 if (!QFile::exists("/boot/grub/menu.lst")) // grub2-only
3802 {
3803 QSettings install(QSettings::SystemScope, "UNetbootin");
3804 install.setValue("Location", "/");
3805 fininstall();
3806 return;
3807 }
3808 }
3809 #endif
3810 #ifdef Q_OS_WIN32
3811 pdesc1->setText(tr("Configuring grldr on %1").arg(targetDev));
3812 if (QFile::exists(QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive))))
3813 {
3814 rmFile(QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive)));
3815 }
3816 QFile::copy(appLoc, QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive)));
3817 QFile::setPermissions(QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive)), QFile::ReadOther|QFile::WriteOther|QFile::ExeOther);
3818 if (QFile::exists(QDir::toNativeSeparators(QString("%1ubnldr").arg(targetDrive))))
3819 {
3820 overwritefileprompt(QDir::toNativeSeparators(QString("%1ubnldr").arg(targetDrive)));
3821 }
3822 instIndvfl("ubnldr", QString("%1ubnldr").arg(targetDrive));
3823 if (QFile::exists(QDir::toNativeSeparators(QString("%1ubnldr.mbr").arg(targetDrive))))
3824 {
3825 overwritefileprompt(QDir::toNativeSeparators(QString("%1ubnldr.mbr").arg(targetDrive)));
3826 }
3827 instIndvfl("ubnldr.mbr", QString("%1ubnldr.mbr").arg(targetDrive));
3828 if (QFile::exists(QDir::toNativeSeparators(QString("%1ubnldr.exe").arg(targetDrive))))
3829 {
3830 overwritefileprompt(QDir::toNativeSeparators(QString("%1ubnldr.exe").arg(targetDrive)));
3831 }
3832 instIndvfl("ubnldr.exe", QString("%1ubnldr.exe").arg(targetDrive));
3833 #endif
3834 QFile menulst;
3835 #ifdef Q_OS_WIN32
3836 menulst.setFileName(QString("%1menu.lst").arg(targetPath));
3837 #endif
3838 #ifdef Q_OS_UNIX
3839 pdesc1->setText(tr("Configuring grub on %1").arg(targetDev));
3840 menulst.setFileName("/boot/grub/menu.lst");
3841 if (QFile::exists(QString("%1.bak").arg(menulst.fileName())))
3842 rmFile(QString("%1.bak").arg(menulst.fileName()));
3843 QFile::copy(menulst.fileName(), QString("%1.bak").arg(menulst.fileName()));
3844 QFile bkmenulst(QString("%1.bak").arg(menulst.fileName()));
3845 bkmenulst.open(QIODevice::ReadOnly | QIODevice::Text);
3846 QTextStream bkmenulstout(&bkmenulst);
3847 #endif
3848 menulst.open(QIODevice::WriteOnly | QIODevice::Text);
3849 QTextStream menulstout(&menulst);
3850 #ifdef Q_OS_UNIX
3851 QRegExp mlstchkistimeout("\\s{0,}timeout\\s{1,}\\d{1,}.{0,}", Qt::CaseInsensitive);
3852 QRegExp mlstchkishiddenmenu("\\s{0,}hiddenmenu.{0,}", Qt::CaseInsensitive);
3853 QStringList ecurmenulstTextL;
3854 bool mlstmustreplacetimeout = true;
3855 bool mlstmustreplacehiddenmenu = true;
3856 QString menulstCurLine;
3857 while (!bkmenulstout.atEnd())
3858 {
3859 menulstCurLine = bkmenulstout.readLine();
3860 if (mlstmustreplacehiddenmenu && mlstchkishiddenmenu.exactMatch(menulstCurLine))
3861 {
3862 ecurmenulstTextL.append("#hiddenmenu");
3863 mlstmustreplacehiddenmenu = false;
3864 }
3865 else if (mlstmustreplacetimeout && mlstchkistimeout.exactMatch(menulstCurLine))
3866 {
3867 ecurmenulstTextL.append("timeout\t\t15");
3868 mlstmustreplacetimeout = false;
3869 }
3870 else
3871 {
3872 ecurmenulstTextL.append(menulstCurLine);
3873 }
3874 }
3875 QString ecurmenulstText = ecurmenulstTextL.join("\n");
3876 #endif
3877 QString menulstxt = QString(
3878 #ifdef Q_OS_UNIX
3879 "%9\n\n"
3880 #endif
3881 #ifdef Q_OS_WIN32
3882 "default 0\n"
3883 "timeout 10\n"
3884 #endif
3885 #ifndef NODEFAULTBOOT
3886 "\ntitle " UNETBOOTINB"\n"
3887 #ifdef Q_OS_WIN32
3888 "find --set-root %3\n"
3889 #endif
3890 #ifdef Q_OS_UNIX
3891 "root %8\n"
3892 #endif
3893 "%1 %2 %3 %4\n"
3894 "%5 %6 %7\n"
3895 "boot\n"
3896 #endif
3897 ).arg(kernelLine).arg(kernelParam).arg(kernelLoc).arg(kernelOpts).arg(initrdLine).arg(initrdLoc).arg(initrdOpts)
3898
3899 #ifdef Q_OS_UNIX
3900 .arg(getGrubNotation(targetDev)).arg(ecurmenulstText)
3901 #endif
3902 ;
3903 if (!extraoptionsPL.first.first.isEmpty())
3904 {
3905 for (int i = 0; i < extraoptionsPL.first.first.size(); ++i)
3906 {
3907 menulstxt.append(QString("\ntitle %1\n"
3908 #ifdef Q_OS_WIN32
3909 "find --set-root %2\n"
3910 #endif
3911 #ifdef Q_OS_UNIX
3912 "root %5\n"
3913 #endif
3914 "kernel %2 %4\n"
3915 "initrd %3\n"
3916 "boot\n").arg(QString(extraoptionsPL.second.first.at(i)).remove("^")).arg(extraoptionsPL.first.first.at(i)).arg(extraoptionsPL.first.second.at(i)).arg(extraoptionsPL.second.second.at(i))
3917 #ifdef Q_OS_UNIX
3918 .arg(getGrubNotation(targetDev))
3919 #endif
3920 );
3921 }
3922 }
3923 menulstout << menulstxt << endl;
3924 menulst.close();
3925 #ifdef Q_OS_WIN32
3926 QSettings install("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
3927 install.setValue("Location", targetDrive);
3928 install.setValue("DisplayName", "UNetbootin");
3929 install.setValue("UninstallString", QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive)));
3930 //QSettings runonce("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", QSettings::NativeFormat);
3931 //runonce.setValue("UNetbootin Uninstaller", QDir::toNativeSeparators(QString("%1unetbtin.exe").arg(targetDrive)));
3932 if (QSysInfo::WindowsVersion == QSysInfo::WV_32s || QSysInfo::WindowsVersion == QSysInfo::WV_95 || QSysInfo::WindowsVersion == QSysInfo::WV_98 || QSysInfo::WindowsVersion == QSysInfo::WV_Me)
3933 {
3934 configsysEdit();
3935 }
3936 else if (QSysInfo::WindowsVersion == QSysInfo::WV_NT || QSysInfo::WindowsVersion == QSysInfo::WV_2000 || QSysInfo::WindowsVersion == QSysInfo::WV_XP || QSysInfo::WindowsVersion == QSysInfo::WV_2003 )
3937 {
3938 bootiniEdit();
3939 }
3940 else if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA) //|| QSysInfo::WindowsVersion == QSysInfo::WV_WINDOWS7) // TODO when upgrading to latest Qt
3941 {
3942 vistabcdEdit();
3943 }
3944 else
3945 {
3946 configsysEdit();
3947 bootiniEdit();
3948 vistabcdEdit();
3949 }
3950 #endif
3951 #ifdef Q_OS_UNIX
3952 QSettings install(QSettings::SystemScope, "UNetbootin");
3953 install.setValue("Location", "/");
3954 #endif
3955 fininstall();
3956 }
3957
rmFile(QFile & fn)3958 void unetbootin::rmFile(QFile &fn)
3959 {
3960 if (!fn.exists()) return;
3961 fn.setPermissions(QFile::WriteUser);
3962 fn.remove();
3963 #ifdef Q_OS_UNIX
3964 callexternapp("sync", "");
3965 #endif
3966 }
3967
rmFile(const QString & fn)3968 void unetbootin::rmFile(const QString &fn)
3969 {
3970 if (!QFile::exists(fn)) return;
3971 QFile::setPermissions(fn, QFile::WriteUser);
3972 QFile::remove(fn);
3973 #ifdef Q_OS_UNIX
3974 callexternapp("sync", "");
3975 #endif
3976 }
3977
mvFile(QFile & fn,QFile & outfn)3978 void unetbootin::mvFile(QFile &fn, QFile &outfn)
3979 {
3980 rmFile(outfn);
3981 fn.rename(outfn.fileName());
3982 #ifdef Q_OS_UNIX
3983 callexternapp("sync", "");
3984 #endif
3985 }
3986
mvFile(const QString & fn,const QString & outfn)3987 void unetbootin::mvFile(const QString &fn, const QString &outfn)
3988 {
3989 rmFile(outfn);
3990 QFile::rename(fn, outfn);
3991 #ifdef Q_OS_UNIX
3992 callexternapp("sync", "");
3993 #endif
3994 }
3995
replaceTextInFile(QString repfilepath,QRegExp replaceme,QString replacewith)3996 void unetbootin::replaceTextInFile(QString repfilepath, QRegExp replaceme, QString replacewith)
3997 {
3998 QFile repfileF(repfilepath);
3999 randtmpfile nrepfileF(QFileInfo(repfilepath).canonicalPath(), "cfg");
4000 QString nrepfilepath = QFileInfo(nrepfileF).canonicalFilePath();
4001 repfileF.open(QIODevice::ReadOnly | QIODevice::Text);
4002 nrepfileF.open(QIODevice::WriteOnly | QIODevice::Text);
4003 QTextStream repfileTS(&repfileF);
4004 QTextStream nrepfileTS(&nrepfileF);
4005 while (!repfileTS.atEnd())
4006 {
4007 nrepfileTS << repfileTS.readLine().replace(replaceme, replacewith) << "\n";
4008 }
4009 repfileF.close();
4010 rmFile(repfilepath);
4011 nrepfileF.rename(repfilepath);
4012 nrepfileF.close();
4013 //mvFile(nrepfilepath, repfilepath);
4014 }
4015
setLabel(QString devname,QString newlabel)4016 void unetbootin::setLabel(QString devname, QString newlabel)
4017 {
4018 #ifdef Q_OS_LINUX
4019 if (isext2)
4020 {
4021 callexternapp(e2labelcommand, devname+" "+newlabel);
4022 }
4023 else
4024 {
4025 callexternapp(mlabelcommand, "-i "+devname+" ::"+newlabel);
4026 }
4027 #endif
4028 #ifdef Q_OS_MAC
4029 callexternapp("diskutil", "rename "+devname+" "+newlabel);
4030 #endif
4031 #ifdef Q_OS_WIN32
4032 callexternapp("label", devname+" "+newlabel);
4033 #endif
4034 this->devlabel = QString(newlabel);
4035 if (this->devluid.startsWith("LABEL="))
4036 this->devluid = "LABEL="+newlabel;
4037 #ifdef Q_OS_MAC
4038 this->targetPath = this->locatemountpoint(devname) + "/";
4039 this->targetDrive = this->targetPath;
4040 #endif
4041 }
4042
fixkernelbootoptions(const QString & cfgfileCL)4043 QString unetbootin::fixkernelbootoptions(const QString &cfgfileCL)
4044 {
4045 if (cfgfileCL.contains("archisolabel=") && (this->devlabel == "" || this->devlabel == "None"))
4046 {
4047 this->devlabel = this->getlabel(this->targetDev);
4048 if (this->installType == tr("USB Drive") && (this->devlabel == "" || this->devlabel == "None"))
4049 {
4050 QString isolabelopt = QString(cfgfileCL).trimmed();
4051 int startIdx = isolabelopt.indexOf("archisolabel=");
4052 if (startIdx >= 0)
4053 {
4054 isolabelopt = isolabelopt.right(isolabelopt.size() - startIdx - QString("archisolabel=").size()).trimmed();
4055 int endIdx = isolabelopt.indexOf(" ");
4056 if (endIdx > 0)
4057 {
4058 isolabelopt = isolabelopt.left(endIdx);
4059 setLabel(this->targetDev, isolabelopt);
4060 }
4061 }
4062 }
4063 }
4064 if ((this->devlabel == "" || this->devlabel == "None") && devluid.contains("LABEL") && (cfgfileCL.contains(QRegExp("root=\\S{0,}LABEL=\\S{0,}")) || cfgfileCL.contains(QRegExp("root=\\S{0,}CDLABEL=\\S{0,}"))))
4065 {
4066 setLabel(this->targetDev, "LIVE");
4067 }
4068 QString ncfgfileCL = cfgfileCL;
4069 if (ncfgfileCL.contains("root=live:CDLABEL"))
4070 {
4071 ncfgfileCL = QString(ncfgfileCL)
4072 .replace(QRegExp("root=\\S{0,}LABEL=\\S{0,}"), QString("root=live:%1").arg(devluid))
4073 .replace(QRegExp("root=\\S{0,}CDLABEL=\\S{0,}"), QString("root=live:%1").arg(devluid));
4074 }
4075 else
4076 {
4077 ncfgfileCL = QString(ncfgfileCL)
4078 .replace(QRegExp("root=\\S{0,}LABEL=\\S{0,}"), QString("root=%1").arg(devluid))
4079 .replace(QRegExp("root=\\S{0,}CDLABEL=\\S{0,}"), QString("root=%1").arg(devluid));
4080 }
4081 return QString(ncfgfileCL)
4082 .replace("rootfstype=iso9660", "rootfstype=auto")
4083 .replace("theme:sabayon", "theme:sabayon cdroot_type=vfat")
4084 .replace("pmedia=cd", "pmedia=usbflash")
4085 .replace(QRegExp("archisolabel=\\S{0,}"), QString("archisolabel=%1").arg(devlabel))
4086 .trimmed();
4087 }
4088
logText(const QString & text)4089 void unetbootin::logText(const QString &text)
4090 {
4091 return;
4092 /*
4093 if (targetPath.isNull() || targetPath.isEmpty())
4094 {
4095 loggedLinesNotYetWritten.append(text);
4096 return;
4097 }
4098 if (logStream == 0)
4099 {
4100 logFile = new QFile(QString("%1unetbootin-log.txt").arg(targetPath));
4101 logFile->open(QIODevice::WriteOnly | QIODevice::Text);
4102 logStream = new QTextStream(logFile);
4103 for (int i = 0; i < loggedLinesNotYetWritten.size(); ++i)
4104 {
4105 *logStream << loggedLinesNotYetWritten.at(i) << endl;
4106 }
4107 loggedLinesNotYetWritten.clear();
4108 }
4109 *logStream << text << endl;
4110 */
4111 }
4112
finishLogging()4113 void unetbootin::finishLogging()
4114 {
4115 if (logFile != 0)
4116 {
4117 logFile->close();
4118 }
4119 }
4120
writeTextToFile(const QString & text,const QString & filePath)4121 void unetbootin::writeTextToFile(const QString &text, const QString &filePath)
4122 {
4123 QFile syslinuxcfg(filePath);
4124 if (syslinuxcfg.exists())
4125 {
4126 rmFile(syslinuxcfg);
4127 }
4128 syslinuxcfg.open(QIODevice::WriteOnly | QIODevice::Text);
4129 QTextStream syslinuxcfgout(&syslinuxcfg);
4130 syslinuxcfgout << text << endl;
4131 syslinuxcfg.close();
4132 }
4133
runinstusb()4134 void unetbootin::runinstusb()
4135 {
4136 this->tprogress->setValue(this->tprogress->maximum()/3);
4137 pdesc1->setText(tr("Installing syslinux to %1").arg(targetDev));
4138 #ifdef Q_OS_WIN32
4139 QString sysltfloc = instTempfl("syslinux.exe", "exe");
4140 callexternapp(sysltfloc, QString("-ma %1").arg(targetDev));
4141 rmFile(sysltfloc);
4142 #endif
4143 #ifdef STATICLINUX
4144 if (QFile::exists(syslinuxcommand))
4145 rmFile(syslinuxcommand);
4146 instIndvfl("ubnsylnx", syslinuxcommand);
4147 QFile::setPermissions(syslinuxcommand, QFile::ReadOwner|QFile::ExeOwner|QFile::ReadGroup|QFile::ExeGroup|QFile::ReadOther|QFile::ExeOther|QFile::WriteOwner);
4148 // chmod(syslinuxcommand, S_IRUSR|S_IRGRP|S_IROTH|S_IRWXU);
4149 if (QFile::exists(extlinuxcommand))
4150 rmFile(extlinuxcommand);
4151 instIndvfl("ubnexlnx", extlinuxcommand);
4152 QFile::setPermissions(extlinuxcommand, QFile::ReadOwner|QFile::ExeOwner|QFile::ReadGroup|QFile::ExeGroup|QFile::ReadOther|QFile::ExeOther|QFile::WriteOwner);
4153 #endif
4154 #ifdef Q_OS_LINUX
4155 isext2 = false;
4156 if (!volidcommand.isEmpty())
4157 {
4158 if (callexternapp(volidcommand, QString("-t %2").arg(targetDev)).contains(QRegExp("(ext2|ext3|ext4)")))
4159 isext2 = true;
4160 }
4161 else
4162 {
4163 QString tstrblk = callexternapp(blkidcommand, QString("-s TYPE %2").arg(targetDev));
4164 if (tstrblk.contains('='))
4165 {
4166 if (tstrblk.contains(QRegExp("(ext2|ext3|ext4)")))
4167 isext2 = true;
4168 }
4169 }
4170 if (isext2)
4171 {
4172 pdesc1->setText(tr("Installing extlinux to %1").arg(targetDev));
4173 callexternapp(extlinuxcommand, QString("-i \"%1\"").arg(targetPath));
4174 }
4175 else
4176 callexternapp(syslinuxcommand, targetDev);
4177 if (rawtargetDev != targetDev)
4178 {
4179 // make active
4180 if (sfdiskcommand != "") {
4181 // use sfdisk if available
4182 callexternapp(sfdiskcommand, QString("%1 -A %2").arg(rawtargetDev, QString(targetDev).remove(rawtargetDev).remove("p")));
4183 } else {
4184 // use fdisk if sfdisk is unavailable
4185 bool isOk = false;
4186 int partitionNumber = QString(targetDev).remove(rawtargetDev).remove("p").toInt(&isOk, 10);
4187 if (isOk)
4188 {
4189 QString output = callexternapp("fdisk", "-l");
4190 QStringList outputL = output.split('\n');
4191 outputL = outputL.filter(targetDev);
4192 if (outputL.size() > 0)
4193 {
4194 outputL = outputL.filter("*");
4195 bool isActive = outputL.size() > 0;
4196 if (!isActive)
4197 {
4198 QString fdiskWriteToStdin = "a\n";
4199 fdiskWriteToStdin += (QString::number(partitionNumber) + "\n");
4200 fdiskWriteToStdin += "w\n";
4201 callexternappWriteToStdin("fdisk", rawtargetDev, fdiskWriteToStdin);
4202 }
4203 }
4204 }
4205 }
4206 QFile usbmbrF(rawtargetDev);
4207 QFile mbrbinF(":/mbr.bin");
4208 #ifdef NOSTATIC
4209 mbrbinF.setFileName(QFile::exists("/usr/share/syslinux/mbr.bin") ? "/usr/share/syslinux/mbr.bin" : "/usr/lib/syslinux/mbr.bin");
4210 if (QFile::exists("/usr/lib/syslinux/mbr/mbr.bin"))
4211 mbrbinF.setFileName("/usr/lib/syslinux/mbr/mbr.bin");
4212 #endif
4213 usbmbrF.open(QIODevice::WriteOnly);
4214 mbrbinF.open(QIODevice::ReadOnly);
4215 usbmbrF.write(mbrbinF.readAll());
4216 mbrbinF.close();
4217 usbmbrF.close();
4218 }
4219 #endif
4220 #ifdef Q_OS_MAC
4221 callexternapp("sync", "");
4222 callexternapp("diskutil", "umount "+targetDev);
4223 callexternapp("sync", "");
4224 callexternapp("hdiutil", "unmount "+targetDev);
4225 callexternapp("sync", "");
4226 callexternapp(resourceDir.absoluteFilePath("mkbootable"), targetDev);
4227 /*
4228 callexternapp("sync", "");
4229 callexternapp("diskutil", "umount "+targetDev);
4230 callexternapp("sync", "");
4231 callexternapp("hdiutil", "unmount "+targetDev);
4232 callexternapp("sync", "");
4233 QFile usbmbrF(rawtargetDev);
4234 QFile mbrbinF(resourceDir.absoluteFilePath("mbr.bin"));
4235 usbmbrF.open(QIODevice::WriteOnly);
4236 mbrbinF.open(QIODevice::ReadOnly);
4237 usbmbrF.write(mbrbinF.readAll());
4238 mbrbinF.close();
4239 usbmbrF.close();
4240 */
4241 callexternapp("sync", "");
4242 callexternapp("diskutil", "mount "+targetDev);
4243 callexternapp("sync", "");
4244 #endif
4245 #ifndef XPUD
4246 if (!dontgeneratesyslinuxcfg)
4247 {
4248 QString syslinuxcfgtxt = QString("default menu.c32\n"
4249 "prompt 0\n"
4250 "menu title UNetbootin\n"
4251 "timeout 100\n\n"
4252 #ifndef NODEFAULTBOOT
4253 "label unetbootindefault\n"
4254 "menu label Default\n"
4255 "kernel %1\n"
4256 "append %4%2 %3\n"
4257 #endif
4258 ).arg(kernelLoc, initrdLoc, kernelOpts, slinitrdLine);
4259
4260 if (!extraoptionsPL.first.first.isEmpty())
4261 {
4262 for (int i = 0; i < extraoptionsPL.first.first.size(); ++i)
4263 {
4264 syslinuxcfgtxt.append(QString("\nlabel %5\n"
4265 "menu label %1\n"
4266 "kernel %2\n"
4267 "append %6%3 %4\n").arg(extraoptionsPL.second.first.at(i)).arg(extraoptionsPL.first.first.at(i)).arg(extraoptionsPL.first.second.at(i)).arg(extraoptionsPL.second.second.at(i)).arg(QString("ubnentry%1").arg(i)).arg(slinitrdLine));
4268 }
4269 }
4270 writeTextToFile(syslinuxcfgtxt, QString("%1syslinux.cfg").arg(targetPath));
4271 }
4272 else
4273 {
4274 for (int j = 0; j < locatedsyslinuxcfgfiles.size(); ++j)
4275 {
4276 QString syslpathloc = QFileInfo(locatedsyslinuxcfgfiles.at(j)).path();
4277 if (syslpathloc == ".") syslpathloc = "";
4278 if (syslpathloc.contains(QDir::toNativeSeparators("/")))
4279 {
4280 if (!syslpathloc.endsWith(QDir::toNativeSeparators("/")))
4281 syslpathloc.append(QDir::toNativeSeparators("/"));
4282 }
4283 else
4284 {
4285 if (!syslpathloc.endsWith("/"))
4286 syslpathloc.append("/");
4287 }
4288 QString abssyslpathloc = QDir::fromNativeSeparators(QString(syslpathloc));
4289 if (!abssyslpathloc.startsWith("/"))
4290 abssyslpathloc.prepend("/");
4291 instIndvfl("menu.c32", QString("%1%2menu.c32").arg(targetPath).arg(syslpathloc));
4292 instIndvfl("libutil.c32", QString("%1%2libutil.c32").arg(targetPath).arg(syslpathloc));
4293 instIndvfl("libcom32.c32", QString("%1%2libcom32.c32").arg(targetPath).arg(syslpathloc));
4294 QString syslrealcfgloc = QString(locatedsyslinuxcfgfiles.at(j)).replace("isolinux.cfg", "syslinux.cfg").replace("extlinux.conf", "syslinux.cfg");
4295 if (syslrealcfgloc != locatedsyslinuxcfgfiles.at(j))
4296 {
4297 QFile::copy(QString("%1%2").arg(targetPath).arg(locatedsyslinuxcfgfiles.at(j)), QString("%1%2").arg(targetPath).arg(syslrealcfgloc));
4298 }
4299 replaceTextInFile(QString("%1%2").arg(targetPath).arg(syslrealcfgloc), QRegExp("\\S{0,}vesamenu.c32"), QString("%1menu.c32").arg(abssyslpathloc));
4300 #ifdef Q_OS_UNIX
4301 if (isext2)
4302 {
4303 QFile::copy(QString("%1%2").arg(targetPath).arg(locatedsyslinuxcfgfiles.at(j)), QString("%1%2extlinux.conf").arg(targetPath).arg(syslpathloc));
4304 QString extlpathloc = QString(syslpathloc).replace("syslinux", "extlinux");
4305 if (syslpathloc != extlpathloc)
4306 callexternapp("ln", QString("-s %1 %2").arg(syslpathloc).arg(extlpathloc));
4307 }
4308 #endif
4309 }
4310 }
4311 #endif
4312 #ifdef Q_OS_UNIX
4313 if (!dontgeneratesyslinuxcfg && isext2)
4314 QFile::copy(QString("%1syslinux.cfg").arg(targetPath), QString("%1extlinux.conf").arg(targetPath));
4315 #endif
4316 if (!dontgeneratesyslinuxcfg)
4317 {
4318 instIndvfl("menu.c32", QString("%1menu.c32").arg(targetPath));
4319 instIndvfl("libutil.c32", QString("%1libutil.c32").arg(targetPath));
4320 instIndvfl("libcom32.c32", QString("%1libcom32.c32").arg(targetPath));
4321 }
4322 setuppersspace();
4323 #ifdef Q_OS_FREEBSD
4324 /*
4325 * On FreeBSD, we only support installing on MSDOSFS (no
4326 * extlinux in the ports). This also simplifies things
4327 * a bit, and that's what most users usually want anyway.
4328 *
4329 * Because of syslinux' stupidity, we have to remove any
4330 * existing ldlinux.c32 and ldlinux.sys files, otherwise
4331 * it will fail to install loader (even with -f switch).
4332 * Then we have to unmount the filesystem to avoid the
4333 * "Operation not permitted" error, and must enforce it
4334 * because syslinux expects a block device, and, well,
4335 * there are no "block devices" in FreeBSD.
4336 */
4337 rmFile(targetPath + "ldlinux.c32");
4338 rmFile(targetPath + "ldlinux.sys");
4339 callexternapp("umount", targetDev);
4340 callexternapp(syslinuxcommand, "-i -f " + targetDev);
4341
4342 if (rawtargetDev != targetDev)
4343 {
4344 /*
4345 * We have partition table (not operating on raw
4346 * disk), so we need to install MBR and mark our
4347 * partition as active. Assume our targetDev is
4348 * /dev/{da,mmcsd}XsY and use the last digit as
4349 * partition index for gpart(8).
4350 */
4351 QString idx = targetDev.right(1);
4352 callexternapp("gpart",
4353 "bootcode -b /boot/mbr " + rawtargetDev);
4354 callexternapp("gpart", "set -a "
4355 "active -i " + idx + " " + rawtargetDev);
4356 }
4357 #endif
4358 fininstall();
4359 }
4360
setuppersspace()4361 void unetbootin::setuppersspace()
4362 {
4363 if (this->persistenceSpaceMB > 0)
4364 {
4365 pdesc1->setText(tr("Setting up persistence"));
4366 this->tprogress->setMaximum(persistenceSpaceMB);
4367 this->tprogress->setValue(0);
4368 QString persfile = "casper-rw";
4369 if (issalt && !saltRootDir.isEmpty()) {
4370 QStringList persistencedir;
4371 persistencedir.append("persistence");
4372 makepathtree(QString("%1%2").arg(targetPath).arg(saltRootDir), persistencedir);
4373 persfile = QString("%1/persistence/%1.save").arg(saltRootDir);
4374 }
4375 #ifdef Q_OS_WIN32
4376 QString mke2fscommand = instTempfl("mke2fs.exe", "exe");
4377 #endif
4378 if (QFile::exists(QString("%1%2").arg(targetPath).arg(persfile)))
4379 {
4380 rmFile(QString("%1%2").arg(targetPath).arg(persfile));
4381 }
4382 QFile persistenceFile(QString("%1%2").arg(targetPath).arg(persfile));
4383 persistenceFile.open(QFile::WriteOnly);
4384 int bytesWritten = 1048576;
4385 char writeEmpty[1048576];
4386 memset(writeEmpty, 0, 1048576);
4387 for (int i = 0; i < persistenceSpaceMB && bytesWritten == 1048576; ++i)
4388 {
4389 this->tprogress->setValue(i);
4390 bytesWritten = persistenceFile.write(writeEmpty, 1048576);
4391 }
4392 this->tprogress->setValue(this->tprogress->maximum());
4393 #ifdef Q_OS_UNIX
4394 callexternapp(mke2fscommand, QString("-F \"%1%2\"").arg(targetPath).arg(persfile));
4395 #endif
4396 #ifdef Q_OS_WIN32
4397 callexternappWriteToStdin(mke2fscommand, QString("\"%1%2\"").arg(targetPath).arg(persfile), "\n");
4398 rmFile(mke2fscommand);
4399 #endif
4400 }
4401 }
4402
killApplication()4403 void unetbootin::killApplication()
4404 {
4405 exit(0);
4406 }
4407
fininstall()4408 void unetbootin::fininstall()
4409 {
4410 #ifdef Q_OS_UNIX
4411 this->tprogress->setValue(this->tprogress->maximum()*2/3);
4412 pdesc1->setText(tr("Syncing filesystems"));
4413 callexternapp("sync", "");
4414 #endif
4415 pdesc1->setText("");
4416 progresslayer->setEnabled(false);
4417 progresslayer->hide();
4418 rebootlayer->setEnabled(true);
4419 rebootlayer->show();
4420 sdesc3->setText(QString(sdesc3->text()).remove("<b>").replace(trcurrent+"</b>", trdone));
4421 sdesc4->setText(QString("<b>%1 %2</b>").arg(sdesc4->text()).arg(trcurrent));
4422 if (installType == tr("Hard Disk"))
4423 {
4424 rebootmsgtext->setText(tr("After rebooting, select the " UNETBOOTINB" menu entry to boot.%1").arg(postinstmsg));
4425 }
4426 if (installType == tr("USB Drive"))
4427 {
4428 #ifndef Q_OS_MAC
4429 rebootmsgtext->setText(tr("After rebooting, select the USB boot option in the BIOS boot menu.%1").arg(postinstmsg));
4430 #endif
4431 #ifdef Q_OS_MAC
4432 rebootmsgtext->setText(tr("After rebooting, hold the option key and select your USB drive to boot from it.%1").arg(postinstmsg));
4433 #endif
4434 }
4435 finishLogging();
4436 if (exitOnCompletion)
4437 {
4438 QTextStream out(stdout);
4439 out << "exitstatus:success" << endl << flush;
4440 QApplication::exit();
4441 exit(0);
4442 }
4443 }
4444