2018-07-20 13:48:29 -04:00
/*******************************************************************************
* retroshare - gui / src / : main . cpp *
* *
* libretroshare : retroshare core library *
* *
* Copyright 2006 by Crypton < retroshare @ lunamutt . com > *
* *
* This program is free software : you can redistribute it and / or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation , either version 3 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 Affero General Public License for more details . *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-14 22:18:48 -05:00
2018-11-04 18:19:45 -05:00
# include "util/stacktrace.h"
2019-08-29 17:15:46 -04:00
# include "util/argstream.h"
2018-11-04 18:19:45 -05:00
CrashStackTrace gCrashStackTrace ;
2007-11-14 22:18:48 -05:00
# include <QObject>
2010-07-23 14:52:58 -04:00
# include <QMessageBox>
2010-10-19 14:06:22 -04:00
# include <QSplashScreen>
2016-08-06 11:15:56 -04:00
2007-11-14 22:18:48 -05:00
# include <rshare.h>
2011-05-17 13:27:47 -04:00
# include "gui/FriendsDialog.h"
2016-08-06 11:15:56 -04:00
# include "gui/GenCertDialog.h"
# include "gui/MainWindow.h"
2010-08-31 16:00:49 -04:00
# include "gui/NetworkDialog.h"
2016-08-06 11:15:56 -04:00
# include "gui/NetworkView.h"
2011-02-22 09:51:03 -05:00
# include "gui/QuickStartWizard.h"
2016-08-06 11:15:56 -04:00
# include "gui/RetroShareLink.h"
# include "gui/SoundManager.h"
2010-06-08 17:38:36 -04:00
# include "gui/StartDialog.h"
2016-08-06 11:15:56 -04:00
# include "gui/chat/ChatDialog.h"
2010-06-08 17:38:36 -04:00
# include "gui/connect/ConfCertDialog.h"
2010-09-14 13:47:11 -04:00
# include "gui/common/Emoticons.h"
2016-08-06 11:15:56 -04:00
# include "gui/FileTransfer/SearchDialog.h"
# include "gui/FileTransfer/TransfersDialog.h"
# include "gui/settings/RsharePeerSettings.h"
# include "gui/settings/rsharesettings.h"
# include "idle/idle.h"
2012-07-15 17:37:35 -04:00
# include "lang/languagesupport.h"
2013-07-14 14:48:40 -04:00
# include "util/RsGxsUpdateBroadcast.h"
2017-12-26 11:21:57 -05:00
# include "util/rsdir.h"
2018-01-27 14:22:31 -05:00
# include "util/rstime.h"
2019-08-29 17:15:46 -04:00
# include "retroshare/rsinit.h"
2016-08-06 11:15:56 -04:00
2019-08-21 09:23:25 -04:00
# ifdef MESSENGER_WINDOW
# include "gui/MessengerWindow.h"
# endif
2018-04-15 06:41:54 -04:00
# ifdef ENABLE_WEBUI
# include "gui / settings / WebuiPage.h"
# endif
2018-09-20 19:58:38 -04:00
# ifdef RS_JSONAPI
# include "gui / settings / JsonApiPage.h"
# endif // RS_JSONAPI
2018-07-25 05:37:40 -04:00
# include "TorControl/TorManager.h"
# include "TorControl/TorControlWindow.h"
2017-12-21 04:43:28 -05:00
2016-08-06 11:15:56 -04:00
# include "retroshare/rsidentity.h"
2017-12-27 12:59:50 -05:00
# include "retroshare/rspeers.h"
2007-11-14 22:18:48 -05:00
2016-06-11 08:38:31 -04:00
# ifdef SIGFPE_DEBUG
# include <fenv.h>
# endif
2013-10-19 19:41:23 -04:00
# if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
# ifdef WINDOWS_SYS
# include <QFileDialog>
# endif
# endif
2017-03-06 00:34:06 -05:00
# ifdef Q_OS_WIN
# if QT_VERSION >= QT_VERSION_CHECK (5, 7, 0)
// see INSTALL.W32 in openssl
// Needed as workaround for gcc 5.3.0 because the call to GetProcAddress in cryptlib.c finds an function pointer
// to the not existing function _OPENSSL_isservice in the executable running on Windows 7.
extern " C " {
__declspec ( dllexport ) __cdecl BOOL _OPENSSL_isservice ( void )
{
DWORD sess ;
if ( ProcessIdToSessionId ( GetCurrentProcessId ( ) , & sess ) )
return sess = = 0 ;
return FALSE ;
}
}
# endif
# endif
2007-11-14 22:18:48 -05:00
/*** WINDOWS DON'T LIKE THIS - REDEFINES VER numbers.
# include <gui/qskinobject/qskinobject.h>
* * * */
2008-08-15 15:03:50 -04:00
# include <util/stringutil.h>
2010-08-06 05:40:23 -04:00
# include <retroshare/rsinit.h>
# include <retroshare/rsiface.h>
2009-12-30 20:34:23 -05:00
# include "gui/notifyqt.h"
2012-04-12 19:29:39 -04:00
# include <unistd.h>
2007-11-14 22:18:48 -05:00
2012-07-20 15:00:10 -04:00
static void displayWarningAboutDSAKeys ( )
{
2014-01-17 21:35:06 -05:00
std : : map < std : : string , std : : vector < std : : string > > unsupported_keys ;
RsAccounts : : GetUnsupportedKeys ( unsupported_keys ) ;
if ( unsupported_keys . empty ( ) )
2012-07-20 15:00:10 -04:00
return ;
QMessageBox msgBox ;
2014-12-30 06:11:08 -05:00
QString txt = QObject : : tr ( " You appear to have nodes associated to DSA keys: " ) ;
2012-07-20 15:00:10 -04:00
txt + = " <UL> " ;
2014-01-17 21:35:06 -05:00
for ( std : : map < std : : string , std : : vector < std : : string > > : : const_iterator it ( unsupported_keys . begin ( ) ) ; it ! = unsupported_keys . end ( ) ; + + it )
2012-07-20 15:00:10 -04:00
{
txt + = " <LI> " + QString : : fromStdString ( it - > first ) ;
txt + = " <UL> " ;
for ( uint32_t i = 0 ; i < it - > second . size ( ) ; + + i )
txt + = " <li> " + QString : : fromStdString ( it - > second [ i ] ) + " </li> " ;
txt + = " </UL> " ;
txt + = " </li> " ;
}
txt + = " </UL> " ;
msgBox . setText ( txt ) ;
2014-12-30 06:11:08 -05:00
msgBox . setInformativeText ( QObject : : tr ( " DSA keys are not yet supported by this version of RetroShare. All these nodes will be unusable. We're very sorry for that. " ) ) ;
2012-07-20 15:00:10 -04:00
msgBox . setStandardButtons ( QMessageBox : : Ok ) ;
msgBox . setDefaultButton ( QMessageBox : : Ok ) ;
2015-06-29 12:08:17 -04:00
msgBox . setWindowIcon ( QIcon ( " :/icons/logo_128.png " ) ) ;
2012-07-20 15:00:10 -04:00
msgBox . exec ( ) ;
}
2013-10-19 19:41:23 -04:00
# ifdef WINDOWS_SYS
2014-06-22 16:40:01 -04:00
# if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0)
2013-10-19 19:41:23 -04:00
QStringList filedialog_open_filenames_hook ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options )
{
return QFileDialog : : getOpenFileNames ( parent , caption , dir , filter , selectedFilter , options | QFileDialog : : DontUseNativeDialog ) ;
}
QString filedialog_open_filename_hook ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options )
{
return QFileDialog : : getOpenFileName ( parent , caption , dir , filter , selectedFilter , options | QFileDialog : : DontUseNativeDialog ) ;
}
QString filedialog_save_filename_hook ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options )
{
return QFileDialog : : getSaveFileName ( parent , caption , dir , filter , selectedFilter , options | QFileDialog : : DontUseNativeDialog ) ;
}
QString filedialog_existing_directory_hook ( QWidget * parent , const QString & caption , const QString & dir , QFileDialog : : Options options )
{
return QFileDialog : : getExistingDirectory ( parent , caption , dir , options | QFileDialog : : DontUseNativeDialog ) ;
}
# endif
# endif
2007-11-14 22:18:48 -05:00
int main ( int argc , char * argv [ ] )
{
2010-11-04 18:54:18 -04:00
# ifdef WINDOWS_SYS
2012-08-31 09:53:54 -04:00
// The current directory of the application is changed when using the native dialog on Windows
// This is a quick fix until libretroshare is using a absolute path in the portable Version
2014-06-22 16:40:01 -04:00
# if QT_VERSION >= QT_VERSION_CHECK (5, 3, 0)
// Do we need a solution in v0.6?
# endif
# if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0)
2013-10-19 19:41:23 -04:00
typedef QStringList ( * _qt_filedialog_open_filenames_hook ) ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options ) ;
typedef QString ( * _qt_filedialog_open_filename_hook ) ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options ) ;
typedef QString ( * _qt_filedialog_save_filename_hook ) ( QWidget * parent , const QString & caption , const QString & dir , const QString & filter , QString * selectedFilter , QFileDialog : : Options options ) ;
typedef QString ( * _qt_filedialog_existing_directory_hook ) ( QWidget * parent , const QString & caption , const QString & dir , QFileDialog : : Options options ) ;
extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook ;
extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook ;
extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook ;
extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook ;
qt_filedialog_open_filename_hook = filedialog_open_filename_hook ;
qt_filedialog_open_filenames_hook = filedialog_open_filenames_hook ;
qt_filedialog_save_filename_hook = filedialog_save_filename_hook ;
qt_filedialog_existing_directory_hook = filedialog_existing_directory_hook ;
2014-06-22 16:40:01 -04:00
# endif
# if QT_VERSION < QT_VERSION_CHECK (5, 0, 0)
2012-08-31 09:53:54 -04:00
extern bool Q_GUI_EXPORT qt_use_native_dialogs ;
qt_use_native_dialogs = false ;
2013-10-19 19:41:23 -04:00
# endif
2012-08-31 09:53:54 -04:00
2012-07-17 18:16:56 -04:00
{
/* Set the current directory to the application dir,
because the start dir with autostart from the registry run key is not the exe dir */
QApplication app ( argc , argv ) ;
QDir : : setCurrent ( QCoreApplication : : applicationDirPath ( ) ) ;
}
2016-06-11 08:38:31 -04:00
# endif
# ifdef SIGFPE_DEBUG
feenableexcept ( FE_INVALID | FE_DIVBYZERO ) ;
2010-11-04 18:54:18 -04:00
# endif
2007-11-14 22:18:48 -05:00
2012-01-22 17:58:23 -05:00
QStringList args = char_array_to_stringlist ( argv + 1 , argc - 1 ) ;
2015-06-27 07:47:37 -04:00
Q_INIT_RESOURCE ( images ) ;
Q_INIT_RESOURCE ( icons ) ;
2007-11-14 22:18:48 -05:00
2016-08-13 08:34:31 -04:00
// Loop through all command-line args/values to get help wanted before RsInit exit.
for ( int i = 0 ; i < args . size ( ) ; + + i ) {
QString arg ;
/* Get the argument name and set a blank value */
arg = args . at ( i ) ;
if ( ( arg . toLower ( ) = = " -h " ) | | ( arg . toLower ( ) = = " --help " ) ) {
QApplication dummyApp ( argc , argv ) ; // needed for QMessageBox
Rshare : : showUsageMessageBox ( ) ;
}
}
2014-01-07 17:51:22 -05:00
// This is needed to allocate rsNotify, so that it can be used to ask for PGP passphrase
//
RsControl : : earlyInitNotificationSystem ( ) ;
2010-07-18 07:43:39 -04:00
NotifyQt * notify = NotifyQt : : Create ( ) ;
2014-01-07 17:51:22 -05:00
rsNotify - > registerNotifyClient ( notify ) ;
2009-11-05 14:38:10 -05:00
2012-01-22 17:58:23 -05:00
/* RetroShare Core Objects */
2009-02-08 09:30:28 -05:00
RsInit : : InitRsConfig ( ) ;
2019-08-29 17:15:46 -04:00
RsConfigOptions conf ;
2019-09-15 10:21:12 -04:00
conf . jsonApiPort = 0 ; // disable JSon API at start. The JSonAPI preference UI will enable it according to saved parameters.
2019-08-29 17:15:46 -04:00
argstream as ( argc , argv ) ;
as > > option ( ' s ' , " stderr " , conf . outStderr , " output to stderr instead of log file. " )
> > option ( ' u ' , " udp " , conf . udpListenerOnly , " Only listen to UDP. " )
> > parameter ( ' c ' , " base-dir " , conf . optBaseDir , " directory " , " Set base directory. " , false )
> > parameter ( ' l ' , " log-file " , conf . logfname , " logfile " , " Set Log filename. " , false )
> > parameter ( ' d ' , " debug-level " , conf . debugLevel , " level " , " Set debug level. " , false )
> > parameter ( ' i ' , " ip-address " , conf . forcedInetAddress , " nnn.nnn.nnn.nnn " , " Force IP address to use (if cannot be detected). " , false )
> > parameter ( ' p ' , " port " , conf . forcedPort , " port " , " Set listenning port to use. " , false )
> > parameter ( ' o ' , " opmode " , conf . opModeStr , " opmode " , " Set Operating mode (Full, NoTurtle, Gaming, Minimal). " , false ) ;
# ifdef RS_JSONAPI
as > > parameter ( ' J ' , " jsonApiPort " , conf . jsonApiPort , " jsonApiPort " , " Enable JSON API on the specified port " , false )
> > parameter ( ' P ' , " jsonApiBindAddress " , conf . jsonApiBindAddress , " jsonApiBindAddress " , " JSON API Bind Address. " , false ) ;
# endif // ifdef RS_JSONAPI
# ifdef LOCALNET_TESTING
as > > parameter ( ' R ' , " restrict-port " , portRestrictions , " port1-port2 " , " Apply port restriction " , false ) ;
# endif // ifdef LOCALNET_TESTING
# ifdef RS_AUTOLOGIN
as > > option ( ' a ' , " auto-login " , conf . autoLogin , " AutoLogin (Windows Only) + StartMinimised " ) ;
# endif // ifdef RS_AUTOLOGIN
conf . main_executable_path = argv [ 0 ] ;
int initResult = RsInit : : InitRetroShare ( conf ) ;
2010-11-03 18:54:34 -04:00
2012-06-09 17:01:22 -04:00
if ( initResult = = RS_INIT_NO_KEYRING ) // happens when we already have accounts, but no pgp key. This is when switching to the openpgp-sdk version.
{
2012-07-17 18:16:56 -04:00
QApplication dummyApp ( argc , argv ) ; // needed for QMessageBox
/* Translate into the desired language */
LanguageSupport : : translate ( LanguageSupport : : defaultLanguageCode ( ) ) ;
2012-06-09 17:01:22 -04:00
QMessageBox msgBox ;
2012-11-28 14:58:14 -05:00
msgBox . setText ( QObject : : tr ( " This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. " ) ) ;
2012-07-13 08:20:44 -04:00
msgBox . setInformativeText ( QObject : : tr ( " Choose between:<br><ul><li><b>Ok</b> to copy the existing keyring from gnupg (safest bet), or </li><li><b>Close without saving</b> to start fresh with an empty keyring (you will be asked to create a new PGP key to work with RetroShare, or import a previously saved pgp keypair). </li><li><b>Cancel</b> to quit and forge a keyring by yourself (needs some PGP skills)</li></ul> " ) ) ;
2012-06-09 17:01:22 -04:00
msgBox . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Discard | QMessageBox : : Cancel ) ;
msgBox . setDefaultButton ( QMessageBox : : Ok ) ;
2015-06-29 12:08:17 -04:00
msgBox . setWindowIcon ( QIcon ( " :/icons/logo_128.png " ) ) ;
2012-06-09 17:01:22 -04:00
int ret = msgBox . exec ( ) ;
if ( ret = = QMessageBox : : Cancel )
return 0 ;
if ( ret = = QMessageBox : : Ok )
{
2014-01-17 21:35:06 -05:00
if ( ! RsAccounts : : CopyGnuPGKeyrings ( ) )
2012-06-09 17:01:22 -04:00
return 0 ;
2019-08-29 17:15:46 -04:00
initResult = RsInit : : InitRetroShare ( conf ) ;
2012-07-20 15:00:10 -04:00
displayWarningAboutDSAKeys ( ) ;
2012-06-09 17:01:22 -04:00
}
else
initResult = RS_INIT_OK ;
}
2010-11-03 18:54:34 -04:00
if ( initResult < 0 ) {
/* Error occured */
2012-07-17 18:16:56 -04:00
QApplication dummyApp ( argc , argv ) ; // needed for QMessageBox
/* Translate into the desired language */
LanguageSupport : : translate ( LanguageSupport : : defaultLanguageCode ( ) ) ;
2012-07-20 15:00:10 -04:00
displayWarningAboutDSAKeys ( ) ;
2010-11-03 18:54:34 -04:00
QMessageBox mb ( QMessageBox : : Critical , QObject : : tr ( " RetroShare " ) , " " , QMessageBox : : Ok ) ;
2015-06-29 12:08:17 -04:00
mb . setWindowIcon ( QIcon ( " :/icons/logo_128.png " ) ) ;
2010-11-03 18:54:34 -04:00
2012-06-09 17:01:22 -04:00
switch ( initResult )
{
case RS_INIT_AUTH_FAILED :
std : : cerr < < " RsInit::InitRetroShare AuthGPG::InitAuth failed " < < std : : endl ;
2012-11-28 14:58:14 -05:00
mb . setText ( QObject : : tr ( " Initialization failed. Wrong or missing installation of PGP. " ) ) ;
2012-06-09 17:01:22 -04:00
break ;
default :
/* Unexpected return code */
std : : cerr < < " RsInit::InitRetroShare unexpected return code " < < initResult < < std : : endl ;
2012-10-11 06:28:24 -04:00
mb . setText ( QObject : : tr ( " An unexpected error occurred. Please report 'RsInit::InitRetroShare unexpected return code %1'. " ) . arg ( initResult ) ) ;
2012-06-09 17:01:22 -04:00
break ;
2010-11-03 18:54:34 -04:00
}
mb . exec ( ) ;
return 1 ;
}
2010-05-20 17:53:27 -04:00
2010-06-14 09:32:13 -04:00
/* create global settings object
path maybe wrong , when no profile exist
in this case it can be use only for default values */
2010-05-20 17:53:27 -04:00
RshareSettings : : Create ( ) ;
2007-11-14 22:18:48 -05:00
/* Setup The GUI Stuff */
2017-12-21 04:43:28 -05:00
Rshare rshare ( args , argc , argv , QString : : fromUtf8 ( RsAccounts : : ConfigDirectory ( ) . c_str ( ) ) ) ;
2016-03-01 07:08:33 -05:00
/* Start RetroShare */
2016-08-06 11:15:56 -04:00
QString sDefaultGXSIdToCreate = " " ;
2010-11-03 18:54:34 -04:00
switch ( initResult ) {
case RS_INIT_OK :
2007-11-14 22:18:48 -05:00
{
2010-11-03 18:54:34 -04:00
/* Login Dialog */
/* check for existing Certificate */
bool genCert = false ;
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > accountIds ;
2014-01-17 21:35:06 -05:00
if ( RsAccounts : : GetAccountIds ( accountIds ) & & ( accountIds . size ( ) > 0 ) )
2009-02-08 09:30:28 -05:00
{
2012-10-31 21:07:36 -04:00
StartDialog sd ;
if ( sd . exec ( ) = = QDialog : : Rejected ) {
return 1 ;
2010-11-03 18:54:34 -04:00
}
/* if we're logged in */
2012-10-31 21:07:36 -04:00
genCert = sd . requestedNewCert ( ) ;
2010-11-03 18:54:34 -04:00
}
else
{
genCert = true ;
2009-02-08 09:30:28 -05:00
}
2007-11-14 22:18:48 -05:00
2010-11-03 18:54:34 -04:00
if ( genCert )
{
2012-10-29 07:02:03 -04:00
GenCertDialog gd ( false ) ;
2017-12-21 12:16:32 -05:00
if ( gd . exec ( ) = = QDialog : : Rejected )
2012-10-31 21:07:36 -04:00
return 1 ;
2017-12-21 12:16:32 -05:00
2016-08-06 11:15:56 -04:00
sDefaultGXSIdToCreate = gd . getGXSNickname ( ) ;
2010-11-03 18:54:34 -04:00
}
2007-11-14 22:18:48 -05:00
2017-12-26 14:42:25 -05:00
//splashScreen.show();
2007-11-14 22:18:48 -05:00
}
2010-11-03 18:54:34 -04:00
break ;
case RS_INIT_HAVE_ACCOUNT :
{
2017-12-26 14:42:25 -05:00
//splashScreen.show();
//splashScreen.showMessage(rshare.translate("SplashScreen", "Load profile"), Qt::AlignHCenter | Qt::AlignBottom);
2010-10-19 14:06:22 -04:00
2014-03-17 16:56:06 -04:00
RsPeerId preferredId ;
2014-01-17 21:35:06 -05:00
RsAccounts : : GetPreferredAccountId ( preferredId ) ;
2010-04-08 11:51:10 -04:00
2010-11-03 18:54:34 -04:00
// true: note auto-login is active
2012-10-31 21:07:36 -04:00
Rshare : : loadCertificate ( preferredId , true ) ;
2010-11-03 18:54:34 -04:00
}
break ;
default :
/* Unexpected return code */
std : : cerr < < " RsInit::InitRetroShare unexpected return code " < < initResult < < std : : endl ;
QMessageBox : : warning ( 0 , QObject : : tr ( " RetroShare " ) , QObject : : tr ( " An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'. " ) . arg ( initResult ) ) ;
return 1 ;
2007-11-14 22:18:48 -05:00
}
2012-01-22 17:58:23 -05:00
/* recreate global settings object, now with correct path */
2011-10-14 17:16:34 -04:00
RshareSettings : : Create ( true ) ;
Rshare : : resetLanguageAndStyle ( ) ;
2012-01-22 17:58:23 -05:00
SoundManager : : create ( ) ;
2018-07-24 17:47:32 -04:00
bool is_hidden_node = false ;
bool is_auto_tor = false ;
bool is_first_time = false ;
2017-12-21 12:16:32 -05:00
2018-07-24 17:47:32 -04:00
RsAccounts : : getCurrentAccountOptions ( is_hidden_node , is_auto_tor , is_first_time ) ;
2017-12-21 12:16:32 -05:00
2018-07-25 05:37:40 -04:00
if ( is_auto_tor )
2018-07-24 17:47:32 -04:00
{
// Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service
2017-12-26 11:21:57 -05:00
2018-07-24 17:47:32 -04:00
QString tor_hidden_service_dir = QString : : fromStdString ( RsAccounts : : AccountDirectory ( ) ) + QString ( " /hidden_service/ " ) ;
2017-12-26 11:21:57 -05:00
2018-07-24 17:47:32 -04:00
Tor : : TorManager * torManager = Tor : : TorManager : : instance ( ) ;
2018-07-27 06:33:06 -04:00
torManager - > setTorDataDirectory ( Rshare : : dataDirectory ( ) + QString ( " /tor/ " ) ) ;
2018-07-24 17:47:32 -04:00
torManager - > setHiddenServiceDirectory ( tor_hidden_service_dir ) ; // re-set it, because now it's changed to the specific location that is run
2018-01-20 11:10:47 -05:00
2018-07-24 17:47:32 -04:00
RsDirUtil : : checkCreateDirectory ( std : : string ( tor_hidden_service_dir . toUtf8 ( ) ) ) ;
2017-12-26 11:21:57 -05:00
2018-07-24 17:47:32 -04:00
torManager - > setupHiddenService ( ) ;
if ( ! torManager - > start ( ) | | torManager - > hasError ( ) )
{
QMessageBox : : critical ( NULL , QObject : : tr ( " Cannot start Tor Manager! " ) , QObject : : tr ( " Tor cannot be started on your system: \n \n " ) + torManager - > errorMessage ( ) ) ;
return 1 ;
}
2017-12-21 12:16:32 -05:00
2017-12-21 15:34:51 -05:00
{
2018-07-24 17:47:32 -04:00
TorControlDialog tcd ( torManager ) ;
QString error_msg ;
tcd . show ( ) ;
2018-02-08 09:26:21 -05:00
2018-07-24 17:47:32 -04:00
while ( tcd . checkForTor ( error_msg ) ! = TorControlDialog : : TOR_STATUS_OK | | tcd . checkForHiddenService ( ) ! = TorControlDialog : : HIDDEN_SERVICE_STATUS_OK ) // runs until some status is reached: either tor works, or it fails.
2018-02-08 09:26:21 -05:00
{
2018-07-24 17:47:32 -04:00
QCoreApplication : : processEvents ( ) ;
rstime : : rs_usleep ( 0.2 * 1000 * 1000 ) ;
if ( ! error_msg . isNull ( ) )
{
QMessageBox : : critical ( NULL , QObject : : tr ( " Cannot start Tor " ) , QObject : : tr ( " Sorry but Tor cannot be started on your system! \n \n The error reported is: \" " ) + error_msg + " \" " ) ;
return 1 ;
}
2018-02-08 09:26:21 -05:00
}
2017-12-21 12:16:32 -05:00
2018-07-24 17:47:32 -04:00
tcd . hide ( ) ;
2017-12-21 12:16:32 -05:00
2018-07-24 17:47:32 -04:00
if ( tcd . checkForHiddenService ( ) ! = TorControlDialog : : HIDDEN_SERVICE_STATUS_OK )
{
QMessageBox : : critical ( NULL , QObject : : tr ( " Cannot start a hidden tor service! " ) , QObject : : tr ( " It was not possible to start a hidden service. " ) ) ;
return 1 ;
}
2017-12-21 15:34:51 -05:00
}
2017-12-21 12:16:32 -05:00
}
2017-12-26 14:42:25 -05:00
QSplashScreen splashScreen ( QPixmap ( " :/images/logo/logo_splash.png " ) /* , Qt::WindowStaysOnTopHint*/ ) ;
splashScreen . show ( ) ;
2010-10-19 14:06:22 -04:00
splashScreen . showMessage ( rshare . translate ( " SplashScreen " , " Load configuration " ) , Qt : : AlignHCenter | Qt : : AlignBottom ) ;
2018-01-19 07:42:31 -05:00
QCoreApplication : : processEvents ( ) ;
2012-02-02 19:15:49 -05:00
/* stop Retroshare if startup fails */
2014-01-07 17:51:22 -05:00
if ( ! RsControl : : instance ( ) - > StartupRetroShare ( ) )
2012-02-02 19:15:49 -05:00
{
std : : cerr < < " libretroshare failed to startup! " < < std : : endl ;
return 1 ;
}
2018-07-25 05:37:40 -04:00
if ( is_auto_tor )
{
// Tor works with viable hidden service. Let's use it!
2017-12-27 12:59:50 -05:00
2018-07-25 05:37:40 -04:00
QString service_id ;
QString onion_address ;
uint16_t service_port ;
uint16_t service_target_port ;
uint16_t proxy_server_port ;
QHostAddress service_target_address ;
QHostAddress proxy_server_address ;
2017-12-27 12:59:50 -05:00
2018-07-25 05:37:40 -04:00
Tor : : TorManager * torManager = Tor : : TorManager : : instance ( ) ;
torManager - > getHiddenServiceInfo ( service_id , onion_address , service_port , service_target_address , service_target_port ) ;
torManager - > getProxyServerInfo ( proxy_server_address , proxy_server_port ) ;
2017-12-27 12:59:50 -05:00
2018-07-25 05:37:40 -04:00
std : : cerr < < " Got hidden service info: " < < std : : endl ;
std : : cerr < < " onion address : " < < onion_address . toStdString ( ) < < std : : endl ;
std : : cerr < < " service_id : " < < service_id . toStdString ( ) < < std : : endl ;
std : : cerr < < " service port : " < < service_port < < std : : endl ;
std : : cerr < < " target port : " < < service_target_port < < std : : endl ;
std : : cerr < < " target address : " < < service_target_address . toString ( ) . toStdString ( ) < < std : : endl ;
2017-12-27 12:59:50 -05:00
2018-07-25 05:37:40 -04:00
std : : cerr < < " Setting proxy server to " < < service_target_address . toString ( ) . toStdString ( ) < < " : " < < service_target_port < < std : : endl ;
2017-12-27 12:59:50 -05:00
2018-07-25 05:37:40 -04:00
rsPeers - > setLocalAddress ( rsPeers - > getOwnId ( ) , service_target_address . toString ( ) . toStdString ( ) , service_target_port ) ;
rsPeers - > setHiddenNode ( rsPeers - > getOwnId ( ) , onion_address . toStdString ( ) , service_port ) ;
rsPeers - > setProxyServer ( RS_HIDDEN_TYPE_TOR , proxy_server_address . toString ( ) . toStdString ( ) , proxy_server_port ) ;
}
2012-02-02 19:15:49 -05:00
2011-11-17 16:17:24 -05:00
Rshare : : initPlugins ( ) ;
2007-11-14 22:18:48 -05:00
2010-10-19 14:06:22 -04:00
splashScreen . showMessage ( rshare . translate ( " SplashScreen " , " Create interface " ) , Qt : : AlignHCenter | Qt : : AlignBottom ) ;
2017-12-27 12:59:50 -05:00
QCoreApplication : : processEvents ( ) ; // forces splashscreen to show up
2010-10-19 14:06:22 -04:00
2010-09-10 14:38:46 -04:00
RsharePeerSettings : : Create ( ) ;
2010-06-14 09:32:13 -04:00
2010-09-14 13:47:11 -04:00
Emoticons : : load ( ) ;
2010-10-19 14:06:22 -04:00
if ( Settings - > value ( QString : : fromUtf8 ( " FirstRun " ) , true ) . toBool ( ) ) {
splashScreen . hide ( ) ;
Settings - > setValue ( QString : : fromUtf8 ( " FirstRun " ) , false ) ;
2012-02-02 19:15:49 -05:00
2015-06-07 13:35:58 -04:00
SoundManager : : initDefault ( ) ;
2015-06-07 08:40:25 -04:00
2012-02-02 19:15:49 -05:00
# ifdef __APPLE__
/* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes
* only on the first run - as the user might want to change it ; )
*/
QString osx_style ( " cleanlooks " ) ;
Rshare : : setStyle ( osx_style ) ;
Settings - > setInterfaceStyle ( osx_style ) ;
# endif
2012-01-27 08:52:13 -05:00
// This is now disabled - as it doesn't add very much.
// Need to make sure that defaults are sensible!
# ifdef ENABLE_QUICKSTART_WIZARD
2010-10-19 14:06:22 -04:00
QuickStartWizard qstartWizard ;
qstartWizard . exec ( ) ;
2012-01-27 08:52:13 -05:00
# endif
2012-02-02 19:15:49 -05:00
2010-10-19 14:06:22 -04:00
}
2010-05-02 20:09:55 -04:00
MainWindow * w = MainWindow : : Create ( ) ;
2010-10-19 14:06:22 -04:00
splashScreen . finish ( w ) ;
2009-01-22 16:06:54 -05:00
2016-03-01 07:08:33 -05:00
w - > processLastArgs ( ) ;
2011-04-14 19:58:30 -04:00
2016-08-06 11:15:56 -04:00
if ( ! sDefaultGXSIdToCreate . isEmpty ( ) ) {
RsIdentityParameters params ;
params . nickname = sDefaultGXSIdToCreate . toUtf8 ( ) . constData ( ) ;
params . isPgpLinked = true ;
params . mImage . clear ( ) ;
uint32_t token = 0 ;
rsIdentity - > createIdentity ( token , params ) ;
}
2009-01-22 16:06:54 -05:00
// I'm using a signal to transfer the hashing info to the mainwindow, because Qt schedules signals properly to
// avoid clashes between infos from threads.
//
2009-08-16 16:10:53 -04:00
qRegisterMetaType < FileDetail > ( " FileDetail " ) ;
2014-06-12 18:06:43 -04:00
qRegisterMetaType < RsPeerId > ( " RsPeerId " ) ;
2009-08-16 16:10:53 -04:00
2009-03-15 18:45:40 -04:00
std : : cerr < < " connecting signals and slots " < < std : : endl ;
2013-02-22 16:42:27 -05:00
QObject : : connect ( notify , SIGNAL ( gotTurtleSearchResult ( qulonglong , FileDetail ) ) , w - > transfersDialog - > searchDialog , SLOT ( updateFiles ( qulonglong , FileDetail ) ) ) ;
2013-03-01 18:00:43 -05:00
QObject : : connect ( notify , SIGNAL ( deferredSignatureHandlingRequested ( ) ) , notify , SLOT ( handleSignatureEvent ( ) ) , Qt : : QueuedConnection ) ;
2013-03-18 19:19:37 -04:00
QObject : : connect ( notify , SIGNAL ( chatLobbyTimeShift ( int ) ) , notify , SLOT ( handleChatLobbyTimeShift ( int ) ) , Qt : : QueuedConnection ) ;
2010-05-21 16:49:48 -04:00
QObject : : connect ( notify , SIGNAL ( diskFull ( int , int ) ) , w , SLOT ( displayDiskSpaceWarning ( int , int ) ) ) ;
2016-08-19 12:49:42 -04:00
QObject : : connect ( notify , SIGNAL ( filesPostModChanged ( bool ) ) , w , SLOT ( postModDirectories ( bool ) ) , Qt : : QueuedConnection ) ;
2009-08-16 16:10:53 -04:00
QObject : : connect ( notify , SIGNAL ( transfersChanged ( ) ) , w - > transfersDialog , SLOT ( insertTransfers ( ) ) ) ;
2011-05-17 13:27:47 -04:00
QObject : : connect ( notify , SIGNAL ( publicChatChanged ( int ) ) , w - > friendsDialog , SLOT ( publicChatChanged ( int ) ) ) ;
2013-05-21 08:55:03 -04:00
QObject : : connect ( notify , SIGNAL ( neighboursChanged ( ) ) , w - > friendsDialog - > networkDialog , SLOT ( securedUpdateDisplay ( ) ) ) ;
2007-11-14 22:18:48 -05:00
2011-05-17 13:27:47 -04:00
QObject : : connect ( notify , SIGNAL ( chatStatusChanged ( const QString & , const QString & , bool ) ) , w - > friendsDialog , SLOT ( updatePeerStatusString ( const QString & , const QString & , bool ) ) ) ;
QObject : : connect ( notify , SIGNAL ( ownStatusMessageChanged ( ) ) , w - > friendsDialog , SLOT ( loadmypersonalstatus ( ) ) ) ;
2009-10-05 15:07:02 -04:00
2017-10-08 15:00:15 -04:00
// QObject::connect(notify,SIGNAL(logInfoChanged(const QString&)) ,w->friendsDialog->networkDialog,SLOT(setLogInfo(QString))) ;
2013-02-22 16:42:27 -05:00
QObject : : connect ( notify , SIGNAL ( discInfoChanged ( ) ) , w - > friendsDialog - > networkView , SLOT ( update ( ) ) , Qt : : QueuedConnection ) ;
2010-02-07 13:10:12 -05:00
QObject : : connect ( notify , SIGNAL ( errorOccurred ( int , int , const QString & ) ) , w , SLOT ( displayErrorMessage ( int , int , const QString & ) ) ) ;
2009-05-05 09:18:53 -04:00
2010-06-15 12:51:48 -04:00
w - > installGroupChatNotifier ( ) ;
2009-07-13 10:01:49 -04:00
2010-06-15 12:51:48 -04:00
/* only show window, if not startMinimized */
2011-04-14 17:59:51 -04:00
if ( RsInit : : getStartMinimised ( ) | | Settings - > getStartMinimized ( ) )
2007-11-14 22:18:48 -05:00
{
2010-10-19 14:06:22 -04:00
splashScreen . close ( ) ;
2010-11-21 17:18:56 -05:00
} else {
w - > show ( ) ;
2008-10-18 12:02:06 -04:00
}
2009-02-08 09:30:28 -05:00
2007-11-14 22:18:48 -05:00
/* Startup a Timer to keep the gui's updated */
QTimer * timer = new QTimer ( w ) ;
timer - > connect ( timer , SIGNAL ( timeout ( ) ) , notify , SLOT ( UpdateGUI ( ) ) ) ;
2009-02-08 09:30:28 -05:00
timer - > start ( 1000 ) ;
2010-08-31 16:00:49 -04:00
2012-05-15 16:35:05 -04:00
notify - > enable ( ) ; // enable notification system after GUI creation, to avoid data races in Qt.
2016-07-28 08:08:49 -04:00
# ifdef ENABLE_WEBUI
2015-04-24 10:31:13 -04:00
WebuiPage : : checkStartWebui ( ) ;
2016-07-28 08:08:49 -04:00
# endif // ENABLE_WEBUI
2015-04-24 10:31:13 -04:00
2018-09-20 19:58:38 -04:00
# ifdef RS_JSONAPI
JsonApiPage : : checkStartJsonApi ( ) ;
# endif // RS_JSONAPI
2017-07-29 16:37:14 -04:00
// This is done using a timer, because the passphrase request from notify is asynchrouneous and therefore clearing the
// passphrase here makes it request for a passphrase when creating the default chat identity.
2017-07-30 04:36:44 -04:00
QTimer : : singleShot ( 10000 , notify , SLOT ( resetCachedPassphrases ( ) ) ) ;
2017-07-29 16:37:14 -04:00
2009-02-08 09:30:28 -05:00
/* dive into the endless loop */
2010-05-20 17:53:27 -04:00
int ti = rshare . exec ( ) ;
delete w ;
2007-11-14 22:18:48 -05:00
2018-09-20 19:58:38 -04:00
# ifdef RS_JSONAPI
JsonApiPage : : checkShutdownJsonApi ( ) ;
# endif // RS_JSONAPI
2016-07-28 08:08:49 -04:00
# ifdef ENABLE_WEBUI
2016-03-01 07:08:33 -05:00
WebuiPage : : checkShutdownWebui ( ) ;
2016-07-28 08:08:49 -04:00
# endif // ENABLE_WEBUI
2011-04-14 17:59:51 -04:00
2010-06-17 13:39:32 -04:00
/* cleanup */
2012-01-17 15:36:36 -05:00
ChatDialog : : cleanupChat ( ) ;
2013-07-14 14:48:40 -04:00
# ifdef RS_ENABLE_GXS
RsGxsUpdateBroadcast : : cleanup ( ) ;
# endif
2010-06-17 13:39:32 -04:00
2014-01-07 17:51:22 -05:00
RsControl : : instance ( ) - > rsGlobalShutDown ( ) ;
2010-05-29 11:14:25 -04:00
2012-01-22 17:58:23 -05:00
delete ( soundManager ) ;
soundManager = NULL ;
2010-05-20 17:53:27 -04:00
Settings - > sync ( ) ;
2012-01-22 17:58:23 -05:00
delete ( Settings ) ;
2007-11-14 22:18:48 -05:00
2010-05-20 17:53:27 -04:00
return ti ;
}