Autor Beitrag
Manfred
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Di 27.01.09 19:05 
Nabend, Freunde!

Vorweg: Da die betreffende Anwendung extrem umfangreich ist, bin ich hierbei an Delphi 6 gebunden.

Ich habe nun leider folgendes Problem: Mit idFTP wird List wie folgt ausgeführt:
ausblenden Delphi-Quelltext
1:
ftp.List(ftplist,'',true);					

ftplist ist ein TStringList, true gibt an, dass alle Informationen angegeben werden sollen.

Das Ergebnis ist theoretisch O.K. Gibt es eine Doku, was die Werte bedeuten?

Beispiel für ein Ergebnis:
ausblenden Quelltext
1:
2:
3:
4:
5:
drwxr-xr-x 1 ftp ftp              0 Oct 15  2008 doku
drwxr-xr-x 1 ftp ftp              0 Dec 03  2008 hosted
drwxr-xr-x 1 ftp ftp              0 Oct 15  2008 update
drwxr-xr-x 1 ftp ftp              0 Jan 27 15:23 source
-rw-r--r-- 1 ftp ftp           3076 Oct 14  2008 led.php


Offenbar ist es so, dass die Uhrzeit nur dann ausgegeben wird, wenn die Datei oder der Ordner aus dem aktuellen Jahr stammen, andernfalls wird das Jahr angegeben. Damit kann ich leben. Aber wie erkenne ich einen Ordner?
In diesem Forum wird alle Nase lang nach einem Punkt im Dateinamen gesucht, was meiner Meinung nach völlig unsinnig ist. Wer sagt, dass ein Dateiname eine Dateinamenserweiterung besitzen muss? Wer sagt, dass ein Ordner keine haben darf?
Ich gehe nun davon aus, dass es sich um das "d" an erster Stelle handelt - ist aber lediglich eine Vermutung.

Und eines macht mir noch bange: Kann es sein, dass bei einem anderen Server ein anders konstruiertes Ergebnis ermittelt wird?

Wo finde ich eine Doku, die mir den Aufbau vollständig erklärt?
Danke.

_________________
Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 27.01.09 23:04 
Moin!

user profile iconManfred hat folgendes geschrieben Zum zitierten Posting springen:
Das Ergebnis ist theoretisch O.K. Gibt es eine Doku, was die Werte bedeuten?
IIRC wird hier einfach der Output des FTP-Servers geliefert. Es hängt also von der Server-Implementation ab, was da raus kommt. :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Manfred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 28.01.09 00:33 
Hi!
Deinen Worten zu folge kann ich also nicht davon ausgehen, dass das Ergebnis einen Standardaufbau besitzt.
Wie kann man denn dann den Ordnerinhalt via FTP ermitteln, wobei Änderungsdatum und die Info ob Ordner oder Datei bedeutsam sind?

_________________
Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Mi 28.01.09 00:37 
Ich nehme mal an, dass es genau dafür die diversen Parser in der Indy Komponente gibt ;)

_________________
PROGRAMMER: A device for converting coffee into software.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 28.01.09 00:41 
Moin!

user profile iconManfred hat folgendes geschrieben Zum zitierten Posting springen:
Deinen Worten zu folge kann ich also nicht davon ausgehen, dass das Ergebnis einen Standardaufbau besitzt.
AFAIK, nein. :nixweiss:

user profile iconManfred hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann man denn dann den Ordnerinhalt via FTP ermitteln, wobei Änderungsdatum und die Info ob Ordner oder Datei bedeutsam sind?
Schau dir alle FTP-Implementationen an, derer du habhaftig werden kannst, und passe deinen Parser darauf hin an. Wenn das Listing deinem Parser "nicht bekannt" vorkommt, Benutzer informieren, abbrechen. :?

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Ich nehme mal an, dass es genau dafür die diversen Parser in der Indy Komponente gibt ;)
Das ist auch nur ein Schritt in die richtige Richtung, "in-Stein-gemeißelte-Regeln" gibt´s trotzdem nicht. :| Aber immerhin besser, als selber schreiben. :P

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 28.01.09 01:32 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Moin!

user profile iconManfred hat folgendes geschrieben Zum zitierten Posting springen:
Deinen Worten zu folge kann ich also nicht davon ausgehen, dass das Ergebnis einen Standardaufbau besitzt.
AFAIK, nein. :nixweiss:

Scheint leider so. Zu mindestens der Spezifkation nach:

Zitat:
LIST (LIST)
This command causes a list to be sent from the server to the
passive DTP. If the pathname specifies a directory or other
group of files, the server should transfer a list of files
in the specified directory. If the pathname specifies a
file then the server should send current information on the
file. A null argument implies the user's current working or
default directory. The data transfer is over the data
connection in type ASCII or type EBCDIC. (The user must
ensure that the TYPE is appropriately ASCII or EBCDIC).
Since the information on a file may vary widely from system
to system, this information may be hard to use automatically
in a program, but may be quite useful to a human user.
Manfred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 28.01.09 11:40 
Hi!
Also gut, nehmen wir also die erste FTP-Implementation, derer ich habhaft bin: FileZilla auf localhost via XAMPP
Ein solcher Eintrag sieht z.B. so aus:
ausblenden Quelltext
1:
drwxr-xr-x 1 ftp ftp              0 Oct 15  2008 doku					

