PureBasic kann weder SFTP (SSH File Transfer Protocol) noch FTPS (FTP über SSL/TLS). Mit dieser Bibliothek ist das möglich. Die Funktionen sind im selben Stil wie die FTP-Bibliothek von PureBasic aufgebaut und FTP wird ebenfalls unterstützt.
Funktionen:
- OpenFTPEx()
- Syntax:
Code: Alles auswählen
Result = OpenFTPEx(ID, Protocol, ServerName$, Port, User$, Password$, Charset, @ErrorOutput)
- Beschreibung: Stellt eine Verbindung zum Server her.
- Parameter:
- ID: Eine eindeutige Nummer für die Verbindung. #PB_Any kann verwendet werden, um die Nummer automatisch zu generieren.
- Protocol: Legt das Protokoll (FTP, SFTP, FTPS) für die Verbindung fest: #PBEx_FTP_Protocol_FTP, #PBEx_FTP_Protocol_SFTP, #PBEx_FTP_Protocol_FTPS_Implicit, #PBEx_FTP_Protocol_FTPS_Explicit
- ServerName$: Die Domain oder IP-Adresse des Servers.
- Port: Die Port-Nummer für die Verbindung.
- User$: Der Benutzername für die Anmeldung.
- Password$: Das Passwort für die Anmeldung.
- Charset: Legt den Zeichensatz fest: #PB_UTF8, #PB_Ascii, #PB_Unicode - Bei SFTP wird standardmäßig UTF-8 verwendet.
- @ErrorOutput: Falls ein Fehler auftrat, dann wird die Fehlermeldung in die Variable gespeichert. Diese Variable muss vor dem Übergeben mit 128 Zeichen reserviert werden. Maximale Länge der Rückgabe beträgt 128 Zeichen einschließlich des NULL-Zeichens. Wenn bei einem Fehler keine Fehlerbeschreibung zurückgegeben werden soll, dann kann stattdessen 0 übergeben werden.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich. Falls #PB_Any verwendet wird, dann wird die ID zurückgegeben.
- Beispielcode:
Code: Alles auswählen
EnableExplicit Global PBEx_FTP #PBEx_FTP_Version$ = "1.0.6.0" #PBEx_FTP_Protocol_FTP = 1 #PBEx_FTP_Protocol_SFTP = 2 #PBEx_FTP_Protocol_FTPS_Implicit = 3 #PBEx_FTP_Protocol_FTPS_Explicit = 4 CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 PBEx_FTP = OpenLibrary(#PB_Any, "PB.Ex_FTP_x86.dll") CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64 PBEx_FTP = OpenLibrary(#PB_Any, "PB.Ex_FTP_x64.dll") CompilerEndIf If PBEx_FTP Prototype OpenFTPEx(ID, Protocol, ServerName.p-Unicode, Port, User.p-Unicode, Password.p-Unicode, Charset, ErrorOutput) Global OpenFTPEx.OpenFTPEx = GetFunction(PBEx_FTP, "OpenFTPEx") Prototype CloseFTPEx(ID, ErrorOutput) Global CloseFTPEx.CloseFTPEx = GetFunction(PBEx_FTP, "CloseFTPEx") Prototype CheckFTPConnectionEx(ID, ErrorOutput) Global CheckFTPConnectionEx.CheckFTPConnectionEx = GetFunction(PBEx_FTP, "CheckFTPConnectionEx") Prototype IsFTPEx(ID, ErrorOutput) Global IsFTPEx.IsFTPEx = GetFunction(PBEx_FTP, "IsFTPEx") Prototype ExamineFTPDirectoryEx(ID, ErrorOutput) Global ExamineFTPDirectoryEx.ExamineFTPDirectoryEx = GetFunction(PBEx_FTP, "ExamineFTPDirectoryEx") Prototype FinishFTPDirectoryEx(ID, ErrorOutput) Global FinishFTPDirectoryEx.FinishFTPDirectoryEx = GetFunction(PBEx_FTP, "FinishFTPDirectoryEx") Prototype NextFTPDirectoryEntryEx(ID, ErrorOutput) Global NextFTPDirectoryEntryEx.NextFTPDirectoryEntryEx = GetFunction(PBEx_FTP, "NextFTPDirectoryEntryEx") Prototype FTPDirectoryEntryNameEx(ID, Output, ErrorOutput) Global FTPDirectoryEntryNameEx.FTPDirectoryEntryNameEx = GetFunction(PBEx_FTP, "FTPDirectoryEntryNameEx") Prototype.q FTPDirectoryEntrySizeEx(ID, ErrorOutput) Global FTPDirectoryEntrySizeEx.FTPDirectoryEntrySizeEx = GetFunction(PBEx_FTP, "FTPDirectoryEntrySizeEx") Prototype FTPDirectoryEntryTypeEx(ID, ErrorOutput) Global FTPDirectoryEntryTypeEx.FTPDirectoryEntryTypeEx = GetFunction(PBEx_FTP, "FTPDirectoryEntryTypeEx") Prototype FTPDirectoryEntryDateEx(ID, ErrorOutput) Global FTPDirectoryEntryDateEx.FTPDirectoryEntryDateEx = GetFunction(PBEx_FTP, "FTPDirectoryEntryDateEx") Prototype FTPDirectoryEntryAttributesEx(ID, ErrorOutput) Global FTPDirectoryEntryAttributesEx.FTPDirectoryEntryAttributesEx = GetFunction(PBEx_FTP, "FTPDirectoryEntryAttributesEx") Prototype GetFTPDirectoryEx(ID, Output, ErrorOutput) Global GetFTPDirectoryEx.GetFTPDirectoryEx = GetFunction(PBEx_FTP, "GetFTPDirectoryEx") Prototype SetFTPDirectoryEx(ID, DirectoryName.p-Unicode, ErrorOutput) Global SetFTPDirectoryEx.SetFTPDirectoryEx = GetFunction(PBEx_FTP, "SetFTPDirectoryEx") Prototype CreateFTPDirectoryEx(ID, DirectoryName.p-Unicode, ErrorOutput) Global CreateFTPDirectoryEx.CreateFTPDirectoryEx = GetFunction(PBEx_FTP, "CreateFTPDirectoryEx") Prototype DeleteFTPDirectoryEx(ID, DirectoryName.p-Unicode, ErrorOutput) Global DeleteFTPDirectoryEx.DeleteFTPDirectoryEx = GetFunction(PBEx_FTP, "DeleteFTPDirectoryEx") Prototype DeleteFTPFileEx(ID, FileName.p-Unicode, ErrorOutput) Global DeleteFTPFileEx.DeleteFTPFileEx = GetFunction(PBEx_FTP, "DeleteFTPFileEx") Prototype RenameFTPFileEx(ID, FileName.p-Unicode, NewFileName.p-Unicode, ErrorOutput) Global RenameFTPFileEx.RenameFTPFileEx = GetFunction(PBEx_FTP, "RenameFTPFileEx") Prototype ReceiveFTPFileEx(ID, RemoteFileName.p-Unicode, FileName.p-Unicode, IsAsynchron, ErrorOutput) Global ReceiveFTPFileEx.ReceiveFTPFileEx = GetFunction(PBEx_FTP, "ReceiveFTPFileEx") Prototype SendFTPFileEx(ID, FileName.p-Unicode, RemoteFileName.p-Unicode, IsAsynchron, ErrorOutput) Global SendFTPFileEx.SendFTPFileEx = GetFunction(PBEx_FTP, "SendFTPFileEx") Prototype FTPProgressEx(ID, PercentValue, TransferRate, EstimatedTime, ErrorOutput) Global FTPProgressEx.FTPProgressEx = GetFunction(PBEx_FTP, "FTPProgressEx") Prototype AbortFTPFileEx(ID, ErrorOutput) Global AbortFTPFileEx.AbortFTPFileEx = GetFunction(PBEx_FTP, "AbortFTPFileEx") EndIf Define ErrorOutput$ = Space(128) Define FileName$ = Space(#MAX_PATH) Debug "SFTP..." If OpenFTPEx(1, #PBEx_FTP_Protocol_SFTP, "test.rebex.net", 22, "demo", "password", #PB_UTF8, @ErrorOutput$) ;If OpenFTPEx(1, #PBEx_FTP_Protocol_SFTP, "demo.wftpserver.com", 2222, "demo-user", "demo-user", #PB_UTF8, @ErrorOutput$) SetFTPDirectoryEx(1, "pub", @ErrorOutput$) SetFTPDirectoryEx(1, "example", @ErrorOutput$) ;SetFTPDirectoryEx(1, "download", @ErrorOutput$) ;SetFTPDirectoryEx(1, "upload", @ErrorOutput$) If ExamineFTPDirectoryEx(1, @ErrorOutput$) While NextFTPDirectoryEntryEx(1, @ErrorOutput$) FTPDirectoryEntryNameEx(1, @FileName$, @ErrorOutput$) Debug FileName$ Wend EndIf ; Define a ; Define PercentValue = 0 ; Define TransferRate = 0 ; Define EstimatedTime = 0 ; ; ReceiveFTPFileEx(1, "wftpserver-linux-64bit.tar.gz", "D:\wftpserver-linux-64bit.tar.gz", 1, @ErrorOutput$) ; ; For a=1 To 100 ; FTPProgressEx(1, @PercentValue, @TransferRate, @EstimatedTime, @ErrorOutput$) ; Debug PercentValue ; Debug TransferRate ; Debug EstimatedTime ; Debug "--------" ; Delay(100) ; Next ; ; Delay(10000) CloseFTPEx(1, @ErrorOutput$) Else Debug ErrorOutput$ EndIf ; Debug "" ; Debug "FTP..." ; ; If OpenFTPEx(1, #PBEx_FTP_Protocol_FTP, ".........", 21, ".........", ".......", #PB_UTF8, @ErrorOutput$) ; If ExamineFTPDirectoryEx(1, @ErrorOutput$) ; While NextFTPDirectoryEntryEx(1, @ErrorOutput$) ; FTPDirectoryEntryNameEx(1, @FileName$, @ErrorOutput$) ; Debug FileName$ ; Wend ; ; EndIf ; ; CloseFTPEx(1, @ErrorOutput$) ; Else ; Debug ErrorOutput$ ;EndIf Debug "" Debug "FTPS explicit..." If OpenFTPEx(1, #PBEx_FTP_Protocol_FTPS_Explicit, "test.rebex.net", 21, "demo", "password", #PB_UTF8, @ErrorOutput$) If ExamineFTPDirectoryEx(1, @ErrorOutput$) While NextFTPDirectoryEntryEx(1, @ErrorOutput$) FTPDirectoryEntryNameEx(1, @FileName$, @ErrorOutput$) Debug FileName$ Wend EndIf CloseFTPEx(1, @ErrorOutput$) Else Debug ErrorOutput$ EndIf Debug "" Debug "FTPS implicit..." If OpenFTPEx(1, #PBEx_FTP_Protocol_FTPS_Implicit, "test.rebex.net", 990, "demo", "password", #PB_UTF8, @ErrorOutput$) If ExamineFTPDirectoryEx(1, @ErrorOutput$) While NextFTPDirectoryEntryEx(1, @ErrorOutput$) FTPDirectoryEntryNameEx(1, @FileName$, @ErrorOutput$) Debug FileName$ Wend EndIf CloseFTPEx(1, @ErrorOutput$) Else Debug ErrorOutput$ EndIf CloseLibrary(PBEx_FTP)
- Syntax:
- CloseFTPEx()
- Syntax:
Code: Alles auswählen
Result = CloseFTPEx(ID, @ErrorOutput)
- Beschreibung: Schließt die offene Verbindung zum Server.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- CheckFTPConnectionEx()
- Syntax:
Code: Alles auswählen
Result = CheckFTPConnectionEx(ID, @ErrorOutput)
- Beschreibung: Überprüft, ob die Verbindung zum Server noch besteht.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Die Verbindung zum Server besteht.
- Syntax:
- IsFTPEx()
- Syntax:
Code: Alles auswählen
Result = IsFTPEx(ID, @ErrorOutput)
- Beschreibung: Überprüft, ob die ID korrekt initialisiert wurde.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Die ID ist gültig.
- Syntax:
- ExamineFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = ExamineFTPDirectoryEx(ID, @ErrorOutput)
- Beschreibung: Startet die Auflistung vom aktuellen Verzeichnis.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- FinishFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = FinishFTPDirectoryEx(ID, @ErrorOutput)
- Beschreibung: Schließt die Auflistung vom aktuellen Verzeichnis.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- NextFTPDirectoryEntryEx()
- Syntax:
Code: Alles auswählen
Result = NextFTPDirectoryEntryEx(ID, @ErrorOutput)
- Beschreibung: Der nächste Ordner oder die nächste Datei wird ermittelt.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Ein weiterer Ordner oder eine weitere Datei existiert.
- Syntax:
- FTPDirectoryEntryNameEx()
- Syntax:
Code: Alles auswählen
Result = FTPDirectoryEntryNameEx(ID, @Output, @ErrorOutput)
- Beschreibung: Der Ordner- oder Dateiname wird ermittelt.
- Parameter:
- ID: Die Nummer der Verbindung.
- @Output: Der Ordner- oder Dateiname wird in die String-Variable gespeichert.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- FTPDirectoryEntrySizeEx()
- Syntax:
Code: Alles auswählen
Result = FTPDirectoryEntrySizeEx(ID, @ErrorOutput)
- Beschreibung: Die Größe der Datei wird ermittelt.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- Die Größe der Datei wird zurückgegeben.
- Syntax:
- FTPDirectoryEntryTypeEx()
- Syntax:
Code: Alles auswählen
Result = FTPDirectoryEntryTypeEx(ID, @ErrorOutput)
- Beschreibung: Prüft, ob der Eintrag eine Datei oder ein Ordner ist.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Es ist eine Datei. #PB_FTP_File kann verwendet werden.
- 2: Es ist ein Ordner. #PB_FTP_Directory kann verwendet werden.
- Syntax:
- FTPDirectoryEntryDateEx()
- Syntax:
Code: Alles auswählen
Result = FTPDirectoryEntryDateEx(ID, @ErrorOutput)
- Beschreibung: Ermittelt das Bearbeitungsdatum der Datei oder des Ordners.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- Das Bearbeitungsdatum der Datei oder des Ordners. Der Wert kann mit der Date-Bibliothek verwendet werden.
- Syntax:
- FTPDirectoryEntryAttributesEx()
- Syntax:
Code: Alles auswählen
Result = FTPDirectoryEntryAttributesEx(ID, @ErrorOutput)
- Beschreibung: Ermittelt die festgelegten Attribute der Datei oder des Ordners.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- Die festgelegten Attribute der Datei oder des Ordners werden zurückgegeben. #PB_FTP_ReadUser, #PB_FTP_WriteUser, #PB_FTP_ExecuteUser, #PB_FTP_ReadGroup, #PB_FTP_WriteGroup, #PB_FTP_ExecuteGroup, #PB_FTP_ReadAll, #PB_FTP_WriteAll und #PB_FTP_ExecuteAll können verwendet werden.
- Syntax:
- GetFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = GetFTPDirectoryEx(ID, @Output, @ErrorOutput)
- Beschreibung: Ermittelt den aktuellen Pfad.
- Parameter:
- ID: Die Nummer der Verbindung.
- @Output: Der aktuelle Pfad wird in die String-Variable gespeichert.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- SetFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = SetFTPDirectoryEx(ID, DirectoryName$, @ErrorOutput)
- Beschreibung: Öffnet einen Unterordner.
- Parameter:
- ID: Die Nummer der Verbindung.
- DirectoryName$: Name des Ordners, der geöffnet werden soll.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- CreateFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = CreateFTPDirectoryEx(ID, DirectoryName$, @ErrorOutput)
- Beschreibung: Erstellt ein neues Verzeichnis.
- Parameter:
- ID: Die Nummer der Verbindung.
- DirectoryName$: Name des Ordners, der erstellt werden soll.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- DeleteFTPDirectoryEx()
- Syntax:
Code: Alles auswählen
Result = DeleteFTPDirectoryEx(ID, DirectoryName$, @ErrorOutput)
- Beschreibung: Löscht ein Verzeichnis.
- Parameter:
- ID: Die Nummer der Verbindung.
- DirectoryName$: Name des Ordners, der gelöscht werden soll.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- DeleteFTPFileEx()
- Syntax:
Code: Alles auswählen
Result = DeleteFTPFileEx(ID, FileName$, @ErrorOutput)
- Beschreibung: Löscht eine Datei.
- Parameter:
- ID: Die Nummer der Verbindung.
- FileName$: Name der Datei, die gelöscht werden soll.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- RenameFTPFileEx()
- Syntax:
Code: Alles auswählen
Result = RenameFTPFileEx(ID, FileName$, NewFileName$, @ErrorOutput)
- Beschreibung: Benennt eine Datei um.
- Parameter:
- ID: Die Nummer der Verbindung.
- FileName$: Name der Datei, die umbenannt werden soll.
- NewFileName$: Der neue Name der Datei.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- ReceiveFTPFileEx()
- Syntax:
Code: Alles auswählen
Result = ReceiveFTPFileEx(ID, RemoteFileName$, FileName$, IsAsynchron, @ErrorOutput)
- Beschreibung: Lädt eine Datei herunter.
- Parameter:
- ID: Die Nummer der Verbindung.
- RemoteFileName$: Name der Datei, die heruntergeladen werden soll.
- FileName$: Lokaler Zielpfad.
- IsAsynchron: Wenn 1, dann wird der Vorgang asynchron durchgeführt. Mit FTPProgressEx() kann ermittelt werden, wie weit der Vorgang ist.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- SendFTPFileEx()
- Syntax:
Code: Alles auswählen
Result = SendFTPFileEx(ID, FileName$, RemoteFileName$, IsAsynchron, @ErrorOutput)
- Beschreibung: Lädt eine Datei hoch.
- Parameter:
- ID: Die Nummer der Verbindung.
- FileName$: Lokaler Pfad der Datei, die hochgeladen werden soll.
- RemoteFileName$: Name der Datei.
- IsAsynchron: Wenn 1, dann wird der Vorgang asynchron durchgeführt. Mit FTPProgressEx() kann ermittelt werden, wie weit der Vorgang ist.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- FTPProgressEx()
- Syntax:
Code: Alles auswählen
Result = FTPProgressEx(ID, @PercentValue, @TransferRate, @EstimatedTime, @ErrorOutput)
- Beschreibung: Ermittelt, wie weit der Vorgang ist. Diese Funktion ist bei ReceiveFTPFileEx() oder SendFTPFileEx() gültig und wenn der Parameter "IsAsynchron" auf 1 gesetzt ist.
- Parameter:
- ID: Die Nummer der Verbindung.
- @PercentValue: In diese Variable wird der Prozentwert gespeichert, wie weit der Vorgang ist.
- @TransferRate: In diese Variable wird die aktuelle Übertragungsrate in Bytes gespeichert.
- @EstimatedTime: In diese Variable wird die geschätzte Zeit in Sekunden gespeichert.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- AbortFTPFileEx()
- Syntax:
Code: Alles auswählen
Result = AbortFTPFileEx(ID, @ErrorOutput)
- Beschreibung: Bricht den aktuellen Download oder Upload ab.
- Parameter:
- ID: Die Nummer der Verbindung.
- @ErrorOutput: Falls ein Fehler auftritt, wird die Fehlermeldung in die String-Variable gespeichert.
- Rückgabewert:
- 1: Der Vorgang war erfolgreich.
- Syntax:
- Windows Vista oder höher
- .NET Framework 4.8 oder höher
- Unicode-Aktivierung (standardmäßig ab PB 5.50)
Folgende Copyright-Texte müssen mitgeliefert werden:
Download: https://www.rsbasic.de/downloads/downlo ... Ex_FTP.zipCopyright (c) 2015 Robin Rodricks and FluentFTP Contributors
Copyright © 2019 RSBasic.de
Ich würde mich über Feedbacks, Verbesserungsvorschläge, Fehlermeldungen oder Wünsche sehr freuen. Wer mich unterstützen möchte, kann mir auch was kleines spenden. Danke