void Application::validateCommandLineParameters()
{
    if (m_commandLineArgs.portableMode && !m_commandLineArgs.profileDir.isEmpty())
        throw CommandLineParameterError(tr("Portable mode and explicit profile directory options are mutually exclusive"));

    if (m_commandLineArgs.portableMode && m_commandLineArgs.relativeFastresumePaths)
        Logger::instance()->addMessage(tr("Portable mode implies relative fastresume"), Log::WARNING);
}
Exemple #2
0
// Main
int main(int argc, char *argv[])
{
    // We must save it here because QApplication constructor may change it
    bool isOneArg = (argc == 2);

#ifdef Q_OS_MAC
    // On macOS 10.12 Sierra, Apple changed the behaviour of CFPreferencesSetValue() https://bugreports.qt.io/browse/QTBUG-56344
    // Due to this, we have to move from native plist to IniFormat
    macMigratePlists();
#endif

#if !defined(DISABLE_GUI) && defined(Q_OS_UNIX)
    setupDpi();
#endif

    try {
        // Create Application
        QString appId = QLatin1String("qBittorrent-") + Utils::Misc::getUserIDString();
        QScopedPointer<Application> app(new Application(appId, argc, argv));

#ifndef DISABLE_GUI
        // after the application object creation because we need a profile to be set already
        // for the migration
        migrateRSS();
#endif

        const QBtCommandLineParameters params = app->commandLineArgs();

        if (!params.unknownParameter.isEmpty()) {
            throw CommandLineParameterError(QObject::tr("%1 is an unknown command line parameter.",
                                                        "--random-parameter is an unknown command line parameter.")
                                                        .arg(params.unknownParameter));
        }
#ifndef Q_OS_WIN
        if (params.showVersion) {
            if (isOneArg) {
                displayVersion();
                return EXIT_SUCCESS;
            }
            throw CommandLineParameterError(QObject::tr("%1 must be the single command line parameter.")
                                     .arg(QLatin1String("-v (or --version)")));
        }
#endif
        if (params.showHelp) {
            if (isOneArg) {
                displayUsage(argv[0]);
                return EXIT_SUCCESS;
            }
            throw CommandLineParameterError(QObject::tr("%1 must be the single command line parameter.")
                                 .arg(QLatin1String("-h (or --help)")));
        }

        // Set environment variable
        if (!qputenv("QBITTORRENT", QBT_VERSION))
            std::cerr << "Couldn't set environment variable...\n";

#ifndef DISABLE_GUI
        if (!userAgreesWithLegalNotice())
            return EXIT_SUCCESS;
#else
        if (!params.shouldDaemonize
            && isatty(fileno(stdin))
            && isatty(fileno(stdout))
            && !userAgreesWithLegalNotice())
            return EXIT_SUCCESS;
#endif

        // Check if qBittorrent is already running for this user
        if (app->isRunning()) {
#ifdef DISABLE_GUI
            if (params.shouldDaemonize) {
                throw CommandLineParameterError(QObject::tr("You cannot use %1: qBittorrent is already running for this user.")
                                     .arg(QLatin1String("-d (or --daemon)")));
            }
            else
#endif
            qDebug("qBittorrent is already running for this user.");

            QThread::msleep(300);
            app->sendParams(params.paramList());

            return EXIT_SUCCESS;
        }

#if defined(Q_OS_WIN)
        // This affects only Windows apparently and Qt5.
        // When QNetworkAccessManager is instantiated it regularly starts polling
        // the network interfaces to see what's available and their status.
        // This polling creates jitter and high ping with wifi interfaces.
        // So here we disable it for lack of better measure.
        // It will also spew this message in the console: QObject::startTimer: Timers cannot have negative intervals
        // For more info see:
        // 1. https://github.com/qbittorrent/qBittorrent/issues/4209
        // 2. https://bugreports.qt.io/browse/QTBUG-40332
        // 3. https://bugreports.qt.io/browse/QTBUG-46015

        qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
#endif

#if defined(Q_OS_MAC)
        // Since Apple made difficult for users to set PATH, we set here for convenience.
        // Users are supposed to install Homebrew Python for search function.
        // For more info see issue #5571.
        QByteArray path = "/usr/local/bin:";
        path += qgetenv("PATH");
        qputenv("PATH", path.constData());

        // On OS X the standard is to not show icons in the menus
        app->setAttribute(Qt::AA_DontShowIconsInMenus);
#endif

#ifndef DISABLE_GUI
        if (!upgrade()) return EXIT_FAILURE;
#else
        if (!upgrade(!params.shouldDaemonize
                     && isatty(fileno(stdin))
                     && isatty(fileno(stdout)))) return EXIT_FAILURE;
#endif
#ifdef DISABLE_GUI
        if (params.shouldDaemonize) {
            app.reset(); // Destroy current application
            if ((daemon(1, 0) == 0)) {
                app.reset(new Application(appId, argc, argv));
                if (app->isRunning()) {
                    // Another instance had time to start.
                    return EXIT_FAILURE;
                }
            }
            else {
                qCritical("Something went wrong while daemonizing, exiting...");
                return EXIT_FAILURE;
            }
        }
#else
        if (!(params.noSplash || Preferences::instance()->isSplashScreenDisabled()))
            showSplashScreen();
#endif

#if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN)
        signal(SIGINT, sigNormalHandler);
        signal(SIGTERM, sigNormalHandler);
        signal(SIGABRT, sigAbnormalHandler);
        signal(SIGSEGV, sigAbnormalHandler);
#endif

        return app->exec(params.paramList());
    }
    catch (CommandLineParameterError &er) {
        displayBadArgMessage(er.messageForUser());
        return EXIT_FAILURE;
    }
}
Exemple #3
0
QBtCommandLineParameters parseCommandLine(const QStringList &args)
{
    QBtCommandLineParameters result {QProcessEnvironment::systemEnvironment()};

    for (int i = 1; i < args.count(); ++i) {
        const QString &arg = args[i];

        if ((arg.startsWith("--") && !arg.endsWith(".torrent"))
            || (arg.startsWith("-") && (arg.size() == 2))) {
            // Parse known parameters
            if ((arg == SHOW_HELP_OPTION)) {
                result.showHelp = true;
            }
#ifndef Q_OS_WIN
            else if (arg == SHOW_VERSION_OPTION) {
                result.showVersion = true;
            }
#endif
            else if (arg == WEBUI_PORT_OPTION) {
                result.webUiPort = WEBUI_PORT_OPTION.value(arg);
                if ((result.webUiPort < 1) || (result.webUiPort > 65535))
                    throw CommandLineParameterError(QObject::tr("%1 must specify a valid port (1 to 65535).")
                                                    .arg(QLatin1String("--webui-port")));
            }
#ifndef DISABLE_GUI
            else if (arg == NO_SPLASH_OPTION) {
                result.noSplash = true;
            }
#else
            else if (arg == DAEMON_OPTION) {
                result.shouldDaemonize = true;
            }
#endif
            else if (arg == PROFILE_OPTION) {
                result.profileDir = PROFILE_OPTION.value(arg);
            }
            else if (arg == RELATIVE_FASTRESUME) {
                result.relativeFastresumePaths = true;
            }
            else if (arg == PORTABLE_OPTION) {
                result.portableMode = true;
            }
            else if (arg == CONFIGURATION_OPTION) {
                result.configurationName = CONFIGURATION_OPTION.value(arg);
            }
            else if (arg == SAVE_PATH_OPTION) {
                result.savePath = SAVE_PATH_OPTION.value(arg);
            }
            else if (arg == PAUSED_OPTION) {
                result.addPaused = PAUSED_OPTION.value(arg);
            }
            else if (arg == SKIP_HASH_CHECK_OPTION) {
                result.skipChecking = true;
            }
            else if (arg == CATEGORY_OPTION) {
                result.category = CATEGORY_OPTION.value(arg);
            }
            else if (arg == SEQUENTIAL_OPTION) {
                result.sequential = true;
            }
            else if (arg == FIRST_AND_LAST_OPTION) {
                result.firstLastPiecePriority = true;
            }
            else if (arg == SKIP_DIALOG_OPTION) {
                result.skipDialog = SKIP_DIALOG_OPTION.value(arg);
            }
            else {
                // Unknown argument
                result.unknownParameter = arg;
                break;
            }
        }
        else {
            QFileInfo torrentPath;
            torrentPath.setFile(arg);

            if (torrentPath.exists())
                result.torrents += torrentPath.absoluteFilePath();
            else
                result.torrents += arg;
        }
    }

    return result;
}