?? ftpsrvc.pas
字號:
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TFtpCtrlSocket.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDataSocket := TWSocket.Create(Self);
FDataSocket.Name := 'DataWSocket';
FBanner := DefaultBanner;
FFtpState := ftpcInvalid;
FHomeDir := 'C:\TEMP\';
FDirectory := FHomeDir;
SetRcvSize(DefaultRcvSize);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TFtpCtrlSocket.Destroy;
begin
SetRcvSize(0); { Free the buffer }
if Assigned(FDataSocket) then begin
FDataSocket.Destroy;
FDataSocket := nil;
end;
inherited Destroy;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.SetRcvSize(newValue : Integer);
begin
if FRcvCnt <> 0 then
raise EFtpCtrlSocketException.Create('Data in buffer, can''t change size');
if FRcvSize < 0 then
FRcvSize := 0;
if FRcvSize = newValue then
Exit; { No change, nothing to do }
{ Free previously allocated buffer }
if FRcvBuf <> nil then begin
FreeMem(FRcvBuf, FRcvSize);
FRcvBuf := nil;
end;
{ Allocate new buffer }
FRcvSize := newValue;
{ If size is nul, then do not allocated the buffer }
if newValue > 0 then
GetMem(FRcvBuf, FRcvSize);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.StartConnection;
begin
FConnectedSince := Now;
FLastCommand := 0;
FCommandCount := 0;
FFtpState := ftpcWaitingUserCode;
SendStr(FBanner + #13#10);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TFtpCtrlSocket.GetPeerAddr: String;
begin
Result := FPeerAddr;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.Dup(newHSocket : TSocket);
begin
inherited Dup(newHSocket);
FPeerAddr := inherited GetPeerAddr;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.TriggerSessionConnected(Error : Word);
begin
FPeerAddr := inherited GetPeerAddr;
inherited TriggerSessionConnected(Error);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.TriggerCommand(CmdBuf : PChar; CmdLen : Integer);
begin
if Assigned(FOnCommand) then
FOnCommand(Self, CmdBuf, CmdLen);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TFtpCtrlSocket.TriggerDataAvailable(Error : Word) : Boolean;
var
Len : Integer;
I : Integer;
begin
Result := TRUE; { We read data }
Len := Receive(@FRcvBuf[FRcvCnt], FRcvSize - FRcvCnt - 1);
if Len <= 0 then
Exit;
FRcvCnt := FRcvCnt + Len;
FRcvBuf[FRcvCnt] := #0;
while TRUE do begin
I := 0;
while (I < FRcvCnt) and (FRcvBuf[I] <> #10) do
Inc(I);
if I >= FRcvCnt then
Exit;
FRcvBuf[I] := #0;
FLastCommand := Now;
Inc(FCommandCount);
if (I > 1) and (FRcvBuf[I - 1] = #13) then begin
FRcvBuf[I - 1] := #0;
TriggerCommand(FRcvBuf, I - 1);
FRcvBuf[I - 1] := #13;
end
else
TriggerCommand(FRcvBuf, I);
FRcvBuf[I] := #10;
if I >= (FRcvCnt - 1) then begin
FRcvCnt := 0;
FRcvBuf[0] := #0;
break;
end;
Move(FRcvBuf[I + 1], FRcvBuf^, FRcvCnt - I);
FRcvCnt := FRcvCnt - I - 1;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.SendAnswer(Answer : String);
begin
SendStr(Answer + #13#10);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function IsUNC(S : String) : Boolean;
begin
Result := (Length(S) >= 2) and (S[2] = '\') and (S[1] = '\');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure PatchIE5(var S : String);
begin
{ \c:\Temp\ -> c:\Temp\ IE5 like this invalid syntax !}
if (Length(S) >= 3) and (S[3] = ':') and (S[1] = '\') then
Delete(S, 1, 1);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.SetDirectory(newValue : String);
var
newDrive : String;
newPath : String;
I : Integer;
begin
if FDirectory = newValue then
Exit;
PatchIE5(newValue);
newDrive := ExtractFileDrive(newValue);
if IsUNC(newDrive) then begin
if not (ftpcUNC in Options) then
raise Exception.Create('Cannot accept UNC path');
FDirectory := newValue;
{ Always terminate with a backslash }
if (Length(FDirectory) > 0) and (FDirectory[Length(FDirectory)] <> '\') then
FDirectory := FDirectory + '\';
Exit;
end;
if Length(newDrive) = 0 then begin
newDrive := ExtractFileDrive(FDirectory);
newPath := newValue;
end
else
newPath := Copy(newValue, 3, Length(newValue));
if Pos(':', newPath) <> 0 then
raise Exception.Create('Invalid directory name syntax');
if newPath = '..' then begin
if IsUNC(FDirectory) then begin
I := Length(FDirectory) - 1;
while (I > 0) and (FDirectory[I] <> '\') do
Dec(I);
if I > Length(newDrive) then
SetLength(FDirectory, I);
Exit;
end
else begin
newPath := Copy(FDirectory, 3, Length(FDirectory));
I := Length(newPath) - 1;
while (I > 0) and (newPath[I] <> '\') do
Dec(I);
SetLength(newPath, I);
end;
end;
if (Length(newPath) > 0) and (newPath[1] <> '\') then begin
{ Relative path }
if IsUNC(FDirectory) then begin
FDirectory := FDirectory + newPath;
{ Always terminate with a backslash }
if (Length(FDirectory) > 0) and (FDirectory[Length(FDirectory)] <> '\') then
FDirectory := FDirectory + '\';
Exit;
end
else begin
if UpperCase(newDrive[1]) <> UpperCase(FDirectory[1]) then
raise Exception.Create('Cannot accept path not relative to current directory');
if Pos('.\', newPath) <> 0 then
raise Exception.Create('Cannot accept relative path using dot notation');
if newPath = '.' then
newPath := Copy(FDirectory, 3, Length(FDirectory))
else
newPath := Copy(FDirectory, 3, Length(FDirectory)) + newPath;
end;
end
else begin
if Pos('.\', newPath) <> 0 then
raise Exception.Create('Cannot accept relative path using dot notation');
end;
if Length(newPath) = 0 then begin
if UpperCase(newDrive[1]) <> UpperCase(FDirectory[1]) then
newPath := '\'
else
newPath := Copy(FDirectory, 3, Length(FDirectory));
end;
{ Always terminate with a backslash }
if (Length(newPath) > 0) and (newPath[Length(newPath)] <> '\') then
newPath := newPath + '\';
FDirectory := newDrive + newPath;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpCtrlSocket.SetAbortingTransfer(newValue : Boolean);
begin
FAbortingTransfer := newValue;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -