Seite 1 von 2

Kommunikation mit ftp-atomic-server

Verfasst: 07.06.2015 16:26
von derschutzhund
Der in den Beispielen von PB enthaltene ftp-atomic-server ist eine gute Grundlage für eigene Weiterentwicklungen.
So ohne weiteres funktioniert er nur leider nicht!
1. Bei der compilierung darf unicode nicht aktiviert sein.
2. Die Verbindung wird zwar aufgebaut aber das Verzeichnis wird nicht angezeigt.

In Ermangelung eines PB-Client habe ich zunächst mit Filezilla Versuche angestellt und eine Problemstelle gefunden.

Code: Alles auswählen

;
; ------------------------------------------------------------
;
;       Atomic FTP Server in PureBasic
;
;          (c) Fantaisie Software
;
; ------------------------------------------------------------
;
;  WICHTIG WICHTIG: Darf nicht mit unicode compiliert werden!!!
;
;
; This program isn't finished, the harder is done but I don't
; have the time to implement the whole RFC 959 commands :-).
; 
;
; 20/05/2002
;   Added a textgadget..
;   Updated for PureBasic 3.20 (Cleaned the code...)
;
; 19/03/2001
;   Listing is now working.
;
; 18/03/2001
;   Based on the Atomic Web Server code..
;   First version.
;

#Version = "0.2"

CompilerIf #PB_Compiler_Unicode
  CompilerError "This program should be compiled in ASCII mode (see Compiler/Compiler Option window)"
CompilerEndIf

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0) : End
EndIf

ClientIP.s
Port = 21
BaseDirectory$    = "ftp/"
CurrentDirectory$ = BaseDirectory$
AtomicTitle$      = "Atomic FTP Server v"+#Version

EOL$ = Chr(13)+Chr(10)

*Buffer = AllocateMemory(10000)

If CreateNetworkServer(0, Port)

  OpenWindow(0, 300, 300, 230, 30, "Atomic FTP Server (Port "+Str(Port)+")")

  TextGadget(1, 10, 8, 200, 20, "Atomic FTP Server Ready.")
  
  Repeat
    
    WEvent = WindowEvent()
    SEvent = NetworkServerEvent()
  
    If WEvent = #PB_Event_CloseWindow
      Quit = 1
    EndIf

    If SEvent
      ClientID = EventClient()
  
      Select SEvent
      
        Case 1  ; New client connected
          SetGadgetText(1, "New client connected !")
          SendNetworkString(ClientID, "220 - Atomic FTP Server v0.1 ready"+EOL$)

        Case 4  ; New client has closed the connection
  
        Default
          RequestLength = ReceiveNetworkData(ClientID, *Buffer, 2000)
           
          If RequestLength > 3
            PokeL(*Buffer+RequestLength-2, 0)
          EndIf
          Gosub ProcessRequest
          
      EndSelect
    Else
      Delay(20)
    EndIf
    
  Until Quit = 1 
  
  CloseNetworkServer(0)
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

End 


