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 }