;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; sFTPc - a simple FTP client
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitNetwork()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Structure to handle FTP-connections
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Structure connection
id.l
adress.s
user.s
pass.s
port.l
EndStructure
Declare establishConnection(List connections.connection())
Declare checkConnection(n.l)
Declare closeConnection(List connections.connection())
Declare fileManager(n.l)
Declare showDir(n.l)
Declare handleFileOptions(n.l)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; List for saving FTP-connections
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NewList connections.connection()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; The menu
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure mainMenu(List connections.connection())
Repeat
ClearConsole()
PrintN("sFTPc-Main Menu//")
PrintN("1 - Open FTP Connection")
PrintN("2 - Close FTP Connection")
PrintN("3 - File-Manager")
PrintN("4 - Quit")
PrintN("")
;; Print opened connections
If ListSize(connections()) > 0
FirstElement(connections())
ForEach connections()
PrintN("Connection number: "+Str(connections()\id))
PrintN("Adress: "+connections()\adress)
PrintN("Username: "+connections()\user)
Print("Connection: ")
checkConnection(connections()\id)
PrintN("")
Next
Else
PrintN("There are currenty no opened connections.")
EndIf
Print("Choose: ")
Select Val(Input())
Case 1
establishConnection(connections())
Case 2
closeConnection(connections())
Case 3
ClearConsole()
Print("Connection number: ")
n = Val(Input())
If IsFTP(n)
fileManager(n)
Else
PrintN("Not a valid connection!")
Print("Push enter.")
Input()
Continue
EndIf
Case 4
End
Default
PrintN("Not a valid option!")
Print("Push enter.")
Input()
Continue
EndSelect
ForEver
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure to open a new connection
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure establishConnection(List connections.connection())
LastElement(connections())
If Not ListSize(connections()) = 0
lastID = connections()\id
Else
lastID = 0
EndIf
*newElement.connection = AddElement(connections())
ClearConsole()
*newElement\id = lastID + 1
Print("URL or IP: ")
*newElement\adress = Input()
Print("Username: ")
*newElement\user = Input()
Print("Password: ")
*newElement\pass = Input()
Print("Port (default is 21): ")
*newElement\port = Val(Input())
If *newElement\port = 0
*newElement\port = 21
EndIf
;; Check if the connection can get opened
If 0 = OpenFTP(*newElement\id,*newElement\adress,*newElement\user,*newElement\pass)
PrintN("Could not open FTP-connection!")
Print("Push enter.")
Input()
;; Couldn't get opened? Delete the element, it's trash
LastElement(connections())
DeleteElement(connections())
EndIf
ProcedureReturn
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Check the state of opened connections
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure checkConnection(n.l)
If 0 = CheckFTPConnection(n)
PrintN("Disconnected!")
Else
PrintN("OK!")
EndIf
ProcedureReturn
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Close a specific connection
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure closeConnection(List connections.connection())
ClearConsole()
;; Print current connections
If ListSize(connections()) > 0
FirstElement(connections())
ForEach connections()
PrintN("Connection number: "+Str(connections()\id))
PrintN("Adress: "+connections()\adress)
PrintN("Username: "+connections()\user)
PrintN("")
Next
Else
PrintN("There are currenty no opened connections.")
Print("Push enter.")
Input()
ProcedureReturn
EndIf
Print("Choose Connection to close: ")
n = Val(Input())
If n <= 0 Or n > ListSize(connections()) Or (Not IsFTP(n))
PrintN("Not a valid value!")
Print("Push enter.")
Input()
ProcedureReturn
EndIf
CloseFTP(n)
ForEach connections()
If connections()\id = n
Break
EndIf
Next
DeleteElement(connections(),1)
ProcedureReturn
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; The build-in fileManager
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure fileManager(n.l)
Repeat
ClearConsole()
showDir(n)
PrintN("")
PrintN("Type help for options.")
Print("> ")
If 1 = handleFileOptions(n)
ProcedureReturn
EndIf
ForEver
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Show current directory
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure showDir(n.l)
PrintN("Current directory: "+GetFTPDirectory(n))
ExamineFTPDirectory(n)
;; List files
While NextFTPDirectoryEntry(n)
attributes = FTPDirectoryEntryAttributes(n)
If attributes & #PB_FTP_ReadUser
Print("r")
Else
Print("-")
EndIf
If attributes & #PB_FTP_WriteUser
Print("w")
Else
Print("-")
EndIf
If attributes & #PB_FTP_ExecuteUser
Print("x")
Else
Print("-")
EndIf
If attributes & #PB_FTP_ReadGroup
Print("r")
Else
Print("-")
EndIf
If attributes & #PB_FTP_WriteGroup
Print("w")
Else
Print("-")
EndIf
If attributes & #PB_FTP_ExecuteGroup
Print("x")
Else
Print("-")
EndIf
If attributes & #PB_FTP_ReadAll
Print("r")
Else
Print("-")
EndIf
If attributes & #PB_FTP_WriteAll
Print("w")
Else
Print("-")
EndIf
If attributes & #PB_FTP_ExecuteAll
Print("x")
Else
Print("-")
EndIf
Print(" "+FTPDirectoryEntryName(n))
If FTPDirectoryEntryType(n) = #PB_FTP_File
PrintN(" File")
ElseIf FTPDirectoryEntryType(n) = #PB_FTP_Directory
PrintN(" Dir")
Else
PrintN("")
EndIf
Wend
ProcedureReturn
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Handle the options of the fm
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Procedure handleFileOptions(n.l)
option.s = Input()
Select option
Case "changeDir"
Print("Dir: ")
newDir.s = Input()
SetFTPDirectory(n, newDir)
ProcedureReturn 0
Case "createDir"
Print("Name: ")
name.s = Input()
CreateFTPDirectory(n, name)
ProcedureReturn 0
Case "deleteDir"
Print("Name: ")
name.s = Input()
DeleteFTPDirectory(n, name)
ProcedureReturn 0
Case "delete"
Print("Name: ")
name.s = Input()
DeleteFTPFile(n, name)
ProcedureReturn 0
Case "download"
Print("Name: ")
name.s = Input()
Print("Name for saving: ")
saveName.s = Input()
ReceiveFTPFile(n, name, saveName)
ProcedureReturn 0
Case "exit"
ProcedureReturn 1
Case "help"
PrintN("changeDir -> change directory")
PrintN("createDir -> create directory")
PrintN("deleteDir -> delete EMPTY directory")
PrintN("delete -> delete file")
PrintN("download -> download file")
PrintN("exit -> return to main menu")
PrintN("help -> this help")
PrintN("rename -> rename file or directory")
PrintN("send -> send file to server")
Print("Push enter.")
Input()
ProcedureReturn 0
Case "rename"
Print("Old Name: ")
name.s = Input()
Print("New name: ")
newName.s = Input()
RenameFTPFile(n, name, newName)
ProcedureReturn 0
Case "send"
Print("File: ")
name.s = Input()
Print("Name for saving: ")
saveName.s = Input()
SendFTPFile(n, name, saveName)
ProcedureReturn 0
Default
PrintN("Not a valid option")
Print("Push enter.")
Input()
ProcedureReturn 0
EndSelect
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Start the program
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OpenConsole()
EnableGraphicalConsole(1)
mainMenu(connections())
Was soll das Programm tun?
Dieses Programm stellt einen einfachen, konsolenbasierten FTP-Client dar. Wenn das Programm gestartet wird, sieht man im Terminal ein Menü. Über den ersten Menüpunkt kann man eine FTP-Session eröffnen, über den zweiten kann man sie wieder schließen und über den dritten kann man die Dateien auf dem FTP-Server durchsuchen und bearbeiten. Der vierte schließt das Programm wieder. Das Programm ist dabei in der Lage mehrere FTP-Sessions zu verwalten. Man muss immer angeben, welche Session gerade bearbeitet werden soll.
Wie funktioniert das Programm?
Am Anfang wird über InitNetwork() die Netzwerk-Bibliothek geladen, wodurch die Befehle für die FTP-Verwaltung verfügbar werden. Die Struktur ist da, um die FTP-Verbindungen zu verwalten. Danach folgt die Deklaration mehrerer Verbindungen, sowie die Deklaration einer Liste, in der die FTP-Verbindungen, repräsentiert über die Struktur connection, orgranisiert werden. Danach werden die Prozeduren definiert. Ganz am Ende des Programmes wird die Konsole geöffnet. EnableGraphicalConsole(1) ermöglicht das Löschen des Inhalts der Konsole. Der letzte Befehl ruft das Hauptmenü auf, dass in der ersten Prozedur definiert ist.
- mainMenu(): Die Prozedur erwartet, dass man ihr die Liste mit den Verbindungen übergibt. Es wird lediglich das Menü dargestellt und auf Eingaben mittels Fallunterscheidungen reagiert. Wenn FTP-Verbindungen eröffnet wurden, stellt das Programm diese dar. Beim Schließen des Programms muss nicht darauf geachtet werden, dass alle Verbindungen geschlossen werden, dies wird automatisch beim Schließen erledigt.
- establishConnection(): Diese Prozedur erwartet ebenfalls die Liste der Verbindungen. Zuerst wird die Nummer der letzten FTP-Verbindung herausgefunden. Das ist wichtig für die Vergabe einer Nummer an die neue Verbindung. Danach wird ein neues Element zur Liste hinzugefügt. AddElement() gibt die Adresse des neuen Elements zurück, die im Zeiger gespeichert wird. Über den Zeiger wird danach auf das Element zugegriffen und die Daten werden eingegeben. Mit OpenFTP() wird dann versucht die Verbindung herzustellen. Wenn sie nicht hergestellt werden kann, wird sie gelöscht.
- checkConnection(): Diese Prozedur überprüft lediglich, ob die Verbindung noch besteht. Dies wird im Hauptmenü genutzt, wo dies angezeigt wird.
- closeConnection(): Es werden alle geöffneten Verbindungen angezeigt. Man wählt eine aus und diese wird geschlossen und aus der Liste gelöscht. Es wird dabei überprüft, ob es sich wirklich um eine geöffnete Verbindung handelt.
- fileManager(): Diese Prozedur steuert den Dateimanager. Es wird das aktuell ausgewählte Verzeichnis angezeigt und man kann mit diesem interagieren.
- showDir(): Es wird einfach der Inhalt des Verzeichnis aufgelistet, zusammen mit den Rechten des Benutzers, mit dem die Verbindung eröffnet wurde.
- handleFileOptions(): Diese Prozedur wird aus fileManager() aufgerufen. Man kann verschiedene Befehle eingeben. Welche das sind, wird über den Befehl help angezeigt.