📄 pop3prot.pas
字号:
end;
end
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WSocketSessionConnected(Sender: TObject; Error: Word);
begin
{ Do not trigger the client SessionConnected from here. We must wait }
{ to have received the server banner. }
if Error <> 0 then begin
FLastResponse := '-ERR ' + WSocketErrorDesc(Error) +
' (Winsock error #' + IntToStr(Error) + ')';
FStatusCode := 500;
FConnected := FALSE;
FRequestResult := Error; { V2.02 }
SetErrorMessage; { V2.03 }
TriggerRequestDone(Error);
FWSocket.Close;
StateChange(pop3Ready);
end
else begin
FConnected := TRUE;
StateChange(pop3WaitingBanner);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WSocketSessionClosed(Sender : TObject; Error : WORD);
begin
FConnected := FALSE;
TriggerSessionClosed(Error);
TriggerRequestDone(WSAEINTR);
FProtocolState := pop3Disconnected;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WSocketDataAvailable(Sender: TObject; Error: Word);
var
Len : Integer;
I, J : Integer;
Remaining : Integer;
begin
repeat
{ Compute remaining space in our buffer. Preserve 3 bytes for CR/LF }
{ and nul terminating byte. }
Remaining := SizeOf(FReceiveBuffer) - FReceiveLen - 3;
if Remaining <= 0 then begin
{ Received message has a line longer than our buffer. This is not }
{ acceptable ! We will add a CR/LF to enable processing, but this }
{ will ALTER received message and could cause strange results. }
{ May be it is better to raise an exception ? }
FReceiveBuffer[SizeOf(FReceiveBuffer) - 3] := #13;
FReceiveBuffer[SizeOf(FReceiveBuffer) - 2] := #10;
Len := 2;
end
else begin
Len := FWSocket.Receive(@FReceiveBuffer[FReceiveLen], Remaining);
if Len <= 0 then
Exit;
end;
FReceiveBuffer[FReceiveLen + Len] := #0;
FReceiveLen := FReceiveLen + Len;
while FReceiveLen > 0 do begin
{ Search LF. We can't use Pos because it stops at first #0 }
I := 1;
while (I < FReceiveLen) and {07/03/2004}
(FReceiveBuffer[I] <> #10) do
Inc(I);
if I >= FReceiveLen then
break; { LF not found }
{ Found a LF. Extract data from buffer, ignoring CR if any }
if (I > 0) and (FReceiveBuffer[I - 1] = #13) then {07/03/2004}
FLastResponse := Copy(FReceiveBuffer, 1, I - 1)
else
FLastResponse := Copy(FReceiveBuffer, 1, I);
TriggerResponse(FLastResponse);
{$IFDEF DUMP}
FDumpBuf := '>|';
FDumpStream.WriteBuffer(FDumpBuf[1], Length(FDumpBuf));
FDumpStream.WriteBuffer(FLastResponse[1], Length(FLastResponse));
FDumpBuf := '|' + #13#10;
FDumpStream.WriteBuffer(FDumpBuf[1], Length(FDumpBuf));
{$ENDIF}
{$IFDEF VER80}
{ Add a nul byte at the end of string for Delphi 1 }
FLastResponse[Length(FLastResponse) + 1] := #0;
{$ENDIF}
FReceiveLen := FReceiveLen - I - 1;
if FReceiveLen > 0 then
Move(FReceiveBuffer[I + 1], FReceiveBuffer[0], FReceiveLen + 1);
if FState = pop3WaitingBanner then begin
DisplayLastResponse;
if not OkResponse then begin
SetErrorMessage;
FRequestResult := FStatusCode;
FWSocket.Close;
Exit;
end;
I := Pos('<', FLastResponse);
J := Pos('>', Copy(FLastResponse, I, Length(FLastREsponse)));
if (I > 0) and (J > 0) then
FTimeStamp := Copy(FLastResponse, I, J);
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;
until (Remaining > 0);
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -