271 lines
8.4 KiB
Plaintext
271 lines
8.4 KiB
Plaintext
|
{
|
|||
|
$Project$
|
|||
|
$Workfile$
|
|||
|
$Revision$
|
|||
|
$DateUTC$
|
|||
|
$Id$
|
|||
|
|
|||
|
This file is part of the Indy (Internet Direct) project, and is offered
|
|||
|
under the dual-licensing agreement described on the Indy website.
|
|||
|
(http://www.indyproject.org/)
|
|||
|
|
|||
|
Copyright:
|
|||
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
|||
|
}
|
|||
|
{
|
|||
|
$Log$
|
|||
|
}
|
|||
|
{
|
|||
|
Rev 1.2 2/23/2005 6:34:30 PM JPMugaas
|
|||
|
New property for displaying permissions ina GUI column. Note that this
|
|||
|
should not be used like a CHMOD because permissions are different on
|
|||
|
different platforms - you have been warned.
|
|||
|
|
|||
|
Rev 1.1 10/26/2004 11:21:16 PM JPMugaas
|
|||
|
Updated refs.
|
|||
|
|
|||
|
Rev 1.0 7/30/2004 8:03:42 AM JPMugaas
|
|||
|
FTP List parser for the Tandem NonStop Guardian file-system.
|
|||
|
}
|
|||
|
|
|||
|
unit IdFTPListParseTandemGuardian;
|
|||
|
|
|||
|
interface
|
|||
|
|
|||
|
{$i IdCompilerDefines.inc}
|
|||
|
|
|||
|
uses
|
|||
|
Classes,
|
|||
|
IdGlobal,
|
|||
|
IdFTPList, IdFTPListParseBase, IdFTPListTypes;
|
|||
|
|
|||
|
{
|
|||
|
This parser is based on the Tandem NonStop Server with a Guardian file system.
|
|||
|
This is primarily based on some correspondances and samples I got from Steeve Howe.
|
|||
|
His correspondance is here and I'm noting it in case I need to refer back later:
|
|||
|
|
|||
|
What are the rules for acceptable filenames on the Tandem? <20>
|
|||
|
>>Must start with a character and must be at least on character long.
|
|||
|
|
|||
|
What charactors can be used?
|
|||
|
>>Alpha characters and numerals.
|
|||
|
|
|||
|
What's the length?
|
|||
|
>><3E> 8 characters max.
|
|||
|
|
|||
|
Can you have file extensions, if so how many and what's the length for
|
|||
|
those?
|
|||
|
>><3E>No file extensions.
|
|||
|
|
|||
|
Is the system case insensitive or case-sensitive?
|
|||
|
>>All filenames are converted to uppercase (from what I can tell)
|
|||
|
|
|||
|
What's Code? Is it always a number?
|
|||
|
>><3E>Code is the type of file. <20>101 is an editable file, 100 is an
|
|||
|
exacutable, 1000 is an user defined executable, there is a type 1600
|
|||
|
and I have seen type 0 (which I think is an unknown binary type of
|
|||
|
file)
|
|||
|
|
|||
|
What's EOF? <20>Is that the file size? <20>I don't know.
|
|||
|
>><3E>Yes, <20>That is the file size.
|
|||
|
|
|||
|
In the Owner column, you have something like this "155, 76". <20>Are
|
|||
|
their only numbers and what do the numbers in the column mean (I
|
|||
|
assume that there is two). <20>Will the Owner column ever have letters?
|
|||
|
>><3E>Never letters.
|
|||
|
<20> first byte is group, second is user
|
|||
|
<20> it describes user and security level
|
|||
|
|
|||
|
What is valid for "RWEP" and what do the letters in that mean and what
|
|||
|
letters are there?
|
|||
|
>><3E>Read, Write, Execute, Purge
|
|||
|
|
|||
|
some valid letters (there are about 7 and I don't know them all):
|
|||
|
N - anyone across system has access
|
|||
|
U - only the user has this priviledge
|
|||
|
A - anyone on local system has priviledge
|
|||
|
G - anyone belonging to same group
|
|||
|
- (dash) <20>- only local super.super has access
|
|||
|
|
|||
|
some further references from Tandem that might help:
|
|||
|
|
|||
|
http://www.hp.com/go/NTL - General technical reference
|
|||
|
http://h30163.www3.hp.com/NTL/library/G06_RVUs/G06_20/Publications/ -HP
|
|||
|
G06.20 Publications
|
|||
|
|
|||
|
hope this helps!
|
|||
|
}
|
|||
|
{
|
|||
|
This parses something like this:
|
|||
|
====
|
|||
|
File Code EOF Last Modification Owner RWEP
|
|||
|
ALV 101 2522 27-Aug-02 13:57:10 155,106 "nnnn"
|
|||
|
ALVO 1000 2048 27-Aug-02 13:57:22 155,106 "nunu"
|
|||
|
====
|
|||
|
}
|
|||
|
|
|||
|
type
|
|||
|
TIdTandemGuardianFTPListItem = class(TIdOwnerFTPListItem)
|
|||
|
protected
|
|||
|
//this is given as a numbeer like the owner. We keep it as a string
|
|||
|
//for consistancy with other FTP list parsers.
|
|||
|
FGroupName : String;
|
|||
|
//this may be an integer value but I'm not sure
|
|||
|
//because one
|
|||
|
FCode : UInt32;
|
|||
|
//This is the RWEP value
|
|||
|
{ It's done like this:
|
|||
|
|
|||
|
Read, Write, Execute, Purge
|
|||
|
|
|||
|
some valid letters (there are about 7 and I don't know them all):
|
|||
|
N - anyone across system has access
|
|||
|
U - only the user has this priviledge
|
|||
|
A - anyone on local system has priviledge
|
|||
|
G - anyone belonging to same group
|
|||
|
- (dash) <20>- only local super.super has access
|
|||
|
|
|||
|
}
|
|||
|
FPermissions : String;
|
|||
|
public
|
|||
|
property GroupName : String read FGroupName write FGroupName;
|
|||
|
property Code : UInt32 read FCode write FCode;
|
|||
|
property Permissions : String read FPermissions write FPermissions;
|
|||
|
end;
|
|||
|
|
|||
|
TIdFTPLPTandemGuardian = class(TIdFTPListBaseHeader)
|
|||
|
protected
|
|||
|
class function MakeNewItem(AOwner : TIdFTPListItems) : TIdFTPListItem; override;
|
|||
|
class function IsHeader(const AData: String): Boolean; override;
|
|||
|
class function ParseLine(const AItem : TIdFTPListItem; const APath : String = ''): Boolean; override;
|
|||
|
public
|
|||
|
class function GetIdent : String; override;
|
|||
|
end;
|
|||
|
|
|||
|
const
|
|||
|
TANDEM_GUARDIAN_ID = 'Tandem NonStop Guardian'; {do not localize}
|
|||
|
|
|||
|
// RLebeau 2/14/09: this forces C++Builder to link to this unit so
|
|||
|
// RegisterFTPListParser can be called correctly at program startup...
|
|||
|
|
|||
|
{$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT}
|
|||
|
{$HPPEMIT LINKUNIT}
|
|||
|
{$ELSE}
|
|||
|
{$HPPEMIT '#pragma link "IdFTPListParseTandemGuardian"'}
|
|||
|
{$ENDIF}
|
|||
|
|
|||
|
implementation
|
|||
|
|
|||
|
uses
|
|||
|
IdFTPCommon, IdGlobalProtocols, SysUtils;
|
|||
|
|
|||
|
{ TIdFTPLPTandemGuardian }
|
|||
|
|
|||
|
class function TIdFTPLPTandemGuardian.GetIdent: String;
|
|||
|
begin
|
|||
|
Result := TANDEM_GUARDIAN_ID;
|
|||
|
end;
|
|||
|
|
|||
|
class function TIdFTPLPTandemGuardian.IsHeader(const AData: String): Boolean;
|
|||
|
var
|
|||
|
LCols : TStrings;
|
|||
|
begin
|
|||
|
Result := False;
|
|||
|
LCols := TStringList.Create;
|
|||
|
try
|
|||
|
SplitDelimitedString(AData, LCols, True);
|
|||
|
if LCols.Count = 7 then
|
|||
|
begin
|
|||
|
Result := (LCols[0] = 'File') and {do not localize}
|
|||
|
(LCols[1] = 'Code') and {do not localize}
|
|||
|
(LCols[2] = 'EOF') and {do not localize}
|
|||
|
(LCols[3] = 'Last') and {do not localize}
|
|||
|
(LCols[4] = 'Modification') and {do not localize}
|
|||
|
(LCols[5] = 'Owner') and {do not localize}
|
|||
|
(LCols[6] = 'RWEP') {do not localize}
|
|||
|
end;
|
|||
|
finally
|
|||
|
FreeAndNil(LCols);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
class function TIdFTPLPTandemGuardian.MakeNewItem(AOwner: TIdFTPListItems): TIdFTPListItem;
|
|||
|
begin
|
|||
|
Result := TIdTandemGuardianFTPListItem.Create(AOwner);
|
|||
|
end;
|
|||
|
|
|||
|
class function TIdFTPLPTandemGuardian.ParseLine(const AItem: TIdFTPListItem;
|
|||
|
const APath: String): Boolean;
|
|||
|
var
|
|||
|
LItem : TIdTandemGuardianFTPListItem;
|
|||
|
LLine, LBuffer : String;
|
|||
|
LDay, LMonth, LYear : Integer;
|
|||
|
begin
|
|||
|
{
|
|||
|
Parse lines like these:
|
|||
|
|
|||
|
ALV 101 2522 27-Aug-02 13:57:10 155,106 "nnnn"
|
|||
|
ALVO 1000 2048 27-Aug-02 13:57:22 155,106 "nunu"
|
|||
|
}
|
|||
|
//
|
|||
|
{ Note from Steeve Howe:
|
|||
|
===
|
|||
|
The directories are flat. <20>The Guardian system appears like this:
|
|||
|
|
|||
|
\<server>.$<volume>.<subvolume>
|
|||
|
|
|||
|
you can change from server to server, volume to volume, subvolume to
|
|||
|
subvolume, but
|
|||
|
nothing deeper. <20>what you get from a directory listing then is just the
|
|||
|
files within that
|
|||
|
subvolume of the volume on the server.
|
|||
|
===
|
|||
|
}
|
|||
|
Result := True;
|
|||
|
LItem := AItem as TIdTandemGuardianFTPListItem;
|
|||
|
LLine := Trim(LItem.Data);
|
|||
|
LItem.ItemType := ditFile;
|
|||
|
//name
|
|||
|
// Steve Howe advised me that a filename can not have a space and is 8 chars
|
|||
|
// with no filename extensions. It is case insensitive.
|
|||
|
LItem.FileName := Fetch(LLine);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
//code
|
|||
|
LItem.Code := IndyStrToInt(Fetch(LLine), 0);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
//EOF
|
|||
|
LItem.Size := IndyStrToInt64(Fetch(LLine), 0);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
//Last Modification
|
|||
|
//date
|
|||
|
LBuffer := Fetch(LLine);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
LDay := IndyStrToInt(Fetch(LBuffer, '-'), 1); {do not localize}
|
|||
|
LMonth := StrToMonth(Fetch(LBuffer, '-')); {do not localize}
|
|||
|
|
|||
|
LYear := IndyStrToInt(Fetch(LBuffer), 1989);
|
|||
|
LYear := Y2Year(LYear);
|
|||
|
//time
|
|||
|
LItem.ModifiedDate := EncodeDate(LYear, LMonth, LDay);
|
|||
|
LBuffer := Fetch(LLine);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
LItem.ModifiedDate := AItem.ModifiedDate + TimeHHMMSS(LBuffer);
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
//group,Owner
|
|||
|
//Steve how advised me that the first number in this column is a group
|
|||
|
//and the number after the comma is an owner
|
|||
|
LItem.GroupName := Fetch(LLine, ','); {do not localize}
|
|||
|
LLine := TrimLeft(LLine);
|
|||
|
LItem.OwnerName := Fetch(LLine);
|
|||
|
//RWEP
|
|||
|
LItem.Permissions := UnquotedStr(LLine);
|
|||
|
LItem.PermissionDisplay := '"' + LItem.Permissions + '"';
|
|||
|
end;
|
|||
|
|
|||
|
initialization
|
|||
|
RegisterFTPListParser(TIdFTPLPTandemGuardian);
|
|||
|
finalization
|
|||
|
UnRegisterFTPListParser(TIdFTPLPTandemGuardian);
|
|||
|
|
|||
|
end.
|