Exemple #1
0
int KMFilterMgr::process(Q_UINT32 serNum, const KMFilter *filter)
{
    bool stopIt = false;
    int result = 1;

    if(!filter)
        return 1;

    if(isMatching(serNum, filter))
    {
        KMFolder *folder = 0;
        int idx = -1;
        // get the message with the serNum
        KMMsgDict::instance()->getLocation(serNum, &folder, &idx);
        if(!folder || (idx == -1) || (idx >= folder->count()))
        {
            return 1;
        }
        KMFolderOpener openFolder(folder, "filtermgr");
        KMMsgBase *msgBase = folder->getMsgBase(idx);
        bool unGet = !msgBase->isMessage();
        KMMessage *msg = folder->getMsg(idx);
        // do the actual filtering stuff
        if(!msg || !beginFiltering(msg))
        {
            if(unGet)
                folder->unGetMsg(idx);
            return 1;
        }
        if(filter->execActions(msg, stopIt) == KMFilter::CriticalError)
        {
            if(unGet)
                folder->unGetMsg(idx);
            return 2;
        }

        KMFolder *targetFolder = MessageProperty::filterFolder(msg);

        endFiltering(msg);
        if(targetFolder)
        {
            tempOpenFolder(targetFolder);
            msg->setTransferInProgress(false);
            result = targetFolder->moveMsg(msg);
            msg->setTransferInProgress(true);
        }
        if(unGet)
            folder->unGetMsg(idx);
    }
    else
    {
        result = 1;
    }
    return result;
}
Exemple #2
0
int KMFilterMgr::process(KMMessage *msg, const KMFilter *filter)
{
    if(!msg || !filter || !beginFiltering(msg))
        return 1;
    bool stopIt = false;
    int result = 1;

    if(FilterLog::instance()->isLogging())
    {
        QString logText(i18n("<b>Evaluating filter rules:</b> "));
        logText.append(filter->pattern()->asString());
        FilterLog::instance()->add(logText, FilterLog::patternDesc);
    }

    if(filter->pattern()->matches(msg))
    {
        if(FilterLog::instance()->isLogging())
        {
            FilterLog::instance()->add(i18n("<b>Filter rules have matched.</b>"),
                                       FilterLog::patternResult);
        }
        if(filter->execActions(msg, stopIt) == KMFilter::CriticalError)
            return 2;

        KMFolder *folder = MessageProperty::filterFolder(msg);

        endFiltering(msg);
        if(folder)
        {
            tempOpenFolder(folder);
            result = folder->moveMsg(msg);
        }
    }
    else
    {
        endFiltering(msg);
        result = 1;
    }
    return result;
}
Exemple #3
0
//-----------------------------------------------------------------------------
int KMFolder::compact(void)
{
  KMFolder* tempFolder;
  KMMessage* msg;
  QString tempName, msgStr;
  int openCount = mOpenCount;
  int num, numStatus;


  if (!needsCompact)
  {
    //debug ("Not compacting %s; it's clean", name().data());
    return 0;
  }
  
  debug ("Compacting %s ", name().data());
  
  tempName = "." + name();
  tempName.detach();
  tempName += ".compacted";
  unlink(tempName);
  //tempFolder = parent()->createFolder(tempName); //sven: shouldn't be in list
  tempFolder = new KMFolder(parent(), tempName);   //sven: we create it
  if(tempFolder->create()) {
    debug("KMFolder::compact() Creating tempFolder failed!\n");
    delete tempFolder;                             //sven: and we delete it
    return 0;
  }

  quiet(TRUE);
  tempFolder->open();
  open();

  for(num=1,numStatus=9; count() > 0; num++, numStatus--)
  {
    if (numStatus <= 0)
    {
      msgStr.sprintf(i18n("Compacting folder: %d messages done"), num);
      emit statusMsg(msgStr);
      numStatus = 10;
    }

    msg = getMsg(0);
    if(msg)
      tempFolder->moveMsg(msg);
  }
  tempName = tempFolder->location();
  tempFolder->close(TRUE);
  close(TRUE);
  mMsgList.clear(TRUE);

  _rename(tempName, location());
  _rename(tempFolder->indexLocation(), indexLocation());

  // Now really free all memory
  delete tempFolder;                //sven: we delete it, not the manager

  if (openCount > 0)
  {
    open();
    mOpenCount = openCount;
  }
  quiet(FALSE);

  if (!mQuiet) emit changed();
  needsCompact = false;             // We are clean now
  return 0;
}
Exemple #4
0
int KMFilterMgr::process(KMMessage *msg, FilterSet set,
                         bool account, uint accountId)
{
    if(bPopFilter)
        return processPop(msg);

    if(set == NoSet)
    {
        kdDebug(5006) << "KMFilterMgr: process() called with not filter set selected"
                      << endl;
        return 1;
    }

    bool stopIt = false;
    bool atLeastOneRuleMatched = false;

    if(!beginFiltering(msg))
        return 1;
    for(QValueListConstIterator<KMFilter *> it = mFilters.constBegin();
            !stopIt && it != mFilters.constEnd() ; ++it)
    {

        if((((set & Inbound) && (*it)->applyOnInbound()) &&
                (!account ||
                 (account && (*it)->applyOnAccount(accountId)))) ||
                ((set & Outbound)  && (*it)->applyOnOutbound()) ||
                ((set & Explicit) && (*it)->applyOnExplicit()))
        {
            // filter is applicable

            if(FilterLog::instance()->isLogging())
            {
                QString logText(i18n("<b>Evaluating filter rules:</b> "));
                logText.append((*it)->pattern()->asString());
                FilterLog::instance()->add(logText, FilterLog::patternDesc);
            }
            if((*it)->pattern()->matches(msg))
            {
                // filter matches
                if(FilterLog::instance()->isLogging())
                {
                    FilterLog::instance()->add(i18n("<b>Filter rules have matched.</b>"),
                                               FilterLog::patternResult);
                }
                atLeastOneRuleMatched = true;
                // execute actions:
                if((*it)->execActions(msg, stopIt) == KMFilter::CriticalError)
                    return 2;
            }
        }
    }

    KMFolder *folder = MessageProperty::filterFolder(msg);
    /* endFilter does a take() and addButKeepUID() to ensure the changed
     * message is on disk. This is unnessecary if nothing matched, so just
     * reset state and don't update the listview at all. */
    if(atLeastOneRuleMatched)
        endFiltering(msg);
    else
        MessageProperty::setFiltering(msg, false);
    if(folder)
    {
        tempOpenFolder(folder);
        folder->moveMsg(msg);
        return 0;
    }
    return 1;
}
Exemple #5
0
//-----------------------------------------------------------------------------
void KMSender::doSendMsg()
{
    if(!kmkernel)   //To handle message sending in progress when kaplan is exited
        return;	//TODO: handle this case better

    const bool someSent = mCurrentMsg;
    if(someSent)
    {
        mSentMessages++;
        mSentBytes += mCurrentMsg->msgSize();
    }

    // Post-process sent message (filtering)
    KMFolder *sentFolder = 0, *imapSentFolder = 0;
    if(mCurrentMsg  && kmkernel->filterMgr())
    {
        mCurrentMsg->setTransferInProgress(false);
        if(mCurrentMsg->hasUnencryptedMsg())
        {
            kdDebug(5006) << "KMSender::doSendMsg() post-processing: replace mCurrentMsg body by unencryptedMsg data" << endl;
            // delete all current body parts
            mCurrentMsg->deleteBodyParts();
            // copy Content-[..] headers from unencrypted message to current one
            KMMessage &newMsg(*mCurrentMsg->unencryptedMsg());
            mCurrentMsg->dwContentType() = newMsg.dwContentType();
            mCurrentMsg->setContentTransferEncodingStr(newMsg.contentTransferEncodingStr());
            QCString newDispo = newMsg.headerField("Content-Disposition").latin1();
            if(newDispo.isEmpty())
                mCurrentMsg->removeHeaderField("Content-Disposition");
            else
                mCurrentMsg->setHeaderField("Content-Disposition", newDispo);
            // copy the body
            mCurrentMsg->setBody(newMsg.body());
            // copy all the body parts
            KMMessagePart msgPart;
            for(int i = 0; i < newMsg.numBodyParts(); ++i)
            {
                newMsg.bodyPart(i, &msgPart);
                mCurrentMsg->addBodyPart(&msgPart);
            }
        }
        mCurrentMsg->setStatus(KMMsgStatusSent);
        mCurrentMsg->setStatus(KMMsgStatusRead); // otherwise it defaults to new on imap
        mCurrentMsg->updateAttachmentState();

        const KPIM::Identity &id = kmkernel->identityManager()
                                   ->identityForUoidOrDefault(mCurrentMsg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt());
        if(!mCurrentMsg->fcc().isEmpty())
        {
            sentFolder = kmkernel->folderMgr()->findIdString(mCurrentMsg->fcc());
            if(sentFolder == 0)
                // This is *NOT* supposed to be imapSentFolder!
                sentFolder =
                    kmkernel->dimapFolderMgr()->findIdString(mCurrentMsg->fcc());
            if(sentFolder == 0)
                imapSentFolder =
                    kmkernel->imapFolderMgr()->findIdString(mCurrentMsg->fcc());
        }
        // No, or no usable sentFolder, and no, or no usable imapSentFolder,
        // let's try the on in the identity
        if((sentFolder == 0 || sentFolder->isReadOnly())
                && (imapSentFolder == 0 || imapSentFolder->isReadOnly())
                && !id.fcc().isEmpty())
        {
            sentFolder = kmkernel->folderMgr()->findIdString(id.fcc());
            if(sentFolder == 0)
                // This is *NOT* supposed to be imapSentFolder!
                sentFolder = kmkernel->dimapFolderMgr()->findIdString(id.fcc());
            if(sentFolder == 0)
                imapSentFolder = kmkernel->imapFolderMgr()->findIdString(id.fcc());
        }
        if(imapSentFolder
                && (imapSentFolder->noContent() || imapSentFolder->isReadOnly()))
            imapSentFolder = 0;

        if(sentFolder == 0 || sentFolder->isReadOnly())
            sentFolder = kmkernel->sentFolder();

        if(sentFolder)
        {
            if(const int err = sentFolder->open("sentFolder"))
            {
                Q_UNUSED(err);
                cleanup();
                return;
            }
        }

        // Disable the emitting of msgAdded signal, because the message is taken out of the
        // current folder (outbox) and re-added, to make filter actions changing the message
        // work. We don't want that to screw up message counts.
        if(mCurrentMsg->parent()) mCurrentMsg->parent()->quiet(true);
        const int processResult = kmkernel->filterMgr()->process(mCurrentMsg, KMFilterMgr::Outbound);
        if(mCurrentMsg->parent()) mCurrentMsg->parent()->quiet(false);

        // 0==processed ok, 1==no filter matched, 2==critical error, abort!
        switch(processResult)
        {
            case 2:
                perror("Critical error: Unable to process sent mail (out of space?)");
                KMessageBox::information(0, i18n("Critical error: "
                                                 "Unable to process sent mail (out of space?)"
                                                 "Moving failing message to \"sent-mail\" folder."));
                if(sentFolder)
                {
                    sentFolder->moveMsg(mCurrentMsg);
                    sentFolder->close("sentFolder");
                }
                cleanup();
                return;
            case 1:
                if(sentFolder && sentFolder->moveMsg(mCurrentMsg) != 0)
                {
                    KMessageBox::error(0, i18n("Moving the sent message \"%1\" from the "
                                               "\"outbox\" to the \"sent-mail\" folder failed.\n"
                                               "Possible reasons are lack of disk space or write permission. "
                                               "Please try to fix the problem and move the message manually.")
                                       .arg(mCurrentMsg->subject()));
                    cleanup();
                    return;
                }
                if(imapSentFolder)
                {
                    // Does proper folder refcounting and message locking
                    KMCommand *command = new KMMoveCommand(imapSentFolder, mCurrentMsg);
                    command->keepFolderOpen(sentFolder);   // will open it, and close it once done
                    command->start();
                }
            default:
                break;
        }
        setStatusByLink(mCurrentMsg);
        if(mCurrentMsg->parent() && !imapSentFolder)
        {
            // for speed optimization, this code assumes that mCurrentMsg is the
            // last one in it's parent folder; make sure that's really the case:
            assert(mCurrentMsg->parent()->find(mCurrentMsg)
                   == mCurrentMsg->parent()->count() - 1);
            // unGet this message:
            mCurrentMsg->parent()->unGetMsg(mCurrentMsg->parent()->count() - 1);
        }

        mCurrentMsg = 0;
    }

    // See if there is another queued message
    mCurrentMsg = mOutboxFolder->getMsg(mFailedMessages);
    if(mCurrentMsg && !mCurrentMsg->transferInProgress() &&
            mCurrentMsg->sender().isEmpty())
    {
        // if we do not have a sender address then use the email address of the
        // message's identity or of the default identity unless those two are also
        // empty
        const KPIM::Identity &id = kmkernel->identityManager()
                                   ->identityForUoidOrDefault(mCurrentMsg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt());
        if(!id.emailAddr().isEmpty())
        {
            mCurrentMsg->setFrom(id.fullEmailAddr());
        }
        else if(!kmkernel->identityManager()->defaultIdentity().emailAddr().isEmpty())
        {
            mCurrentMsg->setFrom(kmkernel->identityManager()->defaultIdentity().fullEmailAddr());
        }
        else
        {
            KMessageBox::sorry(0, i18n("It's not possible to send messages "
                                       "without specifying a sender address.\n"
                                       "Please set the email address of "
                                       "identity '%1' in the Identities "
                                       "section of the configuration dialog "
                                       "and then try again.")
                               .arg(id.identityName()));
            mOutboxFolder->unGetMsg(mFailedMessages);
            mCurrentMsg = 0;
        }
    }
    if(!mCurrentMsg || mCurrentMsg->transferInProgress())
    {
        // a message is locked finish the send
        if(mCurrentMsg && mCurrentMsg->transferInProgress())
            mCurrentMsg = 0;
        // no more message: cleanup and done
        if(sentFolder != 0)
            sentFolder->close("sentFolder");
        if(someSent)
        {
            if(mSentMessages == mTotalMessages)
            {
                setStatusMsg(i18n("%n queued message successfully sent.",
                                  "%n queued messages successfully sent.",
                                  mSentMessages));
            }
            else
            {
                setStatusMsg(i18n("%1 of %2 queued messages successfully sent.")
                             .arg(mSentMessages).arg(mTotalMessages));
            }
        }
        cleanup();
        return;
    }
    mCurrentMsg->setTransferInProgress(true);

    // start the sender process or initialize communication
    if(!mSendInProgress)
    {
        Q_ASSERT(!mProgressItem);
        mProgressItem = KPIM::ProgressManager::createProgressItem(
                            "Sender",
                            i18n("Sending messages"),
                            i18n("Initiating sender process..."),
                            true);
        connect(mProgressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem *)),
                this, SLOT(slotAbortSend()));
        kapp->ref();
        mSendInProgress = true;
    }