📄 ftpsrvc.pas
字号:
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 TFtpCtrlSocket.SetDirectory(newValue : String);
var
newDrive : String;
newPath : String;
I : Integer;
begin
if FDirectory = newValue then
Exit;
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 + -