📄 pop3prot.pas
字号:
FProtocolState := pop3WaitingUser;
StateChange(pop3Connected);
TriggerSessionConnected(Error);
if Assigned(FWhenConnected) then
FWhenConnected
else begin
TriggerRequestDone(0);
end;
end
else if FState = pop3WaitingResponse then begin
if Assigned(FNext) then
FNext
else
raise Pop3Exception.Create('Program error: FNext is nil');
end
else begin
{ Unexpected data received }
DisplayLastResponse;
end;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerResponse(Msg : String);
begin
if Assigned(FOnResponse) then
FOnResponse(Self, Msg);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerStateChange;
begin
if Assigned(FOnStateChange) then
FOnStateChange(Self);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerRequestDone(Error: Word);
begin
{ Special processing for Quit (Roger Morton 24-12-99) }
if FRequestType = pop3Quit then begin
if FWaitingOnQuit then
{ When the second RqDone arrives (from WSocketSessionClosed), }
{ treat it as a normal event by setting a zero Error code }
Error := 0
else begin
{ When the first RqDone arrives, set the FWaitingOnQuit flag so }
{ we're ready to handle a second RqDone. }
{ Take no other action (in particular, we don't advise the user }
{ that the first RqDone has happened) }
FWaitingOnQuit := True;
Exit;
end;
{ Fall down here for all normal RqDone, and after the second RqDone }
{ following a Quit }
FWaitingOnQuit := False;
end;
if not FRequestDoneFlag then begin
FRequestDoneFlag := TRUE;
if Assigned(FNextRequest) then begin
if FState <> pop3Abort then
StateChange(pop3InternalReady);
FNextRequest;
end
else begin
StateChange(pop3Ready);
{ Restore the lastresponse saved before quit command }
if FHighLevelFlag and (FStatusCodeSave >= 0) then begin
FLastResponse := FLastResponseSave;
FStatusCode := FStatusCodeSave;
end;
FHighLevelFlag := FALSE;
PostMessage(Handle, WM_POP3_REQUEST_DONE, 0, Error);
end;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerDisplay(Msg : String);
begin
if Assigned(FOnDisplay) then
FOnDisplay(Self, Msg);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerSessionConnected(Error : Word);
begin
if Assigned(FOnSessionConnected) then
FOnSessionConnected(Self, Error);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.TriggerSessionClosed(Error : Word);
begin
if Assigned(FOnSessionClosed) then
FOnSessionClosed(Self, Error);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.DoHighLevelAsync;
begin
{$IFDEF TRACE} TriggerDisplay('! HighLevelAsync ' + IntToStr(FRequestResult)); {$ENDIF}
if FState = pop3Abort then begin
{$IFDEF TRACE} TriggerDisplay('! Abort detected'); {$ENDIF}
FFctSet := [];
FHighLevelResult := 426;
FErrorMessage := '426 Operation aborted.';
end;
FNextRequest := DoHighLevelAsync;
if FRequestResult <> 0 then begin
{ Previous command had errors }
FHighLevelResult := FRequestResult;
if (FFctPrv = pop3FctQuit) or (not (pop3FctQuit in FFctSet)) then
FFctSet := []
else
FFctSet := [pop3FctQuit];
end;
if pop3FctConnect in FFctSet then begin
FFctPrv := pop3FctConnect;
FFctSet := FFctSet - [FFctPrv];
Connect;
Exit;
end;
if pop3FctUser in FFctSet then begin
FFctPrv := pop3FctUser;
FFctSet := FFctSet - [FFctPrv];
User;
Exit;
end;
if pop3FctPass in FFctSet then begin
FFctPrv := pop3FctPass;
FFctSet := FFctSet - [FFctPrv];
Pass;
Exit;
end;
if pop3FctRPop in FFctSet then begin
FFctPrv := pop3FctRPop;
FFctSet := FFctSet - [FFctPrv];
RPop;
Exit;
end;
if pop3FctDele in FFctSet then begin
FFctPrv := pop3FctDele;
FFctSet := FFctSet - [FFctPrv];
Dele;
Exit;
end;
if pop3FctNoop in FFctSet then begin
FFctPrv := pop3FctNoop;
FFctSet := FFctSet - [FFctPrv];
Noop;
Exit;
end;
if pop3FctList in FFctSet then begin
FFctPrv := pop3FctList;
FFctSet := FFctSet - [FFctPrv];
List;
Exit;
end;
if pop3FctRSet in FFctSet then begin
FFctPrv := pop3FctRSet;
FFctSet := FFctSet - [FFctPrv];
RSet;
Exit;
end;
if pop3FctAPop in FFctSet then begin
FFctPrv := pop3FctAPop;
FFctSet := FFctSet - [FFctPrv];
APop;
Exit;
end;
if pop3FctRetr in FFctSet then begin
FFctPrv := pop3FctRetr;
FFctSet := FFctSet - [FFctPrv];
Retr;
Exit;
end;
if pop3FctTop in FFctSet then begin
FFctPrv := pop3FctTop;
FFctSet := FFctSet - [FFctPrv];
Top;
Exit;
end;
if pop3FctStat in FFctSet then begin
FFctPrv := pop3FctStat;
FFctSet := FFctSet - [FFctPrv];
Stat;
Exit;
end;
if pop3FctUidl in FFctSet then begin
FFctPrv := pop3FctUidl;
FFctSet := FFctSet - [FFctPrv];
Uidl;
Exit;
end;
if pop3FctLast in FFctSet then begin
FFctPrv := pop3FctLast;
FFctSet := FFctSet - [FFctPrv];
Last;
Exit;
end;
if pop3FctQuit in FFctSet then begin
FFctPrv := pop3FctQuit;
FFctSet := FFctSet - [FFctPrv];
Quit;
Exit;
end;
{$IFDEF TRACE} TriggerDisplay('! HighLevelAsync done'); {$ENDIF}
FFctSet := [];
FNextRequest := nil;
FRequestDoneFlag := FALSE;
TriggerRequestDone(FHighLevelResult);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.HighLevelAsync(
RqType : Tpop3Request; Fcts : Tpop3FctSet);
begin
if FConnected and (pop3FctConnect in Fcts) then
raise pop3Exception.Create('pop3 component already connected');
CheckReady;
FLastResponseSave := FLastResponse;
FStatusCodeSave := -1;
FRequestType := RqType;
FRequestResult := 0;
FFctSet := Fcts;
FFctPrv := pop3FctNone;
FHighLevelResult := 0;
FHighLevelFlag := TRUE;
FLastResponse := '';
FRestartFlag := FALSE;
ClearErrorMessage;
DoHighLevelAsync;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.ProcessUidl(Sender : TObject);
begin
ExtractUidl(FMsgNum, FMsgUidl);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.ProcessList(Sender : TObject);
begin
ExtractNumbers(FMsgNum, FMsgSize);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TCustomPop3Cli.ExtractUidl(var N1 : Integer; var N2 : String) : Boolean;
var
p : PChar;
begin
Result := FALSE;
N1 := 0;
N2 := '';
{$IFDEF VER80}
{ Delphi 1 do not automatically nul terminate strings }
FLastResponse := FLastResponse + #0;
{$ENDIF}
{ Search for first digit in response }
p := @FLastResponse[1];
while (p^ <> #0) and (not (p^ in ['0'..'9'])) do
Inc(p);
if p^ = #0 then { Invalid response, need a number }
Exit;
{ Convert first number }
N1 := atoi(p);
{ Search end of number }
while (p^ <> #0) and (p^ in ['0'..'9']) do
Inc(p);
{ Search Uidl }
while (p^ = ' ') do
Inc(p);
{ Copy UIDL }
while (p^ <> #0) and (p^ in [#33..#126]) do begin
N2 := N2 + p^;
Inc(p);
end;
Result := TRUE;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TCustomPop3Cli.ExtractNumbers(var N1 : Integer; var N2 : Integer) : Boolean;
var
p : PChar;
begin
Result := FALSE;
{$IFDEF VER80}
{ Delphi 1 do not automatically nul terminate strings }
FLastResponse := FLastResponse + #0;
{$ENDIF}
{ Search for first digit in response }
p := @FLastResponse[1];
while (p^ <> #0) and (not (p^ in ['0'..'9'])) do
Inc(p);
if p^ = #0 then begin
{ Invalid response, need a number }
N1 := 0;
N2 := 0;
Exit;
end;
{ Convert first number }
N1 := atoi(p);
{ Search end of number }
while (p^ <> #0) and (p^ in ['0'..'9']) do
Inc(p);
{ Search next number }
p := stpblk(p);
if p^ = #0 then begin
{ Invalid response, need a number }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -