Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

popclient.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2001 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qt Palmtop Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 #include "popclient.h"
00021 #include "emailhandler.h"
00022 //#define APOP_TEST
00023 
00024 extern "C" {
00025 #include "md5.h"
00026 }
00027 
00028 #include <qcstring.h>
00029 
00030 PopClient::PopClient()
00031 {
00032 
00033   socket = new QSocket(this, "popClient");
00034   connect(socket, SIGNAL(error(int)), this, SLOT(errorHandling(int)));
00035   connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished()));
00036   connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData()));
00037 
00038   stream = new QTextStream(socket);
00039 
00040   receiving = FALSE;
00041   synchronize = FALSE;
00042   lastSync = 0;
00043   headerLimit = 0;
00044   mailList = 0;
00045   preview = FALSE;
00046 }
00047 
00048 PopClient::~PopClient()
00049 {
00050   delete socket;
00051   delete stream;
00052 }
00053 
00054 void PopClient::newConnection(const QString &target, int port)
00055 {
00056   if (receiving) {
00057     qWarning("socket in use, connection refused");
00058     return;
00059   }
00060 
00061   status = Init;
00062 
00063   socket->connectToHost(target, port);
00064   receiving = TRUE;
00065   //selected = FALSE;
00066 
00067   emit updateStatus(tr("DNS lookup"));
00068 }
00069 
00070 void PopClient::setAccount(const QString &popUser, const QString &popPasswd)
00071 {
00072   popUserName = popUser;
00073   popPassword = popPasswd;
00074 }
00075 
00076 void PopClient::setSynchronize(int lastCount)
00077 {
00078   synchronize = TRUE;
00079   lastSync = lastCount;
00080 }
00081 
00082 void PopClient::removeSynchronize()
00083 {
00084   synchronize = FALSE;
00085   lastSync = 0;
00086 }
00087 
00088 void PopClient::headersOnly(bool headers, int limit)
00089 {
00090   preview = headers;
00091   headerLimit = limit;
00092 }
00093 
00094 void PopClient::setSelectedMails(MailList *list)
00095 {
00096   selected = TRUE;
00097   mailList = list;
00098 }
00099 
00100 void PopClient::connectionEstablished()
00101 {
00102   emit updateStatus(tr("Connection established"));
00103 }
00104 
00105 void PopClient::errorHandling(int status)
00106 {
00107   errorHandlingWithMsg( status, QString::null );
00108 }
00109 void PopClient::errorHandlingWithMsg(int status, const QString & Msg )
00110 {
00111   emit updateStatus(tr("Error Occured"));
00112   emit errorOccurred(status, Msg);
00113   socket->close();
00114   receiving = FALSE;
00115 }
00116 
00117 void PopClient::incomingData()
00118 {
00119   QString response, temp, temp2, timeStamp;
00120   QString md5Source;
00121   int start, end;
00122 //  char *md5Digest;
00123   char md5Digest[16];
00124 //  if ( !socket->canReadLine() )
00125 //    return;
00126 
00127 
00128   response = socket->readLine();
00129 
00130   switch(status) {
00131     //logging in
00132     case Init:  {
00133 #ifdef APOP_TEST
00134        start = response.find('<',0);
00135        end = response.find('>', start);
00136        if( start >= 0 && end > start )
00137        {
00138           timeStamp = response.mid( start , end - start + 1);
00139           md5Source = timeStamp + popPassword;
00140 
00141           md5_buffer( (char const *)md5Source, md5Source.length(),&md5Digest[0]);
00142 
00143            for(int j =0;j < MD5_DIGEST_LENGTH ;j++)
00144            {
00145               printf("%x", md5Digest[j]);
00146            }
00147            printf("\n");
00148 //          qDebug(md5Digest);
00149           *stream << "APOP " <<  popUserName << " " << md5Digest << "\r\n";
00150           //    qDebug("%s", stream);
00151           status = Stat;
00152        }
00153        else
00154 #endif
00155        {
00156           timeStamp = "";
00157           *stream << "USER " << popUserName << "\r\n";
00158           status = Pass;
00159        }
00160 
00161         break;
00162         }
00163 
00164     case Pass:  {
00165           *stream << "PASS " << popPassword << "\r\n";
00166     status = Stat;
00167 
00168           break;
00169         }
00170     //ask for number of messages
00171     case Stat:  {
00172           if (response[0] == '+') {
00173             *stream << "STAT" << "\r\n";
00174             status = Mcnt;
00175           } else errorHandlingWithMsg(ErrLoginFailed, response);
00176             break;
00177           }
00178     //get count of messages, eg "+OK 4 900.." -> int 4
00179     case Mcnt:  {
00180           if (response[0] == '+') {
00181             temp = response.replace(0, 4, "");
00182             int x = temp.find(" ", 0);
00183             temp.truncate((uint) x);
00184             newMessages = temp.toInt();
00185             messageCount = 1;
00186             status = List;
00187 
00188             if (synchronize) {
00189               //messages deleted from server, reload all
00190                 if (newMessages < lastSync)
00191                   lastSync = 0;
00192                 messageCount = 1;
00193               }
00194 
00195             if (selected && mailList ) {
00196                 int *ptr = mailList->first();
00197                 if (ptr != 0) {
00198                   newMessages++;  //to ensure no early jumpout
00199                   messageCount = *ptr;
00200                 } else newMessages = 0;
00201         }
00202 
00203             } else errorHandlingWithMsg(ErrUnknownResponse, response);
00204           }
00205     //Read message number x, count upwards to messageCount
00206     case List:  {
00207           if (messageCount <= newMessages) {
00208             *stream << "LIST " << messageCount << "\r\n";
00209             status = Size;
00210             temp2.setNum(newMessages - lastSync);
00211             temp.setNum(messageCount - lastSync);
00212             if (!selected) {
00213               emit updateStatus(tr("Retrieving ") + temp + "/" + temp2);
00214             } else {
00215               //completing a previously closed transfer
00216              /* if ( (messageCount - lastSync) <= 0) {
00217                 temp.setNum(messageCount);
00218                 emit updateStatus(tr("Previous message ") + temp);
00219               } else {*/
00220                 emit updateStatus(tr("Completing message ") + temp);
00221               //}
00222             }
00223             break;
00224           } else {
00225             emit updateStatus(tr("No new Messages"));
00226             status = Quit;
00227           }
00228         }
00229     //get size of message, eg "500 characters in message.." -> int 500
00230     case Size:  {
00231           if (status != Quit) { //because of idiotic switch
00232             if (response[0] == '+') {
00233               temp = response.replace(0, 4, "");
00234               int x = temp.find(" ", 0);
00235               temp = temp.right(temp.length() - ((uint) x + 1) );
00236               mailSize = temp.toInt();
00237               emit currentMailSize(mailSize);
00238 
00239               status = Retr;
00240             } else {
00241               //qWarning(response);
00242               errorHandlingWithMsg(ErrUnknownResponse, response);
00243             }
00244           }
00245         }
00246     //Read message number x, count upwards to messageCount
00247     case Retr:  {
00248           if (status != Quit) {
00249             if ((selected)||(mailSize <= headerLimit))
00250       {
00251               *stream << "RETR " << messageCount << "\r\n";
00252             } else {        //only header
00253        *stream << "TOP " << messageCount << " 0\r\n";
00254             }
00255             messageCount++;
00256             status = Ignore;
00257             break;
00258           }         }
00259     case Ignore:  {
00260           if (status != Quit) { //because of idiotic switch
00261             if (response[0] == '+') {
00262               message = "";
00263               status = Read;
00264               if (!socket->canReadLine()) //sync. problems
00265                 break;
00266               response = socket->readLine();
00267             } else errorHandlingWithMsg(ErrUnknownResponse, response);
00268           }
00269         }
00270     //add all incoming lines to body.  When size is reached, send
00271     //message, and go back to read new message
00272     case Read:  {
00273           if (status != Quit) { //because of idiotic switch
00274             message += response;
00275             while ( socket->canReadLine() ) {
00276               response = socket->readLine();
00277               message += response;
00278             }
00279             emit downloadedSize(message.length());
00280             int x = message.find("\r\n.\r\n",-5);
00281             if (x == -1) {
00282               break;
00283             } else {  //message reach entire size
00284         if ( (selected)||(mailSize <= headerLimit)) //mail size limit is not used if late download is active
00285         {
00286         emit newMessage(message, messageCount-1, mailSize, TRUE);
00287               } else {  //incomplete mail downloaded
00288     emit newMessage(message, messageCount-1, mailSize, FALSE);
00289               }
00290 
00291               if ((messageCount > newMessages)||(selected)) //last message ?
00292         {
00293                 status = Quit;
00294                 if (selected) {   //grab next from queue
00295                     newMessages--;
00296                     status = Quit;
00297                   }
00298         }
00299               else
00300         {
00301                   *stream << "LIST " << messageCount << "\r\n";
00302                   status = Size;
00303                   temp2.setNum(newMessages - lastSync);
00304                   temp.setNum(messageCount - lastSync);
00305                   emit updateStatus(tr("Retrieving ") + temp + "/" + temp2);
00306 
00307                   break;
00308               }
00309               }
00310             }
00311             if (status != Quit)
00312               break;
00313         }
00314     case Quit:  {
00315           *stream << "Quit\r\n";
00316           status = Done;
00317           int newM = newMessages - lastSync;
00318           if (newM > 0) {
00319             temp.setNum(newM);
00320             emit updateStatus(temp + tr(" new messages"));
00321           } else {
00322             emit updateStatus(tr("No new messages"));
00323           }
00324 
00325           socket->close();
00326           receiving = FALSE;
00327           emit mailTransfered(newM);
00328           break;
00329         }
00330   }
00331 
00332 }

Generated on Sat Nov 5 16:18:09 2005 for OPIE by  doxygen 1.4.2