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"