36 #if defined(Q_OS_UNIX)
37 #include <sys/resource.h>
39 #if !defined Q_OS_WIN && !defined Q_OS_HAIKU
41 #elif defined Q_OS_WIN && defined DISABLE_GUI
51 #include <QMessageBox>
54 #include <QPushButton>
55 #include <QSplashScreen>
60 Q_IMPORT_PLUGIN(QICOPlugin)
81 #include "base/version.h"
93 void sigAbnormalHandler(
int signum);
99 "",
"",
"SIGINT",
"",
"SIGILL",
"",
"SIGABRT_COMPAT",
"",
"SIGFPE",
"",
100 "",
"SIGSEGV",
"",
"",
"",
"SIGTERM",
"",
"",
"",
"",
101 "",
"SIGBREAK",
"SIGABRT",
"",
"",
"",
"",
"",
"",
"",
104 "",
"SIGHUP",
"SIGINT",
"SIGQUIT",
"SIGILL",
"SIGTRAP",
"SIGABRT",
"SIGBUS",
"SIGFPE",
"SIGKILL",
105 "SIGUSR1",
"SIGSEGV",
"SIGUSR2",
"SIGPIPE",
"SIGALRM",
"SIGTERM",
"SIGSTKFLT",
"SIGCHLD",
"SIGCONT",
"SIGSTOP",
106 "SIGTSTP",
"SIGTTIN",
"SIGTTOU",
"SIGURG",
"SIGXCPU",
"SIGXFSZ",
"SIGVTALRM",
"SIGPROF",
"SIGWINCH",
"SIGIO",
107 "SIGPWR",
"SIGUNUSED"
111 #if !(defined Q_OS_WIN && !defined DISABLE_GUI) && !defined Q_OS_HAIKU
119 #if !defined(DISABLE_GUI)
123 #if defined(Q_OS_UNIX)
124 void adjustFileDescriptorLimit();
128 int main(
int argc,
char *argv[])
130 #if defined(Q_OS_UNIX)
131 adjustFileDescriptorLimit();
135 bool isOneArg = (argc == 2);
137 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && !defined(DISABLE_GUI)
139 if (qgetenv(
"QT_ENABLE_HIGHDPI_SCALING").isEmpty() && qgetenv(
"QT_AUTO_SCREEN_SCALE_FACTOR").isEmpty())
140 Application::setAttribute(Qt::AA_EnableHighDpiScaling,
true);
142 if (qgetenv(
"QT_SCALE_FACTOR_ROUNDING_POLICY").isEmpty())
143 Application::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
149 auto app = std::make_unique<Application>(argc, argv);
155 "--random-parameter is an unknown command line parameter.")
158 #if !defined(Q_OS_WIN) || defined(DISABLE_GUI)
167 .arg(QLatin1String(
"-v (or --version)")));
178 .arg(QLatin1String(
"-h (or --help)")));
182 if (!qputenv(
"QBITTORRENT", QBT_VERSION))
183 fprintf(stderr,
"Couldn't set environment variable...\n");
191 #elif defined(Q_OS_WIN)
192 if (_isatty(_fileno(stdin))
193 && _isatty(_fileno(stdout))
197 if (!params.shouldDaemonize
198 && isatty(fileno(stdin))
199 && isatty(fileno(stdout))
208 if (app->isRunning())
210 #if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
211 if (params.shouldDaemonize)
214 .arg(QLatin1String(
"-d (or --daemon)")));
218 qDebug(
"qBittorrent is already running for this user.");
220 QThread::msleep(300);
226 #if defined(Q_OS_WIN)
238 qputenv(
"QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
239 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && !defined(DISABLE_GUI)
241 app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
245 #if defined(Q_OS_MACOS)
249 QByteArray path =
"/usr/local/bin:";
250 path += qgetenv(
"PATH");
251 qputenv(
"PATH", path.constData());
254 app->setAttribute(Qt::AA_DontShowIconsInMenus);
257 app->setAttribute(Qt::AA_DontShowIconsInMenus);
265 if (!
upgrade())
return EXIT_FAILURE;
266 #elif defined(Q_OS_WIN)
267 if (!
upgrade(_isatty(_fileno(stdin))
268 && _isatty(_fileno(stdout))))
return EXIT_FAILURE;
270 if (!
upgrade(!params.shouldDaemonize
271 && isatty(fileno(stdin))
272 && isatty(fileno(stdout))))
return EXIT_FAILURE;
280 #if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
281 if (params.shouldDaemonize)
284 if (daemon(1, 0) == 0)
286 app = std::make_unique<Application>(argc, argv);
287 if (app->isRunning())
295 qCritical(
"Something went wrong while daemonizing, exiting...");
299 #elif !defined(DISABLE_GUI)
307 signal(SIGABRT, sigAbnormalHandler);
308 signal(SIGSEGV, sigAbnormalHandler);
320 #if !(defined Q_OS_WIN && !defined DISABLE_GUI) && !defined Q_OS_HAIKU
323 const size_t strLen = strlen(str);
325 if (write(STDERR_FILENO, str, strLen) <
static_cast<ssize_t
>(strLen))
327 const auto dummy = write(STDOUT_FILENO, str, strLen);
329 if (_write(STDERR_FILENO, str, strLen) <
static_cast<ssize_t
>(strLen))
331 const auto dummy = _write(STDOUT_FILENO, str, strLen);
340 #if !(defined Q_OS_WIN && !defined DISABLE_GUI) && !defined Q_OS_HAIKU
341 const char msg1[] =
"Catching signal: ";
342 const char msg2[] =
"\nExiting cleanly\n";
347 signal(signum, SIG_DFL);
352 void sigAbnormalHandler(
int signum)
355 #if !(defined Q_OS_WIN && !defined DISABLE_GUI) && !defined Q_OS_HAIKU
356 const char msg[] =
"\n\n*************************************************************\n"
357 "Please file a bug report at http://bug.qbittorrent.org and provide the following information:\n\n"
358 "qBittorrent version: " QBT_VERSION
"\n\n"
366 #if defined Q_OS_WIN && !defined DISABLE_GUI
372 signal(signum, SIG_DFL);
377 #if !defined(DISABLE_GUI)
380 QPixmap splashImg(
":/icons/splash.png");
381 QPainter painter(&splashImg);
382 const QString version = QBT_VERSION;
383 painter.setPen(QPen(Qt::white));
384 painter.setFont(QFont(
"Arial", 22, QFont::Black));
385 painter.drawText(224 - painter.fontMetrics().horizontalAdvance(version), 270, version);
386 QSplashScreen *splash =
new QSplashScreen(splashImg);
388 QTimer::singleShot(1500, splash, &QObject::deleteLater);
389 qApp->processEvents();
395 printf(
"%s %s\n", qUtf8Printable(qApp->applicationName()), QBT_VERSION);
400 const QString
help = QObject::tr(
"Run application with -h option to read about command line parameters.");
401 #if defined(Q_OS_WIN) && !defined(DISABLE_GUI)
402 QMessageBox msgBox(QMessageBox::Critical, QObject::tr(
"Bad command line"),
403 message + QLatin1Char(
'\n') +
help, QMessageBox::Ok);
408 const QString errMsg = QObject::tr(
"Bad command line: ") +
'\n'
411 fprintf(stderr,
"%s", qUtf8Printable(errMsg));
421 const QString eula = QString::fromLatin1(
"\n*** %1 ***\n").arg(QObject::tr(
"Legal Notice"))
422 + QObject::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"
423 + QObject::tr(
"No further notices will be issued.") +
"\n\n"
424 + QObject::tr(
"Press %1 key to accept and continue...").arg(
"'y'") +
'\n';
425 printf(
"%s", qUtf8Printable(eula));
427 const char ret = getchar();
428 if ((ret ==
'y') || (ret ==
'Y'))
436 msgBox.setText(QObject::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\nNo further notices will be issued."));
437 msgBox.setWindowTitle(QObject::tr(
"Legal notice"));
438 msgBox.addButton(QObject::tr(
"Cancel"), QMessageBox::RejectRole);
439 const QAbstractButton *agreeButton = msgBox.addButton(QObject::tr(
"I Agree"), QMessageBox::AcceptRole);
443 if (msgBox.clickedButton() == agreeButton)
454 #if defined(Q_OS_UNIX)
455 void adjustFileDescriptorLimit()
459 if (getrlimit(RLIMIT_NOFILE, &limit) != 0)
462 limit.rlim_cur = limit.rlim_max;
463 setrlimit(RLIMIT_NOFILE, &limit);
QString message() const noexcept
static Preferences * instance()
bool isSplashScreenDisabled() const
void setAcceptedLegal(bool accepted)
bool getAcceptedLegal() const
void setStacktraceString(const QString &sigName, const QString &trace)
void displayUsage(const QString &prgName)
int main(int argc, char *argv[])
bool userAgreesWithLegalNotice()
void sigNormalHandler(int signum)
void displayBadArgMessage(const QString &message)
void reportToUser(const char *str)
const char *const sysSigName[]
QPoint screenCenter(const QWidget *w)
const QString getBacktrace()
static void print_stacktrace(FILE *out=stderr, unsigned int max_frames=63)
QStringList paramList() const
void handleChangedDefaults(const DefaultPreferencesMode mode)
void setCurrentMigrationVersion()