PureBasic: sFTPc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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?
[Bearbeiten]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?
[Bearbeiten]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.