Es handelt sich um einen Ordner namens "doku"
d = Directory=Ordner; Dateien werden mit "-" gekennzeichnet
rwxr-xr-x = Zugriffsrechte Owner/Group/Other wie sie über CHMOD festgelegt werden (r=read, w=write, x=execute)
1 = ?
ftp ftp = Eines davon ist wohl der Eigentümer (vermutlich der 2. ftp-Eintrag, da der erste Eintrag nur 3 Zeichen Platz bietet)
0 = Dateigröße, wird rechtsbündig ausgegeben
Oct 15 2008 = Änderungsdatum. Bei Dateien im aktuellen Jahr wird "mmm dd hh:mm" ausgegeben.
Danach Dateiname

Hat jemand eine Idee für die doppelte ftp-Angabe und/oder die Ziffer 1?

_________________
Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mi 28.01.09 14:30 
Da ich auch schonmal ein FTP-Programm gemacht habe:

Jeder Server darf selber Informationen senden, wie er lustig ist. Und das ganze dann auch in einem bliebeigen Format.

Nur weil 70% der Server ungefähr so ähnlich antworten heißt das lange nicht, dass es überall geht.

Ich bin schließlich dazu übergegangen, die Indy-Parser zu verwenden, um nicht das Rad neu erfinden zu müssen. Hatte seitdem deutlich weniger Probleme à la "Fehlermeldung: Format nicht erkannt" ;)

Hier mal, wie ich das damals gemacht hab:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
  TFileInfo = record
    Directory: Boolean;
    Filename,
    Date,
    FileType: String;
    Size: Integer;
  end;

procedure TFtpBrowser.CreateDirectoryListing;
var
  i: Integer;
begin
  Working := True;

  if FFtp.Connected then
  begin
    FFtp.SendCmd('TYPE A');

    FFtp.List (nil'-a', True);

    for i := 0 to Pred (FFtp.ListResult.Count) do
      CreateItemFromFileInfo (GetFileInfo(i));
  end;
  Working := False;
end;

procedure TFtpBrowser.CreateItemFromFileInfo(const FileInfo: TFileInfo);
var
  ListItem: TListItem;
begin
  if FileInfo.Filename <> '.' then
  begin
    ListItem := FFiles.Items.Add;

    if FileInfo.FileType = 'Ordner' then
      if Fileinfo.Filename <> '..' then
        ListItem.ImageIndex := 0
      else
        ListItem.ImageIndex := 1
    else
      ListItem.ImageIndex := 2;

    ListItem.Caption := FileInfo.Filename;

    if FileInfo.Size > 1000000 then
      ListItem.SubItems.Add(IntToStr (FileInfo.Size DIV 1000000) + ' MB')
    else if FileInfo.Size > 1000 then
      ListItem.SubItems.Add(IntToStr (FileInfo.Size DIV 1000) + ' KB')
    else if FileInfo.Size > 0 then
      ListItem.SubItems.Add(IntToStr (FileInfo.Size) + ' Byte')
    else
      ListItem.SubItems.Add('n/a');

    ListItem.SubItems.Add(FileInfo.FileType);
    ListItem.SubItems.Add(FileInfo.Date);
  end;
end;

function TFtpBrowser.GetFileInfo(Index: Integer): TFileInfo;
var
  Registry: TRegistry;
  Filename, Filedetails, TempType, TempSize: String;
begin
  Filename := FFtp.DirectoryListing[Index].FileName;
  Filedetails := FFtp.DirectoryListing[Index].Text;

  Result.Directory := Filedetails[1] = 'd';
  Result.Filename := Filename;

  if Result.Directory then
    Result.FileType := 'Ordner'
  else
  begin
    Result.FileType := ReverseString (copy (ReverseString (Filename), 1, pos ('.', ReverseString (Filename))));

    Registry := TRegistry.Create(KEY_READ);
    try
      Registry.RootKey := HKEY_CLASSES_ROOT;
      if Registry.OpenKey (Result.FileType, False) then
      begin
        TempType := Registry.ReadString('');
        Registry.CloseKey;
        if Registry.OpenKey (TempType, False) then
        begin
          TempType := Registry.ReadString('');
        end;
      end;
    finally
      Registry.Free;
    end;

    if (TempType = ''then
      Result.FileType := Trim (AnsiUpperCase (copy (Result.FileType, 2, length (Result.FileType) - 1)) + ' Datei')
    else
      Result.FileType := TempType;
  end;

  Filedetails := ReverseString(Filedetails);
  Delete (Filedetails, 1, length (Filename));

  Result.Date := ReverseString (Trim (copy (Filedetails, 114)));

  try
    TempSize := Trim (copy (Filedetails, 1410)) + ' ';
    TempSize := Trim (copy (TempSize, 1, pos (' ', TempSize)));
    Result.Size := StrToInt (ReverseString (TempSize));
  except
    Result.Size := 0;
  end;
end;