27 #include "popaccount.h"
29 #include "broadcaststatus.h"
30 using KPIM::BroadcastStatus;
31 #include "progressmanager.h"
32 #include "kmfoldermgr.h"
33 #include "kmfiltermgr.h"
34 #include "kmpopfiltercnfrmdlg.h"
35 #include "protocols.h"
38 #include "accountmanager.h"
41 #include <kstandarddirs.h>
42 #include <tdelocale.h>
43 #include <tdemessagebox.h>
44 #include <tdemainwindow.h>
45 #include <tdeio/scheduler.h>
46 #include <tdeio/passdlg.h>
47 #include <tdeconfig.h>
48 using TDEIO::MetaData;
50 #include <tqstylesheet.h>
52 static const unsigned short int pop3DefaultPort = 110;
56 PopAccount::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();
87 PopAccount::~PopAccount()
91 mMsgsPendingDownload.clear();
95 if ( mMailCheckProgressItem ) {
98 ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
99 mMailCheckProgressItem = 0;
100 savedMailCheckProgressItem->setComplete();
111 TQString PopAccount::protocol()
const {
112 return useSSL() ? POP_SSL_PROTOCOL : POP_PROTOCOL;
115 unsigned short int PopAccount::defaultPort()
const {
116 return pop3DefaultPort;
120 void 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;
137 NetworkAccount::pseudoAssign( a );
152 void 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 );
222 void 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);
237 void 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);
252 void PopAccount::setUsePipelining(
bool b)
258 void PopAccount::setLeaveOnServer(
bool b)
264 void PopAccount::setLeaveOnServerDays(
int days)
266 mLeaveOnServerDays = days;
270 void PopAccount::setLeaveOnServerCount(
int count)
272 mLeaveOnServerCount = count;
276 void PopAccount::setLeaveOnServerSize(
int size)
278 mLeaveOnServerSize = size;
282 void PopAccount::setFilterOnServer(
bool b)
288 void PopAccount::setFilterOnServerCheckSize(
unsigned int aSize)
290 mFilterOnServerCheckSize = aSize;
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 * ) ),
300 connect(job, TQ_SIGNAL(infoMessage( TDEIO::Job*,
const TQString & )),
308 mMsgsPendingDownload.clear();
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();
361 if (stage == Idle)
return;
362 if ( mMailCheckProgressItem )
363 disconnect( mMailCheckProgressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
366 if (job) job->kill();
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* ) ),
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 );
431 MetaData 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);
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]] );
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 );
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 );
824 kdDebug(5006) << k_funcinfo << endl;
826 processMsgsTimer.stop();
829 if ( kmkernel && kmkernel->folderMgr() ) {
830 kmkernel->folderMgr()->syncAllFolders();
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() ) );
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() );
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 );
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();
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()));
1079 kdDebug(5006) <<
"slotGetNextHeader" << endl;
1081 curMsgData.resize(0);
1085 curMsgStrm =
new TQDataStream( curMsgData, IO_WriteOnly );
1088 void PopAccount::killAllJobs(
bool ) {
1093 #include "popaccount.moc"