summaryrefslogtreecommitdiffstats
path: root/src/update.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/update.cpp')
-rw-r--r--src/update.cpp646
1 files changed, 646 insertions, 0 deletions
diff --git a/src/update.cpp b/src/update.cpp
new file mode 100644
index 0000000..0785526
--- /dev/null
+++ b/src/update.cpp
@@ -0,0 +1,646 @@
+/***************************************************************************
+ * $Id: update.cpp,v 1.26 2008/12/08 19:39:02 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * 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. *
+ * *
+ * 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 for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "update.h"
+
+#include <kstaticdeleter.h>
+
+#include <klocale.h>
+#include <kio/netaccess.h>
+
+
+#include <kaction.h>
+
+#include <qcheckbox.h>
+#include <kbuttonbox.h>
+#include <kurlcompletion.h>
+#include <kcombobox.h>
+#include <qlayout.h>
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <ktempfile.h>
+#include <ksystemtray.h>
+#include <ktar.h>
+#include <kprogress.h>
+#include <kprocio.h>
+#include <knotifyclient.h>
+#include <dom/html_misc.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kuser.h>
+
+#include <qtimer.h>
+#include <qdir.h>
+#include "version.h"
+
+#include <stdlib.h>
+
+const char *mirrors[] = {
+ "heanet",
+ "internap",
+ "surfnet",
+ "umn",
+ "nchc",
+ "ufpr",
+ "unc",
+ "jaist",
+ "voxel",
+ "citkit",
+ "optusnet",
+ "ovh",
+ "mesh",
+ "easynews",
+ "switch",
+ "kent",
+ "puzzle",
+ 0
+};
+
+TorkUpdate::TorkUpdate(QWidget *parent, const char *name)
+ : QWidget(parent, name),filelist(new KHTMLPart(this))
+{
+
+}
+
+
+TorkUpdate::~TorkUpdate()
+{
+}
+
+
+void TorkUpdate::downloadComponent(QString component, QString version, QString extension)
+{
+
+ upgradeinprogress = true;
+
+ QString location = getenv("HOME");
+
+ location += "/.tork";
+ QDir torkdir(location);
+ if (!torkdir.exists() && !torkdir.mkdir(location))
+ location = getenv("HOME");
+
+ QString currenttor = location + QString("/%1-%2").arg(component).arg(version);
+ QDir tordir(currenttor);
+
+ QString configure;
+ configure = QString("%1/%2-%3/configure").arg(location).arg(component).arg(version);
+
+ QFile configurefile(configure);
+
+ bool download = true;
+
+ if (torkdir.exists() && configurefile.exists()){
+ int result = KMessageBox::questionYesNo(0, i18n( "You seem to have downloaded %1-%2 already (in %3/%4-%5). Would you like to skip re-downloading it and just try to compile it?").arg(component).arg(version).arg(location).arg(component).arg(version),i18n( "Compile %1" ).arg(component));
+
+ switch (result) {
+ case KMessageBox::Yes :
+ download = true;break;
+ case KMessageBox::No :
+ download = false;
+ }
+ }
+
+ QStringList entry;
+ while (download){
+
+ startProgressDialog( i18n( "Downloading %1-%2..." ).arg(component).arg(version) );
+
+ QString dlLocation;
+ QString dlLocationSig;
+ if (component == "tor"){
+ dlLocation = QString("https://torproject.org/dist/%3").arg(highestsofarfilename);
+ dlLocationSig = QString("https://torproject.org/dist/%3.asc").arg(highestsofarfilename);
+ }else if (component == "privoxy")
+ dlLocation = QString("http://%1.dl.sourceforge.net/sourceforge%3").arg(getMirror()).arg(highestsofarfilename);
+ else if (component == "dante")
+ dlLocation = QString("http://www.mirrors.wiretapped.net/security/firewalls/dante/%3").arg(highestsofarfilename);
+ else if (component == "thttpd")
+ dlLocation = QString("http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz");
+ else if (component == "Mixminion")
+ dlLocation = QString("http://www.mixminion.net/dist/0.0.8alpha3/Mixminion-0.0.8alpha3.tar.gz");
+ else
+ dlLocation = QString("http://%1.dl.sourceforge.net/sourceforge/%2/%3-%4%5").arg(getMirror()).arg(component).arg(component).arg(version).arg(extension);
+
+ QString tmpFile;
+ if ( !KIO::NetAccess::download( dlLocation, tmpFile, 0L ) ){
+ KMessageBox::information (0,i18n("Couldn't download %1.").arg(component));
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ upgradeinprogress = false;
+ return;
+ }
+
+ QString tmpFile2;
+ if (!dlLocationSig.isEmpty()){
+ if ( !KIO::NetAccess::download( dlLocationSig, tmpFile2, 0L ) ){
+ KMessageBox::information (0,i18n("Couldn't download %1 signature file.").arg(component));
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ upgradeinprogress = false;
+ return;
+ }
+ int res = KMessageBox::questionYesNo(0, i18n( "<p>Before proceeding you should verify the source package we have just downloaded. You can copy and paste the commands below into a terminal session such as Konsole.<br>"
+ "<br>"
+ "<b>Step One</b> Import the keys used by the Tor developers to sign the Tor source code:<br>"
+ "<b>gpg --keyserver subkeys.pgp.net --recv-keys 0x28988BF5</b><br>"
+ "<b>gpg --keyserver subkeys.pgp.net --recv-keys 0x165733EA</b><br>"
+ "<br>"
+ "<b>Step Two</b> To verify the source package we have just downloaded:<br>"
+ "<b>gpg --verify %1 %2</b><br>"
+ "<br>"
+ "For further info on what you should expect to see, visit: <b>http://wiki.noreply.org/noreply/TheOnionRouter/VerifyingSignatures</b>"
+ "<br>"
+ "<br> Are you happy that the source file is authentic?</p>").arg(tmpFile2).arg(tmpFile));
+ switch (res) {
+ case KMessageBox::Yes :
+ break;
+ case KMessageBox::No :
+ default:
+ updateCanceled();
+ delete progressDialog;
+ progressDialog = 0;
+ return;
+ return;
+ }
+
+ }
+
+ if ((progressDialog) && (progressDialog->wasCancelled())){
+ updateCanceled();
+ return;
+ }
+
+
+
+ progressDialog->setLabel( i18n( "Unpacking %1-%2 to %3/%4-%5" ).arg(component).arg(version).arg(location).arg(component).arg(version));
+
+ // unpack the tarball
+ KTar tar( tmpFile );
+ if (!(tar.open( IO_ReadOnly ))){
+ int result = KMessageBox::questionYesNo(0, i18n( "The mirror I attempted to download from has not updated yet. Should I try another?"));
+ switch (result) {
+ case KMessageBox::Yes :
+ download = true; break;
+ case KMessageBox::No :
+ download = false;
+ default:
+ download = false;
+ }
+ }else{
+ download = false;
+ }
+ tar.directory()->copyTo( location );
+ entry = tar.directory()->entries();
+ tar.close();
+ // remove the temp file
+ //KIO::NetAccess::removeTempFile( tmpFile );
+
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ }
+
+// if ((progressDialog) && (progressDialog->wasCancelled())){
+// updateCanceled();
+// delete progressDialog;
+// progressDialog = 0;
+// return;
+// }
+
+ //KTar does not honour executable permissions
+
+ if (component == "privoxy"){
+ configure = QString("%1/%2/").arg(location).arg(entry.first());
+ configurefile.setName(configure+"configure.in");
+ }
+
+ if (component == "Mixminion"){
+ configure = QString("%1/%2/").arg(location).arg(entry.first());
+ configurefile.setName(configure+"README");
+ }
+
+ if (torkdir.exists() && configurefile.exists()){
+
+ chmod((const char *)configure,0700);
+
+ int result = KMessageBox::warningContinueCancel(0, i18n( "%1-%2 is ready for compiling and installation. Would you like the wizard to ask you for the root password so it can compile and install it for you? (If not, you can compile it yourself later at %3/%4-%5)").arg(component).arg(version).arg(location).arg(component).arg(version),i18n( "Install %1-%2" ).arg(component).arg(version),i18n( "Use the Wizard" ));
+
+ switch (result) {
+ case 2 :
+ KMessageBox::information (0,i18n("Installation of %1 Cancelled.").arg(component));
+ upgradeinprogress = false;
+ break;
+ case 5 :
+
+ KProcess* arkollonproc = new KShellProcess();
+
+ KMessageBox::information (this,i18n( "<p><b>If this the first time you've compiled software then here are a few useful tips:</b><br>"
+ "1. Any error messages in the log file with the words 'KDE', 'Qt','curl' or 'X' in them mean that you need to install "
+ "the appropriate development libraries.<br>"
+ "2. Any package provided by your distribution with 'lib' or 'devel' in the name is a development library, e.g. qt-devel, libkde.<br>"
+ "</p>" ),"Compilation Tips","compiler");
+
+ QString command;
+ if (component == "Mixminion")
+ command = QString("kdesu -i tork -c 'xterm -hold -e \"cd %1;make install;printf \\\"If there were errors try downloading and installing Mixminion from the Mixminion homepage. If the installation looks successful try sending an anonymous mail to yourself. Close the window to continue.\\\"\"'").arg(configure);
+ else if (component == "privoxy")
+ command = QString("cd %1; autoheader;autoconf;torkarkollon %2").arg(configure).arg(configure);
+ else
+ command = QString("torkarkollon %1/%2-%3").arg(location).arg(component).arg(version);
+
+ *arkollonproc << command;
+
+ connect( arkollonproc, SIGNAL(processExited(KProcess *)), SLOT(torkInstallationExited(KProcess *)) );
+ arkollonproc->start();
+ }
+ }
+
+}
+
+void TorkUpdate::downloadThttpd()
+{
+/* startProgressDialog( i18n( "Downloading thttpd..." ) );*/
+ downloadComponent("thttpd", "2.25b", "tar.gz");
+}
+
+void TorkUpdate::downloadMixminion()
+{
+/* startProgressDialog( i18n( "Downloading thttpd..." ) );*/
+ downloadComponent("Mixminion", "0.0.8alpha3", "tar.gz");
+}
+
+void TorkUpdate::checkForNewTork()
+{
+
+ highestsofarnumeric = 0;
+ tork_url = "http://prdownloads.sourceforge.net/tork/";
+ getLatestVersionFromSFHack(tork_url);
+
+}
+
+void TorkUpdate::checkForNewPrivoxyDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://prdownloads.sourceforge.net/ijbswa/";
+ startProgressDialog( i18n( "Checking for new version of Privoxy..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::checkForNewTorkDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://downloadtork.anonymityanywhere.com/";
+ startProgressDialog( i18n( "Checking for new version of Tork..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+
+void TorkUpdate::checkForNewTorDirectly(bool alpha)
+{
+
+ checkingDirectly = true;
+ m_alpha=alpha;
+ highestsofarnumeric = 0;
+ tork_url = "http://torproject.org/dist/";
+
+ startProgressDialog( i18n( "Checking for new version of Tor..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::checkForNewDanteDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://www.mirrors.wiretapped.net/security/firewalls/dante/";
+
+ startProgressDialog( i18n( "Checking for new version of Dante..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::completedSearchForUpdates(const QString &component, const QString &extension)
+{
+
+ double currentversion;
+
+
+ if (component == "Tork")
+ currentversion = VERSION_TORK;
+ else{
+ if (currentTorVersion.mid(currentTorVersion.length() - 2,1) == ".")
+ currentversion = currentTorVersion.replace(currentTorVersion.length() - 2,1,"").toDouble();
+ else
+ currentversion = currentTorVersion.toDouble();
+ }
+
+ if (highestsofarnumeric > currentversion){
+ int result = KMessageBox::warningContinueCancel(0, i18n( "The newest version of %1 available is %2-%3. Would you like Tork to download and compile it for you?").arg(component).arg(component).arg(highestsofarraw),i18n( "Download and Install %1-%2" ).arg(component).arg(highestsofarraw),i18n( "Download and Install %1-%2" ).arg(component).arg(highestsofarraw));
+
+ switch (result) {
+ case 2 :
+ break;
+ case 5 :
+ downloadComponent(component.lower(), highestsofarraw, extension);
+ }
+ }else if (checkingDirectly){
+ KMessageBox::information (this,i18n("Your installation of %1 is already up-to-date!").arg(component));
+ }
+ checkingDirectly = false;
+ m_alpha=false;
+// tork_options->setEnabled(true);
+// tork_options->setEnabled(true);
+
+// if (filelist)
+// filelist->deleteLater();
+
+}
+
+
+
+void TorkUpdate::startProgressDialog( const QString & text )
+{
+
+
+ progressDialog = new KProgressDialog( 0, "progress_dialog", QString::null, text, false );
+
+ progressDialog->setAllowCancel( true );
+ progressDialog->showCancelButton( true );
+ progressDialog->setPlainCaption( i18n( "Please Wait" ) );
+
+ progressDialog->progressBar()->setTotalSteps( 0 );
+ progressDialog->progressBar()->setPercentageVisible( false );
+
+ progressDialog->setMinimumDuration( 500 );
+ progressDialog->show();
+
+ connect( progressDialog, SIGNAL( cancelClicked() ), this,
+ SLOT( updateCanceled() ) );
+
+ timer = new QTimer( this );
+ connect( timer, SIGNAL( timeout() ), this, SLOT( slotProg() ) );
+
+ timer->start( 200, FALSE );
+}
+
+void TorkUpdate::slotProg()
+{
+
+ if (progressDialog)
+ progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
+}
+
+
+void TorkUpdate::torkInstallationExited(KProcess* arkollonproc)
+{
+
+ arkollonproc = 0;
+ delete arkollonproc;
+ upgradeinprogress = false;
+
+ KMessageBox::information (this,i18n( "If the installation completed successfully you should restart the component for the new version to take effect." ));
+
+}
+
+void
+TorkUpdate::checkInternet() //SLOT
+{
+ m_url.setHost( "prdownloads.sourceforge.net" );
+ if ( !m_url.port() ) m_url.setPort( 80 );
+
+ connect( &m_resolver, SIGNAL( finished( KResolverResults ) ), SLOT( resolved( KResolverResults ) ) );
+ connectToHost();
+}
+
+void
+TorkUpdate::connectToHost() //SLOT
+{
+ m_resolver.setNodeName( m_url.host() );
+ m_resolver.setFamily( KResolver::InetFamily );
+ m_resolver.start();
+}
+
+
+void
+TorkUpdate::resolved( KResolverResults result) // SLOT
+{
+ if ((!( result.error() != KResolver::NoError || result.isEmpty() ))
+ /*&& tork_box->isChecked()*/)
+ checkForNewTork();
+ else
+ kdDebug() << "network error or not set to check for new tork" << endl;
+}
+
+
+
+void TorkUpdate::getLatestVersionFromSF(KURL url)
+{
+
+ connect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPage() ) );
+
+ filelist->setStatusMessagesEnabled(false);
+ filelist->openURL(url);
+
+}
+
+void TorkUpdate::getLatestVersionFromSFHack(KURL url)
+{
+
+
+ if (!filelist)
+ filelist = new KHTMLPart();
+
+ connect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPageHack() ) );
+
+ filelist->setStatusMessagesEnabled(false);
+ filelist->openURL(url);
+
+}
+
+
+
+void TorkUpdate::updateCanceled()
+{
+
+ filelist->closeURL();
+// tork_options->setEnabled(true);
+// tork_options->setEnabled(true);
+
+}
+
+void TorkUpdate::parseSFPage()
+{
+
+ const DOM::HTMLCollection links = filelist->htmlDocument().links();
+
+ if (links.length() == 0){
+ KMessageBox::information (this,i18n( "Could not contact update server!" ));
+ updateCanceled();
+ delete progressDialog;
+ progressDialog = 0;
+ return;
+ }
+
+ disconnect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPage() ) );
+
+ for (unsigned int j=0; j != links.length(); j++ ){
+ const DOM::Node linkNode = links.item( j );
+ getVersionFromLink( linkNode );
+ }
+
+ delete progressDialog;
+ progressDialog = 0;
+
+ if (highestsofarfilename.contains("tork"))
+ completedSearchForUpdates("Tork", ".tar.bz2");
+ else if (highestsofarfilename.contains("tor"))
+ completedSearchForUpdates("Tor", ".tar.gz");
+ else if (highestsofarfilename.contains("privoxy"))
+ completedSearchForUpdates("Privoxy", ".tar.gz");
+ else if (highestsofarfilename.contains("dante"))
+ completedSearchForUpdates("Dante", ".tar.gz");
+
+
+}
+
+void TorkUpdate::parseSFPageHack()
+{
+
+ const DOM::HTMLCollection links = filelist->htmlDocument().links();
+
+ if (links.length() == 0){
+ return;
+ }
+
+ disconnect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPageHack() ) );
+
+ for (unsigned int j=0; j != links.length(); j++ ){
+ const DOM::Node linkNode = links.item( j );
+ getVersionFromLink( linkNode );
+ }
+
+ //delete progressDialog;
+ //progressDialog = 0;
+
+ if (highestsofarfilename.contains("tork"))
+ completedSearchForUpdates("Tork", "tar.bz2");
+ else if (highestsofarfilename.contains("tor"))
+ completedSearchForUpdates("Tor", "tar.gz");
+
+
+}
+
+
+void TorkUpdate::getVersionFromLink( const DOM::Node &n )
+{
+ double numericversion;
+ QString tmpversion;
+
+ if ( n.isNull() || n.nodeType() != DOM::Node::ELEMENT_NODE )
+ return;
+
+ DOM::Element elem = static_cast<DOM::Element>( n );
+
+ KURL href ( elem.getAttribute( "href" ).string() );
+
+ QString name = elem.getAttribute( "href" ).string();
+ QString version = name.replace(".tar.bz2","").replace(".tar.gz","");
+ version = version.replace("tork-","").replace("tor-","")
+ .replace("/ijbswa/privoxy-","")
+ .replace("-stable-src","")
+ .replace("dante-","");
+
+ QString rawversion = version;
+ if (m_alpha) {
+ version.remove("-alpha").remove("-beta").remove("-rc");
+ }
+ numericversion = numericizeVersion(version);
+
+ if (numericversion > highestsofarnumeric){
+ highestsofarnumeric = numericversion;
+ highestsofarraw = rawversion;
+ highestsofarfilename = elem.getAttribute( "href" ).string();
+ }
+
+
+}
+
+QString TorkUpdate::getMirror()
+{
+ int r = 1+(int) (16.0*rand()/(RAND_MAX+1.0));
+ static int previousmirror = 0;
+
+ while (r == previousmirror)
+ r=1+(int) (16.0*rand()/(RAND_MAX+1.0));
+
+ previousmirror = r;
+
+ return mirrors[r];
+}
+
+double TorkUpdate::numericizeVersion(QString &version)
+{
+ QString tmpversion = version;
+ QStringList tokens = QStringList::split(".",tmpversion);
+ for ( QStringList::Iterator it = tokens.begin(); it != tokens.end(); it++ )
+ {
+ if ((*it).length() < 2)
+ (*it).prepend("0");
+ }
+ tmpversion = tokens.join(".");
+
+ unsigned int firstdot = tmpversion.find(".");
+ for (unsigned int j=tmpversion.length(); j != firstdot; j-- ){
+ if (tmpversion.mid(j,1) == "."){
+ tmpversion.remove(j,1);
+ j--;
+ }
+ }
+
+ return tmpversion.toDouble();
+}
+#include "update.moc"
+
+// forward-socks4a / localhost:9050 .