home *** CD-ROM | disk | FTP | other *** search
- {==============================================================================|
- | Project : Delphree - Synapse | 002.001.000 |
- |==============================================================================|
- | Content: POP3 client |
- |==============================================================================|
- | Copyright (c)1999-2002, Lukas Gebauer |
- | All rights reserved. |
- | |
- | Redistribution and use in source and binary forms, with or without |
- | modification, are permitted provided that the following conditions are met: |
- | |
- | Redistributions of source code must retain the above copyright notice, this |
- | list of conditions and the following disclaimer. |
- | |
- | Redistributions in binary form must reproduce the above copyright notice, |
- | this list of conditions and the following disclaimer in the documentation |
- | and/or other materials provided with the distribution. |
- | |
- | Neither the name of Lukas Gebauer nor the names of its contributors may |
- | be used to endorse or promote products derived from this software without |
- | specific prior written permission. |
- | |
- | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
- | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
- | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
- | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
- | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
- | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
- | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
- | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
- | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
- | DAMAGE. |
- |==============================================================================|
- | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
- | Portions created by Lukas Gebauer are Copyright (c)2001-2002. |
- | All Rights Reserved. |
- |==============================================================================|
- | Contributor(s): |
- |==============================================================================|
- | History: see HISTORY.HTM from distribution package |
- | (Found at URL: http://www.ararat.cz/synapse/) |
- |==============================================================================}
-
- {$WEAKPACKAGEUNIT ON}
-
- //RFC-1734
- //RFC-1939
- //RFC-2195
- //RFC-2449
- //RFC-2595
-
- unit POP3send;
-
- interface
-
- uses
- SysUtils, Classes,
- blcksock, SynaUtil, SynaCode;
-
- const
- cPop3Protocol = 'pop3';
-
- type
- TPOP3AuthType = (POP3AuthAll, POP3AuthLogin, POP3AuthAPOP);
-
- TPOP3Send = class(TSynaClient)
- private
- FSock: TTCPBlockSocket;
- FResultCode: Integer;
- FResultString: string;
- FFullResult: TStringList;
- FUsername: string;
- FPassword: string;
- FStatCount: Integer;
- FStatSize: Integer;
- FTimeStamp: string;
- FAuthType: TPOP3AuthType;
- FPOP3cap: TStringList;
- FAutoTLS: Boolean;
- FFullSSL: Boolean;
- function ReadResult(Full: Boolean): Integer;
- function Connect: Boolean;
- function AuthLogin: Boolean;
- function AuthApop: Boolean;
- public
- constructor Create;
- destructor Destroy; override;
- function Capability: Boolean;
- function Login: Boolean;
- procedure Logout;
- function Reset: Boolean;
- function NoOp: Boolean;
- function Stat: Boolean;
- function List(Value: Integer): Boolean;
- function Retr(Value: Integer): Boolean;
- function Dele(Value: Integer): Boolean;
- function Top(Value, Maxlines: Integer): Boolean;
- function Uidl(Value: Integer): Boolean;
- function StartTLS: Boolean;
- function FindCap(const Value: string): string;
- published
- property ResultCode: Integer read FResultCode;
- property ResultString: string read FResultString;
- property FullResult: TStringList read FFullResult;
- property Username: string read FUsername Write FUsername;
- property Password: string read FPassword Write FPassword;
- property StatCount: Integer read FStatCount;
- property StatSize: Integer read FStatSize;
- property TimeStamp: string read FTimeStamp;
- property AuthType: TPOP3AuthType read FAuthType Write FAuthType;
- property Sock: TTCPBlockSocket read FSock;
- property AutoTLS: Boolean read FAutoTLS Write FAutoTLS;
- property FullSSL: Boolean read FFullSSL Write FFullSSL;
- end;
-
- implementation
-
- const
- CRLF = #13#10;
-
- constructor TPOP3Send.Create;
- begin
- inherited Create;
- FFullResult := TStringList.Create;
- FPOP3cap := TStringList.Create;
- FSock := TTCPBlockSocket.Create;
- FSock.CreateSocket;
- FSock.ConvertLineEnd := True;
- FTimeout := 300000;
- FTargetPort := cPop3Protocol;
- FUsername := '';
- FPassword := '';
- FStatCount := 0;
- FStatSize := 0;
- FAuthType := POP3AuthAll;
- FAutoTLS := False;
- FFullSSL := False;
- end;
-
- destructor TPOP3Send.Destroy;
- begin
- FSock.Free;
- FPOP3cap.Free;
- FullResult.Free;
- inherited Destroy;
- end;
-
- function TPOP3Send.ReadResult(Full: Boolean): Integer;
- var
- s: string;
- begin
- Result := 0;
- FFullResult.Clear;
- s := FSock.RecvString(FTimeout);
- if Pos('+OK', s) = 1 then
- Result := 1;
- FResultString := s;
- if Full and (Result = 1) then
- repeat
- s := FSock.RecvString(FTimeout);
- if s = '.' then
- Break;
- FFullResult.Add(s);
- until FSock.LastError <> 0;
- FResultCode := Result;
- end;
-
- function TPOP3Send.AuthLogin: Boolean;
- begin
- Result := False;
- FSock.SendString('USER ' + FUserName + CRLF);
- if ReadResult(False) <> 1 then
- Exit;
- FSock.SendString('PASS ' + FPassword + CRLF);
- Result := ReadResult(False) = 1;
- end;
-
- function TPOP3Send.AuthAPOP: Boolean;
- var
- s: string;
- begin
- s := StrToHex(MD5(FTimeStamp + FPassWord));
- FSock.SendString('APOP ' + FUserName + ' ' + s + CRLF);
- Result := ReadResult(False) = 1;
- end;
-
- function TPOP3Send.Connect: Boolean;
- begin
- // Do not call this function! It is calling by LOGIN method!
- FStatCount := 0;
- FStatSize := 0;
- FSock.CloseSocket;
- FSock.LineBuffer := '';
- FSock.CreateSocket;
- if FFullSSL then
- FSock.SSLEnabled := True;
- FSock.Bind(FIPInterface, cAnyPort);
- FSock.Connect(FTargetHost, FTargetPort);
- Result := FSock.LastError = 0;
- end;
-
- function TPOP3Send.Capability: Boolean;
- begin
- FPOP3cap.Clear;
- Result := False;
- FSock.SendString('CAPA' + CRLF);
- Result := ReadResult(True) = 1;
- if Result then
- FPOP3cap.AddStrings(FFullResult);
- end;
-
- function TPOP3Send.Login: Boolean;
- var
- s, s1: string;
- begin
- Result := False;
- FTimeStamp := '';
- if not Connect then
- Exit;
- if ReadResult(False) <> 1 then
- Exit;
- s := SeparateRight(FResultString, '<');
- if s <> FResultString then
- begin
- s1 := SeparateLeft(s, '>');
- if s1 <> s then
- FTimeStamp := '<' + s1 + '>';
- end;
- Result := False;
- if Capability then
- if FAutoTLS and (Findcap('STLS') <> '') then
- if StartTLS then
- Capability;
- if (FTimeStamp <> '') and not (FAuthType = POP3AuthLogin) then
- begin
- Result := AuthApop;
- if not Result then
- begin
- if not Connect then
- Exit;
- if ReadResult(False) <> 1 then
- Exit;
- end;
- end;
- if not Result and not (FAuthType = POP3AuthAPOP) then
- Result := AuthLogin;
- end;
-
- procedure TPOP3Send.Logout;
- begin
- FSock.SendString('QUIT' + CRLF);
- ReadResult(False);
- FSock.CloseSocket;
- end;
-
- function TPOP3Send.Reset: Boolean;
- begin
- FSock.SendString('RSET' + CRLF);
- Result := ReadResult(False) = 1;
- end;
-
- function TPOP3Send.NoOp: Boolean;
- begin
- FSock.SendString('NOOP' + CRLF);
- Result := ReadResult(False) = 1;
- end;
-
- function TPOP3Send.Stat: Boolean;
- var
- s: string;
- begin
- Result := False;
- FSock.SendString('STAT' + CRLF);
- if ReadResult(False) <> 1 then
- Exit;
- s := SeparateRight(ResultString, '+OK ');
- FStatCount := StrToIntDef(SeparateLeft(s, ' '), 0);
- FStatSize := StrToIntDef(SeparateRight(s, ' '), 0);
- Result := True;
- end;
-
- function TPOP3Send.List(Value: Integer): Boolean;
- begin
- if Value = 0 then
- FSock.SendString('LIST' + CRLF)
- else
- FSock.SendString('LIST ' + IntToStr(Value) + CRLF);
- Result := ReadResult(Value = 0) = 1;
- end;
-
- function TPOP3Send.Retr(Value: Integer): Boolean;
- begin
- FSock.SendString('RETR ' + IntToStr(Value) + CRLF);
- Result := ReadResult(True) = 1;
- end;
-
- function TPOP3Send.Dele(Value: Integer): Boolean;
- begin
- FSock.SendString('DELE ' + IntToStr(Value) + CRLF);
- Result := ReadResult(False) = 1;
- end;
-
- function TPOP3Send.Top(Value, Maxlines: Integer): Boolean;
- begin
- FSock.SendString('TOP ' + IntToStr(Value) + ' ' + IntToStr(Maxlines) + CRLF);
- Result := ReadResult(True) = 1;
- end;
-
- function TPOP3Send.Uidl(Value: Integer): Boolean;
- begin
- if Value = 0 then
- FSock.SendString('UIDL' + CRLF)
- else
- FSock.SendString('UIDL ' + IntToStr(Value) + CRLF);
- Result := ReadResult(Value = 0) = 1;
- end;
-
- function TPOP3Send.StartTLS: Boolean;
- begin
- Result := False;
- FSock.SendString('STLS' + CRLF);
- if ReadResult(False) = 1 then
- begin
- Fsock.SSLDoConnect;
- Result := FSock.LastError = 0;
- end;
- end;
-
- function TPOP3Send.FindCap(const Value: string): string;
- var
- n: Integer;
- s: string;
- begin
- s := UpperCase(Value);
- Result := '';
- for n := 0 to FPOP3cap.Count - 1 do
- if Pos(s, UpperCase(FPOP3cap[n])) = 1 then
- begin
- Result := FPOP3cap[n];
- Break;
- end;
- end;
-
- end.
-