view ui/downloader.cpp @ 975:b3695a3399de

(issue86) Install into default directories on Linux If the mozilla process is now started as root it will try to write into the default directories for NSS Shared and mozilla / thunderbird profiles. Cinst will now start the mozilla process once as root.
author Andre Heinecke <andre.heinecke@intevation.de>
date Fri, 29 Aug 2014 12:59:44 +0200
parents 879a634d0a40
children 2949f1842955
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU GPL (v>=2)
 * and comes with ABSOLUTELY NO WARRANTY!
 * See LICENSE.txt for details.
 */
#include "downloader.h"

#ifndef DOWNLOAD_SERVER
#define DOWNLOAD_SERVER "https://www.intevation.de"
#endif

#include <QFile>
#include <QDir>
#include <QDebug>
#include <QStandardPaths>
#include <QLocale>
#include <QSaveFile>
#include <QSettings>

#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include <polarssl/entropy.h>
#include <polarssl/ctr_drbg.h>
#include <polarssl/error.h>
#include <polarssl/certs.h>

#define MAX_SW_SIZE 15728640
#define MAX_LIST_SIZE 1048576

#ifdef USE_CURL
#include "sslconnection_curl.h"
#else
#include "sslconnection_bare.h"
#endif

Downloader::Downloader(QObject* parent, const QString& url,
                       const QByteArray& certificate,
                       const QDateTime& newestSW,
                       const QDateTime& newestList,
                       const QString& resourceSW,
                       const QString& resourceList,
                       bool downloadSW):
    QThread(parent),
    mLastModSW(newestSW),
    mLastModList(newestList),
    mResourceSW(resourceSW),
    mResourceList(resourceList),
    mDownloadSW(downloadSW)
{
#ifdef USE_CURL
    mSSLConnection = new SSLConnectionCurl(url, certificate);
/* Set up Proxy support. */
    QSettings settings;
    QString settingsProxy = settings.value("ProxyURL").toString();
    if (settingsProxy.isEmpty()) {
        QByteArray envProxy = qgetenv("http_proxy");
        if (envProxy.size()) {
            settingsProxy = QString::fromLocal8Bit(envProxy);
        }
    }
    if (!settingsProxy.isEmpty()) {
        mSSLConnection->setProxy(QUrl(settingsProxy));
    }
#else
    mSSLConnection = new SSLConnectionBare(url, certificate);
#endif
}


Downloader::~Downloader() {
    delete mSSLConnection;
}

QString Downloader::getDataDirectory()
{
    QString candidate =
        QStandardPaths::writableLocation(QStandardPaths::DataLocation);

    if (candidate.isEmpty()) {
        qDebug() << "Could not find writeable locaction for me";
        return QString();
    }

    QDir cDir(candidate);

    if (!cDir.exists()) {
        if (!cDir.mkpath(candidate)) {
            qDebug() << "Could not create path to: " << candidate;
            return QString();
        }
    }
    return cDir.absolutePath();
}


void Downloader::run() {
    int ret;
    QDateTime remoteModList;
    QDateTime remoteModSW;

    if (!mSSLConnection->initialized()) {
        emit error(tr("Failed to initialize SSL Module."), SSLConnection::ErrUnknown);
        return;
    }

    ret = mSSLConnection->connect();

    if (ret != 0) {
        emit error(tr("Failed to connect."),
                   mSSLConnection->getLastError());
        return;
    }

    emit progress(tr("Connected"), 1, -1);

    remoteModSW = mSSLConnection->getLastModifiedHeader(mResourceSW);
    emit lastModifiedDate(remoteModSW);

    if (!remoteModSW.isValid()) {
        emit error (tr("Connection failed."), SSLConnection::InvalidResponse);
        qDebug() << "Could not parse headers for Software";
        return;
    }

    if (!mLastModSW.isValid() || remoteModSW > mLastModSW) {
        QString dataDirectory = getDataDirectory();

        if (dataDirectory.isEmpty()) {
            qDebug() << "Failed to get data directory";
            return;
        }

        QString fileName = dataDirectory.append("/SW-")
            .append(remoteModSW.toString("yyyyMMddHHmmss"))
#ifdef WIN32
            .append(".exe");
#else
            .append(".sh");
#endif

        qDebug() << "fileName: " << fileName;

        if (mDownloadSW) {
            if (!mSSLConnection->downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) {
                emit error(tr("Failed to download File"), SSLConnection::ConnectionLost);
                qDebug() << "Failed to download software update.";
                return;
            }
            QFile::setPermissions(fileName, QFileDevice::ReadOwner |
                                            QFileDevice::WriteOwner |
                                            QFileDevice::ExeOwner);
        }

        emit newSoftwareAvailable(fileName, remoteModSW);
        return;
    }

    remoteModList = mSSLConnection->getLastModifiedHeader(mResourceList);
    if (!remoteModList.isValid()) {
        emit error (tr("Connection failed."), SSLConnection::InvalidResponse);
        qDebug() << "Could not parse headers for List";
        return;
    }

    if (!mLastModList.isValid() || remoteModList > mLastModList) {
        QString dataDirectory = getDataDirectory();

        if (dataDirectory.isEmpty()) {
            qDebug() << "Failed to get data directory";
            return;
        }

        QString fileName = dataDirectory.append("/list-")
            .append(remoteModList.toString("yyyyMMddHHmmss"))
            .append(".txt");

        qDebug() << "fileName: " << fileName;

        if (!mSSLConnection->downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) {
            return;
        }

        emit newListAvailable(fileName, remoteModList);
    }

    emit progress(tr("Closing"), 1, -1);
}

http://wald.intevation.org/projects/trustbridge/