1 /* 2 ** Copyright 2003-2008, Double Precision Inc. 3 ** 4 ** See COPYING for distribution information. 5 */ 6 #ifndef libmail_nntp_H 7 #define libmail_nntp_H 8 9 #include "libmail_config.h" 10 #include "mail.H" 11 #include <sys/types.h> 12 13 #include "maildir/maildirkeywords.h" 14 15 #include "logininfo.H" 16 #include "fd.H" 17 #include "generic.H" 18 #include "search.H" 19 #include <stdio.h> 20 #include <time.h> 21 #include <string> 22 #include <map> 23 #include <list> 24 #include <vector> 25 26 /////////////////////////////////////////////////////////////////////////// 27 // 28 // An NNTP implementation 29 // 30 31 LIBMAIL_START 32 33 ////////////////////////////////////////////////////////////////////////////// 34 35 class nntp : public fd, public generic { 36 37 public: 38 class newsrc; 39 typedef unsigned long msgnum_t; 40 41 private: 42 43 time_t timeoutSetting; 44 time_t autologoutSetting; 45 46 loginInfo nntpLoginInfo; 47 48 loginInfo savedLoginInfo; 49 50 time_t inactivityTimeout; 51 52 callback::folder *folderCallback; 53 54 void resumed(); 55 void handler(std::vector<pollfd> &fds, int &timeout); 56 int socketRead(const std::string &readbuffer); 57 58 void disconnect(const char *reason); 59 60 // Superclass of NNTP tasks. Methods create subclasses of Task 61 // objects, and push them to the tasks queue. Replies from the 62 // NNTP server are routed to the foremost Task on the queue. 63 64 class Task { 65 66 protected: 67 callback *callbackPtr; // App callback. 68 nntp * volatile myserver; 69 // Marked volatile due to destructor monkey business 70 71 public: 72 time_t defaultTimeout; 73 74 virtual void done(); 75 // Task completed, start the next task on the queue, 76 // and delete this Task object. 77 78 void resetTimeout(); 79 80 virtual void success(std::string); 81 virtual void fail(std::string); 82 // success/fail for use by subclasses. Invoke the callback 83 // method, then done. 84 85 Task(callback *callbackArg, 86 nntp &myserverArg); 87 virtual ~Task(); 88 89 virtual int getTimeout(); 90 // How long before this task times out. 91 92 virtual void emptyQueue(); 93 // After removing this task, the task queue is now empty 94 95 virtual void serverResponse(const char *message)=0; 96 // Process a line of text from the server 97 98 virtual void disconnected(const char *reason); 99 // Server has disconnected. 100 // The default implementation takes this task off the queue, 101 // calls the next Task's disconnect method, then deletes 102 // itself. 103 104 virtual void installedTask(); 105 // This task is now at the front of the queue 106 }; 107 108 std::list<Task *> tasks; 109 110 std::vector<std::string> newgroups; 111 bool hasNewgroups; 112 113 std::map<std::string, newsrc> cachedNewsrc; 114 bool didCacheNewsrc; 115 116 void cacheNewsrc(); 117 bool updateCachedNewsrc(); 118 void discardCachedNewsrc(); 119 bool updateOpenedNewsrc(newsrc &); 120 121 void createNewsrc(newsrc &); 122 123 class cachedNewsrcSort; 124 125 class folder; 126 class add; 127 class LoggedInTask; 128 class LoginTask; 129 class LogoutTask; 130 class ListActiveTask; 131 class GroupTask; 132 class GroupInfoTask; 133 class GroupOpenTask; 134 class FetchTask; 135 class FetchTaskBase; 136 class CacheMessageTask; 137 class CacheTask; 138 class XoverTask; 139 class PostTask; 140 class CheckNewTask; 141 142 class XpatTask; 143 class XpatTaskCallback; 144 145 std::string newsrcFilename; // .newsrc file 146 147 std::string openedGroup; // Group we have logically opened 148 149 // Here's the index of an opened group. 'cause Usenet groups can 150 // be fairly large, we try to be extra skimpy on memory usage. 151 152 class nntpMessageInfo { 153 public: 154 nntpMessageInfo(); 155 ~nntpMessageInfo(); 156 msgnum_t msgNum; 157 158 mail::keywords::Message keywords; 159 160 unsigned char msgFlag; 161 #define IDX_DELETED 1 162 #define IDX_FLAGGED 2 163 164 #define IDX_SEARCH 128 // Flag used to mark msgs found by search 165 }; 166 167 private: 168 static bool equalMsgNums(nntpMessageInfo a, 169 nntpMessageInfo b); 170 171 public: 172 mail::keywords::Hashtable keywordHashtable; 173 std::vector<nntpMessageInfo> index; 174 175 msgnum_t loWatermark, hiWatermark; // Saved from last GROUP 176 177 std::string serverGroup; // Group actually open on the server 178 179 callback::disconnect *disconnectCallback; 180 181 void installTask(Task *); 182 public: 183 184 friend class Task; 185 friend class LoggedInTask; 186 friend class folder; 187 friend class LogoutTask; 188 friend class ListActiveTask; 189 friend class GroupTask; 190 friend class GroupInfoTask; 191 friend class GroupOpenTask; 192 friend class FetchTask; 193 friend class FetchTaskBase; 194 friend class CacheMessageTask; 195 friend class CacheTask; 196 friend class XoverTask; 197 friend class add; 198 friend class PostTask; 199 friend class CheckNewTask; 200 friend class XpatTask; 201 friend class XpatTaskCallback; 202 203 nntp(std::string url, std::string passwd, 204 std::vector<std::string> &certificates, 205 std::string newsrcFilename, 206 mail::loginCallback *loginCallbackFunc, 207 callback &callback, 208 callback::disconnect &disconnectCallbackArg); 209 210 nntp(const nntp &); // UNDEFINED 211 nntp &operator=(const nntp &); // UNDEFINED 212 213 ~nntp(); 214 215 void logout(callback &callback); 216 217 void checkNewMail(callback &callback); 218 bool hasCapability(std::string capability); 219 std::string getCapability(std::string capability); 220 221 mail::folder *folderFromString(std::string); 222 223 void readTopLevelFolders(callback::folderList &callback1, 224 callback &callback2); 225 void findFolder(std::string folder, 226 class callback::folderList &callback1, 227 class callback &callback2); 228 std::string translatePath(std::string path); 229 230 mail::folder *getSendFolder(const smtpInfo &info, 231 const mail::folder *folder, 232 std::string &errmsg); 233 234 void readMessageAttributes(const std::vector<size_t> &messages, 235 MessageAttributes attributes, 236 callback::message &callback); 237 238 void readMessageContent(const std::vector<size_t> &messages, 239 bool peek, 240 enum mail::readMode readType, 241 callback::message &callback); 242 243 void readMessageContent(size_t messageNum, 244 bool peek, 245 const mimestruct &msginfo, 246 enum mail::readMode readType, 247 callback::message &callback); 248 249 void readMessageContentDecoded(size_t messageNum, 250 bool peek, 251 const mimestruct &msginfo, 252 callback::message &callback); 253 254 size_t getFolderIndexSize(); 255 messageInfo getFolderIndexInfo(size_t); 256 257 void saveFolderIndexInfo(size_t, 258 const messageInfo &, 259 callback &); 260 261 void updateFolderIndexFlags(const std::vector<size_t> &messages, 262 bool doFlip, 263 bool enableDisable, 264 const messageInfo &flags, 265 callback &callback); 266 267 void updateFolderIndexInfo(callback &); 268 269 void getFolderKeywordInfo(size_t, std::set<std::string> &); 270 271 void updateKeywords(const std::vector<size_t> &messages, 272 const std::set<std::string> &keywords, 273 bool setOrChange, 274 // false: set, true: see changeTo 275 bool changeTo, 276 callback &cb); 277 private: 278 bool genericProcessKeyword(size_t msgNum, 279 updateKeywordHelper &helper); 280 public: 281 void removeMessages(const std::vector<size_t> &messages, 282 callback &cb); 283 284 void copyMessagesTo(const std::vector<size_t> &messages, 285 mail::folder *copyTo, 286 callback &callback); 287 288 void searchMessages(const searchParams &searchInfo, 289 searchCallback &callback); 290 291 void saveSnapshot(); 292 private: 293 void searchMessagesXpat(std::string hdr, std::string srch, 294 bool searchNot, 295 searchParams::Scope searchScope, 296 size_t rangeLo, size_t rangeHi, 297 searchCallback &callback); 298 299 bool fixGenericMessageNumber(std::string uid, size_t &messageNumber); 300 301 void genericMessageRead(std::string uid, 302 size_t messageNumber, 303 bool peek, 304 mail::readMode readTypeArg, 305 callback::message &callback); 306 307 void genericMessageSize(std::string uid, 308 size_t messageNumber, 309 callback::message &callback); 310 311 void genericGetMessageFd(std::string uid, 312 size_t messageNumber, 313 bool peek, 314 int &fdRet, 315 callback &callback); 316 void genericMarkRead(size_t messageNumber); 317 318 void genericGetMessageStruct(std::string uid, 319 size_t messageNumber, 320 struct rfc2045 *&structRet, 321 callback &callback); 322 323 bool genericCachedUid(std::string uid); 324 325 // One message is cached to a temp file, and parsed. 326 327 std::string cachedUid; 328 FILE *genericTmpFp; 329 struct rfc2045 *genericTmpRfcp; 330 331 void cleartmp(); 332 }; 333 334 LIBMAIL_END 335 336 #endif 337