00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
static const char *popmail_conduit_id=
00035
"$Id: popmail-conduit.cc,v 1.61 2003/12/30 10:28:58 adridg Exp $";
00036
00037
#include "options.h"
00038
00039
#include <qsocket.h>
00040
#include <qregexp.h>
00041
00042
00043
#include <sys/types.h>
00044
#include <sys/socket.h>
00045
#include <sys/utsname.h>
00046
#include <ctype.h>
00047
00048
#include <unistd.h>
00049
#include <errno.h>
00050
00051
#include <time.h>
00052
#include <pi-version.h>
00053
#if PILOT_LINK_MAJOR < 10
00054
#include <pi-config.h>
00055
#endif
00056
#include <pi-mail.h>
00057
00058
#include <qdir.h>
00059
#include <qtextstream.h>
00060
#include <qtextcodec.h>
00061
00062
#include <kapplication.h>
00063
#include <kmessagebox.h>
00064
#include <ksock.h>
00065
#include <kconfig.h>
00066
#include <ksimpleconfig.h>
00067
#include <dcopclient.h>
00068
#include <ktempfile.h>
00069
00070
#include "pilotAppCategory.h"
00071
#include "pilotSerialDatabase.h"
00072
00073
#include "passworddialog.h"
00074
#include "popmail-factory.h"
00075
#include "popmail-conduit.h"
00076
00077
00078
extern "C" {
00079
extern time_t parsedate(
char * p);
00080 }
00081
00082
00083
00084
00085
00086
00087
void showMessage(
const QString &message)
00088 {
00089 KMessageBox::error(0L, message, i18n(
"Error retrieving mail"));
00090 }
00091
00092
00093
00094
00095
00096
00097
#define TIMEOUT (-2)
00098
#define PERROR (-3)
00099
00100
#define BADPOP (-333)
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
void showResponseResult(
int const ret,
00116
const char *message,
00117
const char *buffer,
00118
const char *func)
00119 {
00120 QString msg(i18n(message));
00121
00122
if (ret==TIMEOUT)
00123 {
00124 msg.append(i18n(
" (Timed out)"));
00125
#ifdef DEBUG
00126
DEBUGCONDUIT << func
00127 <<
": " << message
00128 << endl;
00129
#endif
00130
}
00131
if (ret==PERROR)
00132 {
00133 kdWarning() << func
00134 <<
": " << message
00135 << perror
00136 << endl ;
00137 }
00138
00139
if (ret>=0)
00140 {
00141
#ifdef DEBUG
00142
DEBUGCONDUIT << func
00143 <<
": " << message
00144 << endl;
00145
#endif
00146
00147
00148
00149
00150
if (buffer && buffer[0])
00151 {
00152 msg.append(CSL1(
"\n"));
00153 msg.append(QString::fromLocal8Bit(buffer));
00154
#ifdef DEBUG
00155
DEBUGCONDUIT << func
00156 <<
": " << buffer
00157 << endl;
00158
#endif
00159
}
00160 }
00161
00162
00163 showMessage(msg);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
static int getResponse(KSocket *s,
char *buffer,
const int bufsiz)
00175 {
00176 FUNCTIONSETUP;
00177
int ret;
00178
00179
00180
00181
00182
00183
00184
do
00185 {
00186 ret=read(s->socket(), buffer, bufsiz-1);
00187 }
00188
while ((ret==-1) && (errno==EAGAIN));
00189
00190 buffer[ret]=0;
00191
00192
return ret;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
static int getPOPResponse(KSocket *s,
const char *message,
00208
char *buffer,
const int bufsiz)
00209 {
00210 FUNCTIONSETUP;
00211
int i,ret;
00212
00213 ret=getResponse(s,buffer,bufsiz);
00214
00215
if (ret==TIMEOUT)
00216 {
00217 showResponseResult(ret,message,buffer,
"getPOPResponse");
00218
return TIMEOUT;
00219 }
00220
00221
00222
00223
00224 i=0;
00225
while(i<ret && isspace(buffer[i]) && i<bufsiz)
00226 {
00227 i++;
00228 }
00229
00230
00231
00232
00233
00234
00235
if(buffer[i] !=
'+')
00236 {
00237 showResponseResult(ret,message,buffer+i,
"getPOPResponse");
00238
return BADPOP;
00239 }
00240
00241
return i;
00242 }
00243
00244
00245
static void disconnectPOP(KSocket *s)
00246 {
00247 FUNCTIONSETUP;
00248
00249
00250
00251
00252
00253
char buffer[12];
00254
const char *quitmsg=
"QUIT\r\n";
00255 write(s->socket(),quitmsg,strlen(quitmsg));
00256 getPOPResponse(s,
"QUIT command to POP server failed",buffer,12);
00257 }
00258
00259
00260
00261
void reset_Mail(
struct Mail *t)
00262 {
00263 t->to = 0;
00264 t->from = 0;
00265 t->cc = 0;
00266 t->bcc = 0;
00267 t->subject = 0;
00268 t->replyTo = 0;
00269 t->sentTo = 0;
00270 t->body = 0;
00271 t->dated = 0;
00272 }
00273
00274 PopMailConduit::PopMailConduit(KPilotDeviceLink *d,
00275
const char *n,
00276
const QStringList &l) :
00277
ConduitAction(d,n,l)
00278 {
00279 FUNCTIONSETUP;
00280
#ifdef DEBUG
00281
DEBUGCONDUIT<<popmail_conduit_id<<endl;
00282
#endif
00283
fConduitName=i18n(
"POP/Mail");
00284 }
00285
00286 PopMailConduit::~PopMailConduit()
00287 {
00288 FUNCTIONSETUP;
00289 }
00290
00291
void
00292 PopMailConduit::doSync()
00293 {
00294 FUNCTIONSETUP;
00295
00296
int mode=0;
00297
int sent_count=0,received_count=0;
00298
00299 addSyncLogEntry(CSL1(
"Mail "));
00300
00301 mode=fConfig->readNumEntry(PopMailConduitFactory::syncOutgoing());
00302
#ifdef DEBUG
00303
DEBUGCONDUIT << fname
00304 <<
": Outgoing mail mail disposition "
00305 << mode << endl;
00306
#endif
00307
00308
if(mode)
00309 {
00310 sent_count=sendPendingMail(mode);
00311 }
00312
00313 mode=fConfig->readNumEntry(PopMailConduitFactory::syncIncoming());
00314
#ifdef DEBUG
00315
DEBUGCONDUIT << fname <<
": Sending mail mode " << mode << endl;
00316
#endif
00317
00318
if(mode)
00319 {
00320 received_count=retrieveIncoming(mode);
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
if ((sent_count>0) || (received_count>0))
00330 {
00331 QString msg = CSL1(
"[ ");
00332
if (sent_count>0)
00333 {
00334 msg.append(i18n(
"Sent one message",
00335
"Sent %n messages",sent_count));
00336
if (received_count>0)
00337 {
00338 msg.append(CSL1(
" ; "));
00339 }
00340 }
00341
if (received_count>0)
00342 {
00343 msg.append(i18n(
"Received one message",
00344
"Received %n messages",received_count));
00345 }
00346 msg.append(CSL1(
" ] "));
00347 addSyncLogEntry(msg);
00348 }
00349 addSyncLogEntry(CSL1(
"OK\n"));
00350 }
00351
00352
00353
00354
int PopMailConduit::sendPendingMail(
int mode)
00355 {
00356 FUNCTIONSETUP;
00357
int count=-1;
00358
00359
00360
if (mode == PopMailConduit::SEND_SMTP)
00361 {
00362 count=sendViaSMTP();
00363 }
00364
if (mode==PopMailConduit::SEND_SENDMAIL)
00365 {
00366 count=sendViaSendmail();
00367 }
00368
if (mode==PopMailConduit::SEND_KMAIL)
00369 {
00370 count=sendViaKMail();
00371 }
00372
00373
if (count < 0)
00374 {
00375 kdWarning() << k_funcinfo
00376 <<
": Mail was not sent at all!"
00377 << endl;
00378 emit logError(TODO_I18N(
"[ No mail could be sent. ]"));
00379 }
00380
else
00381 {
00382
#ifdef DEBUG
00383
DEBUGCONDUIT << fname
00384 <<
": Sent "
00385 << count
00386 <<
" messages"
00387 << endl;
00388
#endif
00389
}
00390
00391
return count;
00392 }
00393
00394
int PopMailConduit::retrieveIncoming(
int mode)
00395 {
00396 FUNCTIONSETUP;
00397
int count=0;
00398
00399
if (mode==RECV_POP)
00400 {
00401 count=doPopQuery();
00402 }
00403
if (mode==RECV_UNIX)
00404 {
00405 count=doUnixStyle();
00406 }
00407
00408
return count;
00409 }
00410
00411
00412
00414
00415
00416
00417
00418
00419
00420
00422
00423
00424
00425
00426
00427
00428
00429
00430 QString getFQDomainName (
const KConfig& config)
00431 {
00432 FUNCTIONSETUP;
00433
00434 QString fqDomainName;
00435
00436
00437
int useExplicitDomainName = 0;
00438
if (!config.readEntry(
"explicitDomainName").isEmpty())
00439 useExplicitDomainName = 1;
00440
00441
00442
if (!useExplicitDomainName && getenv (
"MAILDOMAIN"))
00443 useExplicitDomainName = 2;
00444
00445
#ifdef DEBUG
00446
DEBUGCONDUIT << fname <<
": EDN=" << config.readEntry(
"explicitDomainName") << endl;
00447 DEBUGCONDUIT << fname <<
": useEDN=" << useExplicitDomainName << endl;
00448
#endif
00449
00450
if (useExplicitDomainName > 0) {
00451
00452
00453
if (useExplicitDomainName == 2) {
00454 fqDomainName =
"$MAILDOMAIN";
00455 }
else {
00456
00457
00458 fqDomainName = config.readEntry(
"explicitDomainName", CSL1(
"$MAILDOMAIN"));
00459
#ifdef DEBUG
00460
DEBUGCONDUIT << fname <<
": got from config" << endl;
00461
#endif
00462
}
00463
00464
00465
if (fqDomainName.left(1) == CSL1(
"$")) {
00466 QString envVar = fqDomainName.mid (1);
00467
char* envDomain = getenv (envVar.latin1());
00468
if (envDomain) {
00469 fqDomainName = envDomain;
00470
#ifdef DEBUG
00471
DEBUGCONDUIT << fname <<
": got from env" << endl;
00472
#endif
00473
}
else {
00474
00475 useExplicitDomainName =
false;
00476
00477
#ifdef DEBUG
00478
DEBUGCONDUIT << fname <<
": Promised domain name environment variable "
00479 << fqDomainName <<
" wasn't available." << endl;
00480
#endif
00481
}
00482 }
00483 }
00484
00485
if (useExplicitDomainName == 0) {
00486
00487
00488
struct utsname u;
00489 uname (&u);
00490 fqDomainName = u.nodename;
00491
00492
#ifdef DEBUG
00493
DEBUGCONDUIT << fname
00494 <<
": Got uname.nodename "
00495 << u.nodename << endl;
00496
#endif
00497
}
00498
00499
return fqDomainName;
00500 }
00501
00502
00503 QString extractAddress (
const QString& address) {
00504
int pos = address.find (QRegExp (CSL1(
"<.+>")));
00505
if (pos != -1) {
00506
return address.mid (pos+1, address.find (CSL1(
">"), pos)-pos-1);
00507 }
else
00508
return address;
00509 }
00510
00511 QString buildRFC822Headers (
const QString& sender,
00512
const struct Mail& theMail,
00513
const PopMailConduit&)
00514 {
00515 FUNCTIONSETUP;
00516
00517 QString buffer;
00518 QTextOStream bufs (&buffer);
00519
00520 bufs <<
"From: " << sender <<
"\r\n";
00521 bufs <<
"To: " << theMail.to <<
"\r\n";
00522
if (theMail.cc)
00523 bufs <<
"Cc: " << theMail.cc <<
"\r\n";
00524
if (theMail.bcc)
00525 bufs <<
"Bcc: " << theMail.bcc <<
"\r\n";
00526
if (theMail.replyTo)
00527 bufs <<
"Reply-To: " << theMail.replyTo <<
"\r\n";
00528
if (theMail.subject)
00529 bufs <<
"Subject: " << theMail.subject <<
"\r\n";
00530 bufs <<
"X-mailer: " <<
"Popmail-Conduit " << KPILOT_VERSION <<
"\r\n\r\n";
00531
00532
return buffer;
00533 }
00534
00535
int sendSMTPCommand (KSocket& kSocket,
00536
const QString& sendBuffer,
00537 QTextOStream& logStream,
00538
const QString& logBuffer,
00539
const QRegExp& expect,
00540
const QString& errormsg)
00541 {
00542 FUNCTIONSETUP;
00543
00544
00545 logStream <<
">>> " << sendBuffer;
00546 write (kSocket.socket(), sendBuffer.latin1(), sendBuffer.length());
00547
00548
00549 QByteArray response (1024);
00550
int ret;
00551 ret = getResponse (&kSocket, response.data(), response.size());
00552 logStream <<
"<<< " << (
const char*) response;
00553
00554
00555
if (QString(response).find (expect) == -1) {
00556 QString msg;
00557 msg = errormsg +
00558 i18n(
"\n\nPOPMail conduit sent to SMTP server:\n") +
00559 sendBuffer +
00560 i18n(
"\nSMTP server responded with:\n") +
00561 QString(response);
00562
00563 showMessage (msg);
00564
00565 kdWarning() << k_funcinfo <<
": SMTP error: " << msg << endl;
00566
#ifdef DEBUG
00567
DEBUGCONDUIT << fname <<
": SMTP error: " << logBuffer << endl;
00568
#endif
00569
00570
return -1;
00571 }
00572
00573
return 0;
00574 }
00575
00576
00577
int PopMailConduit::sendViaSMTP ()
00578 {
00579 FUNCTIONSETUP;
00580 QString smtpSrv;
00581
int smtpPort = 25;
00582
int handledCount = 0;
00583
int current = 0;
00584 PilotRecord* pilotRec;
00585
struct Mail theMail;
00586 QCString currentDest, msg;
00587 QString sendBuffer;
00588
int ret;
00589 QByteArray recvBuffer (1024);
00590 QString domainName;
00591 QString logBuffer;
00592 QTextOStream logStream (&logBuffer);
00593
00594
00595 smtpSrv = fConfig->readEntry (
"SMTPServer", CSL1(
"localhost"));
00596 smtpPort = fConfig->readNumEntry (
"SMTPPort", 25);
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 domainName = getFQDomainName (*fConfig);
00608
00609
#ifdef DEBUG
00610
DEBUGCONDUIT << fname <<
": " << domainName << endl;
00611
#endif
00612
00613
00614
00615
00616
00617
00618
#ifdef DEBUG
00619
DEBUGCONDUIT << fname <<
": Connecting to SMTP server "
00620 << smtpSrv <<
" on port " << smtpPort << endl;
00621
#endif
00622
00623
00624
00625
00626
00627
00628
00629 KSocket kSocket (smtpSrv.latin1(), smtpPort);
00630
if (kSocket.socket() < 0) {
00631 showMessage (i18n(
"Cannot connect to SMTP server"));
00632
return -1;
00633 }
00634 kSocket.enableRead (
true);
00635 kSocket.enableWrite (
true);
00636
00637
00638
00639
00640
00641
00642 ret = getResponse (&kSocket, recvBuffer.data(), recvBuffer.size());
00643
00644
00645
if (ret<0 || QString(recvBuffer).find(CSL1(
"220")) == -1) {
00646 showMessage (i18n(
"SMTP server failed to announce itself")+
00647 CSL1(
"\n\n")+logBuffer);
00648
return -1;
00649 }
00650
00651
00652 sendBuffer.sprintf (
"EHLO %s\r\n", domainName.latin1());
00653
if (sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00654 QRegExp(CSL1(
"^250")),
00655 i18n(
"Couldn't EHLO to SMTP server")))
00656
return -1;
00657
00658
00659
00660
00661
00662
00663
00664
for (current=0, handledCount=0; ; current++) {
00665
00666
00667 pilotRec = fDatabase->
readNextRecInCategory (1);
00668
if (pilotRec == 0L)
00669
break;
00670
00671
00672
if ((pilotRec->getAttrib() & dlpRecAttrDeleted)
00673 || (pilotRec->getAttrib() & dlpRecAttrArchived)) {
00674
delete pilotRec;
00675
continue;
00676 }
00677
00678
00679 handledCount++;
00680
00681
00682 unpack_Mail (&theMail, (
unsigned char*)pilotRec->getData(),
00683 pilotRec->getLen());
00684 currentDest =
"Mailing: ";
00685 currentDest += theMail.to;
00686
00687
00688 QString sender = fConfig->readEntry(
"EmailAddress");
00689 QString fromAddress = extractAddress (sender);
00690 fromAddress.replace (QRegExp(CSL1(
"\\s")), QString::null);
00691
00692
00693 sendBuffer.sprintf (
"MAIL FROM: <%s>\r\n", fromAddress.latin1());
00694
if (sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00695 QRegExp(CSL1(
"^250")),
00696 i18n(
"Couldn't start sending new mail.")))
00697 {
00698
return handledCount;
00699 }
00700
00701
00702
00703
00704
00705
00706 QCString recipients = theMail.to;
00707
if (QCString(theMail.cc).length()>1)
00708 recipients += QCString(
",") + QCString (theMail.cc);
00709
if (QCString(theMail.bcc).length()>1)
00710 recipients += QCString(
",") + QCString (theMail.bcc);
00711 recipients.replace (QRegExp(CSL1(
"\\s")),
"");
00712
00713
00714
int rpos=0;
00715
int nextComma=0;
00716
for (rpos=0; rpos<int(recipients.length());) {
00717 QCString recipient;
00718
00719 nextComma = recipients.find (
',', rpos);
00720
if (nextComma > rpos) {
00721 recipient = recipients.mid (rpos, nextComma-rpos);
00722 rpos = nextComma+1;
00723 }
else {
00724 recipient = recipients.mid (rpos);
00725 rpos = recipients.length();
00726 }
00727
00728
00729 sendBuffer.sprintf (
"RCPT TO: <%s>\r\n", recipient.data());
00730
if (sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00731 QRegExp(CSL1(
"^25")),
00732 i18n(
"The recipient doesn't exist!")))
00733
return handledCount;
00734 }
00735
00736
00737 sendBuffer.sprintf(
"DATA\r\n");
00738
if (sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00739 QRegExp(CSL1(
"^354")),
00740 i18n(
"Unable to start writing mail body\n")))
00741
return handledCount;
00742
00743
00744 sendBuffer = buildRFC822Headers (sender, theMail, *
this);
00745 write (kSocket.socket(), sendBuffer.latin1(), sendBuffer.length());
00746
00747
00748
if (theMail.body) {
00749 sendBuffer = QString::fromLatin1 (theMail.body)+CSL1(
"\r\n");
00750 write (kSocket.socket(), sendBuffer.latin1(), sendBuffer.length());
00751 }
00752
00753
00754
if (!fConfig->readPathEntry (
"Signature").isEmpty()) {
00755 QFile f (fConfig->readPathEntry (
"Signature"));
00756
if ( f.open (IO_ReadOnly) ) {
00757 sendBuffer.sprintf (
"\r\n-- \r\n");
00758 write (kSocket.socket(), sendBuffer.latin1(), sendBuffer.length());
00759
00760
00761 QTextStream t ( &f );
00762
while ( !t.eof() ) {
00763 sendBuffer.sprintf (
"%s\r\n", t.readLine().latin1());
00764 write (kSocket.socket(), sendBuffer.latin1(), sendBuffer.length());
00765 }
00766 f.close ();
00767 }
00768 }
00769
00770
00771 sendBuffer.sprintf(
".\r\n");
00772
if (sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00773 QRegExp(CSL1(
"^250")),
00774 i18n(
"Unable to send message")))
00775
return -1;
00776
00777
00778 pilotRec->setCat (3);
00779 pilotRec->setAttrib (pilotRec->getAttrib() & ~dlpRecAttrDirty);
00780 fDatabase->
writeRecord (pilotRec);
00781
delete pilotRec;
00782
00783
00784 free_Mail (&theMail);
00785 }
00786
00787 sendBuffer.sprintf(
"QUIT\r\n");
00788 sendSMTPCommand (kSocket, sendBuffer, logStream, logBuffer,
00789 QRegExp(CSL1(
"^221")),
00790 i18n(
"QUIT command to SMTP server failed.\n"));
00791
00792
return handledCount;
00793 }
00794
00795
00796
00798
00799
00800
00801
00802
00804
00805
int PopMailConduit::sendViaSendmail()
00806 {
00807 FUNCTIONSETUP;
00808
int count=0;
00809
00810
int i = 0;
00811
struct Mail theMail;
00812 QString sendmailCmd;
00813 QString currentDest;
00814 PilotRecord* pilotRec;
00815
00816 sendmailCmd = fConfig->readPathEntry(
"SendmailCmd");
00817
00818
00819
00820
for(i = 0;i<100; i++)
00821 {
00822 FILE* sendf;
00823
00824
#ifdef DEBUG
00825
{
00826 DEBUGCONDUIT << fname <<
": Reading " << i <<
"th message" << endl;
00827 }
00828
#endif
00829
pilotRec = fDatabase->
readNextRecInCategory(1);
00830
if(pilotRec == 0L)
00831 {
00832
#ifdef DEBUG
00833
DEBUGCONDUIT << fname <<
": Got a NULL record from "
00834
"readNextRecord" << endl;
00835
#endif
00836
break;
00837 }
00838
if((pilotRec->getAttrib() & dlpRecAttrDeleted)
00839 || (pilotRec->getAttrib() & dlpRecAttrArchived))
00840 {
00841
#ifdef DEBUG
00842
{
00843 DEBUGCONDUIT << fname <<
": Skipping deleted record." << endl;
00844 }
00845
#endif
00846
delete pilotRec;
00847 }
00848
else
00849 {
00850 unpack_Mail(&theMail, (
unsigned char*)pilotRec->getData()
00851 , pilotRec->getLen());
00852 sendf = popen(sendmailCmd.latin1(),
"w");
00853
if(!sendf)
00854 {
00855 KMessageBox::error(0L, TODO_I18N(
"Cannot talk to sendmail!"),
00856 TODO_I18N(
"Error Sending Mail"));
00857 kdWarning() << k_funcinfo
00858 <<
": Could not start sendmail." << endl;
00859 kdWarning() << k_funcinfo <<
": " << count
00860 <<
" messages sent OK"
00861 << endl ;
00862
return -1;
00863 }
00864
00865 currentDest = CSL1(
"Mailing: ");
00866 currentDest += PilotAppCategory::codec()->toUnicode(theMail.to);
00867 writeMessageToFile(sendf, theMail);
00868 pclose(sendf);
00869
00870 pilotRec->setCat(3);
00871 pilotRec->setAttrib(pilotRec->getAttrib() & ~dlpRecAttrDirty);
00872 fDatabase->
writeRecord(pilotRec);
00873
delete pilotRec;
00874
00875 free_Mail(&theMail);
00876 count++;
00877 }
00878 }
00879
00880
00881
#ifdef DEBUG
00882
{
00883 DEBUGCONDUIT << fname <<
": Sent " << count <<
" messages"
00884 << endl;
00885 }
00886
#endif
00887
00888
return count;
00889 }
00890
00891
00892
00893
00894 QString PopMailConduit::getKMailOutbox()
const
00895
{
00896 FUNCTIONSETUP;
00897
00898
00899
00900
00901
00902
00903 KSimpleConfig c(CSL1(
"kmailrc"),
true);
00904 c.setGroup(
"General");
00905
00906 QString outbox = c.readEntry(
"outboxFolder");
00907
if (outbox.isEmpty())
00908 {
00909 KConfigGroupSaver gs(fConfig,PopMailConduitFactory::group());
00910 outbox = fConfig->readEntry(
"outboxFolder");
00911 }
00912
00913
if (outbox.isEmpty()) outbox=CSL1(
"outbox");
00914
00915
return outbox;
00916 }
00917
00918
00919
00920
00921
00922
int PopMailConduit::sendViaKMail()
00923 {
00924 FUNCTIONSETUP;
00925
int count=0;
00926
bool sendImmediate =
true;
00927 QString kmailOutboxName = getKMailOutbox();
00928
00929 sendImmediate = fConfig->readBoolEntry(
"SendImmediate",
true);
00930
00931 DCOPClient *dcopptr = KApplication::kApplication()->
00932 dcopClient();
00933
if (!dcopptr)
00934 {
00935 kdWarning() << k_funcinfo
00936 <<
": Can't get DCOP client."
00937 << endl;
00938 KMessageBox::error(0L,
00939 i18n(
"Couldn't connect to DCOP server for "
00940
"the KMail connection."),
00941 i18n(
"Error Sending Mail"));
00942
return -1;
00943 }
00944
00945 dcopptr->attach();
00946
while (PilotRecord *pilotRec = fDatabase->
readNextRecInCategory(1))
00947 {
00948
#ifdef DEBUG
00949
DEBUGCONDUIT << fname
00950 <<
": Reading "
00951 << count + 1
00952 <<
"th message"
00953 << endl;
00954
#endif
00955
00956
if (pilotRec->isDeleted() || pilotRec->isArchived())
00957 {
00958
#ifdef DEBUG
00959
DEBUGCONDUIT << fname
00960 <<
": Skipping record."
00961 << endl;
00962
#endif
00963
continue;
00964 }
00965
00966
struct Mail theMail;
00967 KTempFile t;
00968 t.setAutoDelete(
true);
00969
00970
if (t.status())
00971 {
00972 kdWarning() << k_funcinfo
00973 <<
": Can't open temp file."
00974 << endl;
00975 KMessageBox::error(0L,
00976 i18n(
"Cannot open temporary file to store "
00977
"mail from Pilot in."),
00978 i18n(
"Error Sending Mail"));
00979
continue;
00980 }
00981
00982 FILE *sendf = t.fstream();
00983
00984
if (!sendf)
00985 {
00986 kdWarning() << k_funcinfo
00987 <<
": Can't open temporary file for writing!"
00988 << endl;
00989 KMessageBox::error(0L,
00990 i18n(
"Cannot open temporary file to store "
00991
"mail from Pilot in."),
00992 i18n(
"Error Sending Mail"));
00993
continue;
00994 }
00995
00996 unpack_Mail(&theMail,
00997 (
unsigned char*)pilotRec->getData(),
00998 pilotRec->getLen());
00999 writeMessageToFile(sendf, theMail);
01000
01001
01002 QByteArray data,returnValue;
01003 QCString returnType;
01004 QDataStream arg(data,IO_WriteOnly);
01005
01006 arg << kmailOutboxName
01007 << t.name();
01008
01009
if (!dcopptr->call(
"kmail",
01010
"KMailIface",
01011
"dcopAddMessage(QString,QString)",
01012 data,
01013 returnType,
01014 returnValue,
01015
true))
01016 {
01017 kdWarning() << k_funcinfo
01018 <<
": DCOP call failed."
01019 << endl;
01020
01021 KMessageBox::error(0L,
01022 i18n(
"DCOP connection with KMail failed."),
01023 i18n(
"Error Sending Mail"));
01024
continue;
01025 }
01026
01027
#ifdef DEBUG
01028
DEBUGCONDUIT << fname
01029 <<
": DCOP call returned "
01030 << returnType
01031 <<
" of "
01032 << (
const char *)returnValue
01033 << endl;
01034
#endif
01035
01036
01037 pilotRec->setCat(3);
01038 pilotRec->setAttrib(pilotRec->getAttrib() & ~dlpRecAttrDirty);
01039 fDatabase->
writeRecord(pilotRec);
01040
delete pilotRec;
01041
01042 free_Mail(&theMail);
01043
01044 count++;
01045 }
01046
01047
if ((count > 0) && sendImmediate)
01048 {
01049 QByteArray data;
01050
if (dcopptr->send(
"kmail",
"KMailIface",
"sendQueued",data))
01051 {
01052 kdWarning() << k_funcinfo
01053 <<
": Couldn't flush queue."
01054 << endl;
01055 }
01056 }
01057
01058
return count;
01059 }
01060
01061
01062
01063
01064
void
01065 PopMailConduit::writeMessageToFile(FILE* sendf,
struct Mail& theMail)
01066 {
01067 FUNCTIONSETUP;
01068
01069 QTextStream mailPipe(sendf, IO_WriteOnly);
01070
01071 QString fromAddress = fConfig->readEntry(
"EmailAddress");
01072 mailPipe <<
"From: " << fromAddress <<
"\r\n";
01073 mailPipe <<
"To: " << theMail.to <<
"\r\n";
01074
if(theMail.cc)
01075 mailPipe <<
"Cc: " << theMail.cc <<
"\r\n";
01076
if(theMail.bcc)
01077 mailPipe <<
"Bcc: " << theMail.bcc <<
"\r\n";
01078
if(theMail.replyTo)
01079 mailPipe <<
"Reply-To: " << theMail.replyTo <<
"\r\n";
01080
if(theMail.subject)
01081 mailPipe <<
"Subject: " << theMail.subject <<
"\r\n";
01082 mailPipe <<
"X-mailer: " <<
"Popmail-Conduit " << KPILOT_VERSION <<
"\r\n";
01083 mailPipe <<
"\r\n";
01084
01085
01086
#ifdef DEBUG
01087
{
01088 DEBUGCONDUIT << fname <<
": To: " << theMail.to << endl;
01089 }
01090
#endif
01091
01092
01093
if(theMail.body)
01094 {
01095
#ifdef DEBUG
01096
{
01097 DEBUGCONDUIT << fname <<
": Sent body." << endl;
01098 }
01099
#endif
01100
mailPipe << theMail.body <<
"\r\n";
01101 }
01102
01103
01104
if(!fConfig->readPathEntry(
"Signature").isEmpty()) {
01105
#ifdef DEBUG
01106
{
01107 DEBUGCONDUIT << fname <<
": Reading signature" << endl;
01108 }
01109
#endif
01110
01111 QFile f(fConfig->readPathEntry(
"Signature"));
01112
if ( f.open(IO_ReadOnly) ) {
01113 mailPipe <<
"-- \r\n";
01114 QTextStream t( &f );
01115
while ( !t.eof() ) {
01116 mailPipe << t.readLine() <<
"\r\n";
01117 }
01118 f.close();
01119 }
01120 }
01121 mailPipe <<
"\r\n";
01122
01123
#ifdef DEBUG
01124
{
01125 DEBUGCONDUIT << fname <<
": Done" << endl;
01126 }
01127
#endif
01128
}
01129
01130
char*
01131 PopMailConduit::skipspace(
char * c)
01132 {
01133
while (c && ((*c ==
' ') || (*c ==
'\t')))
01134 c++;
01135
return c;
01136 }
01137
01138
int
01139 PopMailConduit::getpopchar(
int socket)
01140 {
01141
unsigned char buf;
01142
int ret;
01143
do
01144 {
01145
do
01146 ret=read(socket, &buf, 1);
01147
while ((ret==-1) && (errno==EAGAIN));
01148
if (ret < 0)
01149
return ret;
01150 }
while ((ret==0) || (buf ==
'\r'));
01151
01152
return buf;
01153 }
01154
01155
int
01156 PopMailConduit::getpopstring(
int socket,
char * buf)
01157 {
01158
int c;
01159
while ((c = getpopchar(socket)) >= 0)
01160 {
01161 *buf++ = c;
01162
if (c ==
'\n')
01163
break;
01164 }
01165 *buf =
'\0';
01166
return c;
01167 }
01168
01169
int
01170 PopMailConduit::getpopresult(
int socket,
char * buf)
01171 {
01172
int c = getpopstring(socket, buf);
01173
01174
if (c<0)
01175
return c;
01176
01177
if (buf[0] ==
'+')
01178
return 0;
01179
else
01180
return 1;
01181 }
01182
01183
void
01184 PopMailConduit::header(
struct Mail * m,
char * t)
01185 {
01186 FUNCTIONSETUP;
01187
01188
static char holding[4096];
01189
01190
if (t && strlen(t) && t[strlen(t)-1] ==
'\n')
01191 t[strlen(t)-1] = 0;
01192
if (t && ((t[0] ==
' ') || (t[0] ==
'\t')))
01193 {
01194
if ((strlen(t) + strlen(holding)) > 4096)
01195
return;
01196 strcat(holding, t+1);
01197
return;
01198 }
01199
01200
01201
01202
if (strncmp(holding,
"From:", 5)==0)
01203 {
01204 m->from = strdup(skipspace(holding+5));
01205 }
01206
else if (strncmp(holding,
"To:",3)==0)
01207 {
01208 m->to = strdup(skipspace(holding+3));
01209 }
01210
else if (strncmp(holding,
"Subject:",8)==0)
01211 {
01212 m->subject = strdup(skipspace(holding+8));
01213 }
01214
else if (strncmp(holding,
"Cc:",3)==0)
01215 {
01216 m->cc = strdup(skipspace(holding+3));
01217 }
01218
else if (strncmp(holding,
"Bcc:",4)==0)
01219 {
01220 m->bcc = strdup(skipspace(holding+4));
01221 }
01222
else if (strncmp(holding,
"Reply-To:",9)==0)
01223 {
01224 m->replyTo = strdup(skipspace(holding+9));
01225 }
01226
else if (strncmp(holding,
"Date:",4)==0)
01227 {
01228 time_t d = parsedate(skipspace(holding+5));
01229
if (d != -1)
01230 {
01231
struct tm * d2;
01232 m->dated = 1;
01233 d2 = localtime(&d);
01234 m->date = *d2;
01235 }
01236 }
01237 holding[0] = 0;
01238
if (t)
01239 strcpy(holding, t);
01240 }
01241
01242
void PopMailConduit::retrievePOPMessages(KSocket *popSocket,
int const msgcount,
01243
int const flags,
01244
char *buffer,
int const bufsiz)
01245 {
01246 FUNCTIONSETUP;
01247
int i,ret;
01248
01249
for(i=1;i<(msgcount+1);i++)
01250 {
01251
int len;
01252
char * msg;
01253
int h;
01254
struct Mail t;
01255 PilotRecord* pilotRec;
01256
01257 reset_Mail(&t);
01258
01259
01260
01261 sprintf(buffer,
"LIST %d\r\n", i);
01262 write(popSocket->socket(), buffer, strlen(buffer));
01263 ret=getPOPResponse(popSocket,
"LIST command failed",
01264 buffer,bufsiz);
01265
if (ret<0)
return;
01266
01267 sscanf(buffer+ret,
"%*s %*d %d", &len);
01268
01269
#ifdef DEBUG
01270
{
01271 DEBUGCONDUIT << fname
01272 <<
": Message " << i
01273 <<
" is " << len <<
" bytes long"
01274 << endl;
01275 }
01276
#endif
01277
01278
if (len > 16000)
01279 {
01280 kdWarning() << k_funcinfo
01281 <<
": Skipped long message " << i
01282 << endl;
01283
continue;
01284 }
01285
01286 sprintf(buffer,
"RETR %d\r\n", i);
01287 write(popSocket->socket(), buffer, strlen(buffer));
01288 ret = getpopstring(popSocket->socket(), buffer);
01289
if ((ret < 0) || (buffer[0] !=
'+'))
01290 {
01291
01292
continue;
01293 }
01294
else
01295 {
01296 buffer[ret] = 0;
01297 }
01298
01299 msg = (
char*)buffer;
01300 h = 1;
01301
for(;;)
01302 {
01303
if (getpopstring(popSocket->socket(), msg) < 0)
01304 {
01305 showMessage(i18n(
"Error reading message"));
01306
return;
01307 }
01308
01309
if (h == 1)
01310 {
01311
01312
if ((msg[0] ==
'.') &&
01313 (msg[1] ==
'\n') && (msg[2] == 0))
01314 {
01315
break;
01316 }
01317
if (msg[0] ==
'\n')
01318 {
01319 h = 0;
01320 header(&t, 0);
01321 }
01322
else
01323 {
01324 header(&t, msg);
01325 }
01326
continue;
01327 }
01328
if ((msg[0] ==
'.') &&
01329 (msg[1] ==
'\n') && (msg[2] == 0))
01330 {
01331 msg[0] = 0;
01332
break;
01333 }
01334
if (msg[0] ==
'.')
01335 {
01336
01337 memmove(msg, msg+1, strlen(msg));
01338 }
01339 msg += strlen(msg);
01340 }
01341
01342
01343
01344
01345
if (h)
01346 {
01347
01348
01349
01350 free_Mail(&t);
01351
continue;
01352 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 t.body = strdup(buffer);
01364
01365 len = pack_Mail(&t, (
unsigned char*)buffer, 0xffff);
01366 pilotRec =
new PilotRecord(buffer, len, 0, 0, 0);
01367
if (fDatabase->
writeRecord(pilotRec) > 0)
01368 {
01369
if (flags & POP_DELE)
01370 {
01371 sprintf(buffer,
"DELE %d\r\n", i);
01372 write(popSocket->socket(),
01373 buffer, strlen(buffer));
01374 getPOPResponse(popSocket,
01375
"Error deleting message",
01376 buffer,bufsiz);
01377
01378 }
01379 }
01380
else
01381 {
01382 showMessage(
01383 i18n(
"Error writing message to the Pilot."));
01384 }
01385
01386
delete pilotRec;
01387
01388 free_Mail(&t);
01389 }
01390
01391 }
01392
01393
01394
01395
int PopMailConduit::doPopQuery()
01396 {
01397 FUNCTIONSETUP;
01398
01399 KSocket* popSocket;
01400
char buffer[0xffff];
01401
int offset;
01402
int flags=0;
01403
int msgcount;
01404
01405
01406
01407
01408
01409
01410
if (fConfig->readNumEntry(
"LeaveMail") == 0)
01411 {
01412 flags |= POP_DELE ;
01413 }
01414
01415 popSocket =
new KSocket(fConfig->readEntry(
"PopServer").latin1(),
01416 fConfig->readNumEntry(
"PopPort"));
01417 Q_CHECK_PTR(popSocket);
01418
01419
#ifdef DEBUG
01420
{
01421 DEBUGCONDUIT << fname
01422 <<
": Attempted to connect to POP3 server "
01423 << fConfig->readEntry(
"PopServer")
01424 << endl;
01425 }
01426
#endif
01427
01428
if(popSocket->socket() < 0)
01429 {
01430 showResponseResult(PERROR,
01431
"Cannot connect to POP server -- no socket",
01432 0L,
"doPopQuery");
01433
delete popSocket;
01434
return -1;
01435 }
01436
01437
01438
01439 popSocket->enableRead(
true);
01440 popSocket->enableWrite(
true);
01441
01442
#ifdef DEBUG
01443
{
01444 DEBUGCONDUIT << fname
01445 <<
": Connected to POP3 server socket "
01446 << popSocket->socket()
01447 << endl ;
01448 }
01449
#endif
01450
01451
01452
01453
01454
01455
01456
if (getPOPResponse(popSocket,
"POP server failed to announce itself",
01457 buffer,1024)<0)
01458 {
01459
delete popSocket;
01460
return -1;
01461 }
01462
01463
01464 sprintf(buffer,
"USER %s\r\n", fConfig->readEntry(
"PopUser").latin1());
01465 write(popSocket->socket(), buffer, strlen(buffer));
01466
if (getPOPResponse(popSocket,
"USER command to POP server failed",
01467 buffer,1024)<0)
01468 {
01469
delete popSocket;
01470
return -1;
01471 }
01472
01473
if(fConfig->readNumEntry(
"StorePass", 0))
01474 {
01475
#ifdef DEBUG
01476
{
01477 DEBUGCONDUIT << fname
01478 <<
": Reading password from config."
01479 << endl;
01480 }
01481
#endif
01482
01483 sprintf(buffer,
"PASS %s\r\n",
01484 fConfig->readEntry(
"PopPass").latin1());
01485 }
01486
else
01487 {
01488
01489
01490
01491 PasswordDialog* passDialog =
new PasswordDialog(
01492 i18n(
"Please enter your POP password:"),
01493 0L,
"PopPassword",
true);
01494 passDialog->show();
01495
if (passDialog->result()==QDialog::Accepted)
01496 {
01497 sprintf(buffer,
"PASS %s\r\n", passDialog->password());
01498
delete passDialog;
01499 }
01500
else
01501 {
01502
#ifdef DEBUG
01503
DEBUGCONDUIT << fname
01504 <<
": Password dialog was canceled."
01505 << endl;
01506
#endif
01507
delete passDialog;
01508 disconnectPOP(popSocket);
01509
delete popSocket;
01510
return -1;
01511 }
01512 }
01513
01514
01515
01516 write(popSocket->socket(), buffer, strlen(buffer));
01517
if (getPOPResponse(popSocket,
"PASS command to POP server failed",
01518 buffer,1024)<0)
01519 {
01520 disconnectPOP(popSocket);
01521
delete popSocket;
01522
return -1;
01523 }
01524
01525
01526 sprintf(buffer,
"STAT\r\n");
01527 write(popSocket->socket(), buffer, strlen(buffer));
01528
if ((offset=getPOPResponse(popSocket,
01529
"STAT command to POP server failed",
01530 buffer,1024))<0)
01531 {
01532 disconnectPOP(popSocket);
01533
delete popSocket;
01534
return -1;
01535 }
01536
01537
01538
01539
01540
01541
01542
01543 QString msg(QString::fromLatin1(buffer+offset));
01544
if (msg.find( fConfig->readEntry(
"PopUser")) != -1)
01545 {
01546 sscanf(buffer+offset,
"%*s %*s %*s %d %*s", &msgcount);
01547 }
01548
else
01549 {
01550 sscanf(buffer+offset,
"%*s %d %*s", &msgcount);
01551 }
01552
01553
#ifdef DEBUG
01554
{
01555 DEBUGCONDUIT << fname
01556 <<
": POP STAT is "
01557 << buffer+offset
01558 << endl;
01559 DEBUGCONDUIT << fname
01560 <<
": Will retrieve "
01561 << msgcount <<
" messages."
01562 << endl;
01563 }
01564
#endif
01565
01566
if(msgcount < 1)
01567 {
01568
01569 disconnectPOP(popSocket);
01570
delete popSocket;
01571
return 0;
01572 }
01573
01574
01575
01576 retrievePOPMessages(popSocket,msgcount,flags,buffer,1024);
01577
01578 disconnectPOP(popSocket);
01579
delete popSocket;
01580
01581
return msgcount;
01582 }
01583
01584
01585
01586
int PopMailConduit::skipBlanks(FILE *f,
char *buffer,
int buffersize)
01587 {
01588 FUNCTIONSETUP;
01589
01590
char *s;
01591
int count=0;
01592
01593
while (!feof(f))
01594 {
01595
if (fgets(buffer,buffersize,f)==0L)
break;
01596
#ifdef DEBUG
01597
{
01598 DEBUGCONDUIT << fname <<
": Got line " << buffer ;
01599 }
01600
#endif
01601
01602 s=buffer;
01603
while (isspace(*s)) s++;
01604
if (*s)
return count;
01605
01606
01607
01608 count++;
01609 }
01610
01611
01612
01613
01614 *buffer=0;
01615
return count;
01616 }
01617
#define LINESIZE (800)
01618
int PopMailConduit::readHeaders(FILE *f,
01619
char *buf,
int bufsiz,
01620
struct Mail *t,
01621
int expectFrom)
01622 {
01623 FUNCTIONSETUP;
01624
01625
char line[LINESIZE];
01626
int count=0;
01627
01628
01629
01630
01631
01632
01633
if (expectFrom)
01634 {
01635
#ifdef DEBUG
01636
{
01637 DEBUGCONDUIT << fname <<
": Looking for From line." << endl;
01638 }
01639
#endif
01640
01641 skipBlanks(f,line,LINESIZE);
01642
if (strncmp(line,
"From ",5))
01643 {
01644 kdWarning() << k_funcinfo
01645 <<
": No leading From line." << endl;
01646
return 0;
01647 }
01648
01649
#ifdef DEBUG
01650
{
01651 DEBUGCONDUIT << fname <<
": Found it." << endl;
01652 }
01653
#endif
01654
}
01655
01656
while ((skipBlanks(f,line,LINESIZE)==0) && !feof(f))
01657 {
01658
if ((line[0]==
'.') && (line[1]==
'\n') && (line[2] == 0))
01659 {
01660
#ifdef DEBUG
01661
{
01662 DEBUGCONDUIT << fname <<
": Found end-of-headers "
01663
"and end-of-message."
01664 << endl;
01665 }
01666
#endif
01667
01668
return -count;
01669 }
01670
01671
01672
01673
01674
01675
01676
if (line[0]==
'\n')
01677 {
01678
#ifdef DEBUG
01679
{
01680 DEBUGCONDUIT << fname <<
": Found end-of-headers"
01681 << endl;
01682 }
01683
#endif
01684
01685 header(t,0);
01686
return count;
01687 }
01688
01689 header(t,line);
01690 count++;
01691 }
01692
01693
#ifdef DEBUG
01694
{
01695 DEBUGCONDUIT << fname <<
": Read " << count <<
" lines." << endl;
01696 }
01697
#endif
01698
strncpy(buf,line,bufsiz);
01699
return count;
01700 }
01701
01702
01703
int PopMailConduit::readBody(FILE *f,
char *buf,
int bufsize)
01704 {
01705 FUNCTIONSETUP;
01706
int count=0;
01707
int linelen=0;
01708
01709
#ifdef DEBUG
01710
{
01711 DEBUGCONDUIT << fname <<
": Buffer @" << (
int) buf << endl;
01712 }
01713
#endif
01714
01715
while(!feof(f) && (bufsize > 80))
01716 {
01717
if (fgets(buf,bufsize,f)==0)
01718 {
01719
01720
01721
01722
01723
return count;
01724 }
01725
01726
#ifdef DEBUG
01727
{
01728 DEBUGCONDUIT << fname <<
": Got line ["
01729 << (
int) buf[0] <<
',' << (
int) buf[1]
01730 <<
']'
01731 << buf;
01732 }
01733
#endif
01734
01735
if ((buf[0]==
'.') && ((buf[1]==
'\n') || (buf[1]==
'\r')))
01736 {
01737
01738
01739
01740
return count;
01741 }
01742
01743 count++;
01744
if (buf[0]==
'.')
01745 {
01746
01747
01748
01749 memmove(buf+1,buf,strlen(buf));
01750 }
01751
01752
01753 linelen=strlen(buf);
01754 buf+=linelen;
01755 bufsize-=linelen;
01756 }
01757
01758
return count;
01759 }
01760
01761
#undef LINESIZE
01762
01763 PilotRecord *PopMailConduit::readMessage(FILE *mailbox,
01764
char *buffer,
int bufferSize)
01765 {
01766 FUNCTIONSETUP;
01767
01768
struct Mail t;
01769
int messageLength=0;
01770
int len;
01771 PilotRecord* pilotRec=0L;
01772
01773 reset_Mail(&t);
01774
01775
01776
01777 messageLength=readHeaders(mailbox,buffer,bufferSize,&t,1);
01778
if (messageLength == 0)
01779 {
01780 kdWarning() << k_funcinfo
01781 <<
": Bad headers in message." << endl;
01782
return 0;
01783 }
01784
01785
01786
if (messageLength>0)
01787 {
01788 messageLength=strlen(buffer);
01789
#ifdef DEBUG
01790
{
01791 DEBUGCONDUIT << fname <<
": Message so far:" << endl
01792 << buffer << endl;
01793 DEBUGCONDUIT << fname <<
": Length "
01794 << messageLength << endl;
01795 DEBUGCONDUIT << fname <<
": Buffer @" << (
int) buffer
01796 << endl;
01797 }
01798
#endif
01799
01800
if (readBody(mailbox,
01801 buffer+messageLength,
01802 bufferSize-messageLength) < 0)
01803 {
01804 kdWarning() << k_funcinfo
01805 <<
": Bad body for message." << endl;
01806
return 0;
01807 }
01808 }
01809
else
01810 {
01811
01812
01813 }
01814
01815 t.body = strdup(buffer);
01816
01817 len = pack_Mail(&t, (
unsigned char*)buffer, bufferSize);
01818 pilotRec =
new PilotRecord(buffer, len, 0, 0, 0);
01819 free_Mail(&t);
01820
01821
return pilotRec;
01822 }
01823
01824
01825
#define BUFFERSIZE (12000)
01826
int PopMailConduit::doUnixStyle()
01827 {
01828 FUNCTIONSETUP;
01829 QString filename;
01830 FILE *mailbox;
01831
01832
01833
01834
01835
01836
01837
01838
01839
char *buffer=
new char[BUFFERSIZE];
01840
int messageCount=0;
01841
01842 PilotRecord *pilotRec=0L;
01843
01844 {
01845 filename=fConfig->readEntry(
"UNIX Mailbox");
01846
if (filename.isEmpty())
return 0;
01847
01848
#ifdef DEBUG
01849
{
01850 DEBUGCONDUIT << fname <<
": Trying to read mailbox "
01851 << filename << endl;
01852 }
01853
#endif
01854
01855 QFileInfo info(filename);
01856
if (!info.exists())
01857 {
01858 kdWarning() << k_funcinfo
01859 <<
": Mailbox doesn't exist."
01860 << endl;
01861
return -1;
01862 }
01863
01864
#ifdef DEBUG
01865
{
01866 DEBUGCONDUIT << fname <<
": Mailbox found." << endl;
01867 }
01868
#endif
01869
01870 }
01871
01872 mailbox=fopen(filename.latin1(),
"r");
01873
if (mailbox==0L)
01874 {
01875 kdWarning() << k_funcinfo <<
": Can't open mailbox:"
01876 << perror
01877 << endl;
01878
return -1;
01879 }
01880
01881
while (!feof(mailbox))
01882 {
01883 pilotRec=readMessage(mailbox,buffer,BUFFERSIZE);
01884
if (pilotRec && fDatabase->
writeRecord(pilotRec)>0)
01885 {
01886 messageCount++;
01887
#ifdef DEBUG
01888
{
01889 DEBUGCONDUIT << fname <<
": Read message "
01890 << messageCount <<
" from mailbox."
01891 << endl;
01892 }
01893
#endif
01894
}
01895
else
01896 {
01897 kdWarning() << k_funcinfo <<
": Message "
01898 << messageCount <<
" couldn't be written."
01899 << endl;
01900 showMessage(i18n(
"Error writing mail message to Pilot"));
01901 }
01902
delete pilotRec;
01903 }
01904
01905
#ifdef DEBUG
01906
{
01907 DEBUGCONDUIT << fname <<
": Wrote "
01908 << messageCount
01909 <<
" messages to pilot."
01910 << endl;
01911 }
01912
#endif
01913
01914
return messageCount;
01915 }
01916
#undef BUFFERSIZE
01917
01918
void PopMailConduit::doTest()
01919 {
01920 FUNCTIONSETUP;
01921
01922
01923 QString outbox = getKMailOutbox();
01924
01925
#ifdef DEBUG
01926
DEBUGCONDUIT << fname
01927 <<
": KMail's outbox is "
01928 << outbox
01929 << endl;
01930
#endif
01931
}
01932
01933
bool PopMailConduit::exec()
01934 {
01935 FUNCTIONSETUP;
01936 DEBUGCONDUIT<<popmail_conduit_id<<endl;
01937
01938
if (!fConfig)
return false;
01939
01940 KConfigGroupSaver cfgs(fConfig,PopMailConduitFactory::group());
01941
01942 fDatabase=
new PilotSerialDatabase(pilotSocket(),
01943 CSL1(
"MailDB"),
this,
"MailDB");
01944
01945
if (!fDatabase || !fDatabase->
isDBOpen())
01946 {
01947 emit logError(i18n(
"Unable to open mail database on handheld"));
01948 KPILOT_DELETE(fDatabase);
01949
return false;
01950 }
01951
01952
if (isTest())
01953 {
01954 doTest();
01955 }
01956
else if (isBackup())
01957 {
01958 emit logError(TODO_I18N(
"Cannot perform backup on mail database"));
01959 }
01960
else
01961 {
01962 doSync();
01963 fDatabase->
resetSyncFlags();
01964 }
01965
01966 KPILOT_DELETE(fDatabase);
01967 emit syncDone(
this);
01968
return true;
01969 }