00001
00005 #ifndef __MAIL_H
00006 #define __MAIL_H
00007
00008 #include "INet.h"
00009 #include "Base64.h"
00010 #include "Progress.h"
00011 #include "GVariant.h"
00012
00013
00014 #define MAX_LINE_SIZE 1024
00015 #define MAX_NAME_SIZE 64
00016 #define EMAIL_LINE_SIZE 76
00017
00018 #define IsDigit(c) ((c) >= '0' AND (c) <= '9')
00019
00020
00021 #define CONTENT_NONE 0
00022 #define CONTENT_BASE64 1
00023 #define CONTENT_QUOTED_PRINTABLE 2
00024 #define CONTENT_OCTET_STREAM 3
00025
00026
00027 #define MAIL_SEND_COLOUR Rgb24(0, 0, 0xff)
00028 #define MAIL_RECEIVE_COLOUR Rgb24(0, 0x8f, 0)
00029 #define MAIL_ERROR_COLOUR Rgb24(0xff, 0, 0)
00030 #define MAIL_WARNING_COLOUR Rgb24(0xff, 0x7f, 0)
00031 #define MAIL_INFO_COLOUR Rgb24(0, 0, 0)
00032
00033
00034 extern void TokeniseStrList(char *Str, List<char> &Output, char *Delim);
00035 extern char ConvHexToBin(char c);
00036 #define ConvBinToHex(i) (((i)<10)?'0'+(i):'A'+(i)-10)
00037 extern void DecodeAddrName(char *Start, char *&Name, char *&Addr, char *DefaultDomain);
00038 extern char *DecodeRfc2047(char *Str);
00039 extern char *EncodeRfc2047(char *Str, char *CodePage, List<char> *CharsetPrefs);
00040 extern char *DecodeBase64Str(char *Str, int Len = -1);
00041 extern char *DecodeQuotedPrintableStr(char *Str, int Len = -1);
00042 extern bool Is8Bit(char *Text);
00043 extern int MaxLineLen(char *Text);
00044 extern char *EncodeImapString(char *s);
00045 extern char *DecodeImapString(char *s);
00046
00047
00048 class MailProtocol;
00049
00050 class MailProtocolProgress
00051 {
00052 public:
00053 int Start;
00054 int Value;
00055 int Range;
00056
00057 MailProtocolProgress()
00058 {
00059 Empty();
00060 }
00061
00062 void Empty()
00063 {
00064 Start = 0;
00065 Value = 0;
00066 Range = 0;
00067 }
00068 };
00069
00070 class LogEntry
00071 {
00072 public:
00073 char *Text;
00074 COLOUR c;
00075
00076 LogEntry(char *t, COLOUR col = 0)
00077 {
00078 c = col;
00079 Text = 0;
00080
00081 if (t)
00082 {
00083 char *n = strchr(t, '\r');
00084 if (n)
00085 {
00086 Text = NewStr(t, (int)n-(int)t);
00087 }
00088 else
00089 {
00090 Text = NewStr(t);
00091 }
00092 }
00093 }
00094
00095 ~LogEntry()
00096 {
00097 DeleteArray(Text);
00098 }
00099 };
00100
00102 class FileDescriptor : public GObject
00103 {
00104 protected:
00105
00106 int64 Size;
00107 char *MimeType;
00108
00109
00110 GFile File;
00111 GFile *Embeded;
00112 bool OwnEmbeded;
00113 int64 Offset;
00114 GSemaphore *Lock;
00115
00116
00117 uchar *Data;
00118
00119 public:
00120 FileDescriptor(GFile *embed, int64 Offset, int64 Size, char *Name);
00121 FileDescriptor(char *name);
00122 FileDescriptor(char *data, int64 len);
00123 FileDescriptor();
00124 ~FileDescriptor();
00125
00126 void SetLock(GSemaphore *l);
00127 GSemaphore *GetLock();
00128 void SetOwnEmbeded(bool i);
00129
00130
00131 GFile *GotoObject();
00132 uchar *GetData();
00133 int Sizeof();
00134 char *GetMimeType() { return MimeType; }
00135 void SetMimeType(char *s) { DeleteArray(MimeType); MimeType = NewStr(s); }
00136
00137
00138 bool Decode(char *ContentType,
00139 char *ContentTransferEncoding,
00140 char *MimeData,
00141 int MimeDataLength);
00142 };
00143
00144 #define MAIL_ADDR_TO 0
00145 #define MAIL_ADDR_CC 1
00146 #define MAIL_ADDR_BCC 2
00147
00149 class AddressDescriptor : public GObject, public GDom
00150 {
00151 public:
00152 uint8 Status;
00153 uchar CC;
00154 char *Name;
00155 char *Addr;
00156
00157 void *Data;
00158
00159 AddressDescriptor(AddressDescriptor *Copy = 0);
00160 ~AddressDescriptor();
00161 void _Delete();
00162
00163 void Print(char *Str);
00164 int Sizeof()
00165 {
00166 return SizeofStr(Name) +
00167 SizeofStr(Addr);
00168 }
00169
00170 bool Serialize(GFile &f, bool Write)
00171 {
00172 bool Status = true;
00173 if (Write)
00174 {
00175 WriteStr(f, Name);
00176 WriteStr(f, Addr);
00177 }
00178 else
00179 {
00180 DeleteArray(Name);
00181 Name = ReadStr(f PassDebugArgs);
00182 DeleteArray(Addr);
00183 Addr = ReadStr(f PassDebugArgs);
00184 }
00185 return Status;
00186 }
00187 };
00188
00189
00190
00191
00192
00193 #define MAIL_PRIORITY_HIGH 1
00194 #define MAIL_PRIORITY_NORMAL 3 // ???
00195 #define MAIL_PRIORITY_LOW 5
00196
00197 class MailMessage
00198 {
00199 public:
00200 List<AddressDescriptor> To;
00201 AddressDescriptor *From;
00202 AddressDescriptor *Reply;
00203 char* Subject;
00204 char* Text;
00205 char* MessageID;
00206 List<FileDescriptor> FileDesc;
00207 char* InternetHeader;
00208 char Priority;
00209 char* CodePage;
00210 char* HtmlText;
00211 int MarkColour;
00212 uint8 DispositionNotificationTo;
00213 char* References;
00214
00215
00216 GObject *Private;
00217
00218
00219 MailMessage();
00220 virtual ~MailMessage();
00221 void Empty();
00222
00223
00224 GStringPipe *Raw;
00225
00226 bool Encode(GStream &Out, GStream *HeadersSink, MailProtocol *Protocol, bool Mime = true);
00227 bool EncodeHeaders(GStream &Out, MailProtocol *Protocol, bool Mime = true);
00228 bool EncodeBody(GStream &Out, MailProtocol *Protocol, bool Mime = true);
00229 bool EncodeQuotedPrintable(GStream &Out, char *In);
00230 bool EncodeText(GStream &Out, char *In);
00231 };
00232
00234 class MailProtocol
00235 {
00236 protected:
00237 char Buffer[4<<10];
00238 GSocket *Socket;
00239
00240 bool Read();
00241 bool Write(char *Buf = NULL, bool Log = false);
00242
00243 virtual void OnUserMessage(char *Str) {}
00244
00245 public:
00246
00247 GWindow *LogNotify;
00248 int LogMsg;
00249 int LogData;
00250 void Log(char *Str, COLOUR c);
00251 void Log(LogEntry *e);
00252
00253
00254 MailProtocolProgress *Items;
00255 MailProtocolProgress *Transfer;
00256
00257
00258 char *ServerMsg;
00259 char *ProgramName;
00260 char *DefaultDomain;
00261 char *ExtraOutgoingHeaders;
00262 List<char> CharsetPrefs;
00263
00264
00265 MailProtocol();
00266 virtual ~MailProtocol();
00267
00268
00269 GSocket *GetSocket() { return Socket; }
00270 };
00271
00273
00274
00276 #define MAIL_USE_STARTTLS 0x01
00277
00278 #define MAIL_USE_AUTH 0x02
00279
00280 #define MAIL_USE_PLAIN 0x04
00281
00282 #define MAIL_USE_LOGIN 0x08
00283
00284 #define MAIL_USE_NTLM 0x10
00285
00287 class MailSink : public MailProtocol
00288 {
00289 public:
00291 virtual bool Open
00292 (
00294 GSocket *S,
00296 char *RemoteHost,
00298 char *LocalDomain,
00300 char *UserName,
00302 char *Password,
00304 int Port,
00306 int Flags
00307 ) = 0;
00309 virtual bool Close() = 0;
00310
00311
00312
00315 virtual GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From) = 0;
00316
00318 virtual bool SendEnd(GStringPipe *Sink) = 0;
00319
00320
00321 virtual bool Send(MailMessage *Msg, bool Mime) { return false; }
00322 };
00323
00324 class MailTransaction
00325 {
00326 public:
00327 int Index;
00328 bool Delete;
00329 bool Status;
00330 bool Oversize;
00331 GStream *Stream;
00332
00333 MailTransaction();
00334 ~MailTransaction();
00335 };
00336
00338 enum MailSrcStatus
00339 {
00341 DownloadAll,
00343 DownloadTop,
00345 DownloadNone,
00347 DownloadAbort
00348 };
00349
00351 typedef MailSrcStatus (*MailSrcCallback)
00352 (
00354 MailTransaction *Trans,
00356 int64 Size,
00358 int *LinesToDownload,
00360 int Data
00361 );
00362
00364 #define MAIL_SOURCE_STARTTLS 0x01
00365
00366 #define MAIL_SOURCE_AUTH 0x02
00367
00368 #define MAIL_SOURCE_USE_PLAIN 0x04
00369
00370 #define MAIL_SOURCE_USE_LOGIN 0x08
00371
00373 class MailSource : public MailProtocol
00374 {
00375 public:
00377 virtual bool Open
00378 (
00380 GSocket *S,
00382 char *RemoteHost,
00384 int Port,
00386 char *User,
00388 char *Password,
00390 char *&Cookie,
00392 int Flags = 0) = 0;
00394 virtual bool Close() = 0;
00395
00397 virtual int GetMessages() = 0;
00399 virtual bool Receive
00400 (
00403 GArray<MailTransaction*> &Trans,
00405 MailSrcCallback Callback = 0,
00407 int Data = 0
00408 ) = 0;
00410 virtual bool Delete(int Message) = 0;
00412 virtual int Sizeof(int Message) = 0;
00414 virtual bool GetSizes(GArray<int> &Sizes) { return false; }
00416 virtual bool GetUid(int Message, char *Id) = 0;
00418 virtual bool GetUidList(List<char> &Id) = 0;
00420 virtual char *GetHeaders(int Message) = 0;
00422 virtual void SetProxy(char *Server, int Port) {}
00423 };
00424
00426
00427
00429 class MailSmtp : public MailSink
00430 {
00431 protected:
00432 bool ReadReply(char *Str, GStringPipe *Pipe = 0);
00433 bool WriteText(char *Str);
00434
00435 public:
00436 MailSmtp();
00437 ~MailSmtp();
00438
00439 bool Open(GSocket *S, char *RemoteHost, char *LocalDomain, char *UserName, char *Password, int Port = SMTP_PORT, int Flags = 0);
00440 bool Close();
00441
00442 GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From);
00443 bool SendEnd(GStringPipe *Sink);
00444
00445 bool Send(MailMessage *Msg, bool Mime = false);
00446 };
00447
00448 class MailSendFolder : public MailSink
00449 {
00450 class MailPostFolderPrivate *d;
00451
00452 public:
00453 MailSendFolder(char *Path);
00454 ~MailSendFolder();
00455
00456 bool Open(GSocket *S, char *RemoteHost, char *LocalDomain, char *UserName, char *Password, int Port = 0, int Flags = 0);
00457 bool Close();
00458
00459 GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From);
00460 bool SendEnd(GStringPipe *Sink);
00461 };
00462
00463 class MailPop3 : public MailSource
00464 {
00465 protected:
00466 bool ReadReply(int Timeout = -1);
00467 bool ReadMultiLineReply(char *&Str);
00468 int GetInt();
00469 bool MailIsEnd(char *Ptr, int Len);
00470
00471 char *End;
00472 char *Marker;
00473 int Messages;
00474
00475 public:
00476 MailPop3();
00477 ~MailPop3();
00478
00479
00480 bool Open(GSocket *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00481 bool Close();
00482
00483
00484 int GetMessages() { return Messages; }
00485 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00486 bool Delete(int Message);
00487 int Sizeof(int Message);
00488 bool GetSizes(GArray<int> &Sizes);
00489 bool GetUid(int Message, char *Id);
00490 bool GetUidList(List<char> &Id);
00491 char *GetHeaders(int Message);
00492 };
00493
00494 class MailReceiveFolder : public MailSource
00495 {
00496 protected:
00497 class MailReceiveFolderPrivate *d;
00498
00499 public:
00500 MailReceiveFolder(char *Path);
00501 ~MailReceiveFolder();
00502
00503
00504 bool Open(GSocket *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00505 bool Close();
00506
00507
00508 int GetMessages();
00509 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00510 bool Delete(int Message);
00511 int Sizeof(int Message);
00512 bool GetUid(int Message, char *Id);
00513 bool GetUidList(List<char> &Id);
00514 char *GetHeaders(int Message);
00515 };
00516
00517 class MailPhp : public MailSource
00518 {
00519 protected:
00520 class MailPhpPrivate *d;
00521
00522 bool Get(GSocket *S, char *Uri, GStream &Out, bool ChopDot);
00523
00524 public:
00525 MailPhp();
00526 ~MailPhp();
00527
00528
00529 bool Open(GSocket *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00530 bool Close();
00531
00532
00533 int GetMessages();
00534 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00535 bool Delete(int Message);
00536 int Sizeof(int Message);
00537 bool GetSizes(GArray<int> &Sizes);
00538 bool GetUid(int Message, char *Id);
00539 bool GetUidList(List<char> &Id);
00540 char *GetHeaders(int Message);
00541 void SetProxy(char *Server, int Port);
00542 };
00543
00544 class MailImapMsg : public GObject
00545 {
00546 public:
00547 uint ImapSeen:1;
00548 uint ImapRecent:1;
00549 uint ImapDeleted:1;
00550 int Index;
00551
00552 MailImapMsg()
00553 {
00554 ImapSeen = 0;
00555 ImapRecent = 0;
00556 ImapDeleted = 0;
00557 Index = -1;
00558 }
00559 };
00560
00561 class MailImapFolder
00562 {
00563 friend class MailIMap;
00564
00565 char Sep;
00566 char *Path;
00567
00568 public:
00569 bool NoSelect;
00570 bool NoInferiors;
00571 bool Marked;
00572 int Exists;
00573 int Recent;
00574 int UnseenIndex;
00575
00576 MailImapFolder();
00577 virtual ~MailImapFolder();
00578
00579 char *GetPath();
00580 void SetPath(char *s);
00581 char *GetName();
00582 void SetName(char *s);
00583 };
00584
00585 class MailIMap : public MailSource, public GSemaphore
00586 {
00587 protected:
00588 class MailIMapPrivate *d;
00589
00590 GSocket *S;
00591 char Buf[256];
00592 List<char> Dialog;
00593 List<char> Uid;
00594
00595 void ClearDialog();
00596 void ClearUid();
00597 bool FillUidList();
00598 bool WriteBuf(bool ObsurePass = false);
00599 bool ReadResponse(int Cmd = -1, GStringPipe *Out = 0);
00600 bool ReadLine(char *Buf, int Size);
00601 bool GetParts(int Message, GStream &Out, char *Parts, char **Flags = 0);
00602
00603 public:
00604 MailIMap();
00605 ~MailIMap();
00606
00607
00608 char GetFolderSep();
00609 char *GetCurrentPath();
00610 bool GetExpungeOnExit();
00611 void SetExpungeOnExit(bool b);
00612
00613
00614 bool Open(GSocket *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00615 bool Close();
00616
00617
00618 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00619 bool ReceiveFlags(MailMessage *Msg);
00620 bool Send(MailImapFolder *Folder, char *Msg, int Index = -1, bool Seen = true);
00621
00622 int GetMessages();
00623 bool Delete(int Message);
00624 int Sizeof(int Message);
00625 bool GetUid(int Message, char *Id);
00626 bool GetUidList(List<char> &Id);
00627 char *GetHeaders(int Message);
00628
00629
00630 bool GetFolders(List<MailImapFolder> &Folders, char *Path = 0);
00631 bool SelectFolder(char *Path, MailImapFolder *f = 0);
00632 char *GetSelectedFolder();
00633 int GetMessages(char *Path);
00634 bool CreateFolder(MailImapFolder *f);
00635 bool DeleteFolder(char *Path);
00636 bool RenameFolder(char *From, char *To);
00637 bool SetFolderFlags(MailImapFolder *f);
00638 bool ExpungeFolder(MailImapFolder *f);
00639
00640
00641 bool OnIdle();
00642 bool Poll(int *Recent = 0);
00643 };
00644
00645 #endif