summaryrefslogtreecommitdiffstats
path: root/installerbuilder/installerbase/installerbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/installerbase/installerbase.cpp')
-rw-r--r--installerbuilder/installerbase/installerbase.cpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/installerbuilder/installerbase/installerbase.cpp b/installerbuilder/installerbase/installerbase.cpp
new file mode 100644
index 000000000..e30a6c097
--- /dev/null
+++ b/installerbuilder/installerbase/installerbase.cpp
@@ -0,0 +1,372 @@
+/**************************************************************************
+**
+** This file is part of Qt SDK**
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
+**
+** Contact: Nokia Corporation qt-info@nokia.com**
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception version
+** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you are unsure which license is appropriate for your use, please contact
+** (qt-info@nokia.com).
+**
+**************************************************************************/
+
+// This file contains the base part of the installer.
+// It lists the files and features the installer should handle.
+
+#include "qinstaller.h"
+#include "qinstallercomponentmodel.h"
+#include "qinstallercomponent.h"
+#include "qinstallergui.h"
+#include "qinstallerglobal.h"
+#include "init.h"
+#include "lib7z_facade.h"
+#include "common/installersettings.h"
+#include "common/fileutils.h"
+#include "common/utils.h"
+#include "fsengineserver.h"
+#include "updater.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+#include <QtCore/QFileInfo>
+#include <QtCore/QResource>
+#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QTimer>
+#include <QtCore/QTranslator>
+#include <QtCore/QUrl>
+#include <QtCore/QPointer>
+#include <QtCore/QSettings>
+#include <QtCore/QThread>
+
+#include <QtGui/QApplication>
+#include <QtGui/QTabWidget>
+#include <QtGui/QLabel>
+#include <QtGui/QMessageBox>
+#include <QtGui/QVBoxLayout>
+
+#include <QtNetwork/QNetworkProxyFactory>
+
+#include <KDToolsCore/KDSelfRestarter>
+#include <KDToolsCore/KDRunOnceChecker>
+
+#include <KDUpdater/Application>
+#include <KDUpdater/UpdateSourcesInfo>
+#include <KDUpdater/PackagesInfo>
+#include <KDUpdater/Update>
+#include <KDUpdater/UpdateFinder>
+#include <KDUpdater/UpdateOperationFactory>
+
+#include <KDUpdater/UpdateOperation>
+
+// QInstallerGui is base of the Gui part of an installer, i.e.
+// the "main installer wizard". In the simplest case it's just
+// a sequence of "standard" wizard pages. A few commonly used
+// ones are provided already in qinstallergui.h.
+
+#include "common/binaryformat.h"
+#include "common/binaryformatenginehandler.h"
+#include "common/errors.h"
+#include "common/range.h"
+
+#include <iostream>
+#include <memory>
+
+#include "installerbasecommons.h"
+#include "maintabwidget.h"
+#include "tabcontroller.h"
+
+using namespace QInstaller;
+using namespace QInstallerCreator;
+
+class Sleep : public QThread
+{
+public:
+ static void sleep(unsigned long ms)
+ {
+ QThread::usleep(ms);
+ }
+};
+
+static void printUsage(bool isInstaller, const QString &productName,
+ const QString &installerBinaryPath)
+{
+ QString str;
+ if (isInstaller) {
+ str = QString::fromLatin1(" [--script <scriptfile>] [<name>=<value>...]\n"
+ "\n Runs the %1 installer\n"
+ "\n --script runs the the installer non-interactively, without UI, using the "
+ "script <scriptfile> to perform the installation.\n").arg(productName);
+ } else {
+ str = QString::fromLatin1(" [<name>=<value>...]\n\n Runs the %1 uninstaller.\n")
+ .arg(productName);
+ }
+ str = QLatin1String("\nUsage: ") + installerBinaryPath + str;
+ std::cerr << qPrintable(str) << std::endl;
+}
+
+int main(int argc, char *argv[])
+{
+ qsrand(QDateTime::currentDateTime().toTime_t());
+ const KDSelfRestarter restarter(argc, argv);
+ KDRunOnceChecker runCheck(QLatin1String("lockmyApp1234865.lock"));
+
+ try {
+
+ {
+ QCoreApplication app(argc, argv);
+ const QStringList args = app.arguments();
+
+ // this isthe FSEngineServer as an admin rights process upon request:
+ if (args.count() >= 3 && args[1] == QLatin1String("--startserver")) {
+#ifdef FSENGINE_TCP
+ FSEngineServer* const server = new FSEngineServer(args[2].toInt());
+#else
+ FSEngineServer* const server = new FSEngineServer(args[2]);
+#endif
+ if (args.count() >= 4)
+ server->setAuthorizationKey(args[3]);
+ QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()));
+ return app.exec();
+ }
+
+ if (args.contains(QLatin1String("--proxy")))
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+
+ if (args.contains(QLatin1String("--checkupdates"))) {
+ if (runCheck.isRunning(KDRunOnceChecker::ProcessList))
+ return 0;
+
+ QInstaller::setVerbose(args.contains(QLatin1String("--verbose")));
+ QInstaller::init();
+ // load the embedded binary resource
+ BinaryContent content = BinaryContent::readFromApplicationFile();
+ content.registerEmbeddedQResources();
+ Updater u;
+ return u.checkForUpdates(true) ? 0 : 1;
+ }
+ }
+
+ QApplication app(argc, argv);
+ if (runCheck.isRunning(KDRunOnceChecker::ProcessList)) {
+ if (runCheck.isRunning(KDRunOnceChecker::Lockfile))
+ return 0;
+
+ while (runCheck.isRunning(KDRunOnceChecker::ProcessList))
+ Sleep::sleep(1);
+ }
+
+ const QStringList args = app.arguments();
+
+ // from here, the "normal" installer binary is running
+ if (args.contains(QLatin1String("--verbose")) || args.contains(QLatin1String("Verbose")))
+ QInstaller::setVerbose(true);
+
+ verbose() << "This is installerbase version " << INSTALLERBASE_VERSION << std::endl;
+ verbose() << "ARGS: " << args << std::endl;
+
+ // install the default translator
+ const QString localeFile =
+ QString::fromLatin1(":/translations/qt_%1").arg(QLocale::system().name());
+ {
+ QTranslator* const translator = new QTranslator(&app);
+ translator->load(localeFile);
+ app.installTranslator(translator);
+ }
+
+ // install "our" default translator
+ const QString ourLocaleFile =
+ QString::fromLatin1(":/translations/%1.qm").arg(QLocale().name().toLower());
+ if (QFile::exists(ourLocaleFile))
+ {
+ QTranslator* const translator = new QTranslator(&app);
+ translator->load(ourLocaleFile);
+ app.installTranslator(translator);
+ }
+
+ verbose() << "resource tree before loading the in-binary resource: " << std::endl;
+
+ QDir dir(QLatin1String(":/"));
+ Q_FOREACH (const QString &i, dir.entryList()) {
+ const QByteArray ba = i.toUtf8();
+ verbose() << ba.constData() << std::endl;
+ }
+
+ // register custom operations before reading the binary content cause they may used in
+ // the uninstaller for the recorded list of during the installation performed operations.
+ QInstaller::init();
+
+ // load the embedded binary resource
+ BinaryContent content = BinaryContent::readFromApplicationFile();
+ content.registerEmbeddedQResources();
+
+ verbose() << "resource tree after loading the in-binary resource: " << std::endl;
+
+ dir = QDir(QLatin1String(":/"));
+ Q_FOREACH (const QString &i, dir.entryList())
+ verbose() << QString::fromLatin1(":/%1").arg(i) << std::endl;
+
+ dir = QDir(QLatin1String(":/metadata/"));
+ Q_FOREACH (const QString &i, dir.entryList())
+ verbose() << QString::fromLatin1(":/metadata/%1").arg(i) << std::endl;
+
+ KDUpdater::Application updaterapp;
+ QInstaller::Installer installer(content.magicmaker, content.performedOperations);
+ installer.setUpdaterApplication(&updaterapp);
+
+ const QString productName = installer.value(QLatin1String("ProductName"));
+
+ QString controlScript;
+ bool isUpdater = false;
+ QHash<QString, QString> params;
+ for (int i = 1; i < args.size(); ++i) {
+ const QString &argument = args.at(i);
+ if (argument.isEmpty())
+ continue;
+
+ if (argument.contains(QLatin1Char('='))) {
+ const QString name = argument.section(QLatin1Char('='), 0, 0);
+ const QString value = argument.section(QLatin1Char('='), 1, 1);
+ params.insert(name, value);
+ installer.setValue(name, value);
+ } else if (argument == QLatin1String("--script") || argument == QLatin1String("Script")) {
+ ++i;
+ if (i < args.size()) {
+ controlScript = args.at(i);
+ if (!QFileInfo(controlScript).exists())
+ return INST_FAILED;
+ } else {
+ return INST_FAILED;
+ }
+ } else if (argument == QLatin1String("--verbose") || argument == QLatin1String("Verbose")) {
+ installer.setVerbose(true);
+ } else if (argument == QLatin1String("--proxy")) {
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+ } else if (argument == QLatin1String("--show-virtual-components")
+ || argument == QLatin1String("ShowVirtualComponents")) {
+ QInstaller::ComponentModel::setVirtualComponentsVisible(true);
+ QFont f;
+ f.setItalic(true);
+ QInstaller::ComponentModel::setVirtualComponentsFont(f);
+ } else if (argument == QLatin1String("--manage-packages")
+ || argument == QLatin1String("ManagePackages")) {
+ installer.setPackageManager();
+ } else if (argument == QLatin1String("--updater") || argument == QLatin1String("Updater")) {
+ isUpdater = true && !installer.isInstaller();
+ } else if (argument == QLatin1String("--help") || argument == QLatin1String("-h")) {
+ return INST_SUCCESS;
+ } else if (argument == QLatin1String("--addTempRepository")
+ || argument == QLatin1String("--setTempRepository")) {
+ ++i;
+ if (i >= args.size()) {
+ std::cerr << "No repository specified" << std::endl;
+ return INST_FAILED;
+ }
+
+ QList<Repository> repoList;
+ QStringList items = args.at(i).split(QLatin1Char(','));
+ foreach(const QString &item, items) {
+ verbose() << "Adding custom repository:" << item << std::endl;
+ Repository rep;
+ rep.setUrl(item);
+ rep.setRequired(true);
+ repoList.append(rep);
+ }
+
+ // We cannot use setRemoteRepositories as that is a synchronous call which "
+ // tries to get the data from server and this isn't what we want at this point
+ const bool replace = (argument == QLatin1String("--setTempRepository"));
+ installer.setTemporaryRepositories(repoList, replace);
+ } else {
+ std::cerr << "Unknown option: " << argument << std::endl;
+ return INST_FAILED;
+ }
+ }
+
+ if (!installer.isInstaller())
+ installer.setPackageManager();
+
+ updaterapp.packagesInfo()->setApplicationName(productName);
+ updaterapp.packagesInfo()->setApplicationVersion(installer
+ .value(QLatin1String("ProductVersion")));
+ updaterapp.addUpdateSource(productName, productName, QString(),
+ QUrl(QLatin1String("resource://metadata/")), 0);
+
+ // Create the wizard gui
+ TabController controller(0);
+ controller.setInstaller(&installer);
+ controller.setInstallerParams(params);
+ controller.setApplication(&updaterapp);
+ controller.setControlScript(controlScript);
+
+ if (installer.isInstaller()) {
+ controller.setInstallerGui(new QtInstallerGui(&installer));
+ } else {
+ controller.setTabWidget(new MainTabWidget());
+ controller.setInstallerGui(new QtUninstallerGui(&installer));
+ }
+
+ int val = isUpdater ? controller.initUpdater() : controller.initPackageManager();
+ if (val != TabController::SUCCESS)
+ return val;
+
+ const int result = app.exec();
+ if (result != 0)
+ return result;
+
+ if (installer.finishedWithSuccess())
+ return INST_SUCCESS;
+
+ const int status = installer.status();
+ const TabController::Status controllerState = controller.getState();
+
+ Q_ASSERT(status == Installer::InstallerFailed || status == Installer::InstallerSucceeded
+ || status == Installer::InstallerCanceledByUser);
+
+ if (controllerState == TabController::SUCCESS)
+ return INST_SUCCESS;
+
+ switch (status) {
+ case Installer::InstallerSucceeded:
+ return INST_SUCCESS;
+
+ case Installer::InstallerCanceledByUser:
+ return INST_CANCELED;
+
+ case Installer::InstallerFailed:
+ default:
+ break;
+ }
+ return INST_FAILED;
+ } catch(const Error &e) {
+ std::cerr << qPrintable(e.message()) << std::endl;
+ } catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ } catch(...) {
+ std::cerr << "Unknown error, aborting." << std::endl;
+ }
+
+ return INST_FAILED;
+}