kioslaves/imap4

imapparser.h

00001 #ifndef _IMAPPARSER_H
00002 #define _IMAPPARSER_H
00003 /**********************************************************************
00004  *
00005  *   imapparser.h  - IMAP4rev1 Parser
00006  *   Copyright (C) 2001-2002 Michael Haeckel <haeckel@kde.org>
00007  *   Copyright (C) 2000 s.carstens@gmx.de
00008  *
00009  *   This program is free software; you can redistribute it and/or modify
00010  *   it under the terms of the GNU General Public License as published by
00011  *   the Free Software Foundation; either version 2 of the License, or
00012  *   (at your option) any later version.
00013  *
00014  *   This program is distributed in the hope that it will be useful,
00015  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *   GNU General Public License for more details.
00018  *
00019  *   You should have received a copy of the GNU General Public License
00020  *   along with this program; if not, write to the Free Software
00021  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  *
00023  *   Send comments and bug fixes to s.carstens@gmx.de
00024  *
00025  *********************************************************************/
00026 
00027 #include <tqstringlist.h>
00028 #include <tqvaluelist.h>
00029 #include <tqptrlist.h>
00030 #include <tqasciidict.h>
00031 
00032 #include <kio/authinfo.h>
00033 #include <kio/slavebase.h>
00034 
00035 #include "imaplist.h"
00036 #include "imapcommand.h"
00037 #include "imapinfo.h"
00038 
00039 #include "mailheader.h"
00040 
00041 class KURL;
00042 class TQString;
00043 class mailAddress;
00044 class mimeHeader;
00045 
00046 
00052 class parseString
00053 {
00054 public:
00055   parseString() { pos = 0; }
00056   char operator[](uint i) const { return data[i + pos]; }
00057   bool isEmpty() const { return pos >= data.size(); }
00058   TQCString cstr() const
00059   {
00060     if (pos >= data.size()) return TQCString();
00061     return TQCString(data.data() + pos, data.size() - pos + 1);
00062   }
00063   int find(char c, int index = 0)
00064   {
00065     int res = data.find(c, index + pos);
00066     return (res == -1) ? res : (res - pos);
00067   }
00068   // Warning: does not check for going past end of "data"
00069   void takeLeft(TQCString& dest, uint len) const
00070   {
00071     dest.resize(len + 1);
00072     tqmemmove(dest.data(), data.data() + pos, len);
00073   }
00074   // Warning: does not check for going past end of "data"
00075   void takeLeftNoResize(TQCString& dest, uint len) const
00076   {
00077     tqmemmove(dest.data(), data.data() + pos, len);
00078   }
00079   // Warning: does not check for going past end of "data"
00080   void takeMid(TQCString& dest, uint start, uint len) const
00081   {
00082     dest.resize(len + 1);
00083     tqmemmove(dest.data(), data.data() + pos + start, len);
00084   }
00085   // Warning: does not check for going past end of "data"
00086   void takeMidNoResize(TQCString& dest, uint start, uint len) const
00087   {
00088     tqmemmove(dest.data(), data.data() + pos + start, len);
00089   }
00090   void clear()
00091   {
00092     data.resize(0);
00093     pos = 0;
00094   }
00095   uint length()
00096   {
00097     if( pos < data.size() ) {
00098       return data.size() - pos;
00099     } else {
00100       return 0;
00101     }
00102   }
00103   void fromString(const TQString &s)
00104   {
00105     clear();
00106     data.duplicate(s.latin1(), s.length());
00107   }
00108   TQByteArray data;
00109   uint pos;
00110 };
00111 
00112 class imapCache
00113 {
00114 public:
00115   imapCache ()
00116   {
00117     myHeader = NULL;
00118     mySize = 0;
00119     myFlags = 0;
00120     myUid = 0;
00121   }
00122 
00123   ~imapCache ()
00124   {
00125     if (myHeader) delete myHeader;
00126   }
00127 
00128   mailHeader *getHeader ()
00129   {
00130     return myHeader;
00131   }
00132   void setHeader (mailHeader * inHeader)
00133   {
00134     myHeader = inHeader;
00135   }
00136 
00137   ulong getSize ()
00138   {
00139     return mySize;
00140   }
00141   void setSize (ulong inSize)
00142   {
00143     mySize = inSize;
00144   }
00145 
00146   ulong getUid ()
00147   {
00148     return myUid;
00149   }
00150   void setUid (ulong inUid)
00151   {
00152     myUid = inUid;
00153   }
00154 
00155   ulong getFlags ()
00156   {
00157     return myFlags;
00158   }
00159   void setFlags (ulong inFlags)
00160   {
00161     myFlags = inFlags;
00162   }
00163 
00164   TQCString getDate ()
00165   {
00166     return myDate;
00167   }
00168   void setDate (const TQCString & _str)
00169   {
00170     myDate = _str;
00171   }
00172   void clear()
00173   {
00174     if (myHeader) delete myHeader;
00175     myHeader = NULL;
00176     mySize = 0;
00177     myFlags = 0;
00178     myDate = TQCString();
00179     myUid = 0;
00180   }
00181 
00182 protected:
00183   mailHeader * myHeader;
00184   ulong mySize;
00185   ulong myFlags;
00186   ulong myUid;
00187   TQCString myDate;
00188 };
00189 
00190 
00191 class imapParser
00192 {
00193 
00194 public:
00195 
00197   enum IMAP_STATE
00198   {
00199     ISTATE_NO,       
00200     ISTATE_CONNECT,  
00201     ISTATE_LOGIN,    
00202     ISTATE_SELECT    
00203   };
00204 
00205 public:
00206     imapParser ();
00207     virtual ~ imapParser ();
00208 
00210   enum IMAP_STATE getState () { return currentState; }
00212   void setState(enum IMAP_STATE state) { currentState = state; }
00213 
00214   /* @brief return the currently selected mailbox */
00215   const TQString getCurrentBox ()
00216   {
00217     return rfcDecoder::fromIMAP(currentBox);
00218   };
00219 
00225   imapCommand *sendCommand (imapCommand * aCmd);
00231   imapCommand *doCommand (imapCommand * aCmd);
00232 
00233 
00241   bool clientLogin (const TQString & aUser, const TQString & aPass, TQString & resultInfo);
00251   bool clientAuthenticate (KIO::SlaveBase *slave, KIO::AuthInfo &ai, const TQString & aFTQDN,
00252     const TQString & aAuth, bool isSSL, TQString & resultInfo);
00253 
00258   int parseLoop ();
00259 
00264   void parseUntagged (parseString & result);
00265 
00267   void parseRecent (ulong value, parseString & result);
00269   void parseResult (TQByteArray & result, parseString & rest,
00270                     const TQString & command = TQString());
00272   void parseCapability (parseString & result);
00274   void parseFlags (parseString & result);
00276   void parseList (parseString & result);
00278   void parseLsub (parseString & result);
00280   void parseListRights (parseString & result);
00282   void parseMyRights (parseString & result);
00284   void parseSearch (parseString & result);
00286   void parsetStatus (parseString & result);
00288   void parseExists (ulong value, parseString & result);
00290   void parseExpunge (ulong value, parseString & result);
00292   void parseAcl (parseString & result);
00294   void parseAnnotation (parseString & result);
00296   void parseNamespace (parseString & result);
00298   void parseQuotaRoot (parseString & result);
00300   void parseQuota (parseString & result);
00302   void parseCustom (parseString & result);
00304   void parseOtherUser (parseString & result);
00306   void parseDelegate (parseString & result);
00308   void parseOutOfOffice (parseString & result);
00309 
00314   void parseFetch (ulong value, parseString & inWords);
00315 
00317   mailHeader *parseEnvelope (parseString & inWords);
00319   void parseAddressList (parseString & inWords, TQPtrList<mailAddress>& list);
00321   const mailAddress& parseAddress (parseString & inWords, mailAddress& buffer);
00322 
00324   void parseBody (parseString & inWords);
00325 
00327   mimeHeader *parseBodyStructure (parseString & inWords,
00328     TQString & section, mimeHeader * inHeader = 0);
00329 
00331   mimeHeader *parseSimplePart (parseString & inWords, TQString & section,
00332       mimeHeader * localPart = 0);
00333 
00335   TQAsciiDict < TQString > parseParameters (parseString & inWords);
00336 
00341   TQAsciiDict < TQString > parseDisposition (parseString & inWords);
00342 
00343   // reimplement these
00344 
00346   virtual void parseRelay (const TQByteArray & buffer);
00347 
00350   virtual void parseRelay (ulong);
00351 
00353   virtual bool parseRead (TQByteArray & buffer, ulong len, ulong relay = 0);
00354 
00356   virtual bool parseReadLine (TQByteArray & buffer, ulong relay = 0);
00357 
00359   virtual void parseWriteLine (const TQString &);
00360 
00361   // generic parser routines
00362 
00364   void parseSentence (parseString & inWords);
00365 
00367   TQCString parseLiteralC(parseString & inWords, bool relay = false,
00368                            bool stopAtBracket = false, int *outlen = 0);
00369   inline TQByteArray parseLiteral (parseString & inWords, bool relay = false,
00370                            bool stopAtBracket = false) {
00371     int len = 0; // string size
00372     // Choice: we can create an extra TQCString, or we can get the buffer in
00373     // the wrong size to start.  Let's try option b.
00374     TQCString tmp = parseLiteralC(inWords, relay, stopAtBracket, &len);
00375     return TQByteArray().duplicate(tmp.data(), len);
00376   }
00377 
00378   // static parser routines, can be used elsewhere
00379 
00380   static TQCString b2c(const TQByteArray &ba)
00381   { return TQCString(ba.data(), ba.size() + 1); }
00382 
00384   static TQCString parseOneWordC (parseString & inWords,
00385     bool stopAtBracket = FALSE, int *len = 0);
00386 
00388   static bool parseOneNumber (parseString & inWords, ulong & num);
00389 
00391   static void parseURL (const KURL & _url, TQString & _box, TQString & _section,
00392                         TQString & _type, TQString & _uid, TQString & _validity,
00393                         TQString & _info);
00394 
00395 
00399   imapCache *getLastHandled ()
00400   {
00401     return lastHandled;
00402   };
00403 
00405   const TQStringList & getResults ()
00406   {
00407     return lastResults;
00408   };
00409 
00411   const imapInfo & geStatus ()
00412   {
00413     return lasStatus;
00414   };
00416   const imapInfo & getSelected ()
00417   {
00418     return selectInfo;
00419   };
00420 
00421   const TQByteArray & getContinuation ()
00422   {
00423     return continuation;
00424   };
00425 
00427   bool hasCapability (const TQString &);
00428 
00429   void removeCapability (const TQString & cap);
00430 
00431   static inline void skipWS (parseString & inWords)
00432   {
00433     char c;
00434     while (!inWords.isEmpty() &&
00435       ((c = inWords[0]) == ' ' || c == '\t' || c == '\r' || c == '\n'))
00436     {
00437       inWords.pos++;
00438     }
00439   }
00440 
00442   TQString namespaceForBox( const TQString & box );
00443 
00444 
00445 protected:
00446 
00448   enum IMAP_STATE currentState;
00449 
00451   TQString currentBox;
00452 
00454   imapInfo selectInfo;
00455 
00457   imapInfo lasStatus;
00458 
00460   TQStringList imapCapabilities;
00461 
00463   TQValueList < imapList > listResponses;
00464 
00466   TQPtrList < imapCommand > sentQueue;  // no autodelete
00467   TQPtrList < imapCommand > completeQueue;  // autodelete !!
00468 
00472   TQStringList unhandled;
00473 
00475   TQByteArray continuation;
00476 
00478   TQString seenUid;
00479   imapCache *lastHandled;
00480 
00481   ulong commandCounter;
00482 
00484   TQStringList lastResults;
00485 
00490   TQMap<TQString, TQString> namespaceToDelimiter;
00491 
00496   TQStringList imapNamespaces;
00497 
00498 private:
00499 
00501   imapParser & operator = (const imapParser &); // hide the copy ctor
00502 
00503 };
00504 #endif