bool WriteMail::sendStage()
{
    if (!isComplete()) {
        // The user must either complete the message, save as draft or explicitly cancel
        return false;
    }

    if (buildMail(true)) {
        if (largeAttachments()) {
            // Ensure this is intentional
            if (QMessageBox::question(qApp->activeWindow(),
                                      tr("Large attachments"),
                                      tr("The message has large attachments. Send now?"),
                                      QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
                draft();
                QMessageBox::warning(qApp->activeWindow(),
                                     tr("Message saved"),
                                     tr("The message has been saved in the Drafts folder"),
                                     QMessageBox::Ok);
                return true;
            }
        }

        emit enqueueMail(mail);
    } else {
        qMailLog(Messaging) << "Unable to build mail for transmission!";
    }

    // Prevent double deletion of composer textedit that leads to crash on exit
    reset();
    close();

    return true;
}
    static quint64 registerFlag(const QString &name)
    {
        if (!QMailStore::instance()->registerAccountStatusFlag(name)) {
            qMailLog(Messaging) << "Unable to register account status flag:" << name << "!";
        }

        return QMailAccount::statusMask(name);
    }
void QMail::closeDatabase()
{
    QDatabaseInstanceData* instance = databaseDataInstance()->localData();

    if (instance->init) {
        qMailLog(Messaging) << "closing database";
        instance->init = false;
        QSqlDatabase::removeDatabase("qmailstore_sql_connection");
    } // else nothing todo
}
void AccountSettings::activityChanged(QMailServiceAction::Activity activity)
{
    if (sender() == static_cast<QObject*>(retrievalAction)) {
        const QMailServiceAction::Status status(retrievalAction->status());
        if (status.accountId.isValid()) {
            QMailAccount account(status.accountId);

            if (activity == QMailServiceAction::Successful) {
                if (account.status() & QMailAccount::MessageSink) {
                    transmitAction->transmitMessages(account.id());
                } else {
                    statusDisplay->setStatus(tr("Configuration tested."));
                }
            } else if (activity == QMailServiceAction::Failed) {
                QString caption(tr("Retrieve Failure"));
                QString action(tr("%1 - Error retrieving folders: %2", "%1: account name, %2: error text"));

                action = action.arg(account.name()).arg(status.text);

                qMailLog(Messaging) << "retrieveFolders failed:" << action;
                statusDisplay->setVisible(false);
                QMessageBox::warning(0, caption, action, QMessageBox::Ok);
            }
        }
    } else if (sender() == static_cast<QObject*>(transmitAction)) {
        if (activity == QMailServiceAction::Successful) {
            statusDisplay->setStatus(tr("Configuration tested."));
        } else if (activity == QMailServiceAction::Failed) {
            const QMailServiceAction::Status status(transmitAction->status());
            QMailAccount account(status.accountId);

            QString caption(tr("Transmission Failure"));
            QString action(tr("%1 - Error testing connection: %2", "%1: account name, %2: error text"));

            action = action.arg(account.name()).arg(status.text);

            qMailLog(Messaging) << "transmitMessages failed:" << action;
            statusDisplay->setVisible(false);
            QMessageBox::warning(0, caption, action, QMessageBox::Ok);
        }
    }
}
void SmtpClient::setAccount(const QMailAccountId &id)
{
    // Load the current configuration for this account
    config = QMailAccountConfiguration(id);
#ifdef USE_ACCOUNTS_QT
    if (!ssoSessionManager) {
        SmtpConfiguration smtpCfg(config);
        ssoSessionManager = new SSOSessionManager(this);
        if (ssoSessionManager->createSsoIdentity(id, "smtp", smtpCfg.smtpAuthentication())) {
            ENFORCE(connect(ssoSessionManager, SIGNAL(ssoSessionResponse(QList<QByteArray>))
                            ,this, SLOT(onSsoSessionResponse(QList<QByteArray>))));
            ENFORCE(connect(ssoSessionManager, SIGNAL(ssoSessionError(QString)),this, SLOT(onSsoSessionError(QString))));
            qMailLog(SMTP) << Q_FUNC_INFO << "SSO identity is found for account id: "<< id;
        } else {
            delete ssoSessionManager;
            ssoSessionManager = 0;
            qMailLog(SMTP) << Q_FUNC_INFO << "SSO identity is not found for account id: "<< id
                           << ", accounts configuration will be used";
        }
    }
#endif
}
void ImapTransport::test()
{
#if 0
    qMailLog(IMAP) << "Rfc1951Compressor and Rfc1951Decompressor functional testing running...";
    // Mainly aiming to test for bounday conditions
    // So make the compression/decompression buffers about the same size as the input/output
    QByteArray data("This\n is some test data.\r\n The quick brown fox jumps over the lazy dog. 0123456789.\r\n");
    for(int i = 10; i <= 100; ++ i) {
        for(int j = 10; i <= 100; ++ i) {
            for (int k = 10; k <= 100; ++k) {
                Rfc1951Compressor compressor(i);
                Rfc1951Decompressor decompressor(j);
                QByteArray input(data.left(k));
                input += "\r\n";
                QByteArray compressed;
                {
                    QDataStream stream(&compressed, QIODevice::WriteOnly);
                    compressor.write(&stream, &input);
                }
                {
                    QByteArray output;
                    QBuffer buffer(&compressed);
                    buffer.open(QIODevice::ReadOnly);
                    decompressor.consume(&buffer);
                    while (decompressor.canReadLine()) {
                        output += decompressor.readLine();
                    }
                    if (input != output) {
                        qMailLog(IMAP) << "Test failure: input" << input.toHex() << "output" << output.toHex();
                        Q_ASSERT(input == output);
                    }
                }
            }
        }
    }
    qMailLog(IMAP) << "Rfc1951Compressor and Rfc1951Decompressor functional testing completed OK";
#endif
}
void SmtpClient::newConnection()
{
    qMailLog(SMTP) << "newConnection" << flush;
    if (sending) {
        operationFailed(QMailServiceAction::Status::ErrConnectionInUse, tr("Cannot send message; transport in use"));
        return;
    }

    if (!config.id().isValid()) {
        status = Done;
        operationFailed(QMailServiceAction::Status::ErrConfiguration, tr("Cannot send message without account configuration"));
        return;
    }

    SmtpConfiguration smtpCfg(config);
    if ( smtpCfg.smtpServer().isEmpty() ) {
        status = Done;
        operationFailed(QMailServiceAction::Status::ErrConfiguration, tr("Cannot send message without SMTP server configuration"));
        return;
    }

    // Calculate the total indicative size of the messages we're sending
    totalSendSize = 0;
    foreach (uint size, sendSize.values())
        totalSendSize += size;

    progressSendSize = 0;
    emit progressChanged(progressSendSize, totalSendSize);

    status = Init;
    sending = true;
    domainName = QByteArray();
    outstandingResponses = 0;

    if (!transport) {
        // Set up the transport
        transport = new QMailTransport("SMTP");

        connect(transport, SIGNAL(readyRead()),
                this, SLOT(readyRead()));
        connect(transport, SIGNAL(connected(QMailTransport::EncryptType)),
                this, SLOT(connected(QMailTransport::EncryptType)));
        connect(transport, SIGNAL(bytesWritten(qint64)),
                this, SLOT(sent(qint64)));
        connect(transport, SIGNAL(updateStatus(QString)),
                this, SIGNAL(updateStatus(QString)));
        connect(transport, SIGNAL(errorOccurred(int,QString)),
                this, SLOT(transportError(int,QString)));
    }
QSqlDatabase QMail::createDatabase()
{
    if (!databaseDataInstance()->hasLocalData()) {
        databaseDataInstance()->setLocalData(new QDatabaseInstanceData);
    }
    QDatabaseInstanceData* instance = databaseDataInstance()->localData();

    QSqlDatabase db;
    if (instance->init) {
        db = QSqlDatabase::database("qmailstore_sql_connection");
    } else {
        qMailLog(Messaging) << "opening database";
        db = QSqlDatabase::addDatabase("QSQLITE", "qmailstore_sql_connection");
        
        QDir dbDir(dataPath() + "database");
        if (!dbDir.exists()) {
#ifdef Q_OS_UNIX
            QString path = dataPath();
            if (path.endsWith('/'))
                path = path.left(path.length() - 1);
            if (!QDir(path).exists() && ::mkdir(QFile::encodeName(path), S_IRWXU) == -1)
                qCritical() << "Cannot create database directory: " << errno;
#endif
            if (!dbDir.mkpath(dataPath() + "database"))
                qCritical() << "Cannot create database path";
        }

        db.setDatabaseName(dataPath() + "database/qmailstore.db");
#endif

        if(!db.open()) {
            QSqlError dbError = db.lastError();
            qCritical() << "Cannot open database: " << dbError.text();
        }

        QDir tp(tempPath());
        if(!tp.exists())
            if(!tp.mkpath(tempPath()))
                qCritical() << "Cannot create temp path";

        instance->init = true;
    }

    return db;
}
void SmtpClient::newConnection()
{
    qMailLog(SMTP) << "newConnection" << flush;
#ifdef USE_ACCOUNTS_QT
    loginFailed = false;
#endif
    if (sending) {
        operationFailed(QMailServiceAction::Status::ErrConnectionInUse, tr("Cannot send message; transport in use"));
        return;
    }

    if (!config.id().isValid()) {
        status = Done;
        operationFailed(QMailServiceAction::Status::ErrConfiguration, tr("Cannot send message without account configuration"));
        return;
    }

    // Load the current configuration for this account
    // Reload the account configuration whenever a new SMTP
    // connection is created, in order to ensure the changes
    // in the account settings are being managed properly.
    config = QMailAccountConfiguration(config.id());

    SmtpConfiguration smtpCfg(config);
    if ( smtpCfg.smtpServer().isEmpty() ) {
        status = Done;
        operationFailed(QMailServiceAction::Status::ErrConfiguration, tr("Cannot send message without SMTP server configuration"));
        return;
    }

    // Calculate the total indicative size of the messages we're sending
    totalSendSize = 0;
    foreach (uint size, sendSize.values())
        totalSendSize += size;

    progressSendSize = 0;
    emit progressChanged(progressSendSize, totalSendSize);

    status = Init;
    sending = true;
    domainName = QByteArray();
    outstandingResponses = 0;

    if (!transport) {
        // Set up the transport
        transport = new QMailTransport("SMTP");

        connect(transport, SIGNAL(readyRead()),
                this, SLOT(readyRead()));
        connect(transport, SIGNAL(connected(QMailTransport::EncryptType)),
                this, SLOT(connected(QMailTransport::EncryptType)));
        connect(transport, SIGNAL(bytesWritten(qint64)),
                this, SLOT(sent(qint64)));
        connect(transport, SIGNAL(updateStatus(QString)),
                this, SIGNAL(updateStatus(QString)));
        connect(transport, SIGNAL(errorOccurred(int,QString)),
                this, SLOT(transportError(int,QString)));
#ifndef QT_NO_OPENSSL
        connect(transport, SIGNAL(sslErrorOccured(QMailServiceAction::Status::ErrorCode,QString)),
                this, SIGNAL(connectionError(QMailServiceAction::Status::ErrorCode,QString)));
#endif
    }