00001
00002
00003
00004
00005 #ifdef HAVE_CONFIG_H
00006 #include <config.h>
00007 #endif
00008
00009 #include "kmacctexppop.h"
00010
00011 #include "kmbroadcaststatus.h"
00012 #include "kmfoldermgr.h"
00013 #include "kmfiltermgr.h"
00014 #include "kmpopfiltercnfrmdlg.h"
00015 #include "kmkernel.h"
00016
00017 #include <kdebug.h>
00018 #include <kstandarddirs.h>
00019 #include <klocale.h>
00020 #include <kmessagebox.h>
00021 #include <kmainwindow.h>
00022 #include <kio/scheduler.h>
00023 #include <kio/passdlg.h>
00024 #include <kconfig.h>
00025 using KIO::MetaData;
00026
00027 static const unsigned short int pop3DefaultPort = 110;
00028
00029
00030 KMAcctExpPop::KMAcctExpPop(KMAcctMgr* aOwner, const QString& aAccountName)
00031 : NetworkAccount(aOwner, aAccountName),
00032 headerIt(headersOnServer)
00033 {
00034 init();
00035 job = 0;
00036 mSlave = 0;
00037 mPort = defaultPort();
00038 stage = Idle;
00039 indexOfCurrentMsg = -1;
00040 curMsgStrm = 0;
00041 processingDelay = 2*100;
00042 mProcessing = false;
00043 dataCounter = 0;
00044
00045 headersOnServer.setAutoDelete(true);
00046 connect(&processMsgsTimer,SIGNAL(timeout()),SLOT(slotProcessPendingMsgs()));
00047 ss = new QTimer();
00048 connect( ss, SIGNAL( timeout() ), this, SLOT( slotGetNextMsg() ));
00049 KIO::Scheduler::connect(
00050 SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
00051 this, SLOT(slotSlaveError(KIO::Slave *, int, const QString &)));
00052
00053 headerDeleteUids.clear();
00054 headerDownUids.clear();
00055 headerLaterUids.clear();
00056 }
00057
00058
00059
00060 KMAcctExpPop::~KMAcctExpPop()
00061 {
00062 if (job) {
00063 job->kill();
00064 idsOfMsgsPendingDownload.clear();
00065 lensOfMsgsPendingDownload.clear();
00066 processRemainingQueuedMessagesAndSaveUidList();
00067 }
00068 delete ss;
00069 }
00070
00071
00072
00073 QString KMAcctExpPop::type(void) const
00074 {
00075 return "pop";
00076 }
00077
00078 QString KMAcctExpPop::protocol() const {
00079 return useSSL() ? "pop3s" : "pop3";
00080 }
00081
00082 unsigned short int KMAcctExpPop::defaultPort() const {
00083 return pop3DefaultPort;
00084 }
00085
00086
00087 void KMAcctExpPop::init(void)
00088 {
00089 NetworkAccount::init();
00090
00091 mUsePipelining = FALSE;
00092 mLeaveOnServer = FALSE;
00093 mFilterOnServer = FALSE;
00094
00095 mFilterOnServerCheckSize = 50000;
00096 }
00097
00098
00099 void KMAcctExpPop::pseudoAssign( const KMAccount * a ) {
00100 slotAbortRequested();
00101 NetworkAccount::pseudoAssign( a );
00102
00103 const KMAcctExpPop * p = dynamic_cast<const KMAcctExpPop*>( a );
00104 if ( !p ) return;
00105
00106 setUsePipelining( p->usePipelining() );
00107 setLeaveOnServer( p->leaveOnServer() );
00108 setFilterOnServer( p->filterOnServer() );
00109 setFilterOnServerCheckSize( p->filterOnServerCheckSize() );
00110 }
00111
00112
00113 void KMAcctExpPop::processNewMail(bool _interactive)
00114 {
00115 if (stage == Idle) {
00116
00117 if(mAskAgain || mPasswd.isEmpty() || mLogin.isEmpty()) {
00118 QString passwd = decryptStr(mPasswd);
00119 bool b = FALSE;
00120 if (KIO::PasswordDialog::getNameAndPassword(mLogin, passwd, &b,
00121 i18n("You need to supply a username and a password to access this "
00122 "mailbox."), FALSE, QString::null, mName, i18n("Account:"))
00123 != QDialog::Accepted)
00124 {
00125 checkDone(false, 0);
00126 return;
00127 } else {
00128 mPasswd = encryptStr(passwd);
00129 mAskAgain = FALSE;
00130 }
00131 }
00132
00133 QString seenUidList = locateLocal( "data", "kmail/" + mLogin + ":" + "@" +
00134 mHost + ":" + QString("%1").arg(mPort) );
00135 KConfig config( seenUidList );
00136 uidsOfSeenMsgs = config.readListEntry( "seenUidList" );
00137 headerLaterUids = config.readListEntry( "downloadLater" );
00138 uidsOfNextSeenMsgs.clear();
00139
00140 interactive = _interactive;
00141 mUidlFinished = FALSE;
00142 startJob();
00143 }
00144 else {
00145 checkDone(false, -1);
00146 return;
00147 }
00148 }
00149
00150
00151
00152 void KMAcctExpPop::readConfig(KConfig& config)
00153 {
00154 NetworkAccount::readConfig(config);
00155
00156 mUsePipelining = config.readNumEntry("pipelining", FALSE);
00157 mLeaveOnServer = config.readNumEntry("leave-on-server", FALSE);
00158 mFilterOnServer = config.readNumEntry("filter-on-server", FALSE);
00159 mFilterOnServerCheckSize = config.readUnsignedNumEntry("filter-os-check-size", 50000);
00160 }
00161
00162
00163
00164 void KMAcctExpPop::writeConfig(KConfig& config)
00165 {
00166 NetworkAccount::writeConfig(config);
00167
00168 config.writeEntry("pipelining", mUsePipelining);
00169 config.writeEntry("leave-on-server", mLeaveOnServer);
00170 config.writeEntry("filter-on-server", mFilterOnServer);
00171 config.writeEntry("filter-os-check-size", mFilterOnServerCheckSize);
00172 }
00173
00174
00175
00176 void KMAcctExpPop::setUsePipelining(bool b)
00177 {
00178 mUsePipelining = b;
00179 }
00180
00181
00182 void KMAcctExpPop::setLeaveOnServer(bool b)
00183 {
00184 mLeaveOnServer = b;
00185 }
00186
00187
00188
00189 void KMAcctExpPop::setFilterOnServer(bool b)
00190 {
00191 mFilterOnServer = b;
00192 }
00193
00194
00195 void KMAcctExpPop::setFilterOnServerCheckSize(unsigned int aSize)
00196 {
00197 mFilterOnServerCheckSize = aSize;
00198 }
00199
00200
00201 void KMAcctExpPop::connectJob() {
00202 KIO::Scheduler::assignJobToSlave(mSlave, job);
00203 if (stage != Dele)
00204 connect(job, SIGNAL( data( KIO::Job*, const QByteArray &)),
00205 SLOT( slotData( KIO::Job*, const QByteArray &)));
00206 connect(job, SIGNAL( result( KIO::Job * ) ),
00207 SLOT( slotResult( KIO::Job * ) ) );
00208 connect(job, SIGNAL(infoMessage( KIO::Job*, const QString & )),
00209 SLOT( slotMsgRetrieved(KIO::Job*, const QString &)));
00210 }
00211
00212
00213
00214 void KMAcctExpPop::slotCancel()
00215 {
00216 idsOfMsgsPendingDownload.clear();
00217 lensOfMsgsPendingDownload.clear();
00218 processRemainingQueuedMessagesAndSaveUidList();
00219 slotJobFinished();
00220 }
00221
00222
00223
00224 void KMAcctExpPop::slotProcessPendingMsgs()
00225 {
00226 if (mProcessing)
00227 return;
00228 mProcessing = true;
00229
00230 bool addedOk;
00231 QValueList<KMMessage*>::Iterator cur = msgsAwaitingProcessing.begin();
00232 QStringList::Iterator curId = msgIdsAwaitingProcessing.begin();
00233 QStringList::Iterator curUid = msgUidsAwaitingProcessing.begin();
00234
00235 while (cur != msgsAwaitingProcessing.end()) {
00236
00237
00238
00239
00240
00241 addedOk = processNewMsg(*cur);
00242
00243 if (!addedOk) {
00244 idsOfMsgsPendingDownload.clear();
00245 lensOfMsgsPendingDownload.clear();
00246 msgIdsAwaitingProcessing.clear();
00247 msgUidsAwaitingProcessing.clear();
00248 break;
00249 }
00250 else {
00251 idsOfMsgsToDelete.append( *curId );
00252 uidsOfNextSeenMsgs.append( *curUid );
00253 }
00254 ++cur;
00255 ++curId;
00256 ++curUid;
00257 }
00258
00259 msgsAwaitingProcessing.clear();
00260 msgIdsAwaitingProcessing.clear();
00261 msgUidsAwaitingProcessing.clear();
00262 mProcessing = false;
00263 }
00264
00265
00266
00267 void KMAcctExpPop::slotAbortRequested()
00268 {
00269 if (stage == Idle) return;
00270 disconnect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()),
00271 this, SLOT(slotAbortRequested()));
00272 stage = Quit;
00273 if (job) job->kill();
00274 job = 0;
00275 mSlave = 0;
00276 slotCancel();
00277 }
00278
00279
00280
00281 void KMAcctExpPop::startJob() {
00282
00283
00284 if (!runPrecommand(precommand()))
00285 {
00286 KMessageBox::sorry(0,
00287 i18n("Couldn't execute precommand: %1").arg(precommand()),
00288 i18n("KMail Error Message"));
00289 checkDone((idsOfMsgs.count() > 0), -1);
00290 return;
00291 }
00292
00293
00294 KURL url = getUrl();
00295
00296 if ( !url.isValid() ) {
00297 KMessageBox::error(0, i18n("Source URL is malformed"),
00298 i18n("Kioslave Error Message") );
00299 return;
00300 }
00301
00302 idsOfMsgsPendingDownload.clear();
00303 lensOfMsgsPendingDownload.clear();
00304 idsOfMsgs.clear();
00305 uidsOfMsgs.clear();
00306 idsOfMsgsToDelete.clear();
00307
00308 headersOnServer.clear();
00309 headers = false;
00310 indexOfCurrentMsg = -1;
00311 KMBroadcastStatus::instance()->reset();
00312 KMBroadcastStatus::instance()->setStatusProgressEnable( "P" + mName, true );
00313 KMBroadcastStatus::instance()->setStatusMsg(
00314 i18n("Preparing transmission from \"%1\"...").arg(mName));
00315 connect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()),
00316 this, SLOT(slotAbortRequested()));
00317
00318 numBytes = 0;
00319 numBytesRead = 0;
00320 stage = List;
00321 mSlave = KIO::Scheduler::getConnectedSlave( url, slaveConfig() );
00322 if (!mSlave)
00323 {
00324 slotSlaveError(0, KIO::ERR_CANNOT_LAUNCH_PROCESS, url.protocol());
00325 return;
00326 }
00327 url.setPath(QString("/index"));
00328 job = KIO::get( url, false, false );
00329 connectJob();
00330 }
00331
00332 MetaData KMAcctExpPop::slaveConfig() const {
00333 MetaData m = NetworkAccount::slaveConfig();
00334
00335 m.insert("progress", "off");
00336 m.insert("pipelining", (mUsePipelining) ? "on" : "off");
00337 if (mAuth == "PLAIN" || mAuth == "LOGIN" || mAuth == "CRAM-MD5" ||
00338 mAuth == "DIGEST-MD5") {
00339 m.insert("auth", "SASL");
00340 m.insert("sasl", mAuth);
00341 } else if ( mAuth == "*" )
00342 m.insert("auth", "USER");
00343 else
00344 m.insert("auth", mAuth);
00345
00346 return m;
00347 }
00348
00349
00350
00351
00352 void KMAcctExpPop::slotMsgRetrieved(KIO::Job*, const QString & infoMsg)
00353 {
00354 if (infoMsg != "message complete") return;
00355 KMMessage *msg = new KMMessage;
00356
00357
00358 uint newSize = KMFolder::crlf2lf( curMsgData.data(), curMsgData.size() );
00359 curMsgData.resize( newSize );
00360 msg->fromByteArray( curMsgData , true );
00361 if (stage == Head)
00362 {
00363 kdDebug(5006) << "Size of Message: " << (*lensOfMsgsPendingDownload.at(
00364 uidsOfMsgs.findIndex(headerIt.current()->uid()))) << endl;
00365 msg->setMsgLength(*lensOfMsgsPendingDownload.at(
00366 uidsOfMsgs.findIndex(headerIt.current()->uid())));
00367 headerIt.current()->setHeader(msg);
00368 ++headerIt;
00369 slotGetNextHdr();
00370 } else {
00371 kdDebug(5006) << "stage == Retr" << endl;
00372 kdDebug(5006) << QString( "curMsgData.size() %1" ).arg( curMsgData.size() ) << endl;
00373 msg->setMsgLength( curMsgData.size() );
00374 msgsAwaitingProcessing.append(msg);
00375 msgIdsAwaitingProcessing.append(idsOfMsgs[indexOfCurrentMsg]);
00376 msgUidsAwaitingProcessing.append(uidsOfMsgs[indexOfCurrentMsg]);
00377 slotGetNextMsg();
00378 }
00379 }
00380
00381
00382
00383
00384 void KMAcctExpPop::slotJobFinished() {
00385 QStringList emptyList;
00386 if (stage == List) {
00387 kdDebug(5006) << "stage == List" << endl;
00388 KURL url = getUrl();
00389 url.setPath(QString("/uidl"));
00390 job = KIO::get( url, false, false );
00391 connectJob();
00392 stage = Uidl;
00393 }
00394 else if (stage == Uidl) {
00395 kdDebug(5006) << "stage == Uidl" << endl;
00396 mUidlFinished = TRUE;
00397
00398 if (mLeaveOnServer && uidsOfMsgs.isEmpty() && uidsOfNextSeenMsgs.isEmpty()
00399 && !idsOfMsgs.isEmpty())
00400 {
00401 KMessageBox::sorry(0, i18n("Your POP3 server doesn't support the UIDL "
00402 "command. This command is required to determine in a reliable way, "
00403 "which of the mails on the server KMail has already seen before.\n"
00404 "The feature to leave the mails on the server will therefore not "
00405 "work properly."));
00406 }
00407
00408 if (uidsOfNextSeenMsgs.isEmpty())
00409 uidsOfNextSeenMsgs = uidsOfSeenMsgs;
00410
00411
00412 if (mFilterOnServer == true) {
00413 QStringList::Iterator hids = idsOfMsgsPendingDownload.begin();
00414 for (hids = idsOfMsgsPendingDownload.begin();
00415 hids != idsOfMsgsPendingDownload.end(); hids++) {
00416 int idx = idsOfMsgsPendingDownload.findIndex(*hids);
00417 kdDebug(5006) << "Length: " << *(lensOfMsgsPendingDownload.at(idx)) << endl;
00418
00419 if ((unsigned int)*(lensOfMsgsPendingDownload.at(idx))
00420 >= mFilterOnServerCheckSize) {
00421 kdDebug(5006) << "bigger than " << mFilterOnServerCheckSize << endl;
00422 headersOnServer.append(new KMPopHeaders(*idsOfMsgsPendingDownload.at(idx),
00423 *uidsOfMsgs.at(idx),
00424 Later));
00425
00426 if(headerDeleteUids.contains(headersOnServer.current()->uid())) {
00427 headersOnServer.current()->setAction(Delete);
00428 }
00429 else if(headerDownUids.contains(headersOnServer.current()->uid())) {
00430 headersOnServer.current()->setAction(Down);
00431 }
00432 else if(headerLaterUids.contains(headersOnServer.current()->uid())) {
00433 headersOnServer.current()->setAction(Later);
00434 }
00435 }
00436 }
00437
00438 headerDeleteUids.clear();
00439 headerDownUids.clear();
00440 headerLaterUids.clear();
00441 }
00442
00443
00444 if ((headersOnServer.count() > 0) && (mFilterOnServer == true)) {
00445 headerIt.toFirst();
00446 KURL url = getUrl();
00447 QString headerIds;
00448 while (headerIt.current())
00449 {
00450 headerIds += headerIt.current()->id();
00451 if (!headerIt.atLast()) headerIds += ",";
00452 ++headerIt;
00453 }
00454 headerIt.toFirst();
00455 url.setPath(QString("/headers/") + headerIds);
00456 job = KIO::get( url, false, false );
00457 connectJob();
00458 slotGetNextHdr();
00459 stage = Head;
00460 }
00461 else {
00462 stage = Retr;
00463 numMsgs = idsOfMsgsPendingDownload.count();
00464 numBytesToRead = 0;
00465 QValueList<int>::Iterator len = lensOfMsgsPendingDownload.begin();
00466 for (len = lensOfMsgsPendingDownload.begin();
00467 len != lensOfMsgsPendingDownload.end(); len++)
00468 numBytesToRead += *len;
00469 KURL url = getUrl();
00470 url.setPath("/download/" + idsOfMsgsPendingDownload.join(","));
00471 job = KIO::get( url, false, false );
00472 connectJob();
00473 slotGetNextMsg();
00474 processMsgsTimer.start(processingDelay);
00475 }
00476 }
00477 else if (stage == Head) {
00478 kdDebug(5006) << "stage == Head" << endl;
00479
00480
00481
00482
00483
00484
00485 KMPopFilterAction action;
00486 bool dlgPopup = false;
00487 for (headersOnServer.first(); headersOnServer.current(); headersOnServer.next()) {
00488 action = (KMPopFilterAction)kmkernel->popFilterMgr()->process(headersOnServer.current()->header());
00489
00490 switch ( action ) {
00491 case NoAction:
00492 kdDebug(5006) << "PopFilterAction = NoAction" << endl;
00493 break;
00494 case Later:
00495 kdDebug(5006) << "PopFilterAction = Later" << endl;
00496 break;
00497 case Delete:
00498 kdDebug(5006) << "PopFilterAction = Delete" << endl;
00499 break;
00500 case Down:
00501 kdDebug(5006) << "PopFilterAction = Down" << endl;
00502 break;
00503 default:
00504 kdDebug(5006) << "PopFilterAction = default oops!" << endl;
00505 break;
00506 }
00507 switch ( action ) {
00508 case NoAction:
00509
00510 dlgPopup = true;
00511 break;
00512 case Later:
00513 if (kmkernel->popFilterMgr()->showLaterMsgs())
00514 dlgPopup = true;
00515 default:
00516 headersOnServer.current()->setAction(action);
00517 headersOnServer.current()->setRuleMatched(true);
00518 break;
00519 }
00520 }
00521
00522
00523
00524 headers = true;
00525 if (dlgPopup) {
00526 KMPopFilterCnfrmDlg dlg(&headersOnServer, this->name(), kmkernel->popFilterMgr()->showLaterMsgs());
00527 dlg.exec();
00528 }
00529
00530 for (headersOnServer.first(); headersOnServer.current(); headersOnServer.next()) {
00531 if (headersOnServer.current()->action() == Delete ||
00532 headersOnServer.current()->action() == Later) {
00533
00534
00535 int idx = idsOfMsgsPendingDownload.findIndex(headersOnServer.current()->id());
00536 if (idx != -1) {
00537 idsOfMsgsPendingDownload.remove( idsOfMsgsPendingDownload
00538 .at( idx ));
00539 lensOfMsgsPendingDownload.remove( lensOfMsgsPendingDownload
00540 .at( idx ));
00541 idsOfMsgs.remove(idsOfMsgs.at( idx ));
00542 uidsOfMsgs.remove(uidsOfMsgs.at( idx ));
00543 }
00544 if (headersOnServer.current()->action() == Delete) {
00545 headerDeleteUids.append(headersOnServer.current()->uid());
00546 uidsOfNextSeenMsgs.append(headersOnServer.current()->uid());
00547 idsOfMsgsToDelete.append(headersOnServer.current()->id());
00548 }
00549 else {
00550 headerLaterUids.append(headersOnServer.current()->uid());
00551 }
00552 }
00553 else if (headersOnServer.current()->action() == Down) {
00554 headerDownUids.append(headersOnServer.current()->uid());
00555 }
00556 }
00557
00558 headersOnServer.clear();
00559 stage = Retr;
00560 numMsgs = idsOfMsgsPendingDownload.count();
00561 numBytesToRead = 0;
00562 QValueList<int>::Iterator len = lensOfMsgsPendingDownload.begin();
00563 for (len = lensOfMsgsPendingDownload.begin();
00564 len != lensOfMsgsPendingDownload.end(); len++)
00565 numBytesToRead += *len;
00566 KURL url = getUrl();
00567 url.setPath("/download/" + idsOfMsgsPendingDownload.join(","));
00568 job = KIO::get( url, false, false );
00569 connectJob();
00570 slotGetNextMsg();
00571 processMsgsTimer.start(processingDelay);
00572 }
00573 else if (stage == Retr) {
00574 processRemainingQueuedMessagesAndSaveUidList();
00575
00576 headerDeleteUids.clear();
00577 headerDownUids.clear();
00578 headerLaterUids.clear();
00579
00580 kmkernel->folderMgr()->syncAllFolders();
00581
00582 KURL url = getUrl();
00583 if (mLeaveOnServer || idsOfMsgsToDelete.isEmpty()) {
00584 url.setPath(QString("/commit"));
00585 job = KIO::get(url, false, false );
00586 }
00587 else {
00588 stage = Dele;
00589 url.setPath("/remove/" + idsOfMsgsToDelete.join(","));
00590 idsOfMsgsToDelete.clear();
00591 job = KIO::get( url, false, false );
00592 }
00593 connectJob();
00594 }
00595 else if (stage == Dele) {
00596 kdDebug(5006) << "stage == Dele" << endl;
00597 KURL url = getUrl();
00598 url.setPath(QString("/commit"));
00599 job = KIO::get( url, false, false );
00600 stage = Quit;
00601 connectJob();
00602 }
00603 else if (stage == Quit) {
00604 kdDebug(5006) << "stage == Quit" << endl;
00605 job = 0;
00606 if (mSlave) KIO::Scheduler::disconnectSlave(mSlave);
00607 mSlave = 0;
00608 stage = Idle;
00609 KMBroadcastStatus::instance()->setStatusProgressPercent( "P" + mName, 100 );
00610 int numMessages = (KMBroadcastStatus::instance()->abortRequested()) ?
00611 indexOfCurrentMsg : idsOfMsgs.count();
00612 KMBroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
00613 numMessages, numBytes, numBytesRead, numBytesToRead, mLeaveOnServer );
00614 KMBroadcastStatus::instance()->setStatusProgressEnable( "P" + mName,
00615 false );
00616 KMBroadcastStatus::instance()->reset();
00617
00618 checkDone((numMessages > 0), numMessages);
00619 }
00620 }
00621
00622
00623
00624 void KMAcctExpPop::processRemainingQueuedMessagesAndSaveUidList()
00625 {
00626 kdDebug(5006) << "processRemainingQueuedMessagesAndSaveUidList" << endl;
00627 slotProcessPendingMsgs();
00628 processMsgsTimer.stop();
00629
00630 stage = Quit;
00631 kmkernel->folderMgr()->syncAllFolders();
00632
00633
00634
00635 if (!mUidlFinished) return;
00636 QString seenUidList = locateLocal( "data", "kmail/" + mLogin + ":" + "@" +
00637 mHost + ":" + QString("%1").arg(mPort) );
00638
00639 KConfig config( seenUidList );
00640 config.writeEntry( "seenUidList", uidsOfNextSeenMsgs );
00641 config.writeEntry( "downloadLater", headerLaterUids );
00642 config.sync();
00643 }
00644
00645
00646
00647 void KMAcctExpPop::slotGetNextMsg()
00648 {
00649 QStringList::Iterator next = idsOfMsgsPendingDownload.begin();
00650 QValueList<int>::Iterator nextLen = lensOfMsgsPendingDownload.begin();
00651
00652 curMsgData.resize(0);
00653 numMsgBytesRead = 0;
00654 curMsgLen = 0;
00655 if (curMsgStrm)
00656 delete curMsgStrm;
00657 curMsgStrm = 0;
00658
00659 if (next == idsOfMsgsPendingDownload.end()) {
00660 kdDebug(5006) << "KMAcctExpPop::slotGetNextMsg was called too often" << endl;
00661 }
00662 else {
00663 curMsgStrm = new QDataStream( curMsgData, IO_WriteOnly );
00664 curMsgLen = *nextLen;
00665 ++indexOfCurrentMsg;
00666 idsOfMsgsPendingDownload.remove( next );
00667 kdDebug(5006) << QString("Length of message about to get %1").arg( *nextLen ) << endl;
00668 lensOfMsgsPendingDownload.remove( nextLen );
00669 }
00670 }
00671
00672
00673
00674 void KMAcctExpPop::slotData( KIO::Job* job, const QByteArray &data)
00675 {
00676 if (data.size() == 0) {
00677 kdDebug(5006) << "Data: <End>" << endl;
00678 if ((stage == Retr) && (numMsgBytesRead < curMsgLen))
00679 numBytesRead += curMsgLen - numMsgBytesRead;
00680 else if (stage == Head){
00681 kdDebug(5006) << "Head: <End>" << endl;
00682 }
00683 return;
00684 }
00685
00686 int oldNumMsgBytesRead = numMsgBytesRead;
00687 if (stage == Retr) {
00688 headers = false;
00689 curMsgStrm->writeRawBytes( data.data(), data.size() );
00690 numMsgBytesRead += data.size();
00691 if (numMsgBytesRead > curMsgLen)
00692 numMsgBytesRead = curMsgLen;
00693 numBytesRead += numMsgBytesRead - oldNumMsgBytesRead;
00694 dataCounter++;
00695 if (dataCounter % 5 == 0)
00696 {
00697 QString msg;
00698 if (numBytes != numBytesToRead && mLeaveOnServer)
00699 {
00700 msg = i18n("Fetching message %1 of %2 (%3 of %4 KB) from %5 "
00701 "(%6 KB remain on the server).")
00702 .arg(indexOfCurrentMsg+1).arg(numMsgs).arg(numBytesRead/1024)
00703 .arg(numBytesToRead/1024).arg(mHost).arg(numBytes/1024);
00704 }
00705 else
00706 {
00707 msg = i18n("Fetching message %1 of %2 (%3 of %4 KB) from %5.")
00708 .arg(indexOfCurrentMsg+1).arg(numMsgs).arg(numBytesRead/1024)
00709 .arg(numBytesToRead/1024).arg(mHost);
00710 }
00711 KMBroadcastStatus::instance()->setStatusMsg( msg );
00712 KMBroadcastStatus::instance()->setStatusProgressPercent("P" + mName,
00713 (numBytesToRead <= 100) ? 50
00714
00715 : (numBytesRead / (numBytesToRead / 100)) );
00716 }
00717 return;
00718 }
00719
00720 if (stage == Head) {
00721 curMsgStrm->writeRawBytes( data.data(), data.size() );
00722 return;
00723 }
00724
00725
00726 QString qdata = data;
00727 qdata = qdata.simplifyWhiteSpace();
00728 int spc = qdata.find( ' ' );
00729 if (spc > 0) {
00730 if (stage == List) {
00731 QString length = qdata.mid(spc+1);
00732 if (length.find(' ') != -1) length.truncate(length.find(' '));
00733 int len = length.toInt();
00734 numBytes += len;
00735 QString id = qdata.left(spc);
00736 idsOfMsgs.append( id );
00737 lensOfMsgsPendingDownload.append( len );
00738 idsOfMsgsPendingDownload.append( id );
00739 }
00740 else {
00741 QString uid = qdata.mid(spc + 1);
00742 uidsOfMsgs.append( uid );
00743 if (uidsOfSeenMsgs.contains(uid)) {
00744 QString id = qdata.left(spc);
00745 int idx = idsOfMsgsPendingDownload.findIndex(id);
00746 if (idx != -1) {
00747 lensOfMsgsPendingDownload.remove( lensOfMsgsPendingDownload
00748 .at( idx ));
00749 idsOfMsgsPendingDownload.remove( id );
00750 idsOfMsgs.remove( id );
00751 uidsOfMsgs.remove( uid );
00752 }
00753 else
00754 kdDebug(5006) << "KMAcctExpPop::slotData synchronization failure." << endl;
00755 if (uidsOfSeenMsgs.contains( uid ))
00756 idsOfMsgsToDelete.append( id );
00757 uidsOfNextSeenMsgs.append( uid );
00758 }
00759 }
00760 }
00761 else {
00762 stage = Idle;
00763 if (job) job->kill();
00764 job = 0;
00765 mSlave = 0;
00766 KMessageBox::error(0, i18n( "Unable to complete LIST operation" ),
00767 i18n("Invalid Response From Server"));
00768 return;
00769 }
00770 }
00771
00772
00773
00774 void KMAcctExpPop::slotResult( KIO::Job* )
00775 {
00776 if (!job) return;
00777 if ( job->error() )
00778 {
00779 if (interactive) {
00780 if (headers) {
00781 idsOfMsgs.clear();
00782 }
00783 if (stage == Head && job->error() == KIO::ERR_COULD_NOT_READ)
00784 {
00785 KMessageBox::error(0, i18n("Your server does not support the "
00786 "TOP command. Therefore it is not possible to fetch the headers "
00787 "of large emails first, before downloading them."));
00788 slotCancel();
00789 return;
00790 }
00791
00792 if (!mStorePasswd) mPasswd = "";
00793 job->showErrorDialog();
00794 }
00795 slotCancel();
00796 }
00797 else
00798 slotJobFinished();
00799 }
00800
00801
00802
00803 void KMAcctExpPop::slotSlaveError(KIO::Slave *aSlave, int error,
00804 const QString &errorMsg)
00805 {
00806 if (aSlave != mSlave) return;
00807 if (error == KIO::ERR_SLAVE_DIED) mSlave = 0;
00808
00809
00810 if ( error == KIO::ERR_CONNECTION_BROKEN && mSlave ) {
00811 KIO::Scheduler::disconnectSlave( mSlave );
00812 mSlave = 0;
00813 }
00814
00815 if (interactive) {
00816 KMessageBox::error(kmkernel->mainWin(), KIO::buildErrorString(error, errorMsg));
00817 }
00818
00819
00820 stage = Quit;
00821 if (error == KIO::ERR_COULD_NOT_LOGIN && !mStorePasswd)
00822 mAskAgain = TRUE;
00823
00824
00825
00826 QTimer::singleShot(0, this, SLOT(slotCancel()));
00827 }
00828
00829
00830 void KMAcctExpPop::slotGetNextHdr(){
00831 kdDebug(5006) << "slotGetNextHeader" << endl;
00832
00833 curMsgData.resize(0);
00834 delete curMsgStrm;
00835 curMsgStrm = 0;
00836
00837 curMsgStrm = new QDataStream( curMsgData, IO_WriteOnly );
00838 }
00839
00840 void KMAcctExpPop::killAllJobs( bool ) {
00841
00842 }
00843
00844 #include "kmacctexppop.moc"