Revamped updater thread: Got rid of some old cruft + now using NC for connectivity test (way faster than Wget).
This commit is contained in:
parent
35159c3d07
commit
a6f6264917
@ -80,7 +80,7 @@ namespace MUtils
|
|||||||
}
|
}
|
||||||
update_status_t;
|
update_status_t;
|
||||||
|
|
||||||
UpdateChecker(const QString &binWGet, const QString &binGnuPG, const QString &binKeys, const QString &applicationId, const quint32 &installedBuildNo, const bool betaUpdates, const bool testMode = false);
|
UpdateChecker(const QString &binWGet, const QString &binNC, const QString &binGnuPG, const QString &binKeys, const QString &applicationId, const quint32 &installedBuildNo, const bool betaUpdates, const bool testMode = false);
|
||||||
~UpdateChecker(void);
|
~UpdateChecker(void);
|
||||||
|
|
||||||
const int getUpdateStatus(void) const { return m_status; }
|
const int getUpdateStatus(void) const { return m_status; }
|
||||||
@ -110,6 +110,7 @@ namespace MUtils
|
|||||||
const quint32 m_installedBuildNo;
|
const quint32 m_installedBuildNo;
|
||||||
|
|
||||||
const QString m_binaryWGet;
|
const QString m_binaryWGet;
|
||||||
|
const QString m_binaryNC;
|
||||||
const QString m_binaryGnuPG;
|
const QString m_binaryGnuPG;
|
||||||
const QString m_binaryKeys;
|
const QString m_binaryKeys;
|
||||||
|
|
||||||
@ -122,12 +123,13 @@ namespace MUtils
|
|||||||
inline void setProgress(const int progress);
|
inline void setProgress(const int progress);
|
||||||
inline void log(const QString &str1, const QString &str2 = QString(), const QString &str3 = QString(), const QString &str4 = QString());
|
inline void log(const QString &str1, const QString &str2 = QString(), const QString &str3 = QString(), const QString &str4 = QString());
|
||||||
|
|
||||||
|
bool getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign);
|
||||||
|
bool tryContactHost(const QString &hostname);
|
||||||
|
bool parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo);
|
||||||
|
|
||||||
bool getFile(const QString &url, const QString &outFile, const unsigned int maxRedir = 5U, bool *httpOk = NULL);
|
bool getFile(const QString &url, const QString &outFile, const unsigned int maxRedir = 5U, bool *httpOk = NULL);
|
||||||
bool getFile(const QString &url, const bool forceIp4, const QString &outFile, const unsigned int maxRedir, bool *httpOk);
|
bool getFile(const QString &url, const bool forceIp4, const QString &outFile, const unsigned int maxRedir, bool *httpOk);
|
||||||
bool getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign);
|
|
||||||
int tryContactHost(const QString &url);
|
|
||||||
bool tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url);
|
|
||||||
bool checkSignature(const QString &file, const QString &signature);
|
bool checkSignature(const QString &file, const QString &signature);
|
||||||
bool parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo);
|
bool tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ static const char *mirror_url_postfix[] =
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *update_mirrors_prim[] =
|
static const char *update_mirrors[] =
|
||||||
{
|
{
|
||||||
"http://muldersoft.com/",
|
"http://muldersoft.com/",
|
||||||
"http://mulder.bplaced.net/", //"http://mulder.cwsurf.de/",
|
"http://mulder.bplaced.net/", //"http://mulder.cwsurf.de/",
|
||||||
@ -66,139 +66,133 @@ static const char *update_mirrors_prim[] =
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *update_mirrors_back[] =
|
|
||||||
{
|
|
||||||
"http://mplayer.savedonthe.net/",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *known_hosts[] = //Taken form: http://www.alexa.com/topsites !!!
|
static const char *known_hosts[] = //Taken form: http://www.alexa.com/topsites !!!
|
||||||
{
|
{
|
||||||
"http://www.163.com/",
|
"www.163.com",
|
||||||
"http://www.7-zip.org/",
|
"www.7-zip.org",
|
||||||
"http://www.ac3filter.net/",
|
"www.ac3filter.net",
|
||||||
"http://clbianco.altervista.org/",
|
"clbianco.altervista.org",
|
||||||
"http://status.aws.amazon.com/",
|
"status.aws.amazon.com",
|
||||||
"http://build.antergos.com/",
|
"build.antergos.com",
|
||||||
"http://www.aol.com/",
|
"www.aol.com",
|
||||||
"http://www.apache.org/",
|
"www.apache.org",
|
||||||
"http://www.apple.com/",
|
"www.apple.com",
|
||||||
"http://www.adobe.com/",
|
"www.adobe.com",
|
||||||
"http://archive.org/web/",
|
"archive.org",
|
||||||
"http://www.artlebedev.ru/",
|
"www.artlebedev.ru",
|
||||||
"http://web.audacityteam.org/",
|
"web.audacityteam.org",
|
||||||
"http://status.automattic.com/",
|
"status.automattic.com",
|
||||||
"http://www.avidemux.org/",
|
"www.avidemux.org",
|
||||||
"http://www.babylon.com/",
|
"www.babylon.com",
|
||||||
"http://www.baidu.com/",
|
"www.baidu.com",
|
||||||
"http://bandcamp.com/",
|
"bandcamp.com",
|
||||||
"http://www.bbc.co.uk/",
|
"www.bbc.co.uk",
|
||||||
"http://www.berlios.de/",
|
"www.berlios.de",
|
||||||
"http://www.bing.com/",
|
"www.bing.com",
|
||||||
"http://www.bingeandgrab.com/",
|
"www.bingeandgrab.com",
|
||||||
"http://www.bucketheadpikes.com/",
|
"www.bucketheadpikes.com",
|
||||||
"http://www.buckethead-coop.com/",
|
"www.buckethead-coop.com",
|
||||||
"http://www.buzzfeed.com/",
|
"www.buzzfeed.com",
|
||||||
"http://www.ccc.de/",
|
"www.ccc.de",
|
||||||
"http://www.citizeninsomniac.com/WMV/",
|
"www.citizeninsomniac.com",
|
||||||
"http://www.cnet.com/",
|
"www.cnet.com",
|
||||||
"http://cnzz.com/",
|
"cnzz.com",
|
||||||
"http://www.codeplex.com/",
|
"www.codeplex.com",
|
||||||
"http://www.codeproject.com/",
|
"www.codeproject.com",
|
||||||
"http://www.der-postillon.com/",
|
"www.der-postillon.com",
|
||||||
"http://www.ebay.com/",
|
"www.ebay.com",
|
||||||
"http://www.equation.com/",
|
"www.equation.com",
|
||||||
"http://www.farbrausch.de/",
|
"www.farbrausch.de",
|
||||||
"http://fc2.com/",
|
"fc2.com",
|
||||||
"http://fedoraproject.org/wiki/Fedora_Project_Wiki",
|
"fedoraproject.org",
|
||||||
"http://blog.fefe.de/",
|
"blog.fefe.de",
|
||||||
"http://www.ffmpeg.org/",
|
"www.ffmpeg.org",
|
||||||
"http://blog.flickr.net/en",
|
"blog.flickr.net",
|
||||||
"http://free-codecs.com/",
|
"free-codecs.com",
|
||||||
"http://git-scm.com/",
|
"git-scm.com",
|
||||||
"http://doc.gitlab.com/",
|
"doc.gitlab.com",
|
||||||
"http://www.gmx.net/",
|
"www.gmx.net",
|
||||||
"http://news.gnome.org/",
|
"news.gnome.org",
|
||||||
"http://www.gnu.org/",
|
"www.gnu.org",
|
||||||
"http://go.com/",
|
"go.com",
|
||||||
"http://code.google.com/",
|
"code.google.com",
|
||||||
"http://haali.su/mkv/",
|
"haali.su",
|
||||||
"http://www.heise.de/",
|
"www.heise.de",
|
||||||
"http://www.huffingtonpost.co.uk/",
|
"www.huffingtonpost.co.uk",
|
||||||
"http://www.iana.org/",
|
"www.iana.org",
|
||||||
"http://www.imdb.com/",
|
"www.imdb.com",
|
||||||
"http://www.imgburn.com/",
|
"www.imgburn.com",
|
||||||
"http://imgur.com/",
|
"imgur.com",
|
||||||
"http://www.jd.com/contact/",
|
"www.jd.com",
|
||||||
"http://www.jiscdigitalmedia.ac.uk/",
|
"www.jiscdigitalmedia.ac.uk",
|
||||||
"http://kannmanumdieuhrzeitschonnbierchentrinken.de/",
|
"kannmanumdieuhrzeitschonnbierchentrinken.de",
|
||||||
"http://mirrors.kernel.org/",
|
"mirrors.kernel.org",
|
||||||
"http://komisar.gin.by/",
|
"komisar.gin.by",
|
||||||
"http://lame.sourceforge.net/",
|
"lame.sourceforge.net",
|
||||||
"http://www.libav.org/",
|
"www.libav.org",
|
||||||
"http://blog.linkedin.com/",
|
"blog.linkedin.com",
|
||||||
"http://www.linuxmint.com/",
|
"www.linuxmint.com",
|
||||||
"http://www.livedoor.com/",
|
"www.livedoor.com",
|
||||||
"http://www.livejournal.com/",
|
"www.livejournal.com",
|
||||||
"http://longplayer.org/",
|
"longplayer.org",
|
||||||
"http://go.mail.ru/",
|
"go.mail.ru",
|
||||||
"http://marknelson.us/",
|
"marknelson.us",
|
||||||
"http://www.mediafire.com/about/",
|
"www.mediafire.com",
|
||||||
"http://www.mod-technologies.com/",
|
"www.mod-technologies.com",
|
||||||
"http://ftp.mozilla.org/",
|
"ftp.mozilla.org",
|
||||||
"http://mplayerhq.hu/",
|
"mplayerhq.hu",
|
||||||
"http://www.msn.com/en-us/",
|
"www.msn.com",
|
||||||
"http://wiki.multimedia.cx/",
|
"wiki.multimedia.cx",
|
||||||
"http://www.nch.com.au/",
|
"www.nch.com.au",
|
||||||
"http://mirror.netcologne.de/",
|
"mirror.netcologne.de",
|
||||||
"http://oss.netfarm.it/",
|
"oss.netfarm.it",
|
||||||
"http://blog.netflix.com/",
|
"blog.netflix.com",
|
||||||
"http://netrenderer.de/",
|
"netrenderer.de",
|
||||||
"http://www.nytimes.com/",
|
"www.nytimes.com",
|
||||||
"http://www.opera.com/",
|
"www.opera.com",
|
||||||
"http://www.partha.com/",
|
"www.partha.com",
|
||||||
"http://pastebin.com/",
|
"pastebin.com",
|
||||||
"http://pastie.org/",
|
"pastie.org",
|
||||||
"http://portableapps.com/about",
|
"portableapps.com",
|
||||||
"http://www.portablefreeware.com/",
|
"www.portablefreeware.com",
|
||||||
"http://support.proboards.com/",
|
"support.proboards.com",
|
||||||
"http://www.qq.com/",
|
"www.qq.com",
|
||||||
"http://www.qt.io/",
|
"www.qt.io",
|
||||||
"http://www.quakelive.com/",
|
"www.quakelive.com",
|
||||||
"http://rationalqm.us/mine.html",
|
"rationalqm.us",
|
||||||
"http://www.seamonkey-project.org/",
|
"www.seamonkey-project.org",
|
||||||
"http://selfhtml.org/",
|
"selfhtml.org",
|
||||||
"http://www.sina.com.cn/",
|
"www.sina.com.cn",
|
||||||
"http://www.sohu.com/",
|
"www.sohu.com",
|
||||||
"http://help.sogou.com/",
|
"help.sogou.com",
|
||||||
"http://sourceforge.net/",
|
"sourceforge.net",
|
||||||
"http://www.spiegel.de/",
|
"www.spiegel.de",
|
||||||
"http://www.sputnikmusic.com/",
|
"www.sputnikmusic.com",
|
||||||
"http://stackoverflow.com/",
|
"stackoverflow.com",
|
||||||
"http://www.t-online.de/",
|
"www.t-online.de",
|
||||||
"http://www.tagesschau.de/",
|
"www.tagesschau.de",
|
||||||
"http://tdm-gcc.tdragon.net/",
|
"tdm-gcc.tdragon.net",
|
||||||
"http://www.tdrsmusic.com/",
|
"www.tdrsmusic.com",
|
||||||
"http://www.ubuntu.com/",
|
"www.ubuntu.com",
|
||||||
"http://www.uol.com.br/",
|
"www.uol.com.br",
|
||||||
"http://www.videohelp.com/",
|
"www.videohelp.com",
|
||||||
"http://www.videolan.org/",
|
"www.videolan.org",
|
||||||
"http://virtualdub.org/",
|
"virtualdub.org",
|
||||||
"http://blog.virustotal.com/",
|
"blog.virustotal.com",
|
||||||
"http://www.vkgoeswild.com/",
|
"www.vkgoeswild.com",
|
||||||
"http://www.warr.org/WAhere.html",
|
"www.warr.org",
|
||||||
"http://www.weibo.com/login.php",
|
"www.weibo.com",
|
||||||
"http://status.wikimedia.org/",
|
"status.wikimedia.org",
|
||||||
"http://www.winamp.com/",
|
"www.winamp.com",
|
||||||
"http://www.winhoros.de/",
|
"www.winhoros.de",
|
||||||
"http://wpde.org/",
|
"wpde.org",
|
||||||
"http://x265.org/",
|
"x265.org",
|
||||||
"http://xhmikosr.1f0.de/",
|
"xhmikosr.1f0.de",
|
||||||
"http://xiph.org/",
|
"xiph.org",
|
||||||
"http://us.mail.yahoo.com/",
|
"us.mail.yahoo.com",
|
||||||
"http://www.youtube.com/yt/about/",
|
"www.youtube.com",
|
||||||
"http://www.zedo.com/",
|
"www.zedo.com",
|
||||||
"http://ffmpeg.zeranoe.com/",
|
"ffmpeg.zeranoe.com",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -210,11 +204,21 @@ static char *USER_AGENT_STR = "Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/201
|
|||||||
static int getMaxProgress(void)
|
static int getMaxProgress(void)
|
||||||
{
|
{
|
||||||
int counter = MIN_CONNSCORE + 2;
|
int counter = MIN_CONNSCORE + 2;
|
||||||
for(int i = 0; update_mirrors_prim[i]; i++) counter++;
|
for(int i = 0; update_mirrors[i]; i++) counter++;
|
||||||
for(int i = 0; update_mirrors_back[i]; i++) counter++;
|
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QStringList buildRandomList(const char *const values[])
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
for (int index = 0; values[index]; index++)
|
||||||
|
{
|
||||||
|
const int pos = next_rand32() % (index + 1);
|
||||||
|
list.insert(pos, QString::fromLatin1(values[index]));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Update Info Class
|
// Update Info Class
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -252,10 +256,11 @@ bool UpdateCheckerInfo::isComplete(void)
|
|||||||
// Constructor & Destructor
|
// Constructor & Destructor
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
UpdateChecker::UpdateChecker(const QString &binWGet, const QString &binGnuPG, const QString &binKeys, const QString &applicationId, const quint32 &installedBuildNo, const bool betaUpdates, const bool testMode)
|
UpdateChecker::UpdateChecker(const QString &binWGet, const QString &binNC, const QString &binGnuPG, const QString &binKeys, const QString &applicationId, const quint32 &installedBuildNo, const bool betaUpdates, const bool testMode)
|
||||||
:
|
:
|
||||||
m_updateInfo(new UpdateCheckerInfo()),
|
m_updateInfo(new UpdateCheckerInfo()),
|
||||||
m_binaryWGet(binWGet),
|
m_binaryWGet(binWGet),
|
||||||
|
m_binaryNC(binNC),
|
||||||
m_binaryGnuPG(binGnuPG),
|
m_binaryGnuPG(binGnuPG),
|
||||||
m_binaryKeys(binKeys),
|
m_binaryKeys(binKeys),
|
||||||
m_applicationId(applicationId),
|
m_applicationId(applicationId),
|
||||||
@ -300,16 +305,13 @@ void UpdateChecker::checkForUpdates(void)
|
|||||||
|
|
||||||
// ----- Test Internet Connection ----- //
|
// ----- Test Internet Connection ----- //
|
||||||
|
|
||||||
int connectionScore = 0;
|
log("Checking internet connection...", "");
|
||||||
int maxConnectTries = (3 * MIN_CONNSCORE) / 2;
|
|
||||||
|
|
||||||
log("Checking internet connection...");
|
|
||||||
setStatus(UpdateStatus_CheckingConnection);
|
setStatus(UpdateStatus_CheckingConnection);
|
||||||
|
|
||||||
const int networkStatus = OS::network_status();
|
const int networkStatus = OS::network_status();
|
||||||
if(networkStatus == OS::NETWORK_TYPE_NON)
|
if(networkStatus == OS::NETWORK_TYPE_NON)
|
||||||
{
|
{
|
||||||
log("", "Operating system reports that the computer is currently offline !!!");
|
log("Operating system reports that the computer is currently offline !!!");
|
||||||
setProgress(m_maxProgress);
|
setProgress(m_maxProgress);
|
||||||
setStatus(UpdateStatus_ErrorNoConnection);
|
setStatus(UpdateStatus_ErrorNoConnection);
|
||||||
return;
|
return;
|
||||||
@ -319,19 +321,14 @@ void UpdateChecker::checkForUpdates(void)
|
|||||||
|
|
||||||
// ----- Test Known Hosts Connectivity ----- //
|
// ----- Test Known Hosts Connectivity ----- //
|
||||||
|
|
||||||
QStringList hostList;
|
int connectionScore = 0;
|
||||||
for(int i = 0; known_hosts[i]; i++)
|
|
||||||
{
|
|
||||||
hostList << QString::fromLatin1(known_hosts[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(!(hostList.isEmpty() || (connectionScore >= MIN_CONNSCORE) || (maxConnectTries < 1)))
|
QStringList hostList = buildRandomList(known_hosts);
|
||||||
|
while(!(hostList.isEmpty() || (connectionScore >= MIN_CONNSCORE)))
|
||||||
{
|
{
|
||||||
switch(tryContactHost(hostList.takeAt(next_rand32() % hostList.count())))
|
if(tryContactHost(hostList.takeFirst()))
|
||||||
{
|
{
|
||||||
case 01: connectionScore += 1; break;
|
connectionScore += 1;
|
||||||
case 02: connectionScore += 2; break;
|
|
||||||
default: maxConnectTries -= 1; break;
|
|
||||||
}
|
}
|
||||||
setProgress(qBound(1, connectionScore + 1, MIN_CONNSCORE + 1));
|
setProgress(qBound(1, connectionScore + 1, MIN_CONNSCORE + 1));
|
||||||
msleep(64);
|
msleep(64);
|
||||||
@ -345,33 +342,12 @@ void UpdateChecker::checkForUpdates(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----- Build Mirror List ----- //
|
|
||||||
|
|
||||||
log("", "----", "", "Checking for updates online...");
|
|
||||||
setStatus(UpdateStatus_FetchingUpdates);
|
|
||||||
|
|
||||||
QStringList mirrorList;
|
|
||||||
for(int index = 0; update_mirrors_prim[index]; index++)
|
|
||||||
{
|
|
||||||
mirrorList << QString::fromLatin1(update_mirrors_prim[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(const int len = mirrorList.count())
|
|
||||||
{
|
|
||||||
const int rounds = len * 1097;
|
|
||||||
for(int i = 0; i < rounds; i++)
|
|
||||||
{
|
|
||||||
mirrorList.swap(i % len, next_rand32() % len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int index = 0; update_mirrors_back[index]; index++)
|
|
||||||
{
|
|
||||||
mirrorList << QString::fromLatin1(update_mirrors_back[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----- Fetch Update Info From Server ----- //
|
// ----- Fetch Update Info From Server ----- //
|
||||||
|
|
||||||
|
log("----", "", "Checking for updates online...");
|
||||||
|
setStatus(UpdateStatus_FetchingUpdates);
|
||||||
|
|
||||||
|
QStringList mirrorList = buildRandomList(update_mirrors);
|
||||||
while(!mirrorList.isEmpty())
|
while(!mirrorList.isEmpty())
|
||||||
{
|
{
|
||||||
QString currentMirror = mirrorList.takeFirst();
|
QString currentMirror = mirrorList.takeFirst();
|
||||||
@ -385,7 +361,7 @@ void UpdateChecker::checkForUpdates(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msleep(64);
|
msleep(25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,21 +405,11 @@ void UpdateChecker::testKnownHosts(void)
|
|||||||
QString currentHost = hostList.takeFirst();
|
QString currentHost = hostList.takeFirst();
|
||||||
qDebug("Testing: %s", currentHost.toLatin1().constData());
|
qDebug("Testing: %s", currentHost.toLatin1().constData());
|
||||||
log("", "Testing:", currentHost, "");
|
log("", "Testing:", currentHost, "");
|
||||||
QString outFile = QString("%1/%2.htm").arg(temp_folder(), rand_str());
|
if (!tryContactHost(currentHost))
|
||||||
bool httpOk = false;
|
|
||||||
if(!getFile(currentHost, outFile, 0, &httpOk))
|
|
||||||
{
|
{
|
||||||
if(httpOk)
|
qWarning("\nConnectivity test FAILED on the following host:\n%s\n", currentHost.toLatin1().constData());
|
||||||
{
|
|
||||||
qWarning("\nConnectivity test was SLOW on the following site:\n%s\n", currentHost.toLatin1().constData());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("\nConnectivity test FAILED on the following site:\n%s\n", currentHost.toLatin1().constData());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log("", "---");
|
log("", "---");
|
||||||
QFile::remove(outFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,35 +443,6 @@ void UpdateChecker::log(const QString &str1, const QString &str2, const QString
|
|||||||
if(!str4.isNull()) emit messageLogged(str4);
|
if(!str4.isNull()) emit messageLogged(str4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UpdateChecker::tryContactHost(const QString &url)
|
|
||||||
{
|
|
||||||
int result = -1; bool httpOkay = false;
|
|
||||||
const QString outFile = QString("%1/%2.htm").arg(temp_folder(), rand_str());
|
|
||||||
log("", "Testing host:", url);
|
|
||||||
|
|
||||||
if(getFile(url, outFile, 0, &httpOkay))
|
|
||||||
{
|
|
||||||
log("Connection to host was established successfully.");
|
|
||||||
result = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(httpOkay)
|
|
||||||
{
|
|
||||||
log("Connection to host timed out after HTTP OK was received.");
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Connection failed: The host could not be reached!");
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile::remove(outFile);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateChecker::tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url)
|
bool UpdateChecker::tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@ -556,155 +493,6 @@ bool UpdateChecker::getUpdateInfo(const QString &url, const QString &outFileVers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateChecker::getFile(const QString &url, const QString &outFile, const unsigned int maxRedir, bool *httpOk)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
if(getFile(url, (i > 0), outFile, maxRedir, httpOk))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateChecker::getFile(const QString &url, const bool forceIp4, const QString &outFile, const unsigned int maxRedir, bool *httpOk)
|
|
||||||
{
|
|
||||||
QFileInfo output(outFile);
|
|
||||||
output.setCaching(false);
|
|
||||||
if(httpOk) *httpOk = false;
|
|
||||||
|
|
||||||
if(output.exists())
|
|
||||||
{
|
|
||||||
QFile::remove(output.canonicalFilePath());
|
|
||||||
if(output.exists())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QProcess process;
|
|
||||||
init_process(process, output.absolutePath());
|
|
||||||
|
|
||||||
QStringList args;
|
|
||||||
if(forceIp4)
|
|
||||||
{
|
|
||||||
args << "-4";
|
|
||||||
}
|
|
||||||
|
|
||||||
args << "-T" << "15" << "--no-cache" << "--no-dns-cache" << QString().sprintf("--max-redirect=%u", maxRedir);
|
|
||||||
args << QString("--referer=%1://%2/").arg(QUrl(url).scheme(), QUrl(url).host()) << "-U" << USER_AGENT_STR;
|
|
||||||
args << "-O" << output.fileName() << url;
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
|
|
||||||
connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit()));
|
|
||||||
connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit()));
|
|
||||||
|
|
||||||
QTimer timer;
|
|
||||||
timer.setSingleShot(true);
|
|
||||||
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
|
||||||
|
|
||||||
const QRegExp httpResponseOK("200 OK$");
|
|
||||||
|
|
||||||
process.start(m_binaryWGet, args);
|
|
||||||
|
|
||||||
if(!process.waitForStarted())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.start(25000);
|
|
||||||
|
|
||||||
while(process.state() != QProcess::NotRunning)
|
|
||||||
{
|
|
||||||
loop.exec();
|
|
||||||
const bool bTimeOut = (!timer.isActive());
|
|
||||||
while(process.canReadLine())
|
|
||||||
{
|
|
||||||
QString line = QString::fromLatin1(process.readLine()).simplified();
|
|
||||||
if(line.contains(httpResponseOK))
|
|
||||||
{
|
|
||||||
line.append(" [OK]");
|
|
||||||
if(httpOk) *httpOk = true;
|
|
||||||
}
|
|
||||||
log(line);
|
|
||||||
}
|
|
||||||
if(bTimeOut)
|
|
||||||
{
|
|
||||||
qWarning("WGet process timed out <-- killing!");
|
|
||||||
process.kill();
|
|
||||||
process.waitForFinished();
|
|
||||||
log("!!! TIMEOUT !!!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.stop();
|
|
||||||
timer.disconnect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
|
||||||
|
|
||||||
log(QString().sprintf("Exited with code %d", process.exitCode()));
|
|
||||||
return (process.exitCode() == 0) && output.exists() && output.isFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateChecker::checkSignature(const QString &file, const QString &signature)
|
|
||||||
{
|
|
||||||
if(QFileInfo(file).absolutePath().compare(QFileInfo(signature).absolutePath(), Qt::CaseInsensitive) != 0)
|
|
||||||
{
|
|
||||||
qWarning("CheckSignature: File and signature should be in same folder!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString keyRingPath(m_binaryKeys);
|
|
||||||
bool removeKeyring = false;
|
|
||||||
if(QFileInfo(file).absolutePath().compare(QFileInfo(m_binaryKeys).absolutePath(), Qt::CaseInsensitive) != 0)
|
|
||||||
{
|
|
||||||
keyRingPath = make_temp_file(QFileInfo(file).absolutePath(), "gpg");
|
|
||||||
removeKeyring = true;
|
|
||||||
if(!QFile::copy(m_binaryKeys, keyRingPath))
|
|
||||||
{
|
|
||||||
qWarning("CheckSignature: Failed to copy the key-ring file!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QProcess process;
|
|
||||||
init_process(process, QFileInfo(file).absolutePath());
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
|
|
||||||
connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit()));
|
|
||||||
connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit()));
|
|
||||||
|
|
||||||
process.start(m_binaryGnuPG, QStringList() << "--homedir" << "." << "--keyring" << QFileInfo(keyRingPath).fileName() << QFileInfo(signature).fileName() << QFileInfo(file).fileName());
|
|
||||||
|
|
||||||
if(!process.waitForStarted())
|
|
||||||
{
|
|
||||||
if(removeKeyring)
|
|
||||||
{
|
|
||||||
remove_file(keyRingPath);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(process.state() == QProcess::Running)
|
|
||||||
{
|
|
||||||
loop.exec();
|
|
||||||
while(process.canReadLine())
|
|
||||||
{
|
|
||||||
log(QString::fromLatin1(process.readLine()).simplified());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(removeKeyring)
|
|
||||||
{
|
|
||||||
remove_file(keyRingPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
log(QString().sprintf("Exited with code %d", process.exitCode()));
|
|
||||||
return (process.exitCode() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo)
|
bool UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo)
|
||||||
{
|
{
|
||||||
QRegExp value("^(\\w+)=(.+)$");
|
QRegExp value("^(\\w+)=(.+)$");
|
||||||
@ -808,6 +596,218 @@ bool UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *upd
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// EXTERNAL TOOLS
|
||||||
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
bool UpdateChecker::getFile(const QString &url, const QString &outFile, const unsigned int maxRedir, bool *httpOk)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (getFile(url, (i > 0), outFile, maxRedir, httpOk))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateChecker::getFile(const QString &url, const bool forceIp4, const QString &outFile, const unsigned int maxRedir, bool *httpOk)
|
||||||
|
{
|
||||||
|
QFileInfo output(outFile);
|
||||||
|
output.setCaching(false);
|
||||||
|
if (httpOk) *httpOk = false;
|
||||||
|
|
||||||
|
if (output.exists())
|
||||||
|
{
|
||||||
|
QFile::remove(output.canonicalFilePath());
|
||||||
|
if (output.exists())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QProcess process;
|
||||||
|
init_process(process, output.absolutePath());
|
||||||
|
|
||||||
|
QStringList args;
|
||||||
|
if (forceIp4)
|
||||||
|
{
|
||||||
|
args << "-4";
|
||||||
|
}
|
||||||
|
|
||||||
|
args << "-T" << "15" << "--no-cache" << "--no-dns-cache" << QString().sprintf("--max-redirect=%u", maxRedir);
|
||||||
|
args << QString("--referer=%1://%2/").arg(QUrl(url).scheme(), QUrl(url).host()) << "-U" << USER_AGENT_STR;
|
||||||
|
args << "-O" << output.fileName() << url;
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
QTimer timer;
|
||||||
|
timer.setSingleShot(true);
|
||||||
|
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
const QRegExp httpResponseOK("200 OK$");
|
||||||
|
|
||||||
|
process.start(m_binaryWGet, args);
|
||||||
|
|
||||||
|
if (!process.waitForStarted())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.start(25000);
|
||||||
|
|
||||||
|
while (process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
loop.exec();
|
||||||
|
const bool bTimeOut = (!timer.isActive());
|
||||||
|
while (process.canReadLine())
|
||||||
|
{
|
||||||
|
QString line = QString::fromLatin1(process.readLine()).simplified();
|
||||||
|
if (line.contains(httpResponseOK))
|
||||||
|
{
|
||||||
|
line.append(" [OK]");
|
||||||
|
if (httpOk) *httpOk = true;
|
||||||
|
}
|
||||||
|
log(line);
|
||||||
|
}
|
||||||
|
if (bTimeOut)
|
||||||
|
{
|
||||||
|
qWarning("WGet process timed out <-- killing!");
|
||||||
|
process.kill();
|
||||||
|
process.waitForFinished();
|
||||||
|
log("!!! TIMEOUT !!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.stop();
|
||||||
|
timer.disconnect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
log(QString().sprintf("Exited with code %d", process.exitCode()));
|
||||||
|
return (process.exitCode() == 0) && output.exists() && output.isFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateChecker::tryContactHost(const QString &hostname)
|
||||||
|
{
|
||||||
|
log(QString("Connecting to host: %1").arg(hostname));
|
||||||
|
|
||||||
|
QProcess process;
|
||||||
|
init_process(process, temp_folder());
|
||||||
|
|
||||||
|
QStringList args;
|
||||||
|
args << "-z" << hostname << QString::number(80);
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
QTimer timer;
|
||||||
|
timer.setSingleShot(true);
|
||||||
|
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
process.start(m_binaryNC, args);
|
||||||
|
|
||||||
|
if (!process.waitForStarted())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.start(25000);
|
||||||
|
|
||||||
|
while (process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
loop.exec();
|
||||||
|
const bool bTimeOut = (!timer.isActive());
|
||||||
|
while (process.canReadLine())
|
||||||
|
{
|
||||||
|
QString line = QString::fromLatin1(process.readLine()).simplified();
|
||||||
|
log(line);
|
||||||
|
}
|
||||||
|
if (bTimeOut)
|
||||||
|
{
|
||||||
|
qWarning("NC process timed out <-- killing!");
|
||||||
|
process.kill();
|
||||||
|
process.waitForFinished();
|
||||||
|
log("!!! TIMEOUT !!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.stop();
|
||||||
|
timer.disconnect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
if (process.exitCode() != 0)
|
||||||
|
{
|
||||||
|
log("Connection has failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
log(QString().sprintf("Exited with code %d", process.exitCode()), "");
|
||||||
|
return (process.exitCode() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateChecker::checkSignature(const QString &file, const QString &signature)
|
||||||
|
{
|
||||||
|
if (QFileInfo(file).absolutePath().compare(QFileInfo(signature).absolutePath(), Qt::CaseInsensitive) != 0)
|
||||||
|
{
|
||||||
|
qWarning("CheckSignature: File and signature should be in same folder!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString keyRingPath(m_binaryKeys);
|
||||||
|
bool removeKeyring = false;
|
||||||
|
if (QFileInfo(file).absolutePath().compare(QFileInfo(m_binaryKeys).absolutePath(), Qt::CaseInsensitive) != 0)
|
||||||
|
{
|
||||||
|
keyRingPath = make_temp_file(QFileInfo(file).absolutePath(), "gpg");
|
||||||
|
removeKeyring = true;
|
||||||
|
if (!QFile::copy(m_binaryKeys, keyRingPath))
|
||||||
|
{
|
||||||
|
qWarning("CheckSignature: Failed to copy the key-ring file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QProcess process;
|
||||||
|
init_process(process, QFileInfo(file).absolutePath());
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
|
||||||
|
connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit()));
|
||||||
|
|
||||||
|
process.start(m_binaryGnuPG, QStringList() << "--homedir" << "." << "--keyring" << QFileInfo(keyRingPath).fileName() << QFileInfo(signature).fileName() << QFileInfo(file).fileName());
|
||||||
|
|
||||||
|
if (!process.waitForStarted())
|
||||||
|
{
|
||||||
|
if (removeKeyring)
|
||||||
|
{
|
||||||
|
remove_file(keyRingPath);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (process.state() == QProcess::Running)
|
||||||
|
{
|
||||||
|
loop.exec();
|
||||||
|
while (process.canReadLine())
|
||||||
|
{
|
||||||
|
log(QString::fromLatin1(process.readLine()).simplified());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeKeyring)
|
||||||
|
{
|
||||||
|
remove_file(keyRingPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(QString().sprintf("Exited with code %d", process.exitCode()));
|
||||||
|
return (process.exitCode() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// SLOTS
|
// SLOTS
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user