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