27#include "popaccount.h"
29#include "broadcaststatus.h"
30using KPIM::BroadcastStatus;
31#include "progressmanager.h"
32#include "kmfoldermgr.h"
33#include "kmfiltermgr.h"
34#include "kmpopfiltercnfrmdlg.h"
38#include "accountmanager.h"
41#include <tdestandarddirs.h>
43#include <tdemessagebox.h>
44#include <tdemainwindow.h>
45#include <tdeio/scheduler.h>
46#include <tdeio/passdlg.h>
50#include <tqstylesheet.h>
52static const unsigned short int pop3DefaultPort = 110;
56PopAccount::PopAccount(
AccountManager* aOwner,
const TQString& aAccountName, uint
id)
57 : NetworkAccount(aOwner, aAccountName, id),
58 headerIt(headersOnServer),
59 processMsgsTimer( 0,
"processMsgsTimer" )
64 mPort = defaultPort();
66 indexOfCurrentMsg = -1;
68 processingDelay = 2*100;
71 mUidsOfSeenMsgsDict.setAutoDelete(
false );
72 mUidsOfNextSeenMsgsDict.setAutoDelete(
false );
74 headersOnServer.setAutoDelete(
true);
75 connect(&processMsgsTimer,TQ_SIGNAL(timeout()),TQ_SLOT(slotProcessPendingMsgs()));
76 TDEIO::Scheduler::connect(
77 TQ_SIGNAL(slaveError(TDEIO::Slave *,
int,
const TQString &)),
78 this, TQ_SLOT(slotSlaveError(TDEIO::Slave *,
int,
const TQString &)));
80 mHeaderDeleteUids.clear();
81 mHeaderDownUids.clear();
82 mHeaderLaterUids.clear();
87PopAccount::~PopAccount()
91 mMsgsPendingDownload.clear();
92 processRemainingQueuedMessages();
95 if ( mMailCheckProgressItem ) {
98 ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
99 mMailCheckProgressItem = 0;
100 savedMailCheckProgressItem->setComplete();
106TQString PopAccount::type(
void)
const
111TQString PopAccount::protocol()
const {
112 return useSSL() ? POP_SSL_PROTOCOL : POP_PROTOCOL;
115unsigned short int PopAccount::defaultPort()
const {
116 return pop3DefaultPort;
120void PopAccount::init(
void)
122 NetworkAccount::init();
124 mUsePipelining =
false;
125 mLeaveOnServer =
false;
126 mLeaveOnServerDays = -1;
127 mLeaveOnServerCount = -1;
128 mLeaveOnServerSize = -1;
129 mFilterOnServer =
false;
131 mFilterOnServerCheckSize = 50000;
135void PopAccount::pseudoAssign(
const KMAccount * a ) {
136 slotAbortRequested();
137 NetworkAccount::pseudoAssign( a );
152void PopAccount::processNewMail(
bool _interactive)
156 if ( (mAskAgain || passwd().isEmpty() || mLogin.isEmpty()) &&
157 mAuth !=
"GSSAPI" ) {
158 TQString passwd = NetworkAccount::passwd();
159 bool b = storePasswd();
160 if (TDEIO::PasswordDialog::getNameAndPassword(mLogin, passwd, &b,
161 i18n(
"You need to supply a username and a password to access this "
162 "mailbox."),
false, TQString(), mName, i18n(
"Account:"))
163 != TQDialog::Accepted)
165 checkDone(
false, CheckAborted );
168 setPasswd( passwd, b );
170 kmkernel->acctMgr()->writeConfig(
true );
176 TQString seenUidList = locateLocal(
"data",
"kmail/" + mLogin +
":" +
"@" +
177 mHost +
":" + TQString(
"%1").arg(mPort) );
178 TDEConfig config( seenUidList );
179 TQStringList uidsOfSeenMsgs = config.readListEntry(
"seenUidList" );
180 TQValueList<int> timeOfSeenMsgs = config.readIntListEntry(
"seenUidTimeList" );
181 mUidsOfSeenMsgsDict.clear();
182 mUidsOfSeenMsgsDict.resize( KMail::nextPrime( ( uidsOfSeenMsgs.count() * 11 ) / 10 ) );
184 for ( TQStringList::ConstIterator it = uidsOfSeenMsgs.begin();
185 it != uidsOfSeenMsgs.end(); ++it, idx++ ) {
189 mUidsOfSeenMsgsDict.insert( *it, (
const int *)idx );
191 mTimeOfSeenMsgsVector.clear();
192 mTimeOfSeenMsgsVector.reserve( timeOfSeenMsgs.size() );
193 for ( TQValueList<int>::ConstIterator it = timeOfSeenMsgs.begin();
194 it != timeOfSeenMsgs.end(); ++it) {
195 mTimeOfSeenMsgsVector.append( *it );
200 if ( mTimeOfSeenMsgsVector.count() != mUidsOfSeenMsgsDict.count() )
201 mTimeOfSeenMsgsVector.clear();
202 TQStringList downloadLater = config.readListEntry(
"downloadLater" );
203 for ( TQStringList::Iterator it = downloadLater.begin(); it != downloadLater.end(); ++it ) {
204 mHeaderLaterUids.insert( *it,
true );
206 mUidsOfNextSeenMsgsDict.clear();
207 mTimeOfNextSeenMsgsMap.clear();
208 mSizeOfNextSeenMsgsDict.clear();
210 interactive = _interactive;
211 mUidlFinished =
false;
215 checkDone(
false, CheckIgnored );
222void PopAccount::readConfig(TDEConfig& config)
224 NetworkAccount::readConfig(config);
226 mUsePipelining = config.readNumEntry(
"pipelining",
false);
227 mLeaveOnServer = config.readNumEntry(
"leave-on-server",
false);
228 mLeaveOnServerDays = config.readNumEntry(
"leave-on-server-days", -1);
229 mLeaveOnServerCount = config.readNumEntry(
"leave-on-server-count", -1);
230 mLeaveOnServerSize = config.readNumEntry(
"leave-on-server-size", -1);
231 mFilterOnServer = config.readNumEntry(
"filter-on-server",
false);
232 mFilterOnServerCheckSize = config.readUnsignedNumEntry(
"filter-os-check-size", 50000);
237void PopAccount::writeConfig(TDEConfig& config)
239 NetworkAccount::writeConfig(config);
241 config.writeEntry(
"pipelining", mUsePipelining);
242 config.writeEntry(
"leave-on-server", mLeaveOnServer);
243 config.writeEntry(
"leave-on-server-days", mLeaveOnServerDays);
244 config.writeEntry(
"leave-on-server-count", mLeaveOnServerCount);
245 config.writeEntry(
"leave-on-server-size", mLeaveOnServerSize);
246 config.writeEntry(
"filter-on-server", mFilterOnServer);
247 config.writeEntry(
"filter-os-check-size", mFilterOnServerCheckSize);
252void PopAccount::setUsePipelining(
bool b)
258void PopAccount::setLeaveOnServer(
bool b)
264void PopAccount::setLeaveOnServerDays(
int days)
266 mLeaveOnServerDays = days;
270void PopAccount::setLeaveOnServerCount(
int count)
272 mLeaveOnServerCount = count;
276void PopAccount::setLeaveOnServerSize(
int size)
278 mLeaveOnServerSize = size;
282void PopAccount::setFilterOnServer(
bool b)
288void PopAccount::setFilterOnServerCheckSize(
unsigned int aSize)
290 mFilterOnServerCheckSize = aSize;
294void PopAccount::connectJob() {
295 TDEIO::Scheduler::assignJobToSlave(mSlave, job);
296 connect(job, TQ_SIGNAL( data( TDEIO::Job*,
const TQByteArray &)),
297 TQ_SLOT( slotData( TDEIO::Job*,
const TQByteArray &)));
298 connect(job, TQ_SIGNAL( result( TDEIO::Job * ) ),
299 TQ_SLOT( slotResult( TDEIO::Job * ) ) );
300 connect(job, TQ_SIGNAL(infoMessage( TDEIO::Job*,
const TQString & )),
301 TQ_SLOT( slotMsgRetrieved(TDEIO::Job*,
const TQString &)));
306void PopAccount::slotCancel()
308 mMsgsPendingDownload.clear();
309 processRemainingQueuedMessages();
316void PopAccount::slotProcessPendingMsgs()
323 TQValueList<KMMessage*>::Iterator cur = msgsAwaitingProcessing.begin();
324 TQStringList::Iterator curId = msgIdsAwaitingProcessing.begin();
325 TQStringList::Iterator curUid = msgUidsAwaitingProcessing.begin();
327 while (cur != msgsAwaitingProcessing.end()) {
333 addedOk = processNewMsg(*cur);
336 mMsgsPendingDownload.clear();
337 msgIdsAwaitingProcessing.clear();
338 msgUidsAwaitingProcessing.clear();
342 idsOfMsgsToDelete.append( *curId );
343 mUidsOfNextSeenMsgsDict.insert( *curUid, (
const int *)1 );
344 mTimeOfNextSeenMsgsMap.insert( *curUid, time(0) );
351 msgsAwaitingProcessing.clear();
352 msgIdsAwaitingProcessing.clear();
353 msgUidsAwaitingProcessing.clear();
359void PopAccount::slotAbortRequested()
361 if (stage == Idle)
return;
362 if ( mMailCheckProgressItem )
363 disconnect( mMailCheckProgressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
364 this, TQ_SLOT( slotAbortRequested() ) );
366 if (job) job->kill();
374void PopAccount::startJob()
377 if (!runPrecommand(precommand()))
379 KMessageBox::sorry(0,
380 i18n(
"Could not execute precommand: %1").arg(precommand()),
381 i18n(
"KMail Error Message"));
382 checkDone(
false, CheckError );
389 if ( !url.isValid() ) {
390 KMessageBox::error(0, i18n(
"Source URL is malformed"),
391 i18n(
"Kioslave Error Message") );
395 mMsgsPendingDownload.clear();
397 mUidForIdMap.clear();
398 idsOfMsgsToDelete.clear();
399 idsOfForcedDeletes.clear();
402 headersOnServer.clear();
404 indexOfCurrentMsg = -1;
406 Q_ASSERT( !mMailCheckProgressItem );
407 TQString escapedName = TQStyleSheet::escape( mName );
408 mMailCheckProgressItem = KPIM::ProgressManager::createProgressItem(
411 i18n(
"Preparing transmission from \"%1\"...").arg( escapedName ),
413 useSSL() || useTLS() );
414 connect( mMailCheckProgressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
415 this, TQ_SLOT( slotAbortRequested() ) );
420 mSlave = TDEIO::Scheduler::getConnectedSlave( url, slaveConfig() );
423 slotSlaveError(0, TDEIO::ERR_CANNOT_LAUNCH_PROCESS, url.protocol());
426 url.setPath(TQString(
"/index"));
427 job = TDEIO::get( url,
false,
false );
431MetaData PopAccount::slaveConfig()
const {
432 MetaData m = NetworkAccount::slaveConfig();
434 m.insert(
"progress",
"off");
435 m.insert(
"pipelining", (mUsePipelining) ?
"on" :
"off");
436 if (mAuth ==
"PLAIN" || mAuth ==
"LOGIN" || mAuth ==
"CRAM-MD5" ||
437 mAuth ==
"DIGEST-MD5" || mAuth ==
"NTLM" || mAuth ==
"GSSAPI") {
438 m.insert(
"auth",
"SASL");
439 m.insert(
"sasl", mAuth);
440 }
else if ( mAuth ==
"*" )
441 m.insert(
"auth",
"USER");
443 m.insert(
"auth", mAuth);
451void PopAccount::slotMsgRetrieved(TDEIO::Job*,
const TQString & infoMsg)
453 if (infoMsg !=
"message complete")
return;
458 uint newSize = Util::crlf2lf( curMsgData.data(), curMsgData.size() );
459 curMsgData.resize( newSize );
460 msg->fromByteArray( curMsgData ,
true );
463 int size = mMsgsPendingDownload[ headerIt.current()->id() ];
464 kdDebug(5006) <<
"Size of Message: " << size << endl;
465 msg->setMsgLength( size );
466 headerIt.current()->setHeader(msg);
472 msg->setMsgLength( curMsgData.size() );
473 msgsAwaitingProcessing.append(msg);
474 msgIdsAwaitingProcessing.append(idsOfMsgs[indexOfCurrentMsg]);
475 msgUidsAwaitingProcessing.append( mUidForIdMap[idsOfMsgs[indexOfCurrentMsg]] );
483void PopAccount::slotJobFinished() {
484 TQStringList emptyList;
486 kdDebug(5006) << k_funcinfo <<
"stage == List" << endl;
489 mUidsOfNextSeenMsgsDict.resize( KMail::nextPrime( ( idsOfMsgs.count() * 11 ) / 10 ) );
491 url.setPath(TQString(
"/uidl"));
492 job = TDEIO::get( url,
false,
false );
496 else if (stage == Uidl) {
497 kdDebug(5006) << k_funcinfo <<
"stage == Uidl" << endl;
498 mUidlFinished =
true;
500 if ( mLeaveOnServer && mUidForIdMap.isEmpty() &&
501 mUidsOfNextSeenMsgsDict.isEmpty() && !idsOfMsgs.isEmpty() ) {
502 KMessageBox::sorry(0, i18n(
"Your POP3 server (Account: %1) does not support "
503 "the UIDL command: this command is required to determine, in a reliable way, "
504 "which of the mails on the server KMail has already seen before;\n"
505 "the feature to leave the mails on the server will therefore not "
506 "work properly.").arg(NetworkAccount::name()) );
508 mUidsOfNextSeenMsgsDict = mUidsOfSeenMsgsDict;
512 if (mFilterOnServer ==
true) {
513 TQMap<TQString, int>::Iterator hids;
514 for ( hids = mMsgsPendingDownload.begin();
515 hids != mMsgsPendingDownload.end(); hids++ ) {
516 kdDebug(5006) <<
"Length: " << hids.data() << endl;
518 if ( (
unsigned int)hids.data() >= mFilterOnServerCheckSize ) {
519 kdDebug(5006) <<
"bigger than " << mFilterOnServerCheckSize << endl;
520 headersOnServer.append(
new KMPopHeaders( hids.key(),
521 mUidForIdMap[hids.key()],
524 if( mHeaderDeleteUids.contains( headersOnServer.current()->uid() ) ) {
525 headersOnServer.current()->setAction(Delete);
527 else if( mHeaderDownUids.contains( headersOnServer.current()->uid() ) ) {
528 headersOnServer.current()->setAction(Down);
530 else if( mHeaderLaterUids.contains( headersOnServer.current()->uid() ) ) {
531 headersOnServer.current()->setAction(Later);
536 mHeaderDeleteUids.clear();
537 mHeaderDownUids.clear();
538 mHeaderLaterUids.clear();
542 if ((headersOnServer.count() > 0) && (mFilterOnServer ==
true)) {
546 while (headerIt.current())
548 headerIds += headerIt.current()->id();
549 if (!headerIt.atLast()) headerIds +=
",";
553 url.setPath(TQString(
"/headers/") + headerIds);
554 job = TDEIO::get( url,
false,
false );
561 numMsgs = mMsgsPendingDownload.count();
563 TQMap<TQString, int>::Iterator len;
564 for ( len = mMsgsPendingDownload.begin();
565 len != mMsgsPendingDownload.end(); len++ )
566 numBytesToRead += len.data();
567 idsOfMsgs = TQStringList( mMsgsPendingDownload.keys() );
569 url.setPath(
"/download/" + idsOfMsgs.join(
",") );
570 job = TDEIO::get( url,
false,
false );
573 processMsgsTimer.start(processingDelay);
576 else if (stage == Head) {
577 kdDebug(5006) << k_funcinfo <<
"stage == Head" << endl;
584 KMPopFilterAction action;
585 bool dlgPopup =
false;
586 for (headersOnServer.first(); headersOnServer.current(); headersOnServer.next()) {
587 action = (KMPopFilterAction)kmkernel->popFilterMgr()->process(headersOnServer.current()->header());
591 kdDebug(5006) <<
"PopFilterAction = NoAction" << endl;
594 kdDebug(5006) <<
"PopFilterAction = Later" << endl;
597 kdDebug(5006) <<
"PopFilterAction = Delete" << endl;
600 kdDebug(5006) <<
"PopFilterAction = Down" << endl;
603 kdDebug(5006) <<
"PopFilterAction = default oops!" << endl;
612 if (kmkernel->popFilterMgr()->showLaterMsgs())
616 headersOnServer.current()->setAction(action);
617 headersOnServer.current()->setRuleMatched(
true);
626 KMPopFilterCnfrmDlg dlg(&headersOnServer, this->name(), kmkernel->popFilterMgr()->showLaterMsgs());
630 for (headersOnServer.first(); headersOnServer.current(); headersOnServer.next()) {
631 if (headersOnServer.current()->action() == Delete ||
632 headersOnServer.current()->action() == Later) {
635 if ( mMsgsPendingDownload.contains( headersOnServer.current()->id() ) ) {
636 mMsgsPendingDownload.remove( headersOnServer.current()->id() );
638 if (headersOnServer.current()->action() == Delete) {
639 mHeaderDeleteUids.insert(headersOnServer.current()->uid(),
true);
640 mUidsOfNextSeenMsgsDict.insert( headersOnServer.current()->uid(),
642 idsOfMsgsToDelete.append(headersOnServer.current()->id());
643 mTimeOfNextSeenMsgsMap.insert( headersOnServer.current()->uid(),
647 mHeaderLaterUids.insert(headersOnServer.current()->uid(),
true);
650 else if (headersOnServer.current()->action() == Down) {
651 mHeaderDownUids.insert(headersOnServer.current()->uid(),
true);
655 headersOnServer.clear();
657 numMsgs = mMsgsPendingDownload.count();
659 TQMap<TQString, int>::Iterator len;
660 for (len = mMsgsPendingDownload.begin();
661 len != mMsgsPendingDownload.end(); len++)
662 numBytesToRead += len.data();
663 idsOfMsgs = TQStringList( mMsgsPendingDownload.keys() );
665 url.setPath(
"/download/" + idsOfMsgs.join(
",") );
666 job = TDEIO::get( url,
false,
false );
669 processMsgsTimer.start(processingDelay);
671 else if (stage == Retr) {
672 if ( mMailCheckProgressItem )
673 mMailCheckProgressItem->setProgress( 100 );
674 processRemainingQueuedMessages();
676 mHeaderDeleteUids.clear();
677 mHeaderDownUids.clear();
678 mHeaderLaterUids.clear();
680 kmkernel->folderMgr()->syncAllFolders();
683 TQMap< TQPair<time_t, TQString>,
int > idsToSave;
686 if ( mLeaveOnServer && !idsOfMsgsToDelete.isEmpty() ) {
688 if ( mLeaveOnServerDays == -1 && mLeaveOnServerCount <= 0 &&
689 mLeaveOnServerSize <= 0)
690 idsOfMsgsToDelete.clear();
692 else if ( mLeaveOnServerDays > 0 && !mTimeOfNextSeenMsgsMap.isEmpty() ) {
693 time_t timeLimit = time(0) - (86400 * mLeaveOnServerDays);
694 kdDebug() <<
"timeLimit is " << timeLimit << endl;
695 TQStringList::Iterator cur = idsOfMsgsToDelete.begin();
696 for ( ; cur != idsOfMsgsToDelete.end(); ++cur) {
697 time_t msgTime = mTimeOfNextSeenMsgsMap[mUidForIdMap[*cur]];
698 kdDebug() <<
"id: " << *cur <<
" msgTime: " << msgTime << endl;
699 if (msgTime >= timeLimit ||
700 !mTimeOfNextSeenMsgsMap[mUidForIdMap[*cur]]) {
701 kdDebug() <<
"Saving msg id " << *cur << endl;
702 TQPair<time_t, TQString> msg(msgTime, *cur);
703 idsToSave.insert( msg, 1 );
708 if ( mLeaveOnServerCount > 0 ) {
709 int numToDelete = idsToSave.count() - mLeaveOnServerCount;
710 kdDebug() <<
"numToDelete is " << numToDelete << endl;
711 if ( numToDelete > 0 && (
unsigned)numToDelete < idsToSave.count() ) {
712 TQMap< TQPair<time_t, TQString>,
int >::Iterator cur = idsToSave.begin();
713 for (
int deleted = 0; deleted < numToDelete && cur != idsToSave.end()
714 ; deleted++, cur++ ) {
715 kdDebug() <<
"deleting msg id " << cur.key().second << endl;
716 idsToSave.remove( cur );
719 else if ( numToDelete > 0 && (
unsigned)numToDelete >= idsToSave.count() )
723 if ( mLeaveOnServerSize > 0 ) {
724 double sizeOnServer = 0;
725 TQMap< TQPair<time_t, TQString>,
int >::Iterator cur = idsToSave.begin();
726 for ( ; cur != idsToSave.end(); cur++ ) {
728 *mSizeOfNextSeenMsgsDict[ mUidForIdMap[ cur.key().second ] ];
730 kdDebug() <<
"sizeOnServer is " << sizeOnServer/(1024*1024) <<
"MB" << endl;
731 long limitInBytes = mLeaveOnServerSize * ( 1024 * 1024 );
732 for ( cur = idsToSave.begin(); cur != idsToSave.end()
733 && sizeOnServer > limitInBytes; cur++ ) {
735 *mSizeOfNextSeenMsgsDict[ mUidForIdMap[ cur.key().second ] ];
736 idsToSave.remove( cur );
740 TQMap< TQPair<time_t, TQString>,
int >::Iterator it = idsToSave.begin();
741 kdDebug() <<
"Going to save " << idsToSave.count() << endl;
742 for ( ; it != idsToSave.end(); ++it ) {
743 kdDebug() <<
"saving msg id " << it.key().second << endl;
744 idsOfMsgsToDelete.remove( it.key().second );
748 if ( !idsOfForcedDeletes.isEmpty() ) {
749 idsOfMsgsToDelete += idsOfForcedDeletes;
750 idsOfForcedDeletes.clear();
754 if ( !idsOfMsgsToDelete.isEmpty() ) {
756 if ( mMailCheckProgressItem )
757 mMailCheckProgressItem->setStatus(
758 i18n(
"Fetched 1 message from %1. Deleting messages from server...",
759 "Fetched %n messages from %1. Deleting messages from server...",
762 url.setPath(
"/remove/" + idsOfMsgsToDelete.join(
","));
763 kdDebug(5006) <<
"url: " << url.prettyURL() << endl;
766 if ( mMailCheckProgressItem )
767 mMailCheckProgressItem->setStatus(
768 i18n(
"Fetched 1 message from %1. Terminating transmission...",
769 "Fetched %n messages from %1. Terminating transmission...",
772 url.setPath(TQString(
"/commit"));
773 kdDebug(5006) <<
"url: " << url.prettyURL() << endl;
775 job = TDEIO::get( url,
false,
false );
778 else if (stage == Dele) {
779 kdDebug(5006) << k_funcinfo <<
"stage == Dele" << endl;
781 for ( TQStringList::ConstIterator it = idsOfMsgsToDelete.begin();
782 it != idsOfMsgsToDelete.end(); ++it ) {
783 mUidsOfNextSeenMsgsDict.remove( mUidForIdMap[*it] );
785 idsOfMsgsToDelete.clear();
786 if ( mMailCheckProgressItem )
787 mMailCheckProgressItem->setStatus(
788 i18n(
"Fetched 1 message from %1. Terminating transmission...",
789 "Fetched %n messages from %1. Terminating transmission...",
793 url.setPath(TQString(
"/commit"));
794 job = TDEIO::get( url,
false,
false );
798 else if (stage == Quit) {
799 kdDebug(5006) << k_funcinfo <<
"stage == Quit" << endl;
802 if (mSlave) TDEIO::Scheduler::disconnectSlave(mSlave);
805 if( mMailCheckProgressItem ) {
806 bool canceled = !kmkernel || kmkernel->mailCheckAborted() || mMailCheckProgressItem->canceled();
807 int numMessages = canceled ? indexOfCurrentMsg : idsOfMsgs.count();
808 BroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
809 this->name(), numMessages, numBytes, numBytesRead, numBytesToRead, mLeaveOnServer, mMailCheckProgressItem );
812 ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
813 mMailCheckProgressItem = 0;
814 savedMailCheckProgressItem->setComplete();
815 checkDone( ( numMessages > 0 ), canceled ? CheckAborted : CheckOK );
822void PopAccount::processRemainingQueuedMessages()
824 kdDebug(5006) << k_funcinfo << endl;
825 slotProcessPendingMsgs();
826 processMsgsTimer.stop();
829 if ( kmkernel && kmkernel->folderMgr() ) {
830 kmkernel->folderMgr()->syncAllFolders();
836void PopAccount::saveUidList()
838 kdDebug(5006) << k_funcinfo << endl;
841 if (!mUidlFinished)
return;
843 TQStringList uidsOfNextSeenMsgs;
844 TQValueList<int> seenUidTimeList;
845 TQDictIterator<int> it( mUidsOfNextSeenMsgsDict );
846 for( ; it.current(); ++it ) {
847 uidsOfNextSeenMsgs.append( it.currentKey() );
848 seenUidTimeList.append( mTimeOfNextSeenMsgsMap[it.currentKey()] );
850 TQString seenUidList = locateLocal(
"data",
"kmail/" + mLogin +
":" +
"@" +
851 mHost +
":" + TQString(
"%1").arg(mPort) );
852 TDEConfig config( seenUidList );
853 config.writeEntry(
"seenUidList", uidsOfNextSeenMsgs );
854 config.writeEntry(
"seenUidTimeList", seenUidTimeList );
855 config.writeEntry(
"downloadLater", TQStringList( mHeaderLaterUids.keys() ) );
861void PopAccount::slotGetNextMsg()
863 TQMap<TQString, int>::Iterator next = mMsgsPendingDownload.begin();
865 curMsgData.resize(0);
871 if ( next != mMsgsPendingDownload.end() ) {
873 int nextLen = next.data();
874 curMsgStrm =
new TQDataStream( curMsgData, IO_WriteOnly );
877 kdDebug(5006) << TQString(
"Length of message about to get %1").arg( nextLen ) << endl;
878 mMsgsPendingDownload.remove( next.key() );
884void PopAccount::slotData( TDEIO::Job* job,
const TQByteArray &data)
886 if (data.size() == 0) {
887 kdDebug(5006) <<
"Data: <End>" << endl;
888 if ((stage == Retr) && (numMsgBytesRead < curMsgLen))
889 numBytesRead += curMsgLen - numMsgBytesRead;
890 else if (stage == Head){
891 kdDebug(5006) <<
"Head: <End>" << endl;
896 int oldNumMsgBytesRead = numMsgBytesRead;
899 curMsgStrm->writeRawBytes( data.data(), data.size() );
900 numMsgBytesRead += data.size();
901 if (numMsgBytesRead > curMsgLen)
902 numMsgBytesRead = curMsgLen;
903 numBytesRead += numMsgBytesRead - oldNumMsgBytesRead;
905 if ( mMailCheckProgressItem &&
906 ( dataCounter % 5 == 0 ||
907 ( indexOfCurrentMsg + 1 == numMsgs && numMsgBytesRead == curMsgLen ) ) )
910 if (numBytes != numBytesToRead && mLeaveOnServer)
912 msg = i18n(
"Fetching message %1 of %2 (%3 of %4 KB) for %5@%6 "
913 "(%7 KB remain on the server).")
914 .arg(indexOfCurrentMsg+1).arg(numMsgs).arg(numBytesRead/1024)
915 .arg(numBytesToRead/1024).arg(mLogin).arg(mHost).arg(numBytes/1024);
919 msg = i18n(
"Fetching message %1 of %2 (%3 of %4 KB) for %5@%6.")
920 .arg(indexOfCurrentMsg+1).arg(numMsgs).arg(numBytesRead/1024)
921 .arg(numBytesToRead/1024).arg(mLogin).arg(mHost);
923 mMailCheckProgressItem->setStatus( msg );
924 mMailCheckProgressItem->setProgress(
925 (numBytesToRead <= 100) ? 50
927 : (numBytesRead / (numBytesToRead / 100)) );
933 curMsgStrm->writeRawBytes( data.data(), data.size() );
938 TQString qdata = data;
939 qdata = qdata.simplifyWhiteSpace();
940 int spc = qdata.find(
' ' );
941 if ( stage == List ) {
943 TQString length = qdata.mid(spc+1);
944 if (length.find(
' ') != -1) length.truncate(length.find(
' '));
945 int len = length.toInt();
947 TQString
id = qdata.left(spc);
948 idsOfMsgs.append(
id );
949 mMsgsPendingDownload.insert(
id, len );
953 if ( job ) job->kill();
956 KMessageBox::error( 0, i18n(
"Unable to complete LIST operation." ),
957 i18n(
"Invalid Response From Server") );
962 Q_ASSERT ( stage == Uidl);
973 int testid = atoi ( qdata.ascii() );
976 kdDebug(5006) <<
"PopAccount::slotData skipping UIDL entry due to parse error "
977 << endl << qdata.ascii() << endl;
980 id.setNum (testid, 10);
982 TQString datestring, serialstring;
984 serialstring.setNum ( ++dataCounter, 10 );
985 datestring.setNum ( time(NULL),10 );
986 uid = TQString(
"uidlgen" ) + datestring + TQString(
"." ) + serialstring;
987 kdDebug(5006) <<
"PopAccount::slotData message " <<
id.ascii()
988 <<
"%d has bad UIDL, cannot keep a copy on server" << endl;
989 idsOfForcedDeletes.append(
id );
992 id = qdata.left( spc );
993 uid = qdata.mid( spc + 1 );
997 *size = mMsgsPendingDownload[id];
998 mSizeOfNextSeenMsgsDict.insert( uid, size );
999 if ( mUidsOfSeenMsgsDict.find( uid ) != 0 ) {
1000 if ( mMsgsPendingDownload.contains(
id ) ) {
1001 mMsgsPendingDownload.remove(
id );
1004 kdDebug(5006) <<
"PopAccount::slotData synchronization failure." << endl;
1005 idsOfMsgsToDelete.append(
id );
1006 mUidsOfNextSeenMsgsDict.insert( uid, (
const int *)1 );
1007 if ( mTimeOfSeenMsgsVector.empty() ) {
1008 mTimeOfNextSeenMsgsMap.insert( uid, time(0) );
1013 mTimeOfNextSeenMsgsMap.insert( uid, mTimeOfSeenMsgsVector[(
int)(
long )
1014 mUidsOfSeenMsgsDict[uid] - 1] );
1017 mUidForIdMap.insert(
id, uid );
1022void PopAccount::slotResult( TDEIO::Job* )
1031 if (stage == Head && job->error() == TDEIO::ERR_COULD_NOT_READ)
1033 KMessageBox::error(0, i18n(
"Your server does not support the "
1034 "TOP command. Therefore it is not possible to fetch the headers "
1035 "of large emails first, before downloading them."));
1040 if (!mStorePasswd) mPasswd =
"";
1041 job->showErrorDialog();
1051void PopAccount::slotSlaveError(TDEIO::Slave *aSlave,
int error,
1052 const TQString &errorMsg)
1054 if (aSlave != mSlave)
return;
1055 if (error == TDEIO::ERR_SLAVE_DIED) mSlave = 0;
1058 if ( error == TDEIO::ERR_CONNECTION_BROKEN && mSlave ) {
1059 TDEIO::Scheduler::disconnectSlave( mSlave );
1063 if (interactive && kmkernel) {
1064 KMessageBox::error(kmkernel->mainWin(), TDEIO::buildErrorString(error, errorMsg));
1069 if (error == TDEIO::ERR_COULD_NOT_LOGIN && !mStorePasswd)
1074 TQTimer::singleShot(0,
this, TQ_SLOT(slotCancel()));
1078void PopAccount::slotGetNextHdr(){
1079 kdDebug(5006) <<
"slotGetNextHeader" << endl;
1081 curMsgData.resize(0);
1085 curMsgStrm =
new TQDataStream( curMsgData, IO_WriteOnly );
1088void PopAccount::killAllJobs(
bool ) {
1093#include "popaccount.moc"
void setComplete(bool v)
Set if the message is a complete message.
The account manager is responsible for creating accounts of various types via the factory method crea...
KMail account for pop mail account.
bool filterOnServer(void) const
Shall messages be filter on the server (true) or not (false).
bool usePipelining(void) const
Sending of several commands at once.
int leaveOnServerDays(void) const
If value is positive, leave mail on the server for so many days.
int leaveOnServerSize(void) const
If value is positive, leave so many MBs on the server.
bool leaveOnServer(void) const
Shall messages be left on the server upon retreival (true) or deleted (false).
int leaveOnServerCount(void) const
If value is positive, leave so many messages on the server.
unsigned int filterOnServerCheckSize(void) const
Size of messages which should be check on the pop server before download.