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 char* Text;
00200 char* TextCharset;
00201
00202 char* Html;
00203 char* HtmlCharset;
00204
00205 public:
00206 List<AddressDescriptor> To;
00207 AddressDescriptor *From;
00208 AddressDescriptor *Reply;
00209 char* Subject;
00210 char* MessageID;
00211 List<FileDescriptor> FileDesc;
00212 char* InternetHeader;
00213 char Priority;
00214 int MarkColour;
00215 uint8 DispositionNotificationTo;
00216 char* References;
00217
00218
00219 void *Private;
00220
00221
00222 MailMessage();
00223 virtual ~MailMessage();
00224 void Empty();
00225
00226 virtual char *GetBody();
00227 virtual bool SetBody(char *Txt, int Bytes = -1, bool Copy = true, char *Cs = 0);
00228 virtual char *GetBodyCharset();
00229 virtual bool SetBodyCharset(char *Cs, bool Copy = true);
00230
00231 virtual char *GetHtml();
00232 virtual bool SetHtml(char *Txt, int Bytes = -1, bool Copy = true, char *Cs = 0);
00233 virtual char *GetHtmlCharset();
00234 virtual bool SetHtmlCharset(char *Cs, bool Copy = true);
00235
00236
00237 GStringPipe *Raw;
00238
00239 bool Encode(GStream &Out, GStream *HeadersSink, MailProtocol *Protocol, bool Mime = true);
00240 bool EncodeHeaders(GStream &Out, MailProtocol *Protocol, bool Mime = true);
00241 bool EncodeBody(GStream &Out, MailProtocol *Protocol, bool Mime = true);
00242 bool EncodeQuotedPrintable(GStream &Out, char *In);
00243 bool EncodeText(GStream &Out, char *In);
00244 };
00245
00247 class MailProtocol
00248 {
00249 protected:
00250 char Buffer[4<<10];
00251 GSocketI *Socket;
00252
00253 bool Read();
00254 bool Write(char *Buf = NULL, bool Log = false);
00255
00256 virtual void OnUserMessage(char *Str) {}
00257
00258 public:
00259
00260 GWindow *LogNotify;
00261 int LogMsg;
00262 int LogData;
00263 void Log(char *Str, COLOUR c);
00264 void Log(LogEntry *e);
00265
00266
00267 MailProtocolProgress *Items;
00268 MailProtocolProgress *Transfer;
00269
00270
00271 char *ServerMsg;
00272 char *ProgramName;
00273 char *DefaultDomain;
00274 char *ExtraOutgoingHeaders;
00275 List<char> CharsetPrefs;
00276
00277
00278 MailProtocol();
00279 virtual ~MailProtocol();
00280
00281
00282 GSocketI *GetSocket() { return Socket; }
00283 };
00284
00286
00287
00289 #define MAIL_USE_STARTTLS 0x01
00290
00291 #define MAIL_USE_AUTH 0x02
00292
00293 #define MAIL_USE_PLAIN 0x04
00294
00295 #define MAIL_USE_LOGIN 0x08
00296
00297 #define MAIL_USE_NTLM 0x10
00298
00300 class MailSink : public MailProtocol
00301 {
00302 public:
00304 virtual bool Open
00305 (
00307 GSocketI *S,
00309 char *RemoteHost,
00311 char *LocalDomain,
00313 char *UserName,
00315 char *Password,
00317 int Port,
00319 int Flags
00320 ) = 0;
00322 virtual bool Close() = 0;
00323
00324
00325
00328 virtual GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From) = 0;
00329
00331 virtual bool SendEnd(GStringPipe *Sink) = 0;
00332
00333
00334 virtual bool Send(MailMessage *Msg, bool Mime) { return false; }
00335 };
00336
00337 class MailTransaction
00338 {
00339 public:
00340 int Index;
00341 bool Delete;
00342 bool Status;
00343 bool Oversize;
00344 GStream *Stream;
00345
00346 MailTransaction();
00347 ~MailTransaction();
00348 };
00349
00351 enum MailSrcStatus
00352 {
00354 DownloadAll,
00356 DownloadTop,
00358 DownloadNone,
00360 DownloadAbort
00361 };
00362
00364 typedef MailSrcStatus (*MailSrcCallback)
00365 (
00367 MailTransaction *Trans,
00369 int64 Size,
00371 int *LinesToDownload,
00373 int Data
00374 );
00375
00377 #define MAIL_SOURCE_STARTTLS 0x01
00378
00379 #define MAIL_SOURCE_AUTH 0x02
00380
00381 #define MAIL_SOURCE_USE_PLAIN 0x04
00382
00383 #define MAIL_SOURCE_USE_LOGIN 0x08
00384
00386 class MailSource : public MailProtocol
00387 {
00388 public:
00390 virtual bool Open
00391 (
00393 GSocketI *S,
00395 char *RemoteHost,
00397 int Port,
00399 char *User,
00401 char *Password,
00403 char *&Cookie,
00405 int Flags = 0) = 0;
00407 virtual bool Close() = 0;
00408
00410 virtual int GetMessages() = 0;
00412 virtual bool Receive
00413 (
00416 GArray<MailTransaction*> &Trans,
00418 MailSrcCallback Callback = 0,
00420 int Data = 0
00421 ) = 0;
00423 virtual bool Delete(int Message) = 0;
00425 virtual int Sizeof(int Message) = 0;
00427 virtual bool GetSizes(GArray<int> &Sizes) { return false; }
00429 virtual bool GetUid(int Message, char *Id) = 0;
00431 virtual bool GetUidList(List<char> &Id) = 0;
00433 virtual char *GetHeaders(int Message) = 0;
00435 virtual void SetProxy(char *Server, int Port) {}
00436 };
00437
00439
00440
00442 class MailSmtp : public MailSink
00443 {
00444 protected:
00445 bool ReadReply(char *Str, GStringPipe *Pipe = 0);
00446 bool WriteText(char *Str);
00447
00448 public:
00449 MailSmtp();
00450 ~MailSmtp();
00451
00452 bool Open(GSocketI *S, char *RemoteHost, char *LocalDomain, char *UserName, char *Password, int Port = SMTP_PORT, int Flags = 0);
00453 bool Close();
00454
00455 GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From);
00456 bool SendEnd(GStringPipe *Sink);
00457
00458 bool Send(MailMessage *Msg, bool Mime = false);
00459 };
00460
00461 class MailSendFolder : public MailSink
00462 {
00463 class MailPostFolderPrivate *d;
00464
00465 public:
00466 MailSendFolder(char *Path);
00467 ~MailSendFolder();
00468
00469 bool Open(GSocketI *S, char *RemoteHost, char *LocalDomain, char *UserName, char *Password, int Port = 0, int Flags = 0);
00470 bool Close();
00471
00472 GStringPipe *SendStart(List<AddressDescriptor> &To, AddressDescriptor *From);
00473 bool SendEnd(GStringPipe *Sink);
00474 };
00475
00476 class MailPop3 : public MailSource
00477 {
00478 protected:
00479 bool ReadReply(int Timeout = -1);
00480 bool ReadMultiLineReply(char *&Str);
00481 int GetInt();
00482 bool MailIsEnd(char *Ptr, int Len);
00483
00484 char *End;
00485 char *Marker;
00486 int Messages;
00487
00488 public:
00489 MailPop3();
00490 ~MailPop3();
00491
00492
00493 bool Open(GSocketI *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00494 bool Close();
00495
00496
00497 int GetMessages() { return Messages; }
00498 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00499 bool Delete(int Message);
00500 int Sizeof(int Message);
00501 bool GetSizes(GArray<int> &Sizes);
00502 bool GetUid(int Message, char *Id);
00503 bool GetUidList(List<char> &Id);
00504 char *GetHeaders(int Message);
00505 };
00506
00507 class MailReceiveFolder : public MailSource
00508 {
00509 protected:
00510 class MailReceiveFolderPrivate *d;
00511
00512 public:
00513 MailReceiveFolder(char *Path);
00514 ~MailReceiveFolder();
00515
00516
00517 bool Open(GSocketI *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00518 bool Close();
00519
00520
00521 int GetMessages();
00522 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00523 bool Delete(int Message);
00524 int Sizeof(int Message);
00525 bool GetUid(int Message, char *Id);
00526 bool GetUidList(List<char> &Id);
00527 char *GetHeaders(int Message);
00528 };
00529
00530 class MailPhp : public MailSource
00531 {
00532 protected:
00533 class MailPhpPrivate *d;
00534
00535 bool Get(GSocketI *S, char *Uri, GStream &Out, bool ChopDot);
00536
00537 public:
00538 MailPhp();
00539 ~MailPhp();
00540
00541
00542 bool Open(GSocketI *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00543 bool Close();
00544
00545
00546 int GetMessages();
00547 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00548 bool Delete(int Message);
00549 int Sizeof(int Message);
00550 bool GetSizes(GArray<int> &Sizes);
00551 bool GetUid(int Message, char *Id);
00552 bool GetUidList(List<char> &Id);
00553 char *GetHeaders(int Message);
00554 void SetProxy(char *Server, int Port);
00555 };
00556
00557 class MailImapMsg
00558 {
00559 public:
00560 uint ImapSeen:1;
00561 uint ImapRecent:1;
00562 uint ImapDeleted:1;
00563 uint ImapExpunged:1;
00564 int Index;
00565
00566 MailImapMsg()
00567 {
00568 ImapSeen = 0;
00569 ImapRecent = 0;
00570 ImapDeleted = 0;
00571 ImapExpunged = 0;
00572 Index = -1;
00573 }
00574 };
00575
00576 class MailImapFolder
00577 {
00578 friend class MailIMap;
00579
00580 char Sep;
00581 char *Path;
00582
00583 public:
00584 bool NoSelect;
00585 bool NoInferiors;
00586 bool Marked;
00587 int Exists;
00588 int Recent;
00589 int Deleted;
00590 int UnseenIndex;
00591
00592 MailImapFolder();
00593 virtual ~MailImapFolder();
00594
00595 char *GetPath();
00596 void SetPath(char *s);
00597 char *GetName();
00598 void SetName(char *s);
00599 };
00600
00601 class MailIMap : public MailSource, public GSemaphore
00602 {
00603 protected:
00604 class MailIMapPrivate *d;
00605
00606 GSocketI *S;
00607 char Buf[1024];
00608 List<char> Dialog;
00609 List<char> Uid;
00610
00611 void ClearDialog();
00612 void ClearUid();
00613 bool FillUidList();
00614 bool WriteBuf(bool ObsurePass = false);
00615 bool ReadResponse(int Cmd = -1, GStringPipe *Out = 0);
00616 bool ReadLine(char *Buf, int Size);
00617 bool GetParts(int Message, GStream &Out, char *Parts, char **Flags = 0);
00618
00619 public:
00620 MailIMap();
00621 ~MailIMap();
00622
00623
00624 char GetFolderSep();
00625 char *GetCurrentPath();
00626 bool GetExpungeOnExit();
00627 void SetExpungeOnExit(bool b);
00628 bool ServerOption(char *Opt);
00629
00630
00631 bool Open(GSocketI *S, char *RemoteHost, int Port, char *User, char *Password, char *&Cookie, int Flags = 0);
00632 bool Close();
00633
00634
00635 bool Receive(GArray<MailTransaction*> &Trans, MailSrcCallback Callback = 0, int Data = 0);
00636 bool ReceiveFlags(MailMessage *Msg);
00637 bool Send(MailImapFolder *Folder, char *Msg, int Index = -1, bool Seen = true);
00638
00639 int GetMessages();
00640 bool Delete(int Message);
00641 int Sizeof(int Message);
00642 bool GetUid(int Message, char *Id);
00643 bool GetUidList(List<char> &Id);
00644 char *GetHeaders(int Message);
00645
00646
00647 bool GetFolders(List<MailImapFolder> &Folders, char *Path = 0);
00648 bool SelectFolder(char *Path, MailImapFolder *f = 0);
00649 char *GetSelectedFolder();
00650 int GetMessages(char *Path);
00651 bool CreateFolder(MailImapFolder *f);
00652 bool DeleteFolder(char *Path);
00653 bool RenameFolder(char *From, char *To);
00654 bool SetFolderFlags(MailImapFolder *f);
00655 bool ExpungeFolder(MailImapFolder *f);
00656
00659 bool OnIdle(int *Exists, int *Recent, GArray<MailImapMsg> *Msg);
00660 bool Poll(int *Recent = 0);
00661 };
00662
00663 #endif