00001
00002 #include <config.h>
00003
00004 #include "kmaccount.h"
00005
00006 #include "accountmanager.h"
00007 using KMail::AccountManager;
00008 #include "kmacctfolder.h"
00009 #include "kmfoldermgr.h"
00010 #include "kmfiltermgr.h"
00011 #include "messagesender.h"
00012 #include "kmmessage.h"
00013 #include "broadcaststatus.h"
00014 using KPIM::BroadcastStatus;
00015 #include "kmfoldercachedimap.h"
00016
00017 #include "progressmanager.h"
00018 using KPIM::ProgressItem;
00019 using KPIM::ProgressManager;
00020
00021 using KMail::FolderJob;
00022
00023 #include <kapplication.h>
00024 #include <klocale.h>
00025 #include <kmessagebox.h>
00026 #include <kdebug.h>
00027 #include <kconfig.h>
00028
00029 #include <qeventloop.h>
00030
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include <errno.h>
00034
00035 #include <assert.h>
00036
00037
00038 #include "kmaccount.moc"
00039
00040
00041 KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent)
00042 : QObject(parent), mPrecommand(precommand)
00043 {
00044 BroadcastStatus::instance()->setStatusMsg(
00045 i18n("Executing precommand %1").arg(precommand ));
00046
00047 mPrecommandProcess.setUseShell(true);
00048 mPrecommandProcess << precommand;
00049
00050 connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)),
00051 SLOT(precommandExited(KProcess *)));
00052 }
00053
00054
00055 KMPrecommand::~KMPrecommand()
00056 {
00057 }
00058
00059
00060
00061 bool KMPrecommand::start()
00062 {
00063 bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit );
00064 if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.")
00065 .arg(mPrecommand));
00066 return ok;
00067 }
00068
00069
00070
00071 void KMPrecommand::precommandExited(KProcess *p)
00072 {
00073 int exitCode = p->normalExit() ? p->exitStatus() : -1;
00074 if (exitCode)
00075 KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2")
00076 .arg(exitCode).arg(strerror(exitCode)));
00077 emit finished(!exitCode);
00078 }
00079
00080
00081
00082 KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id)
00083 : KAccount( id, aName ),
00084 mTrash(KMKernel::self()->trashFolder()->idString()),
00085 mOwner(aOwner),
00086 mFolder(0),
00087 mTimer(0),
00088 mInterval(0),
00089 mExclude(false),
00090 mCheckingMail(false),
00091 mPrecommandSuccess(true),
00092 mHasInbox(false),
00093 mMailCheckProgressItem(0)
00094 {
00095 assert(aOwner != 0);
00096 }
00097
00098 void KMAccount::init() {
00099 mTrash = kmkernel->trashFolder()->idString();
00100 mExclude = false;
00101 mInterval = 0;
00102 mNewInFolder.clear();
00103 }
00104
00105
00106 KMAccount::~KMAccount()
00107 {
00108 if ( (kmkernel && !kmkernel->shuttingDown()) && mFolder ) mFolder->removeAccount(this);
00109 if (mTimer) deinstallTimer();
00110 }
00111
00112
00113
00114 void KMAccount::setName(const QString& aName)
00115 {
00116 mName = aName;
00117 }
00118
00119
00120
00121 void KMAccount::clearPasswd()
00122 {
00123 }
00124
00125
00126
00127 void KMAccount::setFolder(KMFolder* aFolder, bool addAccount)
00128 {
00129 if(!aFolder) {
00130
00131 mFolder = 0;
00132 return;
00133 }
00134 mFolder = (KMAcctFolder*)aFolder;
00135 if (addAccount) mFolder->addAccount(this);
00136 }
00137
00138
00139
00140 void KMAccount::readConfig(KConfig& config)
00141 {
00142 QString folderName;
00143 mFolder = 0;
00144 folderName = config.readEntry("Folder");
00145 setCheckInterval(config.readNumEntry("check-interval", 0));
00146 setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString()));
00147 setCheckExclude(config.readBoolEntry("check-exclude", false));
00148 setPrecommand(config.readPathEntry("precommand"));
00149
00150 if (!folderName.isEmpty())
00151 {
00152 setFolder(kmkernel->folderMgr()->findIdString(folderName), true);
00153 }
00154
00155 if (mInterval == 0)
00156 deinstallTimer();
00157 else
00158 installTimer();
00159 }
00160
00161
00162
00163 void KMAccount::writeConfig(KConfig& config)
00164 {
00165
00166 KAccount::writeConfig(config);
00167
00168 config.writeEntry("Type", type());
00169 config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null);
00170 config.writeEntry("check-interval", mInterval);
00171 config.writeEntry("check-exclude", mExclude);
00172 config.writePathEntry("precommand", mPrecommand);
00173 config.writeEntry("trash", mTrash);
00174 }
00175
00176
00177
00178 void KMAccount::sendReceipt(KMMessage* aMsg)
00179 {
00180 KConfig* cfg = KMKernel::config();
00181 bool sendReceipts;
00182
00183 KConfigGroupSaver saver(cfg, "General");
00184
00185 sendReceipts = cfg->readBoolEntry("send-receipts", false);
00186 if (!sendReceipts) return;
00187
00188 KMMessage *newMsg = aMsg->createDeliveryReceipt();
00189 if (newMsg) {
00190 mReceipts.append(newMsg);
00191 QTimer::singleShot( 0, this, SLOT( sendReceipts() ) );
00192 }
00193 }
00194
00195
00196
00197 bool KMAccount::processNewMsg(KMMessage* aMsg)
00198 {
00199 int rc, processResult;
00200
00201 assert(aMsg != 0);
00202
00203
00204 KMFolderCachedImap* parent = 0;
00205 if( type() == "cachedimap" )
00206 parent = static_cast<KMFolderCachedImap*>( aMsg->storage() );
00207
00208
00209
00210 sendReceipt(aMsg);
00211
00212
00213
00214
00215 if ( type() != "cachedimap" && type() != "imap" ) {
00216 if ( aMsg->isOld() )
00217 aMsg->setStatus(KMMsgStatusUnread);
00218
00219 else
00220 aMsg->setStatus(KMMsgStatusNew);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id());
00233 if (processResult == 2) {
00234 perror("Critical error: Unable to collect mail (out of space?)");
00235 KMessageBox::information(0,(i18n("Critical error: "
00236 "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno)));
00237 return false;
00238 }
00239 else if (processResult == 1)
00240 {
00241 if( type() == "cachedimap" )
00242 ;
00243 else {
00244
00245
00246 kmkernel->filterMgr()->tempOpenFolder(mFolder);
00247 rc = mFolder->addMsg(aMsg);
00248
00249
00250
00251
00252
00253
00254
00255
00256 if (rc) {
00257 perror("failed to add message");
00258 KMessageBox::information(0, i18n("Failed to add message:\n") +
00259 QString(strerror(rc)));
00260 return false;
00261 }
00262 int count = mFolder->count();
00263
00264 if (count != 1) mFolder->unGetMsg(count - 1);
00265 }
00266 }
00267
00268
00269 QString folderId;
00270 if ( processResult == 1 ) {
00271 folderId = ( type() == "cachedimap" ) ? parent->folder()->idString()
00272 : mFolder->idString();
00273 }
00274 else {
00275 folderId = aMsg->parent()->idString();
00276 }
00277 addToNewInFolder( folderId, 1 );
00278
00279 return true;
00280 }
00281
00282
00283 void KMAccount::setCheckInterval(int aInterval)
00284 {
00285 if (aInterval <= 0)
00286 mInterval = 0;
00287 else
00288 mInterval = aInterval;
00289
00290 }
00291
00292 int KMAccount::checkInterval() const
00293 {
00294 if ( mInterval <= 0 )
00295 return mInterval;
00296 return QMAX( mInterval, GlobalSettings::self()->minimumCheckInterval() );
00297 }
00298
00299
00300 void KMAccount::deleteFolderJobs()
00301 {
00302 mJobList.setAutoDelete(true);
00303 mJobList.clear();
00304 mJobList.setAutoDelete(false);
00305 }
00306
00307
00308 void KMAccount::ignoreJobsForMessage( KMMessage* msg )
00309 {
00310
00311 for( QPtrListIterator<FolderJob> it(mJobList); it.current(); ++it ) {
00312 if ( it.current()->msgList().first() == msg) {
00313 FolderJob *job = it.current();
00314 mJobList.remove( job );
00315 delete job;
00316 break;
00317 }
00318 }
00319 }
00320
00321
00322 void KMAccount::setCheckExclude(bool aExclude)
00323 {
00324 mExclude = aExclude;
00325 }
00326
00327
00328
00329 void KMAccount::installTimer()
00330 {
00331 if (mInterval <= 0) return;
00332 if(!mTimer)
00333 {
00334 mTimer = new QTimer(0, "mTimer");
00335 connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck()));
00336 }
00337 else
00338 {
00339 mTimer->stop();
00340 }
00341 mTimer->start( checkInterval() * 60000 );
00342 }
00343
00344
00345
00346 void KMAccount::deinstallTimer()
00347 {
00348 delete mTimer;
00349 mTimer = 0;
00350 }
00351
00352
00353 bool KMAccount::runPrecommand(const QString &precommand)
00354 {
00355
00356 if ( precommand.isEmpty() )
00357 return true;
00358
00359 KMPrecommand precommandProcess(precommand, this);
00360
00361 BroadcastStatus::instance()->setStatusMsg(
00362 i18n("Executing precommand %1").arg(precommand ));
00363
00364 connect(&precommandProcess, SIGNAL(finished(bool)),
00365 SLOT(precommandExited(bool)));
00366
00367 kdDebug(5006) << "Running precommand " << precommand << endl;
00368 if (!precommandProcess.start()) return false;
00369
00370 kapp->eventLoop()->enterLoop();
00371
00372 return mPrecommandSuccess;
00373 }
00374
00375
00376 void KMAccount::precommandExited(bool success)
00377 {
00378 mPrecommandSuccess = success;
00379 kapp->eventLoop()->exitLoop();
00380 }
00381
00382
00383 void KMAccount::mailCheck()
00384 {
00385 if (mTimer)
00386 mTimer->stop();
00387
00388 if ( kmkernel ) {
00389 AccountManager *acctmgr = kmkernel->acctMgr();
00390 if ( acctmgr )
00391 acctmgr->singleCheckMail(this, false);
00392 }
00393 }
00394
00395
00396 void KMAccount::sendReceipts()
00397 {
00398 QValueList<KMMessage*>::Iterator it;
00399 for(it = mReceipts.begin(); it != mReceipts.end(); ++it)
00400 kmkernel->msgSender()->send(*it);
00401 mReceipts.clear();
00402 }
00403
00404
00405 QString KMAccount::encryptStr(const QString &aStr)
00406 {
00407 QString result;
00408 for (uint i = 0; i < aStr.length(); i++)
00409
00410
00411 result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] :
00412 QChar(0x1001F - aStr[i].unicode());
00413 return result;
00414 }
00415
00416
00417 QString KMAccount::importPassword(const QString &aStr)
00418 {
00419 unsigned int i, val;
00420 unsigned int len = aStr.length();
00421 QCString result;
00422 result.resize(len+1);
00423
00424 for (i=0; i<len; i++)
00425 {
00426 val = aStr[i] - ' ';
00427 val = (255-' ') - val;
00428 result[i] = (char)(val + ' ');
00429 }
00430 result[i] = '\0';
00431
00432 return encryptStr(result);
00433 }
00434
00435 void KMAccount::invalidateIMAPFolders()
00436 {
00437
00438 }
00439
00440 void KMAccount::pseudoAssign( const KMAccount * a ) {
00441 if ( !a ) return;
00442
00443 setName( a->name() );
00444 setId( a->id() );
00445 setCheckInterval( a->checkInterval() );
00446 setCheckExclude( a->checkExclude() );
00447 setFolder( a->folder() );
00448 setPrecommand( a->precommand() );
00449 setTrash( a->trash() );
00450 }
00451
00452
00453 void KMAccount::checkDone( bool newmail, CheckStatus status )
00454 {
00455 setCheckingMail( false );
00456
00457
00458 if (mTimer)
00459 mTimer->start( checkInterval() * 60000 );
00460 if ( mMailCheckProgressItem ) {
00461
00462
00463 ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
00464 mMailCheckProgressItem = 0;
00465 savedMailCheckProgressItem->setComplete();
00466 }
00467
00468 emit newMailsProcessed( mNewInFolder );
00469 emit finishedCheck( newmail, status );
00470 mNewInFolder.clear();
00471 }
00472
00473
00474 void KMAccount::addToNewInFolder( QString folderId, int num )
00475 {
00476 if ( mNewInFolder.find( folderId ) == mNewInFolder.end() )
00477 mNewInFolder[folderId] = num;
00478 else
00479 mNewInFolder[folderId] += num;
00480 }