SystemNetworkWatcher::SystemNetworkWatcher(ImapAccess *parent, Model *model):
    NetworkWatcher(parent, model), m_netConfManager(0), m_session(0)
{
    m_netConfManager = new QNetworkConfigurationManager(this);
    resetSession();
    connect(m_netConfManager, &QNetworkConfigurationManager::onlineStateChanged, this, &SystemNetworkWatcher::onGlobalOnlineStateChanged);
    connect(m_netConfManager, &QNetworkConfigurationManager::configurationChanged, this, &SystemNetworkWatcher::networkConfigurationChanged);
}
Exemplo n.º 2
0
void CoreClient::forceReset() {
	if (connector_) {
		std::cerr << "Warning: Client not disconnected properly: Connector still active" << std::endl;
		resetConnector();
	}
	if (sessionStream_ || connection_) {
		std::cerr << "Warning: Client not disconnected properly: Session still active" << std::endl;
		resetSession();
	}
}
/** @short Some of the configuration profiles have changed

This can be some completely harmelss change, like user editting an inactive profile of some random WiFi network.
Unfortunately, this is also the only method in which the Qt's NetworkManager plugin informs us about a switch
from eth0 to wlan0.

There's apparently no better signal, see http://lists.qt-project.org/pipermail/interest/2013-December/010374.html

*/
void SystemNetworkWatcher::networkConfigurationChanged(const QNetworkConfiguration &conf)
{
    bool reconnect = false;

    if (conf == sessionsActiveConfiguration() && !conf.state().testFlag(QNetworkConfiguration::Active) &&
            conf != m_netConfManager->defaultConfiguration() && m_netConfManager->defaultConfiguration().isValid()) {
        // Change of the "session's own configuration" which is not a default config of the system (anymore?), and the new default
        // is something valid.
        // I'm seeing (Qt 5.5-git, Linux, NetworkManager,...) quite a few of these as false positives on a random hotel WiFi.
        // Let's prevent a ton of useless reconnects here by only handling this if the system now believes that a default session
        // is something else.
        m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                          QStringLiteral("Change of configuration of the current session (%1); current default session is %2")
                          .arg(conf.name(), m_netConfManager->defaultConfiguration().name()));
        reconnect = true;
    } else if (conf.state().testFlag(QNetworkConfiguration::Active) && conf.type() == QNetworkConfiguration::InternetAccessPoint &&
               conf != sessionsActiveConfiguration() && conf == m_netConfManager->defaultConfiguration()) {
        // We are going to interpret this as a subtle hint for switching to another session

        if (m_session->configuration().type() == QNetworkConfiguration::UserChoice && !sessionsActiveConfiguration().isValid()) {
            // No configuration has been assigned yet, just ignore this event. This happens on Harmattan when we get a change
            // of e.g. an office WiFi connection in reply to us trying to open a session with the system's default configuration.
            m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                              QStringLiteral("No configuration has been assigned yet, let's wait for it"));
            return;
        }

        m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                          m_session->configuration().type() == QNetworkConfiguration::InternetAccessPoint ?
                              QStringLiteral("Change of system's default configuration: %1. Currently using %2.")
                              .arg(conf.name(), m_session->configuration().name())
                            :
                              QStringLiteral("Change of system's default configuration: %1. Currently using %2 (active: %3).")
                              .arg(conf.name(), m_session->configuration().name(), sessionsActiveConfiguration().name()));
        reconnect = true;
    }

    if (reconnect) {
        m_model->setNetworkPolicy(NETWORK_OFFLINE);
        resetSession();
        if (m_session->configuration().isValid()) {
            m_session->open();
        } else {
            m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                              QStringLiteral("Waiting for network to become available..."));
        }
    }
}
Exemplo n.º 4
0
void CsmaAloha::stateIdle() {
    ack_timer.stop();
    backoff_timer.stop();
    listen_timer.stop();
    resetSession();

    refreshState(CSMA_STATE_IDLE);

    if (print_transitions) printStateInfo();

    if (debug_) cout << NOW << "  CsmaAloha("<< addr << ")::stateIdle() queue size = " << Q.size() << endl;

    if ( !Q.empty() ) {
        refreshReason(CSMA_REASON_LISTEN);
        stateListen();
    }
}
Exemplo n.º 5
0
BaselineInfoPage::BaselineInfoPage(QWidget* parent)
    : ICentPage(parent)
    , m_betaLevelLabel(0)
    , m_thetaLevelLabel(0)
    , m_spinCoefBeta(0)
    , m_spinCoefTheta(0)
    , m_reRecordButton(new QPushButton(tr("Re-record")))
    , m_nextButton(new QPushButton(tr("Next")))
    , m_plot(new BaseLinePlot(tr("Baseline session results")))
    , m_x(0)
    , m_y(0)
    , m_size(0)
{
    createLayout();
    CENT::connect(m_reRecordButton, SIGNAL(clicked()), this, SIGNAL(reRecord()));
    CENT::connect(m_nextButton, SIGNAL(clicked()), this, SIGNAL(next()));
    resetSession();
}
void SystemNetworkWatcher::setDesiredNetworkPolicy(const NetworkPolicy policy)
{
    if (policy != m_desiredPolicy) {
        m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                          QStringLiteral("User's preference changed: %1").arg(policyToString(policy)));
        m_desiredPolicy = policy;
    }
    if (m_model->networkPolicy() == NETWORK_OFFLINE && policy != NETWORK_OFFLINE) {
        // We are asked to connect, the model is not connected yet
        if (isOnline()) {
            if (m_netConfManager->allConfigurations().isEmpty()) {
                m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"),
                                  // Yes, this is quite deliberate call to tr(). We absolutely want users to be able to read this
                                  // (but no so much as to bother them with a popup for now, I guess -- or not?)
                                  tr("Qt does not recognize any network session. Please be sure that qtbearer package "
                                     "(or similar) is installed. Assuming that network is actually already available."));
            }

            m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"), QStringLiteral("Network is online -> connecting"));
            reconnectModelNetwork();
        } else {
            // Chances are that our previously valid session is not valid anymore
            resetSession();
            // We aren't online yet, but we will become online at some point. When that happens, reconnectModelNetwork() will
            // be called, so there is nothing to do from this place.
            m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"), QStringLiteral("Opening network session"));
            m_session->open();
        }
    } else if (m_model->networkPolicy() != NETWORK_OFFLINE && policy == NETWORK_OFFLINE) {
        // This is pretty easy -- just disconnect the model
        m_model->setNetworkPolicy(NETWORK_OFFLINE);
        m_model->logTrace(0, Common::LOG_OTHER, QStringLiteral("Network Session"), QStringLiteral("Closing network session"));
        m_session->close();
    } else {
        // No need to connect/disconnect/reconnect, yay!
        m_model->setNetworkPolicy(m_desiredPolicy);
    }
}
Exemplo n.º 7
0
void TaskManagementMainTab::logoutButtonClicked() {
    auto url = state->taskState->host + "/knossos/session/";
    httpResponse response;
    response.length = 0;
    response.content = (char *)calloc(1, 10240);
    long httpCode;
    CURLcode code;

    setCursor(Qt::WaitCursor);
    bool result = taskState::httpDELETE(url.toUtf8().data(), &response, &httpCode, state->taskState->cookieFile.toUtf8().data(), &code, 5);
    setCursor(Qt::ArrowCursor);

    if(result == false) {
        setResponse("<font color='red'>Request failed. Please check your connection.</font>");
    }
    if(code == CURLE_OK) {
        resetSession("<font color='green'>Logged out successfully.</font>");
    } else {
        setResponse("<font color='red'>Request failed. Please check your connection.</font>");
    }

    free(response.content);
}
Exemplo n.º 8
0
void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
	if (options.forgetPassword) {
		purgePassword();
	}
	resetSession();

	boost::optional<ClientError> actualError;
	if (error) {
		ClientError clientError;
		if (boost::shared_ptr<ClientSession::Error> actualError = boost::dynamic_pointer_cast<ClientSession::Error>(error)) {
			switch(actualError->type) {
				case ClientSession::Error::AuthenticationFailedError:
					clientError = ClientError(ClientError::AuthenticationFailedError);
					break;
				case ClientSession::Error::CompressionFailedError:
					clientError = ClientError(ClientError::CompressionFailedError);
					break;
				case ClientSession::Error::ServerVerificationFailedError:
					clientError = ClientError(ClientError::ServerVerificationFailedError);
					break;
				case ClientSession::Error::NoSupportedAuthMechanismsError:
					clientError = ClientError(ClientError::NoSupportedAuthMechanismsError);
					break;
				case ClientSession::Error::UnexpectedElementError:
					clientError = ClientError(ClientError::UnexpectedElementError);
					break;
				case ClientSession::Error::ResourceBindError:
					clientError = ClientError(ClientError::ResourceBindError);
					break;
				case ClientSession::Error::SessionStartError:
					clientError = ClientError(ClientError::SessionStartError);
					break;
				case ClientSession::Error::TLSError:
					clientError = ClientError(ClientError::TLSError);
					break;
				case ClientSession::Error::TLSClientCertificateError:
					clientError = ClientError(ClientError::ClientCertificateError);
					break;
				case ClientSession::Error::StreamError:
					clientError = ClientError(ClientError::StreamError);
					break;
			}
		}
		else if (boost::shared_ptr<TLSError> actualError = boost::dynamic_pointer_cast<TLSError>(error)) {
			switch(actualError->getType()) {
				case TLSError::CertificateCardRemoved:
					clientError = ClientError(ClientError::CertificateCardRemoved);
					break;
				default:
					clientError = ClientError(ClientError::TLSError);
					break;
			}
		}
		else if (boost::shared_ptr<SessionStream::SessionStreamError> actualError = boost::dynamic_pointer_cast<SessionStream::SessionStreamError>(error)) {
			switch(actualError->type) {
				case SessionStream::SessionStreamError::ParseError:
					clientError = ClientError(ClientError::XMLError);
					break;
				case SessionStream::SessionStreamError::TLSError:
					clientError = ClientError(ClientError::TLSError);
					break;
				case SessionStream::SessionStreamError::InvalidTLSCertificateError:
					clientError = ClientError(ClientError::ClientCertificateLoadError);
					break;
				case SessionStream::SessionStreamError::ConnectionReadError:
					clientError = ClientError(ClientError::ConnectionReadError);
					break;
				case SessionStream::SessionStreamError::ConnectionWriteError:
					clientError = ClientError(ClientError::ConnectionWriteError);
					break;
			}
		}
		else if (boost::shared_ptr<CertificateVerificationError> verificationError = boost::dynamic_pointer_cast<CertificateVerificationError>(error)) {
			switch(verificationError->getType()) {
				case CertificateVerificationError::UnknownError: 
					clientError = ClientError(ClientError::UnknownCertificateError);
					break;
				case CertificateVerificationError::Expired: 
					clientError = ClientError(ClientError::CertificateExpiredError);
					break;
				case CertificateVerificationError::NotYetValid: 
					clientError = ClientError(ClientError::CertificateNotYetValidError);
					break;
				case CertificateVerificationError::SelfSigned: 
					clientError = ClientError(ClientError::CertificateSelfSignedError);
					break;
				case CertificateVerificationError::Rejected: 
					clientError = ClientError(ClientError::CertificateRejectedError);
					break;
				case CertificateVerificationError::Untrusted: 
					clientError = ClientError(ClientError::CertificateUntrustedError);
					break;
				case CertificateVerificationError::InvalidPurpose: 
					clientError = ClientError(ClientError::InvalidCertificatePurposeError);
					break;
				case CertificateVerificationError::PathLengthExceeded: 
					clientError = ClientError(ClientError::CertificatePathLengthExceededError);
					break;
				case CertificateVerificationError::InvalidSignature: 
					clientError = ClientError(ClientError::InvalidCertificateSignatureError);
					break;
				case CertificateVerificationError::InvalidCA: 
					clientError = ClientError(ClientError::InvalidCAError);
					break;
				case CertificateVerificationError::InvalidServerIdentity:
					clientError = ClientError(ClientError::InvalidServerIdentityError);
					break;
				case CertificateVerificationError::Revoked:
					clientError = ClientError(ClientError::RevokedError);
					break;
				case CertificateVerificationError::RevocationCheckFailed:
					clientError = ClientError(ClientError::RevocationCheckFailedError);
					break;
			}
		}
		actualError = boost::optional<ClientError>(clientError);
	}
	onDisconnected(actualError);
}
Exemplo n.º 9
0
void TaskManagementMainTab::loadLastSubmitButtonClicked() {
    auto url = state->taskState->host + "/knossos/activeTask/lastSubmit/";
    httpResponse response;
    response.length = 0;
    response.content = (char *)calloc(1, 10240);
    httpResponse header;
    header.length = 0;
    header.content = (char*)calloc(1, header.length + 1);
    long httpCode = 0;
    CURLcode code;

    setCursor(Qt::WaitCursor);
    bool success = taskState::httpFileGET(url.toUtf8().data(), nullptr, &response, &header, &httpCode, state->taskState->cookieFile.toUtf8().data(), &code, 10);
    setCursor(Qt::ArrowCursor);

    if(success == false) {
        resetSession(QString("<font color='red'>Could not find session cookie. Please login again.</font><br />%0").arg(response.content));
        return;
    }
    if(code != CURLE_OK) {
        setResponse(QString("<font color='red'>Request failed. Please check your connection.</font><br />%0").arg(response.content));
        return;
    }
    if(httpCode == 400) {
        setResponse(QString("<font color='red'>No submit found. Do you have an active task?</font><br />%0").arg(response.content));
        return;
    }
    else if(httpCode == 403) {
        setResponse(QString("<font color='red'>You are not authenticated. Permission denied.</font><br />%0").arg(response.content));
        return;
    }

    QDir taskDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/tasks");
    taskDir.mkpath(".");

    QString tmpfilepath = taskDir.absolutePath() + "/lastSubmit.tmp.nml";
    FILE * const lastNml = fopen(tmpfilepath.toUtf8().constData(), "w");
    if (lastNml == nullptr) {
        statusLabel->setText("<font color='red'>Failed to get submit. No write permission in this folder.</font>");
        return;
    }
    fwrite(response.content, 1, response.length, lastNml);
    fclose(lastNml);

    // 200 - success. Retrieve the filename from response header and rename the previously created tmp.nml
    char filename[1024] = {};
    if (taskState::copyInfoFromHeader(filename, &header, "filename")) {
        QFile tmpfile(tmpfilepath);
        tmpfile.rename(taskDir.absolutePath() + "/" + filename);
        state->skeletonState->skeletonFileAsQString = tmpfile.fileName();
    }

    if (loadSkeletonSignal(state->skeletonState->skeletonFileAsQString) == false) {//BUG signals shall not be used to return something
        statusLabel->setText("<font color='red'>Failed to load skeleton.</font>");
    } else {
        statusLabel->setText("<font color='green'>Loaded last submit successfully.</font>");
    }

    free(header.content);
    free(response.content);
}
Exemplo n.º 10
0
void TaskManagementMainTab::submitDialogOk() {
    // TDItem: write a function for multipart posts
    // for building the multipart formpost
    CURL *handle;
    CURLM *multihandle;
    int still_running;
    struct curl_httppost *formpost = NULL;
    struct curl_httppost *lastptr = NULL;
    struct curl_slist *headerlist = NULL;
    static const char buf[] = "Expect:";
    CURLMcode code;
    long httpCode;
    struct httpResponse response;
    //for checks during the transmission
    struct timeval timeout;
    int rc; // select() return code
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;
    long curl_timeo = -1;

    FILE *cookie;
    cookie = fopen(state->taskState->cookieFile.toUtf8().constData(), "r");
    if(cookie == NULL) {
        resetSession("<font color='red'>Could not find session cookie. Please login again.</font>");
        return;
    }
    fclose(cookie);

    // save first, in case of errors during transmission
    state->skeletonState->skeletonFileAsQString = Skeletonizer::getDefaultSkelFileName();
    emit saveSkeletonSignal(); //increment true

    //prompt for entering a comment for the submission


    handle = curl_easy_init();
    multihandle = curl_multi_init();
    if(handle == NULL || multihandle == NULL) {
        setResponse("<font color='red'>Connection error!</font>");
        return;
    }
    // fill the multipart post form. TDItem: comments are not supported, yet.
    std::string CSRFToken_stdstr = taskState::CSRFToken().toStdString();
    curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "csrfmiddlewaretoken",
                 CURLFORM_COPYCONTENTS, CSRFToken_stdstr.c_str(), CURLFORM_END);
    std::string skeletonFileAsQString_strstr = state->skeletonState->skeletonFileAsQString.toStdString();
    curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit_work_file",
                 CURLFORM_FILE, skeletonFileAsQString_strstr.c_str(), CURLFORM_END);
    curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "filename",
                 CURLFORM_COPYCONTENTS, skeletonFileAsQString_strstr.c_str(), CURLFORM_END);
    std::string submitDialogCommentField_stdstr = submitDialogCommentField->text().toStdString();
    curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit_comment",
                 CURLFORM_COPYCONTENTS, submitDialogCommentField_stdstr.c_str(), CURLFORM_END);
    if(submitDialogFinalCheckbox->isChecked()) {
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit_work_isfinal",
                     CURLFORM_COPYCONTENTS, "True", CURLFORM_END);
    }
    else {
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit_work_isfinal",
                     CURLFORM_COPYCONTENTS, "False", CURLFORM_END);
    }

    headerlist = curl_slist_append(headerlist, buf);
    if(handle == NULL || multihandle == NULL) {
        setResponse("<font color='red'>Failed to initialize request. Please tell the developers!</font>");
        return;
    }

    auto url = state->taskState->host + "/knossos/activeTask/";

    response.length = 0;
    response.content =(char *) calloc(1, response.length + 1);

    curl_easy_setopt(handle, CURLOPT_URL, url.toUtf8().data());
    curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headerlist);
    curl_easy_setopt(handle, CURLOPT_HTTPPOST, formpost);
    curl_easy_setopt(handle, CURLOPT_COOKIEFILE, state->taskState->cookieFile.toUtf8().data());
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, taskState::writeHttpResponse); // use this function to write the response into struct
    curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response); // write response into this struct
    curl_multi_add_handle(multihandle, handle);
    setCursor(Qt::WaitCursor);
    code = curl_multi_perform(multihandle, &still_running);

    do {
        // TDItem: this timeout is chosen arbitrarily, it could be tweaked in the future.
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        curl_multi_timeout(multihandle, &curl_timeo);
        if(curl_timeo >= 0) {
            timeout.tv_sec = curl_timeo / 1000;
            if(timeout.tv_sec > 1) {
              timeout.tv_sec = 1;
            }
            else {
              timeout.tv_usec = (curl_timeo % 1000) * 1000;
            }
        }

        // get file descriptors from the transfers
        FD_ZERO(&fdread);
        FD_ZERO(&fdwrite);
        FD_ZERO(&fdexcep);
        if(curl_multi_fdset(multihandle, &fdread, &fdwrite, &fdexcep, &maxfd) != CURLM_OK) {
            setResponse("<font color='red'>Failed to get file descriptors. Please try again.</font>");
            curl_multi_cleanup(multihandle);
            curl_easy_cleanup(handle);
            curl_formfree(formpost);
            curl_slist_free_all (headerlist);
            free(response.content);
            return;
        }
        // if maxfd is -1, it means libcurl is busy and we have to wait.
        // In that case calling select with maxfd+1 (== 0) is equal to sleep timeout seconds.
        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

        switch(rc) {
        case -1:
            setResponse("<font color='red'>Failed to get file descriptors. Please try again.</font>");
            curl_multi_cleanup(multihandle);
            curl_easy_cleanup(handle);
            curl_formfree(formpost);
            curl_slist_free_all (headerlist);
            free(response.content);
            return;
        case 0:
        default:
            /* timeout or readable/writable sockets */
            code = curl_multi_perform(multihandle, &still_running);
            break;
        }
    } while(still_running);
    setCursor(Qt::ArrowCursor);
    if(code == CURLM_OK) {
        curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &httpCode);
        if(httpCode >= 400) {
            setResponse(QString("<font color='red'>%1</font>").arg(response.content));
        }
        else {
            setResponse(QString("<font color='green'>%1</font>").arg(response.content));
        }
    }
    curl_multi_cleanup(multihandle);
    curl_easy_cleanup(handle);
    curl_formfree(formpost);
    curl_slist_free_all (headerlist);
    free(response.content);

    submitDialog->hide();
}
Exemplo n.º 11
0
void TaskManagementMainTab::startNewTaskButtonClicked() {
    CURLcode code;
    long httpCode;
    FILE *tasknml;
    struct httpResponse header;

    auto postdata = QString("csrfmiddlewaretoken=%0&data=<currentTask>%1</currentTask>").arg(taskState::CSRFToken(), state->taskState->taskFile);

    QDir taskDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/tasks");
    taskDir.mkpath(".");

    state->taskState->taskFile = taskDir.absolutePath() + "/task.tmp.nml";

    tasknml = fopen(state->taskState->taskFile.toUtf8().constData(), "w");
    if (tasknml == nullptr) {
        statusLabel->setText("<font color='red'>Failed to get new task. No write permission in this folder.</font>");
        return;
    }

    auto url = state->taskState->host + "/knossos/newTask/";

    header.length = 0;
    header.content = (char *)calloc(1, header.length + 1);

    setCursor(Qt::WaitCursor);
    httpResponse response;
    response.length = 0;
    response.content = (char *)calloc(1, 10240);
    bool success = taskState::httpFileGET(url.toUtf8().data(), postdata.toUtf8().data(), &response, &header, &httpCode, state->taskState->cookieFile.toUtf8().data(), &code, 5);
    setCursor(Qt::ArrowCursor);
    if(success == false) {
        resetSession(QString("<font color='red'>Could not find session cookie. Please login again.</font><br />%0").arg(response.content));
        return;
    }
    if(code != CURLE_OK) {
        setResponse(QString("<font color='red'>Request failed. Please check your connection.</font><br />%0").arg(response.content));
        taskState::removeCookie();
        free(header.content);
        return;
    }

    if(httpCode == 400) {
        setResponse(QString("<font color='red'>Current task not finished or no new task available.</font><br />%0").arg(response.content));
        QFile(state->taskState->taskFile).remove();
        free(header.content);
        return;
    }
    else if(httpCode == 403) {
        setResponse(QString("<font color='red'>You are not authenticated. Permission denied.</font><br />%0").arg(response.content));
        QFile(state->taskState->taskFile).remove();
        free(header.content);
        return;
    }
    else if(httpCode != 200){
        setResponse(QString("<font color='red'>Error received from server.</font><br />%0").arg(response.content));
        QFile(state->taskState->taskFile).remove();
        free(header.content);
        return;
    }
    fwrite(response.content, 1, response.length, tasknml);
    fclose(tasknml);
    // 200 - success. Retrieve the filename from response header and rename the previously created tmp.nml
    char filename[1024] = {};
    if (taskState::copyInfoFromHeader(filename, &header, "filename")) {
        QFile tmpFile(state->taskState->taskFile);
        tmpFile.rename(filename);
        state->taskState->taskFile = tmpFile.fileName();
    }
    // get task name
    char taskname[1024] = {};
    taskState::copyInfoFromHeader(taskname, &header, "taskname");
    state->taskState->taskName = taskname;
    setTask(state->taskState->taskName);

    // get task category description and task comment
    QByteArray descriptionBuffer(8192, '\0');
    QByteArray commentBuffer(8192, '\0');
    taskState::copyInfoFromHeader(descriptionBuffer.data(), &header, "description");
    taskState::copyInfoFromHeader(commentBuffer.data(), &header, "comment");
    QString description = QByteArray::fromBase64(descriptionBuffer);
    QString comment = QByteArray::fromBase64(commentBuffer);

    QMessageBox prompt;
    prompt.setWindowFlags(Qt::WindowStaysOnTopHint);
    prompt.setIcon(QMessageBox::Information);
    prompt.setWindowTitle(state->taskState->taskName);
    prompt.setText(QString("<p style='width:200px;'><b>Category %1:</b> %2<br><br><b>Task %3:</b> %4</p>")
                   .arg(taskState::getCategory())
                   .arg(description)
                   .arg(taskState::getTask())
                   .arg(comment));
    prompt.addButton("Ok", QMessageBox::ActionRole); // closes prompt by default
    prompt.resize(400, 300);
    prompt.exec();
    emit setDescriptionSignal(description);
    emit setCommentSignal(comment);
    emit loadSkeletonSignal(state->taskState->taskFile);
    setResponse("<font color='green'>Loaded task successfully.</font>");
    free(header.content);
}