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