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