2014-01-04 06:14:30 +00:00
# include "installdialog.h"
# include "mainwindow.h"
# include "ui_installdialog.h"
2014-01-06 04:59:41 +00:00
# include "../node/Constants.hpp"
2014-01-04 06:14:30 +00:00
# include "../node/Defaults.hpp"
2014-01-06 00:24:12 +00:00
# include "../node/SoftwareUpdater.hpp"
2014-01-04 06:14:30 +00:00
2014-01-06 04:59:41 +00:00
# ifdef __UNIX_LIKE__
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/stat.h>
# include <fcntl.h>
# endif
2014-01-04 06:14:30 +00:00
# include <QMainWindow>
# include <QMessageBox>
# include <QByteArray>
# include <QSslSocket>
2014-01-06 04:59:41 +00:00
# include <QFile>
# include <QDir>
# include <QProcess>
2014-01-04 06:14:30 +00:00
InstallDialog : : InstallDialog ( QWidget * parent ) :
QDialog ( parent ) ,
ui ( new Ui : : InstallDialog ) ,
2014-01-06 00:24:12 +00:00
nam ( new QNetworkAccessManager ( this ) ) ,
phase ( FETCHING_NFO )
2014-01-04 06:14:30 +00:00
{
ui - > setupUi ( this ) ;
QObject : : connect ( nam , SIGNAL ( finished ( QNetworkReply * ) ) , this , SLOT ( on_networkReply ( QNetworkReply * ) ) ) ;
const char * nfoUrl = ZeroTier : : ZT_DEFAULTS . updateLatestNfoURL . c_str ( ) ;
if ( ! * nfoUrl ) {
QMessageBox : : critical ( this , " Download Failed " , " Download failed: internal error: no update URL configured in build! " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
QNetworkReply * reply = nam - > get ( QNetworkRequest ( QUrl ( nfoUrl ) ) ) ;
QObject : : connect ( reply , SIGNAL ( downloadProgress ( qint64 , qint64 ) ) , this , SLOT ( on_downloadProgress ( qint64 , qint64 ) ) ) ;
}
InstallDialog : : ~ InstallDialog ( )
{
delete ui ;
}
void InstallDialog : : on_networkReply ( QNetworkReply * reply )
{
reply - > deleteLater ( ) ;
if ( reply - > error ( ) ! = QNetworkReply : : NoError ) {
2014-01-06 04:59:41 +00:00
QMessageBox : : critical ( this , " Download Failed " , QString ( " Download failed: " ) + reply - > errorString ( ) + " \n \n Are you connected to the Internet? " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
2014-01-04 06:14:30 +00:00
QApplication : : exit ( 1 ) ;
} else {
if ( reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) = = 200 ) {
QByteArray installerData ( reply - > readAll ( ) ) ;
2014-01-06 00:24:12 +00:00
switch ( phase ) {
case FETCHING_NFO : {
unsigned int vMajor = 0 , vMinor = 0 , vRevision = 0 ;
installerData . append ( ( char ) 0 ) ;
const char * err = ZeroTier : : SoftwareUpdater : : parseNfo ( installerData . data ( ) , vMajor , vMinor , vRevision , signedBy , signature , url ) ;
if ( err ) {
QMessageBox : : critical ( this , " Download Failed " , " Download failed: there is a problem with the software update web site. \n Try agian later. (invalid .nfo file) " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
phase = FETCHING_INSTALLER ;
reply = nam - > get ( QNetworkRequest ( QUrl ( url . c_str ( ) ) ) ) ;
QObject : : connect ( reply , SIGNAL ( downloadProgress ( qint64 , qint64 ) ) , this , SLOT ( on_downloadProgress ( qint64 , qint64 ) ) ) ;
} break ;
case FETCHING_INSTALLER : {
if ( ! ZeroTier : : SoftwareUpdater : : validateUpdate ( installerData . data ( ) , installerData . length ( ) , signedBy , signature ) ) {
QMessageBox : : critical ( this , " Download Failed " , " Download failed: there is a problem with the software update web site. \n Try agian later. (failed signature check) " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
2014-01-06 04:59:41 +00:00
# ifdef __APPLE__
QString zt1Caches ( QDir : : homePath ( ) + " /Library/Caches/ZeroTier/One " ) ;
QDir : : root ( ) . mkpath ( zt1Caches ) ;
QString instPath ( zt1Caches + " /ZeroTierOneInstaller " ) ;
int outfd = : : open ( instPath . toStdString ( ) . c_str ( ) , O_CREAT | O_TRUNC | O_WRONLY , 0755 ) ;
if ( outfd < = 0 ) {
QMessageBox : : critical ( this , " Download Failed " , QString ( " Installation failed: unable to write to " ) + instPath , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
if ( : : write ( outfd , installerData . data ( ) , installerData . length ( ) ) ! = installerData . length ( ) ) {
QMessageBox : : critical ( this , " Installation Failed " , QString ( " Installation failed: unable to write to " ) + instPath , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
: : close ( outfd ) ;
: : chmod ( instPath . toStdString ( ) . c_str ( ) , 0755 ) ;
QString installHelperPath ( QCoreApplication : : applicationDirPath ( ) + " /../Resources/helpers/mac/ZeroTier One (Install).app/Contents/MacOS/applet " ) ;
if ( ! QFile : : exists ( installHelperPath ) ) {
QMessageBox : : critical ( this , " Unable to Locate Helper " , " Unable to locate install helper, cannot install service. " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
QProcess : : execute ( installHelperPath , QStringList ( ) ) ;
if ( ! QFile : : exists ( " /Library/Application Support/ZeroTier/One/zerotier-one " ) ) {
QMessageBox : : critical ( this , " Installation Failed " , " Installation failed. Are you sure you entered your password correctly? " , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
return ;
}
( ( QMainWindow * ) this - > parent ( ) ) - > setHidden ( false ) ;
this - > close ( ) ;
return ;
# endif
2014-01-06 00:24:12 +00:00
} break ;
}
ui - > progressBar - > setMinimum ( 0 ) ;
ui - > progressBar - > setMaximum ( 100 ) ;
ui - > progressBar - > setValue ( 0 ) ;
2014-01-04 06:14:30 +00:00
} else {
QMessageBox : : critical ( this , " Download Failed " , QString ( " Download failed: HTTP status code " ) + reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) . toString ( ) , QMessageBox : : Ok , QMessageBox : : NoButton ) ;
QApplication : : exit ( 1 ) ;
}
}
}
void InstallDialog : : on_InstallDialog_rejected ( )
{
QApplication : : exit ( ) ;
}
void InstallDialog : : on_cancelButton_clicked ( )
{
QApplication : : exit ( ) ;
}
void InstallDialog : : on_downloadProgress ( qint64 bytesReceived , qint64 bytesTotal )
{
if ( bytesTotal < = 0 ) {
ui - > progressBar - > setValue ( 0 ) ;
ui - > progressBar - > setMinimum ( 0 ) ;
ui - > progressBar - > setMaximum ( 0 ) ;
} else {
double pct = ( ( double ) bytesReceived / ( double ) bytesTotal ) * 100.0 ;
if ( pct > 100.0 )
pct = 100.0 ;
ui - > progressBar - > setMinimum ( 0 ) ;
ui - > progressBar - > setMaximum ( 100 ) ;
ui - > progressBar - > setValue ( ( int ) pct ) ;
}
}