2006-09-30 20:02:39 +04:00
/*
* Bittorrent Client using Qt4 and libtorrent .
2007-07-14 18:31:59 +04:00
* Copyright ( C ) 2006 Christophe Dumez
2006-09-30 20:02:39 +04:00
*
2007-07-14 18:31:59 +04:00
* 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 .
2006-09-30 20:02:39 +04:00
*
* 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
2007-07-14 18:31:59 +04:00
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
2009-04-05 21:00:55 +04:00
* In addition , as a special exception , the copyright holders give permission to
* link this program with the OpenSSL project ' s " OpenSSL " library ( or with
* modified versions of it that use the same license as the " OpenSSL " library ) ,
* and distribute the linked executables . You must obey the GNU General Public
* License in all respects for all of the code used other than " OpenSSL " . If you
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* but you are not obligated to do so . If you do not wish to do so , delete this
* exception statement from your version .
*
2007-07-14 18:31:59 +04:00
* Contact : chris @ qbittorrent . org
2006-09-30 20:02:39 +04:00
*/
# include <QLocale>
# include <QTranslator>
# include <QFile>
2009-12-15 13:56:41 +03:00
2009-12-15 14:08:22 +03:00
# ifndef DISABLE_GUI
2010-01-03 02:03:46 +03:00
# include <QApplication>
2010-01-09 18:26:20 +03:00
# include <QMessageBox>
2010-01-31 20:30:17 +03:00
# include <QStyleFactory>
2010-01-03 02:03:46 +03:00
# include <QSplashScreen>
2010-03-04 11:36:23 +03:00
# include <QPushButton>
2010-01-03 02:03:46 +03:00
# include "qgnomelook.h"
# include "GUI.h"
# include "ico.h"
2009-12-15 14:08:22 +03:00
# else
2010-01-03 02:03:46 +03:00
# include <QCoreApplication>
2010-01-09 18:26:20 +03:00
# include <iostream>
# include <stdio.h>
2010-01-03 02:03:46 +03:00
# include "headlessloader.h"
2009-12-15 13:56:41 +03:00
# endif
2006-11-14 23:26:32 +03:00
# include <QSettings>
2009-09-30 22:57:06 +04:00
# include <QLocalSocket>
# include <unistd.h>
# include <sys/types.h>
2008-12-26 19:23:53 +03:00
# ifndef Q_WS_WIN
2009-09-30 22:57:06 +04:00
# include <signal.h>
# include <execinfo.h>
# include "stacktrace.h"
2008-12-26 19:23:53 +03:00
# endif
2007-03-19 17:45:17 +03:00
2006-09-30 20:02:39 +04:00
# include <stdlib.h>
# include "misc.h"
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
# include "preferences.h"
2008-11-05 01:39:43 +03:00
2009-12-15 14:10:47 +03:00
# ifdef DISABLE_GUI
2010-01-03 02:03:46 +03:00
QCoreApplication * app ;
2009-12-15 14:10:47 +03:00
# else
2010-01-03 02:03:46 +03:00
QApplication * app ;
2009-12-15 14:10:47 +03:00
# endif
2008-12-26 19:23:53 +03:00
2010-01-03 02:40:57 +03:00
class UsageDisplay : public QObject {
2010-01-09 18:26:20 +03:00
Q_OBJECT
2010-01-03 02:40:57 +03:00
public :
static void displayUsage ( char * prg_name ) {
std : : cout < < tr ( " Usage: " ) . toLocal8Bit ( ) . data ( ) < < std : : endl ;
2010-03-03 15:55:42 +03:00
std : : cout < < ' \t ' < < prg_name < < " --version: " < < qPrintable ( tr ( " displays program version " ) ) < < std : : endl ;
2010-01-03 02:40:57 +03:00
# ifndef DISABLE_GUI
2010-03-03 15:55:42 +03:00
std : : cout < < ' \t ' < < prg_name < < " --no-splash: " < < qPrintable ( tr ( " disable splash screen " ) ) < < std : : endl ;
2010-01-03 02:40:57 +03:00
# endif
2010-03-03 15:55:42 +03:00
std : : cout < < ' \t ' < < prg_name < < " --help: " < < qPrintable ( tr ( " displays this help message " ) ) < < std : : endl ;
std : : cout < < ' \t ' < < prg_name < < " --webui-port=x: " < < qPrintable ( tr ( " changes the webui port (current: %1) " ) . arg ( QString : : number ( Preferences : : getWebUiPort ( ) ) ) ) < < std : : endl ;
std : : cout < < ' \t ' < < prg_name < < " " < < qPrintable ( tr ( " [files or urls]: downloads the torrents passed by the user (optional) " ) ) < < std : : endl ;
2010-01-03 02:40:57 +03:00
}
} ;
2010-01-09 18:26:20 +03:00
class LegalNotice : public QObject {
Q_OBJECT
public :
static bool userAgreesWithNotice ( ) {
QSettings settings ( QString : : fromUtf8 ( " qBittorrent " ) , QString : : fromUtf8 ( " qBittorrent " ) ) ;
if ( settings . value ( QString : : fromUtf8 ( " LegalNotice/Accepted " ) , false ) . toBool ( ) ) // Already accepted once
return true ;
# ifdef DISABLE_GUI
2010-03-03 15:55:42 +03:00
std : : cout < < std : : endl < < " *** " < < qPrintable ( tr ( " Legal Notice " ) ) < < " *** " < < std : : endl ;
std : : cout < < qPrintable ( tr ( " qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. \n \n No further notices will be issued. " ) ) < < std : : endl < < std : : endl ;
std : : cout < < qPrintable ( tr ( " Press %1 key to accept and continue... " ) . arg ( " 'y' " ) ) < < std : : endl ;
2010-01-18 22:20:59 +03:00
char ret = getchar ( ) ; // Read pressed key
if ( ret = = ' y ' | | ret = = ' Y ' ) {
// Save the answer
settings . setValue ( QString : : fromUtf8 ( " LegalNotice/Accepted " ) , true ) ;
return true ;
}
2010-01-19 00:28:54 +03:00
return false ;
2010-01-09 18:26:20 +03:00
# else
QMessageBox msgBox ;
2010-01-18 22:16:18 +03:00
msgBox . setText ( tr ( " qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. \n \n No further notices will be issued. " ) ) ;
2010-01-09 18:26:20 +03:00
msgBox . setWindowTitle ( tr ( " Legal notice " ) ) ;
msgBox . addButton ( tr ( " Cancel " ) , QMessageBox : : RejectRole ) ;
2010-03-03 18:23:34 +03:00
QAbstractButton * agree_button = msgBox . addButton ( tr ( " I Agree " ) , QMessageBox : : AcceptRole ) ;
2010-01-09 18:26:20 +03:00
msgBox . exec ( ) ;
if ( msgBox . clickedButton ( ) = = agree_button ) {
// Save the answer
settings . setValue ( QString : : fromUtf8 ( " LegalNotice/Accepted " ) , true ) ;
return true ;
}
return false ;
# endif
}
} ;
2010-01-03 02:40:57 +03:00
# include "main.moc"
2008-12-26 19:23:53 +03:00
# ifndef Q_WS_WIN
2010-01-03 02:03:46 +03:00
void sigintHandler ( int ) {
2010-01-03 17:41:29 +03:00
signal ( SIGINT , 0 ) ;
2010-01-03 02:03:46 +03:00
qDebug ( " Catching SIGINT, exiting cleanly " ) ;
app - > exit ( ) ;
}
2009-09-30 22:57:06 +04:00
void sigtermHandler ( int ) {
2010-01-03 17:41:29 +03:00
signal ( SIGTERM , 0 ) ;
2009-09-30 22:57:06 +04:00
qDebug ( " Catching SIGTERM, exiting cleanly " ) ;
app - > exit ( ) ;
}
void sigsegvHandler ( int ) {
2010-01-03 17:38:59 +03:00
signal ( SIGABRT , 0 ) ;
2010-01-03 17:41:29 +03:00
signal ( SIGSEGV , 0 ) ;
2009-09-30 22:57:06 +04:00
std : : cerr < < " \n \n ************************************************************* \n " ;
std : : cerr < < " Catching SIGSEGV, please report a bug at http://bug.qbittorrent.org \n and provide the following backtrace: \n " ;
print_stacktrace ( ) ;
std : : raise ( SIGINT ) ;
std : : abort ( ) ;
}
2009-11-15 13:42:03 +03:00
void sigabrtHandler ( int ) {
2010-01-03 17:38:59 +03:00
signal ( SIGABRT , 0 ) ;
2010-01-03 17:41:29 +03:00
signal ( SIGSEGV , 0 ) ;
2009-11-15 13:42:03 +03:00
std : : cerr < < " \n \n ************************************************************* \n " ;
std : : cerr < < " Catching SIGABRT, please report a bug at http://bug.qbittorrent.org \n and provide the following backtrace: \n " ;
print_stacktrace ( ) ;
std : : raise ( SIGINT ) ;
std : : abort ( ) ;
}
2008-12-26 19:23:53 +03:00
# endif
2006-09-30 20:02:39 +04:00
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2010-01-31 20:30:17 +03:00
void useStyle ( QApplication * app , QString style ) {
2010-01-31 20:46:21 +03:00
if ( ! style . isEmpty ( ) ) {
2010-01-31 20:30:17 +03:00
QApplication : : setStyle ( QStyleFactory : : create ( style ) ) ;
}
if ( app - > style ( ) - > objectName ( ) = = " cleanlooks " ) {
// Force our own cleanlooks style
qDebug ( " Forcing our own cleanlooks style " ) ;
2009-09-30 22:57:06 +04:00
app - > setStyle ( new QGnomeLookStyle ( ) ) ;
2007-09-08 21:07:29 +04:00
}
2010-01-31 20:46:21 +03:00
Preferences : : setStyle ( app - > style ( ) - > objectName ( ) ) ;
2007-03-28 12:05:37 +04:00
}
2009-12-15 13:56:41 +03:00
# endif
2007-03-28 12:05:37 +04:00
2006-09-30 20:02:39 +04:00
// Main
int main ( int argc , char * argv [ ] ) {
QFile file ;
QString locale ;
2009-10-22 20:50:34 +04:00
QSettings settings ( QString : : fromUtf8 ( " qBittorrent " ) , QString : : fromUtf8 ( " qBittorrent " ) ) ;
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2009-09-30 22:57:06 +04:00
bool no_splash = false ;
2009-12-15 13:56:41 +03:00
# endif
2010-02-05 22:02:27 +03:00
//Check if there is another instance running
QLocalSocket localSocket ;
QString uid = QString : : number ( getuid ( ) ) ;
localSocket . connectToServer ( " qBittorrent- " + uid , QIODevice : : WriteOnly ) ;
if ( localSocket . waitForConnected ( 1000 ) ) {
std : : cout < < " Another qBittorrent instance is already running... \n " ;
// Send parameters
if ( argc > 1 ) {
QStringList params ;
for ( int i = 1 ; i < argc ; + + i ) {
params < < QString : : fromLocal8Bit ( argv [ i ] ) ;
std : : cout < < argv [ i ] < < ' \n ' ;
}
QByteArray block = params . join ( " \n " ) . toLocal8Bit ( ) ;
std : : cout < < " writting: " < < block . data ( ) < < ' \n ' ;
std : : cout < < " size: " < < block . size ( ) < < ' \n ' ;
uint val = localSocket . write ( block ) ;
if ( localSocket . waitForBytesWritten ( 5000 ) ) {
std : : cout < < " written( " < < val < < " ): " < < block . data ( ) < < ' \n ' ;
} else {
std : : cerr < < " Writing to the socket timed out \n " ;
}
localSocket . disconnectFromServer ( ) ;
std : : cout < < " disconnected \n " ;
}
localSocket . close ( ) ;
return 0 ;
}
// Create Application
# ifdef DISABLE_GUI
app = new QCoreApplication ( argc , argv ) ;
# else
app = new QApplication ( argc , argv ) ;
# endif
// Load translation
locale = settings . value ( QString : : fromUtf8 ( " Preferences/General/Locale " ) , QString ( ) ) . toString ( ) ;
QTranslator translator ;
if ( locale . isEmpty ( ) ) {
locale = QLocale : : system ( ) . name ( ) ;
settings . setValue ( QString : : fromUtf8 ( " Preferences/General/Locale " ) , locale ) ;
}
if ( translator . load ( QString : : fromUtf8 ( " :/lang/qbittorrent_ " ) + locale ) ) {
2010-03-03 15:55:42 +03:00
qDebug ( " %s locale recognized, using translation. " , qPrintable ( locale ) ) ;
2010-02-05 22:02:27 +03:00
} else {
2010-03-03 15:55:42 +03:00
qDebug ( " %s locale unrecognized, using default (en_GB). " , qPrintable ( locale ) ) ;
2010-02-05 22:02:27 +03:00
}
app - > installTranslator ( & translator ) ;
app - > setApplicationName ( QString : : fromUtf8 ( " qBittorrent " ) ) ;
// Check for executable parameters
2006-09-30 20:02:39 +04:00
if ( argc > 1 ) {
2010-03-03 15:55:42 +03:00
if ( QString : : fromLocal8Bit ( argv [ 1 ] ) = = QString : : fromUtf8 ( " --version " ) ) {
2006-09-30 20:02:39 +04:00
std : : cout < < " qBittorrent " < < VERSION < < ' \n ' ;
2010-02-05 22:02:27 +03:00
delete app ;
2006-09-30 20:02:39 +04:00
return 0 ;
}
2010-03-03 15:55:42 +03:00
if ( QString : : fromLocal8Bit ( argv [ 1 ] ) = = QString : : fromUtf8 ( " --help " ) ) {
2010-01-03 02:40:57 +03:00
UsageDisplay : : displayUsage ( argv [ 0 ] ) ;
2010-02-05 22:02:27 +03:00
delete app ;
2006-09-30 20:02:39 +04:00
return 0 ;
}
2010-01-03 01:20:37 +03:00
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
for ( int i = 1 ; i < argc ; + + i ) {
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2010-03-03 15:55:42 +03:00
if ( QString : : fromLocal8Bit ( argv [ i ] ) = = QString : : fromUtf8 ( " --no-splash " ) ) {
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
no_splash = true ;
} else {
2009-12-15 13:56:41 +03:00
# endif
2010-03-03 15:55:42 +03:00
if ( QString : : fromLocal8Bit ( argv [ i ] ) . startsWith ( " --webui-port= " ) ) {
QStringList parts = QString : : fromLocal8Bit ( argv [ i ] ) . split ( " = " ) ;
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
if ( parts . size ( ) = = 2 ) {
bool ok = false ;
int new_port = parts . last ( ) . toInt ( & ok ) ;
2010-01-20 12:54:51 +03:00
if ( ok & & new_port > 0 & & new_port < = 65535 ) {
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
Preferences : : setWebUiPort ( new_port ) ;
}
}
}
2010-01-03 01:20:37 +03:00
# ifndef DISABLE_GUI
* Replace priority combo boxes by check boxes in Web UI as in Regular UI
* Prepare http server and preferences classes to add new settings to Web UI
* Tabified Program preferences in Web UI since there will be a lot of settings soon
* Started to add new settings to Web UI (PeX, LSD, Encryption, save path, temp path, scan dir, preallocateall, queueing, listen_port, upnp, nat-pmp, language, ip filter) -> Proxy is missing
* Added a command line parameter to change the web ui port
* Fix PeerGuardian .p2b binary filter support
2009-12-28 22:39:47 +03:00
}
2010-01-03 01:20:37 +03:00
# endif
2009-09-30 22:57:06 +04:00
}
2006-09-30 20:02:39 +04:00
}
2010-01-03 01:20:37 +03:00
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2009-10-22 20:50:34 +04:00
if ( settings . value ( QString : : fromUtf8 ( " Preferences/General/NoSplashScreen " ) , false ) . toBool ( ) ) {
no_splash = true ;
}
2009-12-15 13:56:41 +03:00
# endif
2006-09-30 20:02:39 +04:00
// Set environment variable
2008-12-15 22:24:10 +03:00
if ( putenv ( ( char * ) " QBITTORRENT= " VERSION ) ) {
2006-10-16 13:02:53 +04:00
std : : cerr < < " Couldn't set environment variable... \n " ;
2006-09-30 20:02:39 +04:00
}
2010-02-05 22:02:27 +03:00
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2010-01-31 20:46:21 +03:00
useStyle ( app , settings . value ( " Preferences/General/Style " , " " ) . toString ( ) ) ;
2008-12-26 19:23:53 +03:00
app - > setStyleSheet ( " QStatusBar::item { border-width: 0; } " ) ;
2009-10-25 02:11:29 +03:00
QSplashScreen * splash = 0 ;
2009-09-30 22:57:06 +04:00
if ( ! no_splash ) {
splash = new QSplashScreen ( QPixmap ( QString : : fromUtf8 ( " :/Icons/skin/splash.png " ) ) ) ;
splash - > show ( ) ;
}
2009-12-15 13:56:41 +03:00
# endif
2010-02-05 22:02:27 +03:00
2010-01-09 18:26:20 +03:00
if ( ! LegalNotice : : userAgreesWithNotice ( ) ) {
# ifndef DISABLE_GUI
delete splash ;
# endif
delete app ;
return 0 ;
}
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2008-12-26 19:23:53 +03:00
app - > setQuitOnLastWindowClosed ( false ) ;
2009-12-15 13:56:41 +03:00
# endif
2009-01-18 18:12:38 +03:00
# ifndef Q_WS_WIN
2009-11-15 13:42:03 +03:00
signal ( SIGABRT , sigabrtHandler ) ;
2009-01-18 18:12:38 +03:00
signal ( SIGTERM , sigtermHandler ) ;
2010-01-03 02:03:46 +03:00
signal ( SIGINT , sigintHandler ) ;
2009-01-18 18:12:38 +03:00
signal ( SIGSEGV , sigsegvHandler ) ;
# endif
2006-09-30 20:02:39 +04:00
// Read torrents given on command line
2008-12-26 19:23:53 +03:00
QStringList torrentCmdLine = app - > arguments ( ) ;
2006-09-30 20:02:39 +04:00
// Remove first argument (program name)
torrentCmdLine . removeFirst ( ) ;
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2008-12-26 19:27:52 +03:00
GUI * window = new GUI ( 0 , torrentCmdLine ) ;
2009-09-30 22:57:06 +04:00
if ( ! no_splash ) {
splash - > finish ( window ) ;
delete splash ;
}
2009-12-15 13:56:41 +03:00
# else
// Load Headless class
2009-12-15 14:59:48 +03:00
HeadlessLoader * loader = new HeadlessLoader ( torrentCmdLine ) ;
2009-12-15 13:56:41 +03:00
# endif
2008-12-26 19:27:52 +03:00
int ret = app - > exec ( ) ;
2010-01-03 02:03:46 +03:00
# ifndef Q_WS_WIN
// Application has exited, stop catching SIGINT and SIGTERM
signal ( SIGINT , 0 ) ;
signal ( SIGTERM , 0 ) ;
# endif
2009-12-15 13:56:41 +03:00
# ifndef DISABLE_GUI
2008-12-26 19:27:52 +03:00
delete window ;
2009-12-01 00:30:14 +03:00
qDebug ( " GUI was deleted! " ) ;
2009-12-15 14:08:22 +03:00
# else
delete loader ;
2009-12-15 13:56:41 +03:00
# endif
2009-12-01 00:30:14 +03:00
qDebug ( " Deleting app... " ) ;
2008-12-26 19:27:52 +03:00
delete app ;
2009-12-01 00:30:14 +03:00
qDebug ( " App was deleted! All good. " ) ;
2008-12-26 19:27:52 +03:00
return ret ;
2006-09-30 20:02:39 +04:00
}