📄 ftpsrv.pas
字号:
write FOnValidatePut;
property OnValidateDele : TFtpSrvValidateXferEvent
read FOnValidateDele
write FOnValidateDele;
property OnValidateRmd : TFtpSrvValidateXferEvent
read FOnValidateRmd
write FOnValidateRmd;
property OnValidateRnFr : TFtpSrvValidateXferEvent
read FOnValidateRnFr
write FOnValidateRnFr;
property OnValidateRnTo : TFtpSrvValidateXferEvent
read FOnValidateRnTo
write FOnValidateRnTo;
property OnValidateGet : TFtpSrvValidateXferEvent
read FOnValidateGet
write FOnValidateGet;
property OnStorDataAvailable : TFtpSrvDataAvailableEvent
read FOnStorDataAvailable
write FOnStorDataAvailable;
property OnGetUniqueFileName : TFtpSrvGetUniqueFileNameEvent
read FOnGetUniqueFileName
write FOnGetUniqueFileName ;
property OnGetProcessing : TFtpSrvGetProcessingEvent
read FOnGetProcessing
write FOnGetProcessing;
end;
procedure Register;
implementation
const
msgDftBanner = '220 ICS FTP Server ready.';
msgTooMuchClients = '421 Too many users connected.';
msgCmdUnknown = '500 ''%s'': command not understood.';
msgLoginFailed = '530 Login incorrect.';
msgNotLogged = '530 Please login with USER and PASS.';
msgNoUser = '503 Login with USER first.';
msgLogged = '230 User %s logged in.';
msgPassRequired = '331 Password required for %s.';
msgCWDSuccess = '250 CWD command successful. "%s" is current directory.';
msgCWDFailed = '501 CWD failed. %s';
msgPWDSuccess = '257 "%s" is current directory.';
msgQuit = '221 Goodbye.';
msgPortSuccess = '200 Port command successful.';
msgPortFailed = '501 Invalid PORT command.';
msgStorDisabled = '501 Permission Denied'; {'500 Cannot STOR.';}
msgStorSuccess = '150 Opening data connection for %s.';
msgStorFailed = '501 Cannot STOR. %s';
msgStorAborted = '426 Connection closed; %s.';
msgStorOk = '226 File received ok';
msgStorError = '426 Connection closed; transfer aborted. Error #%d';
msgRetrDisabled = '500 Cannot RETR.';
msgRetrSuccess = '150 Opening data connection for %s.';
msgRetrFailed = '501 Cannot RETR. %s';
msgRetrAborted = '426 Connection closed; %s.';
msgRetrOk = '226 File sent ok';
msgRetrError = '426 Connection closed; transfer aborted. Error #%d';
msgSystem = '215 UNIX Type: L8 Internet Component Suite';
msgDirOpen = '150 Opening data connection for directory list.';
msgDirFailed = '451 Failed: %s.';
msgTypeOk = '200 Type set to %s.';
msgTypeFailed = '500 ''TYPE %s'': command not understood.';
msgDeleNotExists = '550 ''%s'': no such file or directory.';
msgDeleOk = '250 File ''%s'' deleted.';
msgDeleFailed = '450 File ''%s'' can''t be deleted.';
msgDeleSyntax = '501 Syntax error in parameter.';
msgDeleDisabled = '550 Cannot delete.';
msgRnfrNotExists = '550 ''%s'': no such file or directory.';
msgRnfrSyntax = '501 Syntax error is parameter.';
msgRnfrOk = '350 File exists, ready for destination name.';
msgRnFrDisabled = '500 Cannot RNFR.';
msgRntoNotExists = '550 ''%s'': no such file or directory.';
msgRntoAlready = '553 ''%s'': file already exists.';
msgRntoOk = '250 File ''%s'' renamed to ''%s''.';
msgRntoFailed = '450 File ''%s'' can''t be renamed.';
msgRntoSyntax = '501 Syntax error in parameter.';
msgRnToDisabled = '500 Cannot RNTO.';
msgMkdOk = '257 ''%s'': directory created.';
msgMkdAlready = '550 ''%s'': file or directory already exists.';
msgMkdFailed = '550 ''%s'': can''t create directory.';
msgMkdSyntax = '501 Syntax error in parameter.';
msgRmdOk = '250 ''%s'': directory removed.';
msgRmdNotExists = '550 ''%s'': no such directory.';
msgRmdFailed = '550 ''%s'': can''t remove directory.';
msgRmdDisabled = '500 Cannot remove directory.';
msgRmdSyntax = '501 Syntax error in parameter.';
msgNoopOk = '200 Ok. Parameter was ''%s''.';
msgAborOk = '225 ABOR command successful.';
msgPasvLocal = '227 Entering Passive Mode (127,0,0,1,%d,%d).';
msgPasvRemote = '227 Entering Passive Mode (%d,%d,%d,%d,%d,%d).';
msgPasvExcept = '500 PASV exception: ''%s''.';
msgSizeOk = '213 %d';
msgSizeFailed = '550 Command failed: %s.';
msgSizeSyntax = '501 Syntax error in parameter.';
msgRestOk = '350 REST supported. Ready to resume at byte offset %d.';
msgRestZero = '501 Required byte offset parameter bad or missing.';
msgRestFailed = '501 Syntax error in parameter: %s.';
msgAppeFailed = '550 APPE failed.';
msgAppeSuccess = '150 Opening data connection for %s (append).';
msgAppeDisabled = '500 Cannot APPE.';
msgAppeAborted = '426 Connection closed; %s.';
msgAppeOk = '226 File received ok';
msgAppeError = '426 Connection closed; transfer aborted. Error #%d';
msgAppeReady = '150 APPE supported. Ready to append file "%s" at offset %d.';
msgStruOk = '200 Ok. STRU parameter ''%s'' ignored.';
msgMdtmOk = '213 %s';
msgMdtmFailed = '550 %s';
msgMdtmSyntax = '501 Syntax error in MDTM parameter.';
msgMdtmNotExists = '550 ''%s'': no such file or directory.';
msgModeOK = '200 MODE Ok';
msgModeSyntax = '501 Missing argument for MODE';
msgModeNotS = '502 MODE other than S not supported';
msgOverflow = '500 Command too long';
msgStouOk = '250 ''%s'': file created.' ;
msgStouSuccess = msgStorSuccess;
msgStouFailed = '501 Cannot STOU. %s';
msgStouAborted = msgStorAborted;
msgStouError = msgStorError;
function SlashesToBackSlashes(const S : String) : String; forward;
function BackSlashesToSlashes(const S : String) : String; forward;
function BuildFilePath(const Directory : String;
FileName : String) : String; forward;
var
ThisYear, ThisMonth, ThisDay : Word;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure Register;
begin
RegisterComponents('FPiette', [TFtpServer]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFDEF VER80}
procedure SetLength(var S: string; NewLength: Integer);
begin
S[0] := chr(NewLength);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TrimRight(Str : String) : String;
var
i : Integer;
begin
i := Length(Str);
while (i > 0) and (Str[i] = ' ') do
i := i - 1;
Result := Copy(Str, 1, i);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TrimLeft(Str : String) : String;
var
i : Integer;
begin
if Str[1] <> ' ' then
Result := Str
else begin
i := 1;
while (i <= Length(Str)) and (Str[i] = ' ') do
i := i + 1;
Result := Copy(Str, i, Length(Str) - i + 1);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function Trim(Str : String) : String;
begin
Result := TrimLeft(TrimRight(Str));
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetFileSize(FileName : String) : LongInt;
var
SR : TSearchRec;
begin
{$IFNDEF VER80}{$WARNINGS OFF}{$ENDIF}
if FindFirst(FileName, faReadOnly or faHidden or
faSysFile or faArchive, SR) = 0 then
Result := SR.Size
else
Result := -1;
FindClose(SR);
{$IFNDEF VER80}{$WARNINGS ON}{$ENDIF}
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TFtpServer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowHandle := WSocket.AllocateHWnd(WndProc);
FServSocket := TWSocket.Create(Self);
FServSocket.Name := 'ServerWSocket';
FClientList := TList.Create;
FPort := 'ftp';
FAddr := '0.0.0.0';
FBanner := msgDftBanner;
FClientClass := TFtpCtrlSocket;
AddCommand('PORT', CommandPORT);
AddCommand('STOR', CommandSTOR);
AddCommand('RETR', CommandRETR);
AddCommand('CWD', CommandCWD);
AddCommand('XPWD', CommandXPWD);
AddCommand('PWD', CommandPWD);
AddCommand('USER', CommandUSER);
AddCommand('PASS', CommandPASS);
AddCommand('LIST', CommandLIST);
AddCommand('NLST', CommandNLST);
AddCommand('TYPE', CommandTYPE);
AddCommand('SYST', CommandSYST);
AddCommand('QUIT', CommandQUIT);
AddCommand('DELE', CommandDELE);
AddCommand('SIZE', CommandSIZE);
AddCommand('REST', CommandREST);
AddCommand('RNFR', CommandRNFR);
AddCommand('RNTO', CommandRNTO);
AddCommand('MKD', CommandMKD);
AddCommand('RMD', CommandRMD);
AddCommand('ABOR', CommandABOR);
AddCommand('PASV', CommandPASV);
AddCommand('NOOP', CommandNOOP);
AddCommand('CDUP', CommandCDUP);
AddCommand('APPE', CommandAPPE);
AddCommand('STRU', CommandSTRU);
AddCommand('XMKD', CommandMKD);
AddCommand('XRMD', CommandRMD);
AddCommand('MDTM', CommandMDTM);
AddCommand('MODE', CommandMODE);
AddCommand('OVER', CommandOverflow);
AddCommand('STOU', CommandSTOU);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TFtpServer.Destroy;
begin
if Assigned(FServSocket) then begin
FServSocket.Destroy;
FServSocket := nil;
end;
if Assigned(FClientList) then begin
FClientList.Destroy;
FClientList := nil;
end;
WSocket.DeallocateHWnd(FWindowHandle);
inherited Destroy;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpServer.WndProc(var MsgRec: TMessage);
begin
with MsgRec do begin
case Msg of
WM_FTPSRV_CLOSE_REQUEST : WMFtpSrvCloseRequest(MsgRec);
WM_FTPSRV_CLIENT_CLOSED : WMFtpSrvClientClosed(MsgRec);
WM_FTPSRV_ABORT_TRANSFER : WMFtpSrvAbortTransfer(MsgRec);
WM_FTPSRV_CLOSE_DATA : WMFtpSrvCloseData(MsgRec);
WM_FTPSRV_START_SEND : WMFtpSrvStartSend(MsgRec);
else
Result := DefWindowProc(Handle, Msg, wParam, lParam);
end;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TFtpServer.WMFtpSrvCloseRequest(var msg: TMessage);
var
Client : TFtpCtrlSocket;
I : Integer;
begin
Client := TFtpCtrlSocket(msg.LParam);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -