📄 ftpsend.pas
字号:
end;
end;
function TFTPSend.DataWrite(const SourceStream: TStream): Boolean;
var
x: integer;
begin
Result := False;
try
if not AcceptDataSocket then
Exit;
FDSock.SendStreamRaw(SourceStream);
if FDSock.LastError <> 0 then
Exit;
FDSock.CloseSocket;
x := ReadResult;
Result := (x div 100) = 2;
finally
FDSock.CloseSocket;
end;
end;
function TFTPSend.List(Directory: string; NameList: Boolean): Boolean;
var
x: integer;
begin
Result := False;
FDataStream.Clear;
FFTPList.Clear;
if Directory <> '' then
Directory := ' ' + Directory;
FTPCommand('TYPE A');
if not DataSocket then
Exit;
if NameList then
x := FTPCommand('NLST' + Directory)
else
x := FTPCommand('LIST' + Directory);
if (x div 100) <> 1 then
Exit;
Result := DataRead(FDataStream);
if (not NameList) and Result then
begin
FDataStream.Seek(0, soFromBeginning);
FFTPList.Lines.LoadFromStream(FDataStream);
FFTPList.ParseLines;
end;
FDataStream.Seek(0, soFromBeginning);
end;
function TFTPSend.RetrieveFile(const FileName: string; Restore: Boolean): Boolean;
var
RetrStream: TStream;
begin
Result := False;
if FileName = '' then
Exit;
if not DataSocket then
Exit;
Restore := Restore and FCanResume;
if FDirectFile then
if Restore and FileExists(FDirectFileName) then
RetrStream := TFileStream.Create(FDirectFileName,
fmOpenReadWrite or fmShareExclusive)
else
RetrStream := TFileStream.Create(FDirectFileName,
fmCreate or fmShareDenyWrite)
else
RetrStream := FDataStream;
try
if FBinaryMode then
FTPCommand('TYPE I')
else
FTPCommand('TYPE A');
if Restore then
begin
RetrStream.Seek(0, soFromEnd);
if (FTPCommand('REST ' + IntToStr(RetrStream.Size)) div 100) <> 3 then
Exit;
end
else
if RetrStream is TMemoryStream then
TMemoryStream(RetrStream).Clear;
if (FTPCommand('RETR ' + FileName) div 100) <> 1 then
Exit;
Result := DataRead(RetrStream);
if not FDirectFile then
RetrStream.Seek(0, soFromBeginning);
finally
if FDirectFile then
RetrStream.Free;
end;
end;
function TFTPSend.InternalStor(const Command: string; RestoreAt: integer): Boolean;
var
SendStream: TStream;
StorSize: integer;
begin
Result := False;
if FDirectFile then
if not FileExists(FDirectFileName) then
Exit
else
SendStream := TFileStream.Create(FDirectFileName,
fmOpenRead or fmShareDenyWrite)
else
SendStream := FDataStream;
try
if not DataSocket then
Exit;
if FBinaryMode then
FTPCommand('TYPE I')
else
FTPCommand('TYPE A');
StorSize := SendStream.Size;
if not FCanResume then
RestoreAt := 0;
if (StorSize > 0) and (RestoreAt = StorSize) then
begin
Result := True;
Exit;
end;
if RestoreAt > StorSize then
RestoreAt := 0;
FTPCommand('ALLO ' + IntToStr(StorSize - RestoreAt));
if FCanResume then
if (FTPCommand('REST ' + IntToStr(RestoreAt)) div 100) <> 3 then
Exit;
SendStream.Seek(RestoreAt, soFromBeginning);
if (FTPCommand(Command) div 100) <> 1 then
Exit;
Result := DataWrite(SendStream);
finally
if FDirectFile then
SendStream.Free;
end;
end;
function TFTPSend.StoreFile(const FileName: string; Restore: Boolean): Boolean;
var
RestoreAt: integer;
begin
Result := False;
if FileName = '' then
Exit;
RestoreAt := 0;
Restore := Restore and FCanResume;
if Restore then
begin
RestoreAt := Self.FileSize(FileName);
if RestoreAt < 0 then
RestoreAt := 0;
end;
Result := InternalStor('STOR ' + FileName, RestoreAt);
end;
function TFTPSend.StoreUniqueFile: Boolean;
begin
Result := InternalStor('STOU', 0);
end;
function TFTPSend.AppendFile(const FileName: string): Boolean;
begin
Result := False;
if FileName = '' then
Exit;
Result := InternalStor('APPE '+FileName, 0);
end;
function TFTPSend.NoOp: Boolean;
begin
Result := (FTPCommand('NOOP') div 100) = 2;
end;
function TFTPSend.RenameFile(const OldName, NewName: string): Boolean;
begin
Result := False;
if (FTPCommand('RNFR ' + OldName) div 100) <> 3 then
Exit;
Result := (FTPCommand('RNTO ' + NewName) div 100) = 2;
end;
function TFTPSend.DeleteFile(const FileName: string): Boolean;
begin
Result := (FTPCommand('DELE ' + FileName) div 100) = 2;
end;
function TFTPSend.FileSize(const FileName: string): integer;
var
s: string;
begin
Result := -1;
if (FTPCommand('SIZE ' + FileName) div 100) = 2 then
begin
s := Trim(SeparateRight(ResultString, ' '));
s := Trim(SeparateLeft(s, ' '));
Result := StrToIntDef(s, -1);
end;
end;
function TFTPSend.ChangeWorkingDir(const Directory: string): Boolean;
begin
Result := (FTPCommand('CWD ' + Directory) div 100) = 2;
end;
function TFTPSend.ChangeToRootDir: Boolean;
begin
Result := (FTPCommand('CDUP') div 100) = 2;
end;
function TFTPSend.DeleteDir(const Directory: string): Boolean;
begin
Result := (FTPCommand('RMD ' + Directory) div 100) = 2;
end;
function TFTPSend.CreateDir(const Directory: string): Boolean;
begin
Result := (FTPCommand('MKD ' + Directory) div 100) = 2;
end;
function TFTPSend.GetCurrentDir: String;
begin
Result := '';
if (FTPCommand('PWD') div 100) = 2 then
begin
Result := SeparateRight(FResultString, '"');
Result := Trim(Separateleft(Result, '"'));
end;
end;
procedure TFTPSend.Abort;
begin
FDSock.StopFlag := True;
end;
{==============================================================================}
procedure TFTPListRec.Assign(Value: TFTPListRec);
begin
FFileName := Value.FileName;
FDirectory := Value.Directory;
FReadable := Value.Readable;
FFileSize := Value.FileSize;
FFileTime := Value.FileTime;
FOriginalLine := Value.OriginalLine;
FMask := Value.Mask;
end;
constructor TFTPList.Create;
begin
inherited Create;
FList := TList.Create;
FLines := TStringList.Create;
FMasks := TStringList.Create;
FUnparsedLines := TStringList.Create;
//various UNIX
FMasks.add('pppppppppp $!!!S*$TTT$DD$hh mm ss$YYYY$n*');
FMasks.add('pppppppppp $!!!S*$DD$TTT$hh mm ss$YYYY$n*');
FMasks.add('pppppppppp $!!!S*$TTT$DD$UUUUU$n*'); //mostly used UNIX format
FMasks.add('pppppppppp $!!!S*$DD$TTT$UUUUU$n*');
//MacOS
FMasks.add('pppppppppp $!!S*$TTT$DD$UUUUU$n*');
FMasks.add('pppppppppp $!S*$TTT$DD$UUUUU$n*');
//Novell
FMasks.add('d $!S*$TTT$DD$UUUUU$n*');
//Windows
FMasks.add('MM DD YY hh mmH !S* n*');
FMasks.add('MM DD YY hh mmH $ d!n*');
FMasks.add('MM DD YYYY hh mmH !S* n*');
FMasks.add('MM DD YYYY hh mmH $ d!n*');
FMasks.add('DD MM YYYY hh mmH !S* n*');
FMasks.add('DD MM YYYY hh mmH $ d!n*');
//VMS
FMasks.add('v*$ DD TTT YYYY hh mm');
FMasks.add('v*$!DD TTT YYYY hh mm');
//AS400
FMasks.add('!S*$MM DD YY hh mm ss !n*');
FMasks.add('!S*$DD MM YY hh mm ss !n*');
FMasks.add('n*!S*$MM DD YY hh mm ss d');
FMasks.add('n*!S*$DD MM YY hh mm ss d');
//VxWorks
FMasks.add('$S* TTT DD YYYY hh mm ss $n* $ d');
FMasks.add('$S* TTT DD YYYY hh mm ss $n*');
//Distinct
FMasks.add('d $S*$TTT DD YYYY hh mm$n*');
FMasks.add('d $S*$TTT DD$hh mm$n*');
//PC-NFSD
FMasks.add('nnnnnnnn.nnn dSSSSSSSSSSS MM DD YY hh mmH');
//VOS
FMasks.add('- SSSSS YY MM DD hh mm ss n*');
FMasks.add('- d= SSSSS YY MM DD hh mm ss n*');
//Unissys ClearPath
FMasks.add('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn SSSSSSSSS MM DD YYYY hh mm');
FMasks.add('n*\x SSSSSSSSS MM DD YYYY hh mm');
//IBM
FMasks.add('- SSSSSSSSSSSS d MM DD YYYY hh mm n*');
//OS9
FMasks.add('- YY MM DD hhmm d SSSSSSSSS n*');
//tandem
FMasks.add('nnnnnnnn SSSSSSS DD TTT YY hh mm ss');
//MVS
FMasks.add('- YYYY MM DD SSSSS d=O n*');
//BullGCOS8
FMasks.add(' $S* MM DD YY hh mm ss !n*');
FMasks.add('d $S* MM DD YY !n*');
//BullGCOS7
FMasks.add(' TTT DD YYYY n*');
FMasks.add(' d n*');
end;
destructor TFTPList.Destroy;
begin
Clear;
FList.Free;
FLines.Free;
FMasks.Free;
FUnparsedLines.Free;
inherited Destroy;
end;
procedure TFTPList.Clear;
var
n:integer;
begin
for n := 0 to FList.Count - 1 do
if Assigned(FList[n]) then
TFTPListRec(FList[n]).Free;
FList.Clear;
FLines.Clear;
FUnparsedLines.Clear;
end;
function TFTPList.Count: integer;
begin
Result := FList.Count;
end;
function TFTPList.GetListItem(Index: integer): TFTPListRec;
begin
Result := nil;
if Index < Count then
Result := TFTPListRec(FList[Index]);
end;
procedure TFTPList.Assign(Value: TFTPList);
var
flr: TFTPListRec;
n: integer;
begin
Clear;
for n := 0 to Value.Count - 1 do
begin
flr := TFTPListRec.Create;
flr.Assign(Value[n]);
Flist.Add(flr);
end;
Lines.Assign(Value.Lines);
Masks.Assign(Value.Masks);
UnparsedLines.Assign(Value.UnparsedLines);
end;
procedure TFTPList.ClearStore;
begin
Monthnames := '';
BlockSize := '';
DirFlagValue := '';
FileName := '';
VMSFileName := '';
Day := '';
Month := '';
ThreeMonth := '';
YearTime := '';
Year := '';
Hours := '';
HoursModif := '';
Minutes := '';
Seconds := '';
Size := '';
Permissions := '';
DirFlag := '';
end;
function TFTPList.ParseByMask(Value, NextValue, Mask: string): Integer;
var
Ivalue, IMask: integer;
MaskC, LastMaskC: Char;
c: char;
s: string;
begin
ClearStore;
Result := 0;
if Value = '' then
Exit;
if Mask = '' then
Exit;
Ivalue := 1;
IMask := 1;
Result := 1;
LastMaskC := ' ';
while Imask <= Length(mask) do
begin
if (Mask[Imask] <> '*') and (Ivalue > Length(Value)) then
begin
Result := 0;
Exit;
end;
MaskC := Mask[Imask];
if Ivalue > Length(Value) then
Exit;
c := Value[Ivalue];
case MaskC of
'n':
FileName := FileName + c;
'v':
VMSFileName := VMSFileName + c;
'.':
begin
if c in ['.', ' '] then
FileName := TrimSP(FileName) + '.'
else
begin
Result := 0;
Exit;
end;
end;
'D':
Day := Day + c;
'M':
Month := Month + c;
'T':
ThreeMonth := ThreeMonth + c;
'U':
YearTime := YearTime + c;
'Y':
Year := Year + c;
'h':
Hours := Hours + c;
'H':
HoursModif := HoursModif + c;
'm':
Minutes := Minutes + c;
's':
Seconds := Seconds + c;
'S':
Size := Size + c;
'p':
Permissions := Permissions + c;
'd':
DirFlag := DirFlag + c;
'x':
if c <> ' ' then
begin
Result := 0;
Exit;
end;
'*':
begin
s := '';
if LastMaskC in ['n', 'v'] then
begin
if Imask = Length(Mask) then
s := Copy(Value, IValue, Maxint)
else
while IValue <= Length(Value) do
begin
if Value[Ivalue] = ' ' then
break;
s := s + Value[Ivalue];
Inc(Ivalue);
end;
if LastMaskC = 'n' then
FileName := FileName + s
else
VMSFileName := VMSFileName + s;
end
else
begin
while IValue <= Length(Value) do
begin
if not(Value[Ivalue] in ['0'..'9']) then
break;
s := s + Value[Ivalue];
Inc(Ivalue);
end;
case LastMaskC of
'S':
Size := Size + s;
end;
end;
Dec(IValue);
end;
'!':
begin
while IValue <= Length(Value) do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -