aboutsummaryrefslogtreecommitdiffstats
path: root/sysutils/unetbootin
diff options
context:
space:
mode:
authordanfe <danfe@FreeBSD.org>2019-03-22 21:37:04 +0800
committerdanfe <danfe@FreeBSD.org>2019-03-22 21:37:04 +0800
commitf41fb2cc5b37f0365a6b33d3b2a66f8f4f304b09 (patch)
tree23ea7225a322ad3d1ade35014c0e6e6570571237 /sysutils/unetbootin
parent97d686c5ece1626de8b84c3d2b4959ee64b45779 (diff)
downloadfreebsd-ports-gnome-f41fb2cc5b37f0365a6b33d3b2a66f8f4f304b09.tar.gz
freebsd-ports-gnome-f41fb2cc5b37f0365a6b33d3b2a66f8f4f304b09.tar.zst
freebsd-ports-gnome-f41fb2cc5b37f0365a6b33d3b2a66f8f4f304b09.zip
- Resurrect and apply unofficial patch from Gentoo to build against
Qt version 5 (this breaks unetbootin::lstFtpDirFiles() due to https://bugreports.qt.io/browse/QTBUG-26294) - Comment out all sources that require FTP LIST command - Don't wait until file is fully downloaded before dumping it on disk - Fix some QNetworkReply/QFile resource freeing bugs - Delete unetbootin::dlprogressupdate64() because it's never used - Fix some slot warnings while here Patches by: Valeriy Malov <jazzvoid@gmail.com> Obtained from: https://bugs.gentoo.org/show_bug.cgi?id=644360
Diffstat (limited to 'sysutils/unetbootin')
-rw-r--r--sysutils/unetbootin/Makefile47
-rw-r--r--sysutils/unetbootin/distinfo3
-rw-r--r--sysutils/unetbootin/files/patch-main.cpp70
-rw-r--r--sysutils/unetbootin/files/patch-unetbootin.cpp687
-rw-r--r--sysutils/unetbootin/files/patch-unetbootin.h81
-rw-r--r--sysutils/unetbootin/files/patch-unetbootin.pro23
-rw-r--r--sysutils/unetbootin/pkg-descr6
-rw-r--r--sysutils/unetbootin/pkg-message3
-rw-r--r--sysutils/unetbootin/pkg-plist63
9 files changed, 983 insertions, 0 deletions
diff --git a/sysutils/unetbootin/Makefile b/sysutils/unetbootin/Makefile
new file mode 100644
index 000000000000..f3cd1667ef5e
--- /dev/null
+++ b/sysutils/unetbootin/Makefile
@@ -0,0 +1,47 @@
+# Created by: Alexey Dokuchaev <danfe@FreeBSD.org>
+# $FreeBSD$
+
+PORTNAME= unetbootin
+PORTVERSION= 661
+CATEGORIES= sysutils
+MASTER_SITES= https://github.com/${PORTNAME}/${PORTNAME}/releases/download/${PORTVERSION}/
+DISTNAME= ${PORTNAME}-source-${PORTVERSION}
+
+MAINTAINER= danfe@FreeBSD.org
+COMMENT= Bootable Live USB creator for various Linux distributions
+
+LICENSE= GPLv2+
+
+RUN_DEPENDS= 7z:archivers/p7zip \
+ syslinux:sysutils/syslinux \
+ mke2fs:sysutils/e2fsprogs
+
+USES= qt:5
+USE_QT= buildtools_build linguisttools_build qmake_build \
+ core gui network widgets
+QMAKE_ARGS= DEFINES+=LOCALBASE=\\\\\\\"${LOCALBASE}\\\\\\\"
+
+NO_WRKSUBDIR= yes
+
+post-patch:
+ @${REINPLACE_CMD} -e 's,/usr/,${PREFIX}/,g' \
+ ${WRKSRC}/main.cpp
+
+do-configure:
+ ${LUPDATE} ${WRKSRC}/unetbootin.pro
+ ${LRELEASE} ${WRKSRC}/unetbootin.pro
+ cd ${WRKSRC} && ${QMAKE_ENV} ${QMAKE} ${QMAKE_ARGS}
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/unetbootin ${STAGEDIR}${PREFIX}/bin
+ ${INSTALL_DATA} ${WRKSRC}/unetbootin.xpm \
+ ${STAGEDIR}${PREFIX}/share/pixmaps
+ @${MKDIR} ${STAGEDIR}${DATADIR}
+ ${INSTALL_DATA} ${WRKSRC}/unetbootin_*.qm ${STAGEDIR}${DATADIR}
+.for n in 16 22 24 32 48 64 128 192 256 512
+ @${MKDIR} ${STAGEDIR}${PREFIX}/share/icons/hicolor/${n}x${n}/apps
+ ${INSTALL_DATA} ${WRKSRC}/unetbootin_${n}.png \
+ ${STAGEDIR}${PREFIX}/share/icons/hicolor/${n}x${n}/apps/unetbootin.png
+.endfor
+
+.include <bsd.port.mk>
diff --git a/sysutils/unetbootin/distinfo b/sysutils/unetbootin/distinfo
new file mode 100644
index 000000000000..b39cf0d1e517
--- /dev/null
+++ b/sysutils/unetbootin/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1524913051
+SHA256 (unetbootin-source-661.tar.gz) = 0f909a1a473617e3b8d40d14741b6de58697c48b4c4c782d3d427a82a3b9cd10
+SIZE (unetbootin-source-661.tar.gz) = 768431
diff --git a/sysutils/unetbootin/files/patch-main.cpp b/sysutils/unetbootin/files/patch-main.cpp
new file mode 100644
index 000000000000..9feb8efa68d4
--- /dev/null
+++ b/sysutils/unetbootin/files/patch-main.cpp
@@ -0,0 +1,70 @@
+--- main.cpp.orig 2016-05-16 08:57:42 UTC
++++ main.cpp
+@@ -9,6 +9,8 @@ This program is distributed in the hope that it will b
+
+ #include "unetbootin.h"
+
++#include <QMessageBox>
++
+ #ifdef Q_OS_WIN32
+
+ void configsysUndo(QString uninstPathL)
+@@ -292,9 +294,9 @@ int main(int argc, char **argv)
+ }
+ argsconc += "\"rootcheck=no\"";
+ argsconcSingleQuote += "'rootcheck=no'";
+-#ifdef Q_OS_LINUX
++#ifdef Q_OS_UNIX
+ QString gksuarg1;
+- gksuarg1 += QString("bash -c 'QT_X11_NO_MITSHM=1 ");
++ gksuarg1 += QString("sh -c 'QT_X11_NO_MITSHM=1 ");
+ gksuarg1 += QString("%1 %2").arg(app.applicationFilePath()).arg(argsconc);
+ gksuarg1 += QString("'");
+ QStringList gksuargs;
+@@ -370,7 +372,7 @@ int main(int argc, char **argv)
+ #ifdef Q_OS_WIN32
+ QSettings chkinst("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
+ #endif
+- #ifdef Q_OS_LINUX
++ #ifdef Q_OS_UNIX
+ QSettings chkinst(QSettings::SystemScope, "UNetbootin");
+ #endif
+ #ifndef Q_OS_MAC
+@@ -380,18 +382,16 @@ int main(int argc, char **argv)
+ uninstmsgb.setIcon(QMessageBox::Information);
+ uninstmsgb.setWindowTitle(uninstaller::tr("%1 Uninstaller").arg(UNETBOOTINB));
+ uninstmsgb.setText(uninstaller::tr("%1 is currently installed. Remove the existing version?").arg(UNETBOOTINB));
+- uninstmsgb.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+- switch (uninstmsgb.exec())
+- {
+- case QMessageBox::Ok:
+- {
+- ubnUninst();
+- }
+- case QMessageBox::Cancel:
+- break;
+- default:
+- break;
+- }
++ uninstmsgb.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
++ switch (uninstmsgb.exec())
++ {
++ case QMessageBox::Ok:
++ ubnUninst();
++ break;
++ case QMessageBox::Cancel:
++ default:
++ break;
++ }
+ return 0;
+ }
+ #endif
+@@ -405,7 +405,7 @@ int main(int argc, char **argv)
+ icon.addFile(":/unetbootin_24.png", QSize(24,24));
+ icon.addFile(":/unetbootin_32.png", QSize(32,32));
+ icon.addFile(":/unetbootin_48.png", QSize(48,48));
+-#ifdef Q_OS_LINUX
++#ifdef Q_OS_UNIX
+ icon.addFile("/usr/share/pixmaps/unetbootin.png");
+ icon.addFile("/usr/share/pixmaps/unetbootin.xpm");
+ #endif
diff --git a/sysutils/unetbootin/files/patch-unetbootin.cpp b/sysutils/unetbootin/files/patch-unetbootin.cpp
new file mode 100644
index 000000000000..8339d1b2ff33
--- /dev/null
+++ b/sysutils/unetbootin/files/patch-unetbootin.cpp
@@ -0,0 +1,687 @@
+--- unetbootin.cpp.orig 2018-04-28 01:24:54 UTC
++++ unetbootin.cpp
+@@ -9,6 +9,11 @@ This program is distributed in the hope that it will b
+
+ #include "unetbootin.h"
+
++#include <QMessageBox>
++#include <QFileDialog>
++#include <QProgressDialog>
++#include <QDebug>
++
+ static const QList<QRegExp> ignoredtypesbothRL = QList<QRegExp>()
+ << QRegExp("isolinux.bin$", Qt::CaseInsensitive)
+ << QRegExp("isolinux.cfg$", Qt::CaseInsensitive)
+@@ -101,8 +106,8 @@ void callexternappT::run()
+ void callexternappWriteToStdinT::run()
+ {
+ QProcess lnexternapp;
+- lnexternapp.start("\"" + execFile + "\" " + execParm);
+- lnexternapp.write(writeToStdin.toAscii().data());
++ lnexternapp.start("\"" + execFile + "\" " + execParm);
++ lnexternapp.write(writeToStdin.toLatin1().data());
+ lnexternapp.closeWriteChannel();
+ lnexternapp.waitForFinished(-1);
+ retnValu = QString(lnexternapp.readAll());
+@@ -133,16 +138,6 @@ void copyfileT::run()
+ emit finished();
+ }
+
+-ubngetrequestheader::ubngetrequestheader(QString urhost, QString urpath)
+-{
+- this->setRequest("GET", urpath);
+- this->setValue("HOST", urhost);
+- this->setValue("User-Agent", "UNetbootin/1.1.1");
+-// this->setValue("User-Agent", "Wget/1.10.2");
+- this->setValue("Accept", "*/*");
+- this->setValue("Connection", "Keep-Alive");
+-}
+-
+ randtmpfile::randtmpfile(QString rfpath, QString rfextn)
+ {
+ QString basefn = getrandfilename(rfpath, rfextn);
+@@ -159,7 +154,7 @@ QString randtmpfile::getrandfilename(QString rfpath, Q
+ }
+ return basefn;
+ }
+-
++/*
+ void nDirListStor::sAppendSelfUrlInfoList(QUrlInfo curDirUrl)
+ {
+ if (curDirUrl.isValid() && curDirUrl.isReadable() && curDirUrl.isFile() && curDirUrl.size() > nMinFileSizeBytes && curDirUrl.size() < nMaxFileSizeBytes)
+@@ -171,7 +166,7 @@ void nDirListStor::sAppendSelfUrlInfoList(QUrlInfo cur
+ nDirFileListSL.append(curDirUrl.name());
+ }
+ }
+-
++*/
+ unetbootin::unetbootin(QWidget *parent)
+ : QWidget(parent)
+ {
+@@ -301,8 +296,13 @@ bool unetbootin::ubninitialize(QList<QPair<QString, QS
+ #endif
+ sevzcommand = locatecommand("7z", tr("either"), "p7zip-full");
+ #endif // Q_OS_LINUX
++#ifdef Q_OS_FREEBSD
++ syslinuxcommand = locatecommand("syslinux", tr("FAT32-formatted USB drive"), "syslinux");
++ sevzcommand = locatecommand("7z", tr("either"), "p7zip");
++ mke2fscommand = locatecommand("mke2fs", tr("LiveUSB persistence"), "e2fsprogs");
++#endif // Q_OS_FREEBSD
+ ubntmpf = QDir::toNativeSeparators(QString("%1/").arg(QDir::tempPath()));
+- #ifdef Q_OS_LINUX
++ #ifdef Q_OS_UNIX
+ if (ubntmpf.isEmpty() || ubntmpf == "/")
+ {
+ ubntmpf = "/tmp/";
+@@ -471,19 +471,23 @@ bool unetbootin::ubninitialize(QList<QPair<QString, QS
+ {
+ if (psecond.contains("listdistros", Qt::CaseInsensitive))
+ {
++ QTextStream out(stdout);
+ for (int i = 1; i < this->distroselect->count(); ++i)
+ {
+- printf("%s\n", this->distroselect->itemText(i).toAscii().constData());
++ out << this->distroselect->itemText(i) << endl;
+ }
++ out.flush();
+ QApplication::exit();
+ exit(0);
+ }
+ else if (psecond.contains("listversions", Qt::CaseInsensitive))
+ {
++ QTextStream out(stdout);
+ for (int i = 0; i < this->dverselect->count(); ++i)
+ {
+- printf("%s\n", this->dverselect->itemText(i).toAscii().constData());
++ out << this->dverselect->itemText(i) << endl;
+ }
++ out.flush();
+ QApplication::exit();
+ exit(0);
+ }
+@@ -649,6 +653,57 @@ QStringList unetbootin::listsanedrives()
+ }
+ */
+ #endif
++#ifdef Q_OS_FREEBSD
++ struct xvfsconf fsconf;
++ struct statfs *fslist;
++
++ /*
++ * Make sure that MSDOSFS is configured with the kernel.
++ * As a nice side effect, this would allow to compare a
++ * number (assigned by VFS) instead of "msdosfs" string
++ * when iterating over mounted filesystems.
++ */
++ if (getvfsbyname("msdosfs", &fsconf) == -1)
++ goto out;
++
++ /*
++ * Quick sanity check of the number of active mountpoints
++ * using the filesystem (we need mounted storage to work).
++ */
++ if (fsconf.vfc_refcount < 1)
++ goto out;
++
++ int numfs = getmntinfo(&fslist, MNT_NOWAIT);
++ if (numfs < 1)
++ goto out;
++
++ QRegExp pendrives_sdcards("^/dev/(da|mmcsd)\\d+");
++
++ for (int i = 0; i < numfs; ++i)
++ {
++ /*
++ * We're interested in MSDOSFS (FAT) filesystems
++ * that are mounted off removable storage (e.g.,
++ * USB memsticks, SD cards). Assume that device
++ * names for those are /dev/da* and /dev/mmcsd*.
++ * (Perhaps not entirely accurate assumption.)
++ */
++ if ((int)fslist[i].f_type == fsconf.vfc_typenum &&
++ QString(fslist[i].f_mntfromname)
++ .contains(pendrives_sdcards))
++ {
++ /*
++ * Unlike other implementations above, we
++ * append tuples of device name *and* the
++ * mount point, so we do not have to find
++ * mount point separately later.
++ */
++ fulldrivelist.append(QString("%1:%2")
++ .arg(fslist[i].f_mntfromname)
++ .arg(fslist[i].f_mntonname));
++ }
++ }
++#endif
+ #ifdef Q_OS_MAC
+ QString systemprofilertext = callexternapp("system_profiler", "SPStorageDataType");
+ QRegExp filesystemregex("File System: (.+)\\n");
+@@ -669,6 +724,7 @@ for (int i = 0; i < filesystemlist.size(); ++i)
+ }
+ #endif
+ }
++out:
+ return fulldrivelist;
+ }
+
+@@ -700,17 +756,17 @@ QStringList unetbootin::listalldrives()
+ return fulldrivelist;
+ }
+
+-void unetbootin::on_typeselect_currentIndexChanged(int typeselectIndex)
++void unetbootin::on_typeselect_currentIndexChanged(int)
+ {
+ refreshdriveslist();
+ }
+
+-void unetbootin::on_dverselect_currentIndexChanged()
++void unetbootin::on_dverselect_currentIndexChanged(int)
+ {
+ radioDistro->setChecked(true);
+ }
+
+-void unetbootin::on_diskimagetypeselect_currentIndexChanged()
++void unetbootin::on_diskimagetypeselect_currentIndexChanged(int)
+ {
+ radioFloppy->setChecked(true);
+ }
+@@ -1098,9 +1154,14 @@ bool unetbootin::checkifoutofspace(QString destindir)
+ bool outofspace = false;
+ #ifdef Q_OS_UNIX
+ struct statfs diskstatS;
+- if (!statfs(QString(destindir+"/.").toAscii(), &diskstatS))
++ if (!statfs(QString(destindir+"/.").toLatin1(), &diskstatS))
+ {
+- if (diskstatS.f_bavail * diskstatS.f_bfree < 1024)
++ /*
++ * Refuse to work if available disk space is less than 1MB
++ * (1024KB). Even this seems very low, but original value
++ * of 1024 bytes was simply ridiculous.
++ */
++ if (diskstatS.f_bsize / 1024 * diskstatS.f_bavail < 1024)
+ outofspace = true;
+ }
+ #endif
+@@ -2620,31 +2681,27 @@ void unetbootin::downloadfile(QString fileurl, QString
+ {
+ rmFile(targetfile);
+ }
+- QUrl dlurl(fileurl);
+- bool isftp = false;
+- if (dlurl.scheme() == "ftp")
+- {
+- isftp = true;
+- }
+- QHttp dlhttp;
+- QFtp dlftp;
++ QNetworkAccessManager manager;
++ QNetworkRequest dlurl(fileurl);
++ QNetworkReply * networkReply = manager.get(dlurl);
++
+ QEventLoop dlewait;
+ pdesc5->setText("");
+ pdesc4->setText(tr("Downloading files, please wait..."));
+ pdesc3->setText(tr("<b>Source:</b> <a href=\"%1\">%1</a>").arg(fileurl));
+ pdesc2->setText(tr("<b>Destination:</b> %1").arg(targetfile));
+ pdesc1->setText(tr("<b>Downloaded:</b> 0 bytes"));
+- QString realupath = QString(fileurl).remove(0, fileurl.indexOf(QString("://%1").arg(dlurl.host())) + QString("://%1").arg(dlurl.host()).length());
+- if (isftp)
+- {
+- connect(&dlftp, SIGNAL(done(bool)), &dlewait, SLOT(quit()));
+- connect(&dlftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(dlprogressupdate64(qint64, qint64)));
+- }
+- else
+- {
+- connect(&dlhttp, SIGNAL(done(bool)), &dlewait, SLOT(quit()));
+- connect(&dlhttp, SIGNAL(dataReadProgress(int, int)), this, SLOT(dlprogressupdate(int, int)));
+- }
++
++ QUrl redirectUrl;
++ bool downloadFailed = false;
++ QNetworkReply::NetworkError errorCode;
++
++ connect(networkReply, &QNetworkReply::finished, &dlewait, &QEventLoop::quit);
++ connect(networkReply, &QNetworkReply::downloadProgress, this, &unetbootin::dlprogressupdate64);
++ connect(networkReply, &QNetworkReply::redirected, [&](const QUrl &url){ redirectUrl = url; });
++ connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
++ [&](QNetworkReply::NetworkError code){ downloadFailed = true; errorCode = code; });
++
+ QFile dloutfile;
+ if (installType == tr("USB Drive"))
+ {
+@@ -2655,82 +2712,38 @@ void unetbootin::downloadfile(QString fileurl, QString
+ dloutfile.setFileName(targetfile);
+ }
+ dloutfile.open(QIODevice::WriteOnly);
+- if (isftp)
+- {
+- dlftp.connectToHost(dlurl.host());
+- dlftp.login();
+- dlftp.get(realupath, &dloutfile);
+- }
+- else
+- {
+- dlhttp.setHost(dlurl.host());
+- ubngetrequestheader dlrequest(dlurl.host(), realupath);
+- dlhttp.request(dlrequest, 0, &dloutfile);
+- }
++
++ connect(networkReply, &QNetworkReply::downloadProgress, [&](qint64, qint64){
++ dloutfile.write(networkReply->readAll());
++ });
++
+ dlewait.exec();
+- if (!isftp)
++
++ if (!redirectUrl.isEmpty())
+ {
+- QHttpResponseHeader dlresponse(dlhttp.lastResponse());
+- int dlrstatus = dlresponse.statusCode();
+- if (dlrstatus >= 300 && dlrstatus < 400 && dlresponse.hasKey("Location"))
+- {
+- dloutfile.close();
+- rmFile(dloutfile);
+- downloadfile(dlresponse.value("Location"), targetfile, minsize);
+- return;
+- }
++ networkReply->deleteLater();
++ downloadfile(redirectUrl.toString(), targetfile, minsize);
++ return;
+ }
+- if (isftp)
++
++ if (downloadFailed)
+ {
+- dlftp.close();
++ qDebug() << "Failed to download URL: " << fileurl;
++ qDebug() << "Error code: " << errorCode;
++ qDebug() << "Error string: " << networkReply->errorString();
++ networkReply->deleteLater();
++ showDownloadFailedScreen(fileurl);
++ return;
+ }
+- else
+- {
+- dlhttp.close();
+- }
++
++ dloutfile.write(networkReply->readAll());
++ networkReply->deleteLater();
+ dloutfile.close();
+ if (installType == tr("USB Drive"))
+ {
+ dloutfile.rename(targetfile);
+ }
+- if (QFile(targetfile).size() <= 4096)
+- {
+- QString redirectTargetURL;
+- QFile seeRedirect(targetfile);
+- seeRedirect.open(QIODevice::ReadOnly | QIODevice::Text);
+- QTextStream seeRedirectTextStream(&seeRedirect);
+- while (!seeRedirectTextStream.atEnd())
+- {
+- QString curline = seeRedirectTextStream.readLine();
+- if (curline.contains("content=\"0;url="))
+- {
+- int urlstartidx = curline.indexOf("content=\"0;url=") + QString("content=\"0;url=").size();
+- redirectTargetURL = curline.mid(urlstartidx);
+- if (redirectTargetURL.contains("\""))
+- {
+- redirectTargetURL = redirectTargetURL.left(redirectTargetURL.indexOf("\""));
+- }
+- break;
+- }
+- if (curline.contains("content='0;url="))
+- {
+- int urlstartidx = curline.indexOf("content='0;url=") + QString("content='0;url=").size();
+- redirectTargetURL = curline.mid(urlstartidx);
+- if (redirectTargetURL.contains("'"))
+- {
+- redirectTargetURL = redirectTargetURL.left(redirectTargetURL.indexOf("'"));
+- }
+- break;
+- }
+- }
+- seeRedirect.close();
+- if (!redirectTargetURL.isEmpty())
+- {
+- rmFile(targetfile);
+- downloadfile(redirectTargetURL, targetfile, minsize);
+- return;
+- }
+- }
++
+ if (QFile(targetfile).size() < minsize)
+ {
+ // download failed
+@@ -2745,7 +2758,8 @@ void unetbootin::downloadfile(QString fileurl, QString
+ if (testingDownload)
+ {
+ // Note that this only tests that the first download succeeds
+- printf("exitstatus:downloadcomplete\n");
++ QTextStream out(stdout);
++ out << "exitstatus:downloadcomplete" << endl << flush;
+ QApplication::exit();
+ exit(0);
+ }
+@@ -2761,40 +2775,26 @@ void unetbootin::showDownloadFailedScreen(const QStrin
+ this->downloadFailed = true;
+ if (exitOnCompletion)
+ {
+- printf("exitstatus:downloadfailed\n");
++ QTextStream out(stdout);
++ out << "exitstatus:downloadfailed" << endl << flush;
+ QApplication::exit();
+ exit(0);
+ }
+ }
+
+-void unetbootin::dlprogressupdate(int dlbytes, int maxbytes)
+-{
+- QTime time = QTime::currentTime();
+- static int oldsec = 0;
+- // refresh the progress bar every second
+- if(oldsec != time.second())
+- {
+- oldsec = time.second();
+- tprogress->setValue(dlbytes);
+- tprogress->setMaximum(maxbytes);
+- // display the downloaded size with suffix
+- pdesc1->setText(tr("<b>Downloaded:</b> %1 of %2").arg(displayfisize(dlbytes)).arg(displayfisize(maxbytes)));
+- }
+-}
+-
+ void unetbootin::dlprogressupdate64(qint64 dlbytes, qint64 maxbytes)
+ {
+- QTime time = QTime::currentTime();
+- static int oldsec = 0;
+- // refresh the progress bar every second
+- if(oldsec != time.second())
+- {
+- oldsec = time.second();
+- tprogress->setValue(dlbytes);
+- tprogress->setMaximum(maxbytes);
+- // display the downloaded size with suffix
+- pdesc1->setText(tr("<b>Downloaded:</b> %1 of %2").arg(displayfisize(dlbytes)).arg(displayfisize(maxbytes)));
+- }
++ QTime time = QTime::currentTime();
++ static int oldsec = 0;
++ // refresh the progress bar every second
++ if(oldsec != time.second())
++ {
++ oldsec = time.second();
++ tprogress->setValue(dlbytes);
++ tprogress->setMaximum(maxbytes);
++ // display the downloaded size with suffix
++ pdesc1->setText(tr("<b>Downloaded:</b> %1 of %2").arg(displayfisize(dlbytes)).arg(displayfisize(maxbytes)));
++ }
+ }
+
+ void unetbootin::cpprogressupdate64(qint64 dlbytes, qint64 maxbytes)
+@@ -2812,31 +2812,35 @@ void unetbootin::cpprogressupdate64(qint64 dlbytes, qi
+ }
+ }
+
+-QString unetbootin::downloadpagecontents(QString pageurl)
++QString unetbootin::downloadpagecontents(QUrl pageurl)
+ {
+- QUrl pgurl(pageurl);
+- QHttp pghttp;
++ QNetworkAccessManager manager;
++ QNetworkRequest dlurl(pageurl);
++ QNetworkReply * networkReply = manager.get(dlurl);
+ QEventLoop pgwait;
+- connect(&pghttp, SIGNAL(done(bool)), &pgwait, SLOT(quit()));
+- pghttp.setHost(pgurl.host());
+- QString realpgupath = QString(pageurl).remove(0, pageurl.indexOf(QString("://%1").arg(pgurl.host())) + QString("://%1").arg(pgurl.host()).length());
+- ubngetrequestheader pgrequest(pgurl.host(), realpgupath);
+- pghttp.request(pgrequest);
++ QUrl redirectUrl;
++ connect(networkReply, &QNetworkReply::finished, &pgwait, &QEventLoop::quit);
++ connect(networkReply, &QNetworkReply::redirected, [&redirectUrl](const QUrl &url){ redirectUrl = url; });
++
+ pgwait.exec();
+- QHttpResponseHeader pgresponse(pghttp.lastResponse());
+- int pgrstatus = pgresponse.statusCode();
+- if (pgrstatus >= 300 && pgrstatus < 400 && pgresponse.hasKey("Location"))
++
++ if (!redirectUrl.isEmpty())
+ {
+- return downloadpagecontents(pgresponse.value("Location"));
++ networkReply->deleteLater();
++ return downloadpagecontents(redirectUrl);
+ }
+- else
+- {
+- return QString(pghttp.readAll());
+- }
++
++ QString result = networkReply->readAll();
++ networkReply->close();
++ networkReply->deleteLater();
++ return result;
+ }
+
+ QStringList unetbootin::lstFtpDirFiles(QString ldfDirStringUrl, int ldfMinSize, int ldfMaxSize)
+ {
++ qDebug() << "lstFtpDirFiles called for " << ldfDirStringUrl;
++ return {};
++/*
+ QUrl ldfDirUrl(ldfDirStringUrl);
+ QFtp ldfFtp;
+ QEventLoop ldfWait;
+@@ -2851,14 +2855,14 @@ QStringList unetbootin::lstFtpDirFiles(QString ldfDirS
+ ldfFtp.list(ldfDirUrl.path());
+ ldfWait.exec();
+ ldfFtp.close();
+- return nDirListStorL.nDirFileListSL;
++ return nDirListStorL.nDirFileListSL;*/
+ }
+
+ QStringList unetbootin::lstHttpDirFiles(QString ldfDirStringUrl)
+ {
+ QStringList relativefilelinksL;
+ QStringList relativelinksLPreFilter =
+- downloadpagecontents(ldfDirStringUrl)
++ downloadpagecontents(QUrl(ldfDirStringUrl))
+ .replace(">", ">\n")
+ .replace("<", "\n<")
+ .split("\n");
+@@ -3218,11 +3222,11 @@ int unetbootin::letterToNumber(QChar lettertoconvert)
+ {
+ if (lettertoconvert.isLower())
+ {
+- return static_cast<int>(lettertoconvert.toAscii() - 'a');
++ return static_cast<int>(lettertoconvert.toLatin1() - 'a');
+ }
+ if (lettertoconvert.isUpper())
+ {
+- return static_cast<int>(lettertoconvert.toAscii() - 'A');
++ return static_cast<int>(lettertoconvert.toLatin1() - 'A');
+ }
+ else
+ {
+@@ -3412,21 +3416,36 @@ void unetbootin::instIndvfl(QString srcfName, QString
+ srcF.setFileName(QFile::exists("/usr/share/syslinux/memdisk") ? "/usr/share/syslinux/memdisk" : "/usr/lib/syslinux/memdisk");
+ else if (srcfName == "menu.c32")
+ {
++#ifdef Q_OS_LINUX
+ srcF.setFileName(QFile::exists("/usr/share/syslinux/menu.c32") ? "/usr/share/syslinux/menu.c32" : "/usr/lib/syslinux/menu.c32");
+ if (QFile::exists("/usr/lib/syslinux/modules/bios/menu.c32"))
+ srcF.setFileName("/usr/lib/syslinux/modules/bios/menu.c32");
++#endif
++#ifdef Q_OS_FREEBSD
++ srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/menu/menu.c32");
++#endif
+ }
+ else if (srcfName == "libutil.c32")
+ {
++#ifdef Q_OS_LINUX
+ srcF.setFileName(QFile::exists("/usr/share/syslinux/libutil.c32") ? "/usr/share/syslinux/libutil.c32" : "/usr/lib/syslinux/libutil.c32");
+ if (QFile::exists("/usr/lib/syslinux/modules/bios/libutil.c32"))
+ srcF.setFileName("/usr/lib/syslinux/modules/bios/libutil.c32");
++#endif
++#ifdef Q_OS_FREEBSD
++ srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/libutil/libutil.c32");
++#endif
+ }
+ else if (srcfName == "libcom32.c32")
+ {
++#ifdef Q_OS_LINUX
+ srcF.setFileName(QFile::exists("/usr/share/syslinux/libcom32.c32") ? "/usr/share/syslinux/libcom32.c32" : "/usr/lib/syslinux/libcom32.c32");
+ if (QFile::exists("/usr/lib/syslinux/modules/bios/libcom32.c32"))
+ srcF.setFileName("/usr/lib/syslinux/modules/bios/libcom32.c32");
++#endif
++#ifdef Q_OS_FREEBSD
++ srcF.setFileName(LOCALBASE "/share/syslinux/bios/com32/lib/libcom32.c32");
++#endif
+ }
+ else if (srcfName == "mbr.bin")
+ {
+@@ -3516,11 +3535,19 @@ void unetbootin::runinst()
+ }
+ if (installType == tr("USB Drive"))
+ {
++#ifdef Q_OS_LINUX
+ targetDev = driveselect->currentText();
+ devluid = getdevluid(targetDev);
+ ginstallDir = "";
+ installDir = ginstallDir;
+ targetDrive = QString("%1/").arg(locatemountpoint(targetDev));
++#endif
++#ifdef Q_OS_FREEBSD
++ QStringList driveinfo = driveselect->currentText().split(":");
++ targetDev = driveinfo.at(0);
++ installDir = ginstallDir = "";
++ targetDrive = QString("%1/").arg(driveinfo.at(1));
++#endif
+ }
+ #ifdef Q_OS_LINUX
+ if (targetDev.contains(QRegExp("p\\d$")))
+@@ -3528,7 +3555,7 @@ void unetbootin::runinst()
+ else
+ rawtargetDev = QString(targetDev).remove(QRegExp("\\d$"));
+ #endif
+-#ifdef Q_OS_MAC
++#ifdef Q_OS_UNIX
+ rawtargetDev = QString(targetDev).remove(QRegExp("s\\d$"));
+ #endif
+ #endif
+@@ -3724,7 +3751,7 @@ void unetbootin::writegrub2cfg()
+ QString menulstxt = QString(
+ "%9\n\n"
+ #ifndef NODEFAULTBOOT
+- "\nmenuentry \""UNETBOOTINB"\" {\n"
++ "\nmenuentry \"" UNETBOOTINB "\" {\n"
+ "\tset root=%8\n"
+ "\t%1 %2 %3 %4\n"
+ "\t%5 %6 %7\n"
+@@ -3845,7 +3872,7 @@ void unetbootin::runinsthdd()
+ "timeout 10\n"
+ #endif
+ #ifndef NODEFAULTBOOT
+- "\ntitle "UNETBOOTINB"\n"
++ "\ntitle " UNETBOOTINB "\n"
+ #ifdef Q_OS_WIN32
+ "find --set-root %3\n"
+ #endif
+@@ -4281,21 +4308,47 @@ void unetbootin::runinstusb()
+ instIndvfl("libutil.c32", QString("%1libutil.c32").arg(targetPath));
+ instIndvfl("libcom32.c32", QString("%1libcom32.c32").arg(targetPath));
+ }
++ setuppersspace();
++#ifdef Q_OS_FREEBSD
++ /*
++ * On FreeBSD, we only support installing on MSDOSFS (no
++ * extlinux in the ports). This also simplifies things
++ * a bit, and that's what most users usually want anyway.
++ *
++ * Because of syslinux' stupidity, we have to remove any
++ * existing ldlinux.c32 and ldlinux.sys files, otherwise
++ * it will fail to install loader (even with -f switch).
++ * Then we have to unmount the filesystem to avoid the
++ * "Operation not permitted" error, and must enforce it
++ * because syslinux expects a block device, and, well,
++ * there are no "block devices" in FreeBSD.
++ */
++ rmFile(targetPath + "ldlinux.c32");
++ rmFile(targetPath + "ldlinux.sys");
++ callexternapp("umount", targetDev);
++ callexternapp(syslinuxcommand, "-i -f " + targetDev);
++
++ if (rawtargetDev != targetDev)
++ {
++ /*
++ * We have partition table (not operating on raw
++ * disk), so we need to install MBR and mark our
++ * partition as active. Assume our targetDev is
++ * /dev/{da,mmcsd}XsY and use the last digit as
++ * partition index for gpart(8).
++ */
++ QString idx = targetDev.right(1);
++ callexternapp("gpart",
++ "bootcode -b /boot/mbr " + rawtargetDev);
++ callexternapp("gpart", "set -a "
++ "active -i " + idx + " " + rawtargetDev);
++ }
++#endif
+ fininstall();
+ }
+
+-void unetbootin::killApplication()
++void unetbootin::setuppersspace()
+ {
+- exit(0);
+-}
+-
+-void unetbootin::fininstall()
+-{
+- #ifdef Q_OS_UNIX
+- this->tprogress->setValue(this->tprogress->maximum()*2/3);
+- pdesc1->setText(tr("Syncing filesystems"));
+- callexternapp("sync", "");
+- #endif
+ if (this->persistenceSpaceMB > 0)
+ {
+ pdesc1->setText(tr("Setting up persistence"));
+@@ -4334,6 +4387,20 @@ void unetbootin::fininstall()
+ rmFile(mke2fscommand);
+ #endif
+ }
++}
++
++void unetbootin::killApplication()
++{
++ exit(0);
++}
++
++void unetbootin::fininstall()
++{
++ #ifdef Q_OS_UNIX
++ this->tprogress->setValue(this->tprogress->maximum()*2/3);
++ pdesc1->setText(tr("Syncing filesystems"));
++ callexternapp("sync", "");
++ #endif
+ pdesc1->setText("");
+ progresslayer->setEnabled(false);
+ progresslayer->hide();
+@@ -4343,7 +4410,7 @@ void unetbootin::fininstall()
+ sdesc4->setText(QString("<b>%1 %2</b>").arg(sdesc4->text()).arg(trcurrent));
+ if (installType == tr("Hard Disk"))
+ {
+- rebootmsgtext->setText(tr("After rebooting, select the "UNETBOOTINB" menu entry to boot.%1").arg(postinstmsg));
++ rebootmsgtext->setText(tr("After rebooting, select the " UNETBOOTINB " menu entry to boot.%1").arg(postinstmsg));
+ }
+ if (installType == tr("USB Drive"))
+ {
+@@ -4357,7 +4424,8 @@ void unetbootin::fininstall()
+ finishLogging();
+ if (exitOnCompletion)
+ {
+- printf("exitstatus:success\n");
++ QTextStream out(stdout);
++ out << "exitstatus:success" << endl << flush;
+ QApplication::exit();
+ exit(0);
+ }
diff --git a/sysutils/unetbootin/files/patch-unetbootin.h b/sysutils/unetbootin/files/patch-unetbootin.h
new file mode 100644
index 000000000000..4837c4b9f502
--- /dev/null
+++ b/sysutils/unetbootin/files/patch-unetbootin.h
@@ -0,0 +1,81 @@
+--- unetbootin.h.orig 2018-04-28 01:24:54 UTC
++++ unetbootin.h
+@@ -35,6 +35,10 @@ This program is distributed in the hope that it will b
+ #include <sys/vfs.h>
+ #endif
+
++#ifdef Q_OS_FREEBSD
++#include <sys/mount.h>
++#endif
++
+ #ifdef AUTOSUPERGRUBDISK
+ #define UNETBOOTINB "Auto Super Grub Disk"
+ #define NOEXTERN
+@@ -152,19 +156,13 @@ signals:
+ void finished();
+ };
+
+-class ubngetrequestheader : public QHttpRequestHeader
+-{
+-public:
+- ubngetrequestheader(QString urhost, QString urpath);
+-};
+-
+ class randtmpfile : public QFile
+ {
+ public:
+ randtmpfile(QString rfpath, QString rfextn);
+ static QString getrandfilename(QString rfpath, QString rfextn);
+ };
+-
++/*
+ class nDirListStor : public QObject
+ {
+ Q_OBJECT
+@@ -178,7 +176,7 @@ class nDirListStor : public QObject (public)
+ public slots:
+ void sAppendSelfUrlInfoList(QUrlInfo curDirUrl);
+ };
+-
++*/
+ class unetbootin : public QWidget, private Ui::unetbootinui
+ {
+ Q_OBJECT
+@@ -280,7 +278,7 @@ class unetbootin : public QWidget, private Ui::unetboo
+ QString searchforgrub2includesfile(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes);
+ QPair<QPair<QStringList, QStringList>, QPair<QStringList, QStringList> > searchforgrub2includesfileL(QString includesfile, QString archivefile, QStringList archivefileconts, QStringList visitedincludes);
+ void downloadfile(QString fileurl, QString targetfile, int minsize);
+- QString downloadpagecontents(QString pageurl);
++ QString downloadpagecontents(QUrl pageurl);
+ QStringList lstFtpDirFiles(QString ldfDirStringUrl, int ldfMinSize, int ldfMaxSize);
+ QStringList lstHttpDirFiles(QString ldfDirStringUrl);
+ QStringList lstNetDirFiles(QString ldfDirStringUrl, int ldfMinSize, int ldfMaxSize);
+@@ -333,6 +331,7 @@ class unetbootin : public QWidget, private Ui::unetboo
+ void logText(const QString &text);
+ void finishLogging();
+ void writeTextToFile(const QString &text, const QString &filePath);
++ void setuppersspace();
+ void fininstall();
+ void rmFile(const QString &fn);
+ void rmFile(QFile &fn);
+@@ -342,9 +341,9 @@ class unetbootin : public QWidget, private Ui::unetboo
+
+ private slots:
+ void on_distroselect_currentIndexChanged(int distroselectIndex);
+- void on_typeselect_currentIndexChanged(int typeselectIndex);
+- void on_dverselect_currentIndexChanged();
+- void on_diskimagetypeselect_currentIndexChanged();
++ void on_typeselect_currentIndexChanged(int);
++ void on_dverselect_currentIndexChanged(int);
++ void on_diskimagetypeselect_currentIndexChanged(int);
+ void on_FloppyFileSelector_clicked();
+ void on_KernelFileSelector_clicked();
+ void on_InitrdFileSelector_clicked();
+@@ -353,7 +352,6 @@ private slots:
+ void on_fexitbutton_clicked();
+
+ public slots:
+- void dlprogressupdate(int dlbytes, int maxbytes);
+ void dlprogressupdate64(qint64 dlbytes, qint64 maxbytes);
+ void cpprogressupdate64(qint64 dlbytes, qint64 maxbytes);
+ void on_okbutton_clicked();
diff --git a/sysutils/unetbootin/files/patch-unetbootin.pro b/sysutils/unetbootin/files/patch-unetbootin.pro
new file mode 100644
index 000000000000..b867e8ed14ac
--- /dev/null
+++ b/sysutils/unetbootin/files/patch-unetbootin.pro
@@ -0,0 +1,23 @@
+--- unetbootin.pro.orig 2018-04-28 09:30:55 UTC
++++ unetbootin.pro
+@@ -2,18 +2,18 @@ TEMPLATE = app
+ TARGET = unetbootin
+ DEPENDPATH += .
+ INCLUDEPATH += .
+-CONFIG += release \
+- static
+
+ HEADERS += unetbootin.h
+ FORMS += unetbootin.ui
+ SOURCES += main.cpp \
+ unetbootin.cpp \
++ customdistrolst.cpp \
+ distrolst.cpp \
+ distrover.cpp \
+ distrovercust.cpp
+ QT += core \
+ gui \
++ widgets \
+ network
+ ICON = unetbootin.icns
+ TRANSLATIONS += unetbootin.ts \
diff --git a/sysutils/unetbootin/pkg-descr b/sysutils/unetbootin/pkg-descr
new file mode 100644
index 000000000000..8fbb19dd699a
--- /dev/null
+++ b/sysutils/unetbootin/pkg-descr
@@ -0,0 +1,6 @@
+UNetbootin allows to create bootable Live USB drives for Ubuntu, Fedora,
+and other Linux distributions without burning a CD. This is useful when
+supplied ISO image cannot be directly written to USB drive or SD card to
+get a bootable media.
+
+WWW: http://unetbootin.github.io/
diff --git a/sysutils/unetbootin/pkg-message b/sysutils/unetbootin/pkg-message
new file mode 100644
index 000000000000..0d461173cf3b
--- /dev/null
+++ b/sysutils/unetbootin/pkg-message
@@ -0,0 +1,3 @@
+ If SysLinux refuses to boot with a "Boot error" message when written to
+ a PC partition (slice), try to reformat the drive in raw (or dedicated)
+ mode (that is, without a partition table), then reinstall things again.
diff --git a/sysutils/unetbootin/pkg-plist b/sysutils/unetbootin/pkg-plist
new file mode 100644
index 000000000000..9d823004dda3
--- /dev/null
+++ b/sysutils/unetbootin/pkg-plist
@@ -0,0 +1,63 @@
+bin/unetbootin
+share/icons/hicolor/16x16/apps/unetbootin.png
+share/icons/hicolor/22x22/apps/unetbootin.png
+share/icons/hicolor/24x24/apps/unetbootin.png
+share/icons/hicolor/32x32/apps/unetbootin.png
+share/icons/hicolor/48x48/apps/unetbootin.png
+share/icons/hicolor/64x64/apps/unetbootin.png
+share/icons/hicolor/128x128/apps/unetbootin.png
+share/icons/hicolor/192x192/apps/unetbootin.png
+share/icons/hicolor/256x256/apps/unetbootin.png
+share/icons/hicolor/512x512/apps/unetbootin.png
+share/pixmaps/unetbootin.xpm
+%%DATADIR%%/unetbootin_am.qm
+%%DATADIR%%/unetbootin_ar.qm
+%%DATADIR%%/unetbootin_ast.qm
+%%DATADIR%%/unetbootin_be.qm
+%%DATADIR%%/unetbootin_bg.qm
+%%DATADIR%%/unetbootin_bn.qm
+%%DATADIR%%/unetbootin_ca.qm
+%%DATADIR%%/unetbootin_cs.qm
+%%DATADIR%%/unetbootin_da.qm
+%%DATADIR%%/unetbootin_de.qm
+%%DATADIR%%/unetbootin_el.qm
+%%DATADIR%%/unetbootin_eo.qm
+%%DATADIR%%/unetbootin_es.qm
+%%DATADIR%%/unetbootin_et.qm
+%%DATADIR%%/unetbootin_eu.qm
+%%DATADIR%%/unetbootin_fa.qm
+%%DATADIR%%/unetbootin_fi.qm
+%%DATADIR%%/unetbootin_fo.qm
+%%DATADIR%%/unetbootin_fr.qm
+%%DATADIR%%/unetbootin_gl.qm
+%%DATADIR%%/unetbootin_he.qm
+%%DATADIR%%/unetbootin_hr.qm
+%%DATADIR%%/unetbootin_hu.qm
+%%DATADIR%%/unetbootin_id.qm
+%%DATADIR%%/unetbootin_it.qm
+%%DATADIR%%/unetbootin_ja.qm
+%%DATADIR%%/unetbootin_lt.qm
+%%DATADIR%%/unetbootin_lv.qm
+%%DATADIR%%/unetbootin_ml.qm
+%%DATADIR%%/unetbootin_ms.qm
+%%DATADIR%%/unetbootin_nan.qm
+%%DATADIR%%/unetbootin_nb.qm
+%%DATADIR%%/unetbootin_nl.qm
+%%DATADIR%%/unetbootin_nn.qm
+%%DATADIR%%/unetbootin_pl.qm
+%%DATADIR%%/unetbootin_pt.qm
+%%DATADIR%%/unetbootin_pt_BR.qm
+%%DATADIR%%/unetbootin_ro.qm
+%%DATADIR%%/unetbootin_ru.qm
+%%DATADIR%%/unetbootin_si.qm
+%%DATADIR%%/unetbootin_sk.qm
+%%DATADIR%%/unetbootin_sl.qm
+%%DATADIR%%/unetbootin_sr.qm
+%%DATADIR%%/unetbootin_sv.qm
+%%DATADIR%%/unetbootin_sw.qm
+%%DATADIR%%/unetbootin_tr.qm
+%%DATADIR%%/unetbootin_uk.qm
+%%DATADIR%%/unetbootin_ur.qm
+%%DATADIR%%/unetbootin_vi.qm
+%%DATADIR%%/unetbootin_zh_CN.qm
+%%DATADIR%%/unetbootin_zh_TW.qm