From d9c8f2a53260be070680f95fa87bebd711867320 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 25 Mar 2014 08:26:45 +0000 Subject: [PATCH] Core/POP3 (thanks Oblivion!) git-svn-id: svn://ultimatepp.org/upp/trunk@7091 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/POP3/InetMessage.cpp | 86 +++++++ uppsrc/Core/POP3/POP3.cpp | 238 ++++++++++++++++++ uppsrc/Core/POP3/POP3.h | 75 ++++++ uppsrc/Core/POP3/POP3.upp | 15 ++ uppsrc/Core/POP3/init | 5 + .../Core/POP3/src.tpp/InetMessage$en-us.tpp | 68 +++++ uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp | 141 +++++++++++ uppsrc/Core/src.tpp/InetHeader$en-us.tpp | 62 +++++ 8 files changed, 690 insertions(+) create mode 100644 uppsrc/Core/POP3/InetMessage.cpp create mode 100644 uppsrc/Core/POP3/POP3.cpp create mode 100644 uppsrc/Core/POP3/POP3.h create mode 100644 uppsrc/Core/POP3/POP3.upp create mode 100644 uppsrc/Core/POP3/init create mode 100644 uppsrc/Core/POP3/src.tpp/InetMessage$en-us.tpp create mode 100644 uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp create mode 100644 uppsrc/Core/src.tpp/InetHeader$en-us.tpp diff --git a/uppsrc/Core/POP3/InetMessage.cpp b/uppsrc/Core/POP3/InetMessage.cpp new file mode 100644 index 000000000..c795342b4 --- /dev/null +++ b/uppsrc/Core/POP3/InetMessage.cpp @@ -0,0 +1,86 @@ +#include "POP3.h" + +bool InetMessage::ReadHeader(VectorMap& hdr, StringStream& ss) +{ + for(;;) { + if(ss.IsEof()) + return false; + String s = ss.GetLine(); + if(s.IsEmpty()) + return true; + if(s[0] == ' ' || s[0] == '\t') { + if(hdr.GetCount()) + hdr.Top().Cat(TrimLeft(s.Mid(1))); + } + else { + int q = s.Find(':'); + if(q >= 0) + hdr.Add(ToLower(s.Mid(0, q)), TrimLeft(s.Mid(q + 1))); + } + } +} + +bool InetMessage::ReadHeader(const String& s) +{ + part.Clear(); + header.Clear(); + StringStream ss(s); + return ReadHeader(header, ss); +} + +bool InetMessage::Read(const String& s) +{ + part.Clear(); + header.Clear(); + StringStream ss(s); + if(!ReadHeader(header, ss)) + return false; + + String type = header.Get("content-type"); + if(!type.StartsWith("multipart")) { + part.Add().body = LoadStream(ss); + return true; + } + + String boundary; + int q = type.Find("boundary="); + if(q < 0) + return false; + q += strlen("boundary="); + int qq = type.Find(";", q); + if(qq >= 0) + boundary = type.Mid(q, qq); + else + boundary = type.Mid(q); + + if(*boundary == '\"') + boundary = boundary.Mid(1); + if(*boundary.Last() == '\"') + boundary.Trim(boundary.GetCount() - 1); + + boundary = "--" + boundary; + String end_boundary = boundary + "--"; + + for(;;) { + String ln = ss.GetLine(); + if(ln == boundary) + break; + if(ss.IsEof()) + return false; + } + for(;;) { + Part& p = part.Add(); + if(!ReadHeader(p.header, ss)) + return false; + for(;;) { + if(ss.IsEof()) + return false; + String ln = ss.GetLine(); + if(ln == boundary) + break; + if(ln == end_boundary) + return true; + p.body << ln << "\r\n"; + } + } +} diff --git a/uppsrc/Core/POP3/POP3.cpp b/uppsrc/Core/POP3/POP3.cpp new file mode 100644 index 000000000..21e45f774 --- /dev/null +++ b/uppsrc/Core/POP3/POP3.cpp @@ -0,0 +1,238 @@ +#include "POP3.h" + +static bool sPop3Trace; +#define LLOG(x) do { if(sPop3Trace) RLOG(x); } while(0) + +void Pop3::Trace(bool b) +{ + sPop3Trace = b; +} + +String Pop3::GetTimeStamp() +{ + int begin = data.Find('<'); + if(begin >= 0) { + int end = data.Find('>', begin); + if(end > begin) { + end++; + return data.Mid(begin, end - begin); + } + } + return Null; +} + +bool Pop3::GetListItems(ValueMap& list, dword type1, dword type2) +{ + StringStream s(data); + for(;;) { + String line = s.GetLine(); + if(s.IsError()) + return false; + if(s.IsEof()) + break; + Vector s = Split(line, ' '); + if(s.GetCount() < 2) + return false; + list.Add(Scan(type1, s[0]), Scan(type2, s[1])); + } + return true; +} + +int Pop3::GetMessageCount() +{ + if(!PutGet("STAT\r\n")) + return Null; + String ok, cnt, tsz; + if(!SplitTo(data, ' ', ok, cnt, tsz)) + return Null; + return StrInt(cnt); +} + +String Pop3::GetMessage(int index) +{ + if(!PutGet(Format("RETR %d\r\n", index), true)) + return Null; + return data; +} + +String Pop3::GetMessageHeader(int index) +{ + if(!PutGet(Format("TOP %d %d\r\n", index, 0), true)) + return Null; + return data; +} + +bool Pop3::GetMessageList(ValueMap& list) +{ + VectorMap v; + + if(!PutGet("LIST\r\n", true)) + return false; + return GetListItems(list, INT_V, INT_V); +} + + +String Pop3::GetMessageUniqueId(int index) +{ + if(!PutGet(Format("UIDL %d\r\n", index))) + return Null; + String ok, id, tsz; + if(!SplitTo(data, ' ', ok, id, tsz)) + return Null; + return id; +} + +bool Pop3::GetMessageUniqueIds(ValueMap& uids) +{ + if(!PutGet("UIDL\r\n", true)) + return false; + return GetListItems(uids, INT_V, STRING_V); +} + +bool Pop3::RemoveMessage(int index) +{ + return PutGet(Format("DELE %d\r\n", index)); +} + +bool Pop3::Undo() +{ + return PutGet("RSET\r\n"); +} + +bool Pop3::Noop() +{ + return PutGet("NOOP\r\n"); +} + +String Pop3::GetDataLine() +{ + // We can't use TcpSocket::GetLine(), since it omits carriage returns we need. + String line; + for(;;) { + int c = Get(); + if(c < 0) { + if(!IsError()) + continue; + return String::GetVoid(); + } + line.Cat(c); + if(line.EndsWith("\r\n")) + return line; + } +} + +bool Pop3::PutGet(const String& s, bool multiline, bool nolog) +{ + // Put() request. + if(!s.IsEmpty()) { + if(!nolog) + LLOG(">> " << TrimRight(s)); + if(!PutAll(s)) { + LLOG("-- " << GetLastError()); + return false; + } + } + // Get() respone. + data.Clear(); + String line = GetDataLine(); + if(!line.IsEmpty()) { + LLOG("<< " << TrimRight(line)); + if(line.StartsWith("+OK")) { + if(!multiline) { + data << line; + return true; + } + else + for(;;) { + line = GetDataLine(); + if(line.IsEmpty()) + break; + if(line.StartsWith("..")) + line.Remove(0); + data << line; + if(!data.EndsWith("\r\n.\r\n")) + continue; + LLOG("<< ..."); + return true; + } + } + else + if(line.StartsWith("-ERR")) + error = line; + } + LLOG("-- " << GetLastError()); + return false; +} + +bool Pop3::Authenticate() +{ + // Try using APOP authentication. + String timestamp = GetTimeStamp(); + if(!timestamp.IsEmpty()) { + if(PutGet("APOP " + user + " " + MD5String(timestamp << pass) + "\r\n")) + return true; + } + else + if(PutGet("USER " + user + "\r\n")) { + LLOG(">>PASS ******"); + if(PutGet("PASS " + pass + "\r\n", false, true)) + return true; + } + + return false; +} + +bool Pop3::Login() +{ + try { + if(host.IsEmpty()) + throw Exc(t_("Hostname is not specified.")); + if(user.IsEmpty()) + throw Exc(t_("Username is not specified.")); + if(pass.IsEmpty()) + throw Exc(t_("Password is nor specified.")); + if(!Connect(host, Nvl(port, ssl ? 995 : 110))) + throw Exc(GetErrorDesc()); + LLOG(Format(t_("Opening connection to %s:%d."), host, port)); + if(ssl) { + if(!StartSSL()) + throw Exc(t_("Couldn't start SSL session.")); + LLOG(t_("SSL session successfully started.")); + } + // Receive server greetings. + if(!PutGet(Null)) + throw Exc(GetLastError()); + if(!Authenticate()) + throw Exc(GetLastError()); + } + catch (Exc e) { + error = e; + LLOG("-- " + e); + Logout(); + return false; + } + return online = true; +} + +bool Pop3::Logout() +{ + if(IsOnline()) + PutGet("QUIT\r\n"); + LLOG(Format(t_("Closing connection to %s:%d."), host, port)); + Close(); + online = false; + return true; +} + +Pop3::Pop3() +{ + ssl = false; + online = false; + Timeout(60000); +} + +Pop3::~Pop3() +{ + if(IsOpen()) + Close(); +} diff --git a/uppsrc/Core/POP3/POP3.h b/uppsrc/Core/POP3/POP3.h new file mode 100644 index 000000000..d3bc1180f --- /dev/null +++ b/uppsrc/Core/POP3/POP3.h @@ -0,0 +1,75 @@ +#ifndef _POP3_POP3_h +#define _POP3_POP3_h + +#include + +using namespace Upp; + +class Pop3 : public TcpSocket +{ + String host; + String user; + String pass; + String error; + String data; + int port; + bool ssl; + bool online; + + bool GetListItems(ValueMap& list, dword type1, dword type2); + String GetTimeStamp(); + bool Authenticate(); + String GetDataLine(); + bool PutGet(const String& s, bool multiline = false, bool nolog = false); + +public: + Pop3& Host(const String& h) { host = h; return *this; } + Pop3& Port(int p) { port = p; return *this; } + Pop3& User(const String& u, const String& p) { user = u; pass = p; return *this; } + Pop3& SSL(bool b = true) { ssl = b; return *this; } + + int GetMessageCount(); + String GetMessage(int index); + String GetMessageHeader(int index); + bool RemoveMessage(int index); + + bool GetMessageList(ValueMap& list); + String GetMessageUniqueId(int index); + bool GetMessageUniqueIds(ValueMap& uids); + + bool Undo(); + bool Noop(); + + bool Login(); + bool Logout(); + + bool IsOnline() const { return online; } + + String GetLastError() { return IsError() ? GetErrorDesc() : error; } + static void Trace(bool b = true); + + Pop3(); + ~Pop3(); +}; + +struct InetMessage { + struct Part : Moveable { + VectorMap header; + String body; + }; + + VectorMap header; + Vector part; + + bool Read(const String& msg); + bool ReadHeader(const String& msg); + String operator[](const char *id) const { return header.Get(id, Null); } + int GetPartCount() const { return part.GetCount(); } + String GetPartBody(int i) const { return part[i].body; } + String GetPartHeader(int i, const char *id) { return part[i].header.Get(id, Null); } + +private: + bool ReadHeader(VectorMap& hdr, StringStream& ss); +}; + +#endif diff --git a/uppsrc/Core/POP3/POP3.upp b/uppsrc/Core/POP3/POP3.upp new file mode 100644 index 000000000..e5d5b852a --- /dev/null +++ b/uppsrc/Core/POP3/POP3.upp @@ -0,0 +1,15 @@ +description "Post Office Protocol, version 3 encapsulation. Author: İsmail Yılmaz\377"; + +uses + Core, + Core/SSL; + +file + POP3.h, + POP3.cpp, + InetMessage.cpp, + src.tpp; + +mainconfig + "" = ""; + diff --git a/uppsrc/Core/POP3/init b/uppsrc/Core/POP3/init new file mode 100644 index 000000000..35aef293f --- /dev/null +++ b/uppsrc/Core/POP3/init @@ -0,0 +1,5 @@ +#ifndef _Core_POP3_icpp_init_stub +#define _Core_POP3_icpp_init_stub +#include "Core/init" +#include "Core/SSL/init" +#endif diff --git a/uppsrc/Core/POP3/src.tpp/InetMessage$en-us.tpp b/uppsrc/Core/POP3/src.tpp/InetMessage$en-us.tpp new file mode 100644 index 000000000..e911b7c4c --- /dev/null +++ b/uppsrc/Core/POP3/src.tpp/InetMessage$en-us.tpp @@ -0,0 +1,68 @@ +topic "struct InetMessage"; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,2#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] +[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] +[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] +[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] +[b42;2 $$9,9#13035079074754324216151401829390:normal] +[{_} +[ {{10000@(113.42.0) [s0;%% [*@7;4 InetMessage]]}}&] +[s0;i448;a25;kKO9;@(0.0.255) &] +[s0;i448;a25;kKO9; [@(0.0.255)3 struct][3 _][*3 InetMessage]&] +[s2; This is helper class intended for parsing Pop3 (or generally, +RFC822) messages. It parses messages to header map and one or +multiple (for multipart content) parts. Header names are converted +to lower`-case before being stored to map.&] +[s0;i448;a25;kKO9;:noref:@(0.0.255) &] +[ {{10000F(128)G(128)@1 [s0;%% [* Public Members List]]}}&] +[s3; &] +[s5;:InetMessage`:`:header: [_^VectorMap^ VectorMap]<[_^String^ String], +[_^String^ String]>_[* header]&] +[s2;%% Map of header fields.&] +[s3; &] +[s4; &] +[s5;:InetMessage`:`:part: [_^Vector^ Vector]<[_^InetMessage`:`:Part^ Part]>_[* part]&] +[s2;%% Message parts. Part is defined as&] +[s2;%% [C1 -|struct Part : Moveable `{]&] +[s2;%% [C1 -|-|VectorMap header;]&] +[s2;%% [C1 -|-|String body;]&] +[s2;%% [C1 -|`};]&] +[s3; &] +[s4; &] +[s5;:InetMessage`:`:Read`(const String`&`): [@(0.0.255) bool]_[* Read]([@(0.0.255) const]_[_^String^ S +tring][@(0.0.255) `&]_[*@3 msg])&] +[s2;%% Attempts to parse the whole message. Returns true on success.&] +[s3;%% &] +[s4;%% &] +[s5;:InetMessage`:`:ReadHeader`(const String`&`): [@(0.0.255) bool]_[* ReadHeader]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 msg])&] +[s2;%% Attempts to parse only the message header (part is left empty). +Returns true on success.&] +[s3;%% &] +[s4;%% &] +[s5;:InetMessage`:`:operator`[`]`(const char`*`)const: [_^String^ String]_[* operator`[`] +]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&] +[s2;%% Returns the value of header field or empty String if header +field is not present. [%-*@3 id] should be lower`-case (as all +header names are converted to lower`-case by Read).&] +[s3;%% &] +[s4;%% &] +[s5;:InetMessage`:`:GetPartCount`(`)const: [@(0.0.255) int]_[* GetPartCount]()_[@(0.0.255) c +onst]&] +[s2;%% Returns the number of message parts. This is 1 for non`-multipart +message.&] +[s3;%% &] +[s4;%% &] +[s5;:InetMessage`:`:GetPartBody`(int`)const: [_^String^ String]_[* GetPartBody]([@(0.0.255) i +nt]_[*@3 i])_[@(0.0.255) const]&] +[s2;%% Returns the body of part [%-*@3 i].&] +[s3;%% &] +[s4;%% &] +[s5;:InetMessage`:`:GetPartHeader`(int`,const char`*`): [_^String^ String]_[* GetPartHead +er]([@(0.0.255) int]_[*@3 i], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])&] +[s2;%% Returns header [%-*@3 id] for part [%-*@3 i].&] +[s3;%% ]] \ No newline at end of file diff --git a/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp b/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp new file mode 100644 index 000000000..1e2b42499 --- /dev/null +++ b/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp @@ -0,0 +1,141 @@ +topic "POP3"; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,2#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] +[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] +[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] +[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] +[b42;2 $$9,9#13035079074754324216151401829390:normal] +[{_} +[ {{10000@(113.42.0) [s0;%% [*@7;4 Pop3]]}}&] +[s1;@(0.0.255)3 &] +[s1;:Pop3`:`:class: [@(0.0.255)3 class][3 _][*3 Pop3][3 _:_][@(0.0.255)3 public][3 _][*@3;3 TcpSocke +t]&] +[s2;%% Encapsulates the Post Office Protocol, Version 3 (POP3) as +specified in the [^http`:`/`/tools`.ietf`.org`/html`/rfc1939^ RFC +1939]. This class provides a simplified interface to a single +POP3 mailbox.&] +[s2;%% Important: Pop3 indicies are 1 based! Thus the correct loop +to obtain all messages is for(int i `= 1; i <`= pop3.GetMessageCount(); +i`+`+).&] +[s2;%% &] +[s6;%% Requires OpenSSL library.&] +[s3; &] +[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&] +[s0; &] +[s5;:Pop3`:`:Host`(const String`&`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Host]([@(0.0.255) const +]_[_^String^ String][@(0.0.255) `&]_[*@3 h])&] +[s2;%% Sets hostname. Returns `*this for method chaining.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:Port`(int`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Port]([@(0.0.255) int]_[*@3 p])&] +[s2;%% Sets port number. Returns `*this for method chaining.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:User`(const String`&`,const String`&`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* User]( +[@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 u], [@(0.0.255) const]_[_^String^ S +tring][@(0.0.255) `&]_[*@3 p])&] +[s2;%% Sets username and password. Returns `*this for method chaining.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:SSL`(bool`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* SSL]([@(0.0.255) bool]_[*@3 b]_`=_[@(0.0.255) t +rue])&] +[s2;%% Activates POP3S mode (using SSL). Requires Core/SSL package. +Returns `*this for method chaining.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:GetMessageCount`(`): [@(0.0.255) int]_[* GetMessageCount]()&] +[s2;%% Returns the number of currently available messages in the +POP3 mailbox. Returns `-1 on failure.&] +[s3; &] +[s4; &] +[s5;:Pop3`:`:GetMessage`(int`): [_^String^ String]_[* GetMessage]([@(0.0.255) int]_[*@3 index +])&] +[s2;%% Retreives a message with the given [%-*@3 index] from the POP3 +mailbox. Returns Null on failure. First message has index 1, +last GetMessageCount().&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:GetMessageHeader`(int`): [_^String^ String]_[* GetMessageHeader]([@(0.0.255) i +nt]_[*@3 index])&] +[s2;%% Retreives the header section of a message with the given [%-*@3 index] +from the POP3 mailbox. Returns Null on failure. First message +has index 1, last GetMessageCount().&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:GetMessageList`(ValueMap`&`): [@(0.0.255) bool]_[* GetMessageList]([_^ValueMap^ V +alueMap][@(0.0.255) `&]_[*@3 list])&] +[s2;%% Retrieves the list of currently available messages in the +POP3 mailbox. [%-*@3 list] is a ValueMap containing messages indices +and sizes as integer key and integer value pairs. Returns true +on success.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:GetMessageUniqueId`(int`): [_^String^ String]_[* GetMessageUniqueId]([@(0.0.255) i +nt]_[*@3 index])&] +[s2;%% Retreives the unique identifier string of a message with the +given [%-*@3 index] from the POP3 mailbox. Returns Null on failure.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:GetMessageUniqueIds`(ValueMap`&`): [@(0.0.255) bool]_[* GetMessageUniqueIds]( +[_^topic`:`/`/Core`/src`/ValueMap`$en`-us`#ValueMap`:`:class^ ValueMap][@(0.0.255) `& +]_[*@3 uids])&] +[s2;%% Retrieves the unique identifier strings of currently available +messages in the POP3 mailbox. [%-*@3 uids] is a ValueMap containing +messages indices and unique identifiers as integer key and String +value pairs. Returns true on success.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:RemoveMessage`(int`): [@(0.0.255) bool]_[* RemoveMessage]([@(0.0.255) int]_[*@3 i +ndex])&] +[s2;%% Marks a message with the given [%-*@3 index] to be deleted from +the POP3 mailbox. Messages marked for deletion are only deleted +by the POP3 server after a successful [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Logout`(`)^ L +ogout()]. If you want to unmark messages, you must invoke [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Undo`(`)^ U +ndo()] method before logging out. Returns true on success. &] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:Undo`(`): [@(0.0.255) bool]_[* Undo]()&] +[s2;%% Resets POP3 session. Useful for unmarking the messages marked +to be deleted. This method must be invoked before any [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Logout`(`)^ L +ogout()]. Returns true on success.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:Noop`(`): [@(0.0.255) bool]_[* Noop]()&] +[s2;%% Sends a NOOP command to the POP3 server. Useful for keeping +connections alive.&] +[s3; &] +[s4; &] +[s5;:Pop3`:`:Login`(`): [@(0.0.255) bool]_[* Login]()&] +[s2;%% Connect and login to the POP3 server. User name and password +must be set. Uses APOP authentication mechanism, if available. +Returns true on success.&] +[s3; &] +[s4; &] +[s5;:Pop3`:`:Logout`(`): [@(0.0.255) bool]_[* Logout]()&] +[s2;%% Logout of and disconnect from the POP3 server. Messages marked +for deletion will be permanently deleted from the server after +a successful logout. Returns true on success.&] +[s3; &] +[s4; &] +[s5;:Pop3`:`:IsOnline`(`)const: [@(0.0.255) bool]_[* IsOnline]()_[@(0.0.255) const]&] +[s2;%% Returns true if the POP3 mailbox is online. &] +[s3; &] +[s4; &] +[s5;:Pop3`:`:GetLastError`(`): [_^String^ String]_[* GetLastError]()&] +[s2;%% Returns the description of last error.&] +[s3; &] +[s4; &] +[s5;:Pop3`:`:Trace`(bool`): [@(0.0.255) static] [@(0.0.255) void]_[* Trace]([@(0.0.255) bool]_ +[*@3 b]_`=_[@(0.0.255) true])&] +[s2;%% Activates logging of POP3.&] +[s3;%% &] +[ {{10000F(128)G(128)@1 [s0;%% [* Constructor detail]]}}&] +[s0; &] +[s5;:Pop3`:`:Pop3`(`): [* Pop3]()&] +[s2;%% Default constructor.&] +[s3; &] +[s0;%% ]] \ No newline at end of file diff --git a/uppsrc/Core/src.tpp/InetHeader$en-us.tpp b/uppsrc/Core/src.tpp/InetHeader$en-us.tpp new file mode 100644 index 000000000..a00a5aba5 --- /dev/null +++ b/uppsrc/Core/src.tpp/InetHeader$en-us.tpp @@ -0,0 +1,62 @@ +topic ""; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,2#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] +[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] +[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] +[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] +[b42;2 $$9,9#13035079074754324216151401829390:normal] +[{_} +[ {{10000@(113.42.0) [s0;%% [*@7;4 InetHeader]]}}&] +[s3; &] +[s1;:InetHeader`:`:struct: [@(0.0.255)3 struct][3 _][*3 InetHeader]&] +[s2;%% InetHeader is a simple helper class for parsing internet header +texts (RFC822). In addition, InetHeader also detects `"set`-cookie`" +headers and parses the content according to cookie syntax (this +can be ignored if header is not HTTP related).&] +[s3; &] +[ {{10000F(128)G(128)@1 [s0;%% [* Public Member List]]}}&] +[s3; &] +[s5;:InetHeader`:`:fields: [_^VectorMap^ VectorMap]<[_^String^ String], +[_^String^ String]>_[* fields]&] +[s2;%% Http fields as key`-value pairs. Keys are converted to lower`-case. +Note that the same key can be present multiple times.&] +[s3; &] +[s4; &] +[s5;:InetHeader`:`:cookies: [_^VectorMap^ VectorMap]<[_^String^ String], +[_^HttpCookie^ HttpCookie]>_[* cookies]&] +[s2;%% Set of http response http cookies (filled based on Set`-Cookie +headers during parsing).&] +[s3; &] +[s4; &] +[s5;:InetHeader`:`:Clear`(`): [@(0.0.255) void]_[* Clear]()&] +[s2;%% Clears data.&] +[s3; &] +[s4; &] +[s5;:InetHeader`:`:ParseAdd`(const String`&`): [@(0.0.255) bool]_[* ParseAdd]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&] +[s2;%% Parses the header (all lines of header) into [* first`_line +]and [* fields].&] +[s3;%% &] +[s4; &] +[s5;:InetHeader`:`:Parse`(const String`&`): [@(0.0.255) bool]_[* Parse]([@(0.0.255) const]_ +[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&] +[s2;%% Calls Clear and parses the header (all lines of header) into +[* first`_line ]and [* fields].&] +[s3;%% &] +[s4; &] +[s5;:InetHeader`:`:GetCookie`(const char`*`)const: [_^String^ String]_[* GetCookie]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&] +[s2;%% Returns the value of first cookie of response (set by Set`-Cookie) +with name [%-*@3 id].&] +[s3;%% &] +[s4;%% &] +[s5;:InetHeader`:`:operator`[`]`(const char`*`)const: [_^String^ String]_[* operator`[`]]( +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&] +[s2;%% Returns the first http header field with key [%-*@3 id] (must +be lower`-case) or empty string if such field is not present.&] +[s3;%% &] +[s0;%% ]] \ No newline at end of file