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     qmemmove(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     qmemmove(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     qmemmove(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     qmemmove(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     return data.size() - pos;
00098   }
00099   void fromString(const TQString &s)
00100   {
00101     clear();
00102     data.duplicate(s.latin1(), s.length());
00103   }
00104   TQByteArray data;
00105   uint pos;
00106 };
00107 
00108 class imapCache
00109 {
00110 public:
00111   imapCache ()
00112   {
00113     myHeader = NULL;
00114     mySize = 0;
00115     myFlags = 0;
00116     myUid = 0;
00117   }
00118 
00119   ~imapCache ()
00120   {
00121     if (myHeader) delete myHeader;
00122   }
00123 
00124   mailHeader *getHeader ()
00125   {
00126     return myHeader;
00127   }
00128   void setHeader (mailHeader * inHeader)
00129   {
00130     myHeader = inHeader;
00131   }
00132 
00133   ulong getSize ()
00134   {
00135     return mySize;
00136   }
00137   void setSize (ulong inSize)
00138   {
00139     mySize = inSize;
00140   }
00141 
00142   ulong getUid ()
00143   {
00144     return myUid;
00145   }
00146   void setUid (ulong inUid)
00147   {
00148     myUid = inUid;
00149   }
00150 
00151   ulong getFlags ()
00152   {
00153     return myFlags;
00154   }
00155   void setFlags (ulong inFlags)
00156   {
00157     myFlags = inFlags;
00158   }
00159 
00160   TQCString getDate ()
00161   {
00162     return myDate;
00163   }
00164   void setDate (const TQCString & _str)
00165   {
00166     myDate = _str;
00167   }
00168   void clear()
00169   {
00170     if (myHeader) delete myHeader;
00171     myHeader = NULL;
00172     mySize = 0;
00173     myFlags = 0;
00174     myDate = TQCString();
00175     myUid = 0;
00176   }
00177 
00178 protected:
00179   mailHeader * myHeader;
00180   ulong mySize;
00181   ulong myFlags;
00182   ulong myUid;
00183   TQCString myDate;
00184 };
00185 
00186 
00187 class imapParser
00188 {
00189 
00190 public:
00191 
00193   enum IMAP_STATE
00194   {
00195     ISTATE_NO,       
00196     ISTATE_CONNECT,  
00197     ISTATE_LOGIN,    
00198     ISTATE_SELECT    
00199   };
00200 
00201 public:
00202     imapParser ();
00203     virtual ~ imapParser ();
00204 
00206   enum IMAP_STATE getState () { return currentState; }
00208   void setState(enum IMAP_STATE state) { currentState = state; }
00209 
00210   /* @brief return the currently selected mailbox */
00211   const TQString getCurrentBox ()
00212   {
00213     return rfcDecoder::fromIMAP(currentBox);
00214   };
00215 
00221   imapCommand *sendCommand (imapCommand * aCmd);
00227   imapCommand *doCommand (imapCommand * aCmd);
00228 
00229 
00237   bool clientLogin (const TQString & aUser, const TQString & aPass, TQString & resultInfo);
00247   bool clientAuthenticate (KIO::SlaveBase *slave, KIO::AuthInfo &ai, const TQString & aFQDN,
00248     const TQString & aAuth, bool isSSL, TQString & resultInfo);
00249 
00254   int parseLoop ();
00255 
00260   void parseUntagged (parseString & result);
00261 
00263   void parseRecent (ulong value, parseString & result);
00265   void parseResult (TQByteArray & result, parseString & rest,
00266                     const TQString & command = TQString::null);
00268   void parseCapability (parseString & result);
00270   void parseFlags (parseString & result);
00272   void parseList (parseString & result);
00274   void parseLsub (parseString & result);
00276   void parseListRights (parseString & result);
00278   void parseMyRights (parseString & result);
00280   void parseSearch (parseString & result);
00282   void parseStatus (parseString & result);
00284   void parseExists (ulong value, parseString & result);
00286   void parseExpunge (ulong value, parseString & result);
00288   void parseAcl (parseString & result);
00290   void parseAnnotation (parseString & result);
00292   void parseNamespace (parseString & result);
00294   void parseQuotaRoot (parseString & result);
00296   void parseQuota (parseString & result);
00298   void parseCustom (parseString & result);
00300   void parseOtherUser (parseString & result);
00302   void parseDelegate (parseString & result);
00304   void parseOutOfOffice (parseString & result);
00305 
00310   void parseFetch (ulong value, parseString & inWords);
00311 
00313   mailHeader *parseEnvelope (parseString & inWords);
00315   void parseAddressList (parseString & inWords, TQPtrList<mailAddress>& list);
00317   const mailAddress& parseAddress (parseString & inWords, mailAddress& buffer);
00318 
00320   void parseBody (parseString & inWords);
00321 
00323   mimeHeader *parseBodyStructure (parseString & inWords,
00324     TQString & section, mimeHeader * inHeader = 0);
00325 
00327   mimeHeader *parseSimplePart (parseString & inWords, TQString & section,
00328       mimeHeader * localPart = 0);
00329 
00331   TQAsciiDict < TQString > parseParameters (parseString & inWords);
00332 
00337   TQAsciiDict < TQString > parseDisposition (parseString & inWords);
00338 
00339   // reimplement these
00340 
00342   virtual void parseRelay (const TQByteArray & buffer);
00343 
00346   virtual void parseRelay (ulong);
00347 
00349   virtual bool parseRead (TQByteArray & buffer, ulong len, ulong relay = 0);
00350 
00352   virtual bool parseReadLine (TQByteArray & buffer, ulong relay = 0);
00353 
00355   virtual void parseWriteLine (const TQString &);
00356 
00357   // generic parser routines
00358 
00360   void parseSentence (parseString & inWords);
00361 
00363   TQCString parseLiteralC(parseString & inWords, bool relay = false,
00364                            bool stopAtBracket = false, int *outlen = 0);
00365   inline TQByteArray parseLiteral (parseString & inWords, bool relay = false,
00366                            bool stopAtBracket = false) {
00367     int len = 0; // string size
00368     // Choice: we can create an extra TQCString, or we can get the buffer in
00369     // the wrong size to start.  Let's try option b.
00370     TQCString tmp = parseLiteralC(inWords, relay, stopAtBracket, &len);
00371     return TQByteArray().duplicate(tmp.data(), len);
00372   }
00373 
00374   // static parser routines, can be used elsewhere
00375 
00376   static TQCString b2c(const TQByteArray &ba)
00377   { return TQCString(ba.data(), ba.size() + 1); }
00378 
00380   static TQCString parseOneWordC (parseString & inWords,
00381     bool stopAtBracket = FALSE, int *len = 0);
00382 
00384   static bool parseOneNumber (parseString & inWords, ulong & num);
00385 
00387   static void parseURL (const KURL & _url, TQString & _box, TQString & _section,
00388                         TQString & _type, TQString & _uid, TQString & _validity,
00389                         TQString & _info);
00390 
00391 
00395   imapCache *getLastHandled ()
00396   {
00397     return lastHandled;
00398   };
00399 
00401   const TQStringList & getResults ()
00402   {
00403     return lastResults;
00404   };
00405 
00407   const imapInfo & getStatus ()
00408   {
00409     return lastStatus;
00410   };
00412   const imapInfo & getSelected ()
00413   {
00414     return selectInfo;
00415   };
00416 
00417   const TQByteArray & getContinuation ()
00418   {
00419     return continuation;
00420   };
00421 
00423   bool hasCapability (const TQString &);
00424 
00425   void removeCapability (const TQString & cap);
00426 
00427   static inline void skipWS (parseString & inWords)
00428   {
00429     char c;
00430     while (!inWords.isEmpty() &&
00431       ((c = inWords[0]) == ' ' || c == '\t' || c == '\r' || c == '\n'))
00432     {
00433       inWords.pos++;
00434     }
00435   }
00436 
00438   TQString namespaceForBox( const TQString & box );
00439 
00440 
00441 protected:
00442 
00444   enum IMAP_STATE currentState;
00445 
00447   TQString currentBox;
00448 
00450   imapInfo selectInfo;
00451 
00453   imapInfo lastStatus;
00454 
00456   TQStringList imapCapabilities;
00457 
00459   TQValueList < imapList > listResponses;
00460 
00462   TQPtrList < imapCommand > sentQueue;  // no autodelete
00463   TQPtrList < imapCommand > completeQueue;  // autodelete !!
00464 
00468   TQStringList unhandled;
00469 
00471   TQByteArray continuation;
00472 
00474   TQString seenUid;
00475   imapCache *lastHandled;
00476 
00477   ulong commandCounter;
00478 
00480   TQStringList lastResults;
00481 
00486   TQMap<TQString, TQString> namespaceToDelimiter;
00487 
00492   TQStringList imapNamespaces;
00493 
00494 private:
00495 
00497   imapParser & operator = (const imapParser &); // hide the copy ctor
00498 
00499 };
00500 #endif