ProcessRequest:

 ; Command$ = PeekS(*Buffer,#PB_Unicode)
  Command$ = PeekS(*Buffer)
  Debug Command$
   
  Position = FindString(Command$, " ", 1)
  If Position
   Argument$ = Mid(Command$, Position+1, Len(Command$)-Position)
    Command$ = UCase(RTrim(Left(Command$, Position-1)))
  EndIf

  SetGadgetText(1, "Last command: "+Command$)

  Select Command$

    Case "HELP"
      Gosub Command_HELP

    Case "LIST"
      Gosub Command_LIST

    Case "PASS"
      Gosub Command_PASS

    Case "PORT"
      Gosub Command_PORT

    Case "PWD"
      Gosub Command_PWD

    Case "SYST"
      Gosub Command_SYST

    Case "USER"
      Gosub Command_USER

    Default
      Gosub Command_UNKNOWN

  EndSelect

Return


Command_HELP:
  SendNetworkString(ClientID, "214 - You wanna some help ? :-D"+EOL$)
Return


Command_LIST:
  SendNetworkString(ClientID, "150 - Opening connection"+EOL$)
  
  FTPConnection = OpenNetworkConnection(ClientIP, ClientPort)
  If FTPConnection
    
    a$ = ""
    If ExamineDirectory(0, CurrentDirectory$, "*.*")
    
      NumberFiles = -1
      While NextDirectoryEntry(0)
        
        If DirectoryEntryType(0) = 2
          a$ = a$+"drwxr-xr-x 6 1024 512 Jan 23 10:18 "+DirectoryEntryName(0)+EOL$
        ElseIf Type = 1
          a$ = a$+"rwxr-xr-x 6 512 "+Str(DirectoryEntrySize(0))+" Jan 23 10:18 "+DirectoryEntryName(0)+EOL$
        EndIf
        
        NumberFiles+1
      Wend
    EndIf
    
    SendNetworkString(FTPConnection, "total "+Str(NumberFiles)+EOL$+a$)
    CloseNetworkConnection(FTPConnection)
  EndIf
  
  SendNetworkString(ClientID, "226 - Listing finished"+EOL$)
Return


Command_PASS:
  SendNetworkString(ClientID, "230 - Welcome, enjoy this FTP site"+EOL$)
Return


Command_PORT:

  ; Build a real IP
  ;
  ClientIP = ""
  
  Position = FindString(Argument$, ",", 1)
  ClientIP = ClientIP+Mid(Argument$, 1, Position-1)+"."

  NewPosition = FindString(Argument$, ",", Position+1)
  ClientIP = ClientIP+Mid(Argument$, Position+1, NewPosition-Position-1)+"."

  Position = FindString(Argument$, ",", NewPosition+1)
  ClientIP = ClientIP+Mid(Argument$, NewPosition+1, Position-NewPosition-1)+"."

  NewPosition = FindString(Argument$, ",", Position+1)
  ClientIP = ClientIP+Mid(Argument$, Position+1, NewPosition-Position-1)

  ClientIP = Trim(ClientIP)

  ; Get the port..
  ;
  Position = FindString(Argument$, ",", NewPosition+1)
  
  ClientPort = Val(Mid(Argument$, NewPosition+1, Position-NewPosition-1)) << 8+Val(Right(Argument$, Len(Argument$)-Position))

  SendNetworkString(ClientID, "200 - Ok"+EOL$)
Return


Command_PWD:
  SendNetworkString(ClientID, "257 /"+EOL$)
Return


Command_UNKNOWN:
  SendNetworkString(ClientID, "500 - Unknow command"+EOL$)
Return


Command_USER:
  If Argument$ = "anonymous"
    a$ = "331 - User anonymous accepted. Please enter your e-mail"+EOL$
  Else
    a$ = "331 - Hello "+Argument$+". Please enter your password"+EOL$
  EndIf

  SendNetworkString(ClientID, a$)
Return

Command_SYST:
  SendNetworkString(ClientID, "215 - Atomic FTP Server v"+#Version+EOL$)
Return

 


mit Command_LIST: wird der Inhalt des aktiven Verzeichnisses zurück gesendet.
Das passiert aber nicht weil die IP und der Port des client nicht da ist und die sind nicht vorhanden weil vorher nicht Command_PORT: aufgerufen wurde.
Das tut aber Filezilla wohl nicht.
Auch in keinem Beispielcode von PB habe ich so einen Aufruf gefunden.
Wenn ich es richtig verstehe müsste der Client neben dem Befehl "PORT" auch noch seine eigene IP und den Port für die ftp-Übertragung übermitteln.

Wenn ich testweise im Server testweise die mir bekannte IP des client eintrage und den Port 21 dann funktioniert das auch nicht weil der Port ja schon belegt ist.

Die Frage ist nun wie muss ein PB-Client aussehen der wirklich mit dem ftp-atomic-server kommunizieren kann?
LG

Wolfgang

Re: Kommunikation mit ftp-atomic-server

Verfasst: 09.06.2015 10:22
von Eisbaer
Es sind auch zwei Ports die benötigt werden.
Port 21 und Port 20.

Eine Übersicht über Ports und Kommandos:
http://www.elektronik-kompendium.de/sit ... 902241.htm

Re: Kommunikation mit ftp-atomic-server

Verfasst: 09.06.2015 14:10
von derschutzhund
Ok, aber wie sieht dann ein komplett lauffähiger Client dafür aus?
Warum läuft Filezilla nicht mit dem Server.
Filezilla sollte doch die ganzen Standarts besitzen und wenigstens den Inhalt des Verzeichnisses anzeigen.

LG

Wolfgang

Re: Kommunikation mit ftp-atomic-server

Verfasst: 09.06.2015 14:17
von Imhotheb
derschutzhund hat geschrieben:Ok, aber wie sieht dann ein komplett lauffähiger Client dafür aus?
Warum läuft Filezilla nicht mit dem Server.
Filezilla sollte doch die ganzen Standarts besitzen und wenigstens den Inhalt des Verzeichnisses anzeigen.

LG

Wolfgang
das liegt vermutlich daran, daß das Kommando "LIST" nur unzureichend implementiert ist.
Allgemein finde ich den ganzen Ansatz von dem Server eher "Dirty" als Sinnvoll

Re: Kommunikation mit ftp-atomic-server

Verfasst: 09.06.2015 14:42
von derschutzhund
Allgemein finde ich den ganzen Ansatz von dem Server eher "Dirty" als Sinnvoll
Ok, das kann ich jetzt nicht beurteilen!
Ich habe halt bisher nichts anderes in PB gefunden.
Vielleicht ist meine Anwendung für ein LAN halt auch nicht so interessant für viele die mit einem ftp über das Internet arbeiten wollen.
Das will ich ja nicht und kann mir daher einige Sicherheitsdinge sparen (hoffentlich).

LG

Wolfgang

Re: Kommunikation mit ftp-atomic-server

Verfasst: 10.06.2015 14:03
von Imhotheb
hier eine kurze Übersicht der Kommandos: http://www.nsftools.com/tips/RawFTP.htm

Re: Kommunikation mit ftp-atomic-server

Verfasst: 12.06.2015 08:38
von uweb
So wie es die Zeit zulässt bastle ich schon länger an einem FTP-Proxy.
http://www.codeproject.com/Articles/954 ... TP-clients

Die Idee ist es via FTP ein gefiltertes File-Mapping
http://www.thewindowsclub.com/map-an-ftp-drive-windows
zur verfügung zu stellen.
Über eine GUI (eventuell HTML/JS) Attribute(Tags) auszuwählen anhand derer bei einem FTP-List gefiltert werden soll.
Bei einem Proxy bräuchte ich viele FTP-Komandos nur durchreichen statt sie selbst zu verarbeiten
und ich könnte die Filter auch auf externe Server anwenden.

Die beiden Links hatte ich auch schon. Trotzdem hat mich z.B. die Frage
Was genau passiert wenn der Server fertig ist auf Kanal 20 (hier kann auch ein anderer Port gewählt werden) zu senden?
vor einiger Zeit länger beschäft.
Die Antwort ist (glaube ich) einfacher als von mir erwartet : Er schließt ohne weiteres den Kanal.
Das ist nur ein Beispiel dafür, dass es oft Dinge gibt die für den einen selbstverständlich und nicht erwähnenswert sind und der andere lange danach suchen muss. Es kommt hinzu, dass man bei einem neuen Thema oft auch nicht die passenden (Such-) Begriffe hat.

Meine Empfehlung ist es nicht nur den FileZilla-Client (mit Debugger) zu benutzen, sondern auch den FileZilla-Server (als Referenz).

Auf meiner ToDo-Liste steht nun
Threads, Erkennen wenn eine Verbindung beendet wird (WSA ?) und Verbindungsverwaltung
- Ohne die geht es vermutlich nicht, da verschiedene Clients immer wieder die Verbindung beenden und neu aufbauen.
Benutzerverwaltung
- Die ist im ersten Schritt nicht nötig. Aber das ist nur eine Frage der Zeit.

Für die Verwaltungsgeschichten halte ich folgendes für interessant:
http://forums.purebasic.com/german/view ... 7&start=20

Eine noch umfangreichere Sammlung von FTP-Kommandos gibt es hier:
http://www.iana.org/assignments/ftp-com ... ions.xhtml

Bei der Gelegenheit : Hat jemand einen Link zu deutschen Übersetzungen von RFCs?

Mein Code wäre übrigens z.Zt. eher eine Zumutung als eine Hilfe.
Aber wenn Interesse an einer gemeinsamen Entwicklung besteht wäre ein Server anstelle eines Proxys für mich auch eine Option.

Re: Kommunikation mit ftp-atomic-server

Verfasst: 12.06.2015 10:06
von ts-soft
@uweb:
Bitte richtige Links zum Forum verwenden:
statt: http://forums.purebasic.com/german/view ... 7&start=20
bitte: http://purebasic.fr/german/viewtopic.ph ... 7&start=20

Das warum und wieso erkläre ich jetzt nicht, wurde oft diskutiert :mrgreen:

Re: Kommunikation mit ftp-atomic-server

Verfasst: 12.06.2015 10:26
von uweb
Danke! Ich werde mich bemühen.
Anwendbare konstruktive Kritik ist mir immer willkommen.

Re: Kommunikation mit ftp-atomic-server

Verfasst: 12.06.2015 16:07
von derschutzhund
Wenn ich FTP oder HTTP-Server höre dann denke ich erst mal sofort an Internet.
Gibt es denn für meine Anwendung, die ja nur innerhalb des LAN arbeiten soll, eine "einfachere" Lösung bei der Laufwerke bzw. ein Verzeichnis direkt auf anderen PC gemountet werden?
Da wird bei Linux immer gesagt, dass es eigentlich ein Netzwerksystem ist und dann bricht man sich einen ab wenn man Verzeichnisse von LAN-PCs mounten will.
Sogar ein Verzeichnis eines XP-Rechners kann ich unter meinem PuppyLinux mounten. Irgendwie schaffe ich es aber nicht ein Verzeichnis von einem LinuxPC auf dem anderen LinuxPC zu mounten.

LG

Wolfgang