FTP-Modul

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

BtbN

Betreff: FTP-Modul

BeitragSo, Jun 25, 2006 10:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Modul ist komplett ausdokumentiert. Um es zu installieren muss das Code nach "*bmaxdir*/mod/btbn.mod/ftp.mod/ftp.bmx" kopiert werden. Danach das Modul kompilieren und docmods ausführen.
Wenn ihr der Ansicht seid, der Source ist zu lang um in Code-Tags gepostet zu werden, sagt es, dann lad ich das Modul hoch.

Hier das Modul:
Code: [AUSKLAPPEN]
SuperStrict

Rem
bbdoc: FTP
about: !!!WARNING!!! You Should NOT hardcode you FTP Username and Password unencrypted in you Application !!!WARNING!!!<br><br>
This Module also provides a StreamFactory for FTP-File-Transfer. So if you import this module, you can Read or Write Streams to a FTP-Server like this:
<pre>ReadStream("ftp::username:password:ftp.server.net/file.txt")
WriteStream("ftp::username:password:ftp.server.net/file2.txt")</pre>
<br>
For anonymous access use:
<pre>ReadStream("ftp::::ftp.server.net/file.txt")</pre>
<br>
You can use 'ftpa' for ASCII-Transfer-Mode and 'ftpb' or just 'ftp' for binary mode:
<pre>ReadStream("ftpa::::ftp.server.net/file.txt") 'ASCII
ReadStream("ftpb::::ftp.server.net/file.txt") 'Binary
ReadStream("ftp::::ftp.server.net/file.txt") 'Binary</pre>
<br>
OpenStream is not supported!
EndRem
Module BtbN.FTP

ModuleInfo "Version: 1.00"
ModuleInfo "Author: BtbN"
ModuleInfo "License: Public Domain"

Import BRL.SocketStream
Import BRL.BankStream
?debug
Import BRL.StandardIO
?


Rem
bbdoc: FTP Type
EndRem
Type TFTP
    Field cmdstream:TStream,datastream:TStream
    Field lastCode:Int,lastErrorCode:Int
    Field infoString:String,serverString:String
    Field server:String,user:String,pass:String,port:Int
    Field curDir:String

    Rem
    bbdoc: Initialisates the FTP-Object with Server,Username,Password
    about: !!!WARNING!!! You Should NOT hardcode you FTP Username and Password unencrypted in you Application !!!WARNING!!!<br><br>
    You can Create an instance like this: <pre>Local ftp:TFTP = (New TFTP).init("myserver.com","myuser","mypassword")</pre>
    EndRem
    Method init:TFTP(srv:String,usr:String="anonymous",pw:String="nobody@blitzmax.com",prt:Int=21)
        server = srv
        user = usr
        pass = pw
        port = prt
        curDir = "/"
        connect()
        Return Self
    EndMethod

    Rem
    bbdoc: Connects to and Loggs in on the Server
    EndRem
    Method connect:Int()
        If cmdstream And Not cmdstream.Eof() Then cmdstream.WriteLine("QUIT")
        If cmdstream Then cmdstream.close()
        cmdstream = Null

        cmdstream = TSocketStream.CreateClient(server,port)
        If Not cmdstream Then Return False

        If getCode() <> 220 Then cmdstream.close(); cmdstream = Null; Return False
        serverString = infoString

        If Not command("USER "+user,331) Then cmdstream.close(); cmdstream = Null; Return False

        If Not command("PASS "+pass,230) Then cmdstream.close(); cmdstream = Null; Return False

        Return True
    EndMethod

    Rem
    bbdoc: Disconnects from the FTP-Server
    EndRem
    Method disconnect()
        If Not command("QUIT") Then Return
        cmdstream.close()
        cmdstream = Null
    EndMethod

    Rem
    bbdoc: Returns infos about the Server.
    EndRem
    Method ServerInfo:String()
        Return serverString
    EndMethod

    Rem
    bbdoc: Returns infos about the Server's System.
    EndRem
    Method ServerSystem:String()
        If Not command("SYST",215) Then Return Null
        Return infoString
    EndMethod

    Rem
    bbdoc: Returns the last output from the server.
    EndRem
    Method LastOutput:String()
        Return infoString
    EndMethod

    Rem
    bbdoc: Returns the last error code.
    EndRem
    Method LastError:Int()
        Return lastErrorCode
    EndMethod

    Rem
    bbdoc: Resturns the Last Result-Code.
    EndRem
    Method LastResult:Int()
        Return lastCode
    EndMethod

    Rem
    bbdoc: Executes a command on the Server.
    about: If @code is other than -1 #command returns @True is the FTP-Code is equal @code.
    EndRem
    Method command:Int(cmd:String,code:Int=-1)
        If Not ready() Then Return False
        ?debug
            If cmd[..4].toUpper() = "PASS" Then
                Print "PASS ********"
            Else
                Print cmd
            EndIf
        ?
        cmdstream.WriteLine(cmd)
        getCode()
        If code = -1 Then Return True
        If lastCode <> code Then Return False
        Return True
    EndMethod

    Rem
    bbdoc: Sets the FTP-Mode to ASCII is @ascii is true, else to Binary
    EndRem
    Method setAsciiMode(ascii:Int=True)
        If ascii Then
            command("TYPE A")
        Else
            command("TYPE I")
        EndIf
    EndMethod

    Rem
    bbdoc: Sets the FTP-Mode to Binary is @binary is true, else to ASCII
    EndRem
    Method setBinMode(binary:Int=True)
        If binary Then
            command("TYPE I")
        Else
            command("TYPE A")
        EndIf
    EndMethod

    Rem
    bbdoc: Creates a dir with the name @name.
    EndRem
    Method MakeDir:Int(name:String)
        Return command("MKD "+name,257)
    EndMethod

    Rem
    bbdoc: Removes the dir @name.
    EndRem
    Method RemoveDir:Int(name:String)
        Return command("RMD "+name,250)
    EndMethod

    Rem
    bbdoc: Deletes the file @name
    EndRem
    Method DeleteFile:Int(name:String)
        Return command("DELE "+name,250)
    EndMethod

    Rem
    bbdoc: Returns a Stream with the File-list from the Current wirkoing Dir.
    EndRem
    Method list:TStream()
        If Not ready() Then Return Null

        setAsciiMode()
        If Not openData() Then Return Null

        If Not command("LIST",150) Then Return Null

        Local tmpbankstrm:TBankStream = CreateBankStream(CreateBank())
        While Not datastream.Eof()
            tmpbankstrm.WriteByte(datastream.ReadByte())
        Wend
        tmpbankstrm.Seek(0)

        datastream.close()
        datastream = Null

        getCode()

        Return tmpbankstrm
    EndMethod

    Rem
    bbdoc: Uploads the file represented by @url.
    EndRem
    Method PutFile:Int(url:Object,file:String,bufsize:Int=4096)
        If (Not ready()) Or (Not openData()) Then Return False

        If Not command("STOR "+file,150) Return False

        Local tmpbnk:TBank = LoadBank(url)
        Local tmpbnkstrm:TBankStream = CreateBankStream(tmpbnk)

        CopyBytes(tmpbnkstrm,datastream,tmpbnk.size(),bufsize)
        datastream.Flush()

        datastream.close()
        datastream = Null

        tmpbnkstrm.close()
        tmpbnkstrm = Null
        tmpbnk = Null

        getcode()

        Return True
    EndMethod

    Rem
    bbdoc: Renames @fromfile to @tofile
    EndRem
    Method Rename:Int(fromfile:String,tofile:String)
        If Not ready() Then Return False
        If Not command("RNFR "+fromfile,350) Then Return False
        If Not command("RNTO "+tofile,250) Then Return False
        Return True
    EndMethod

    Rem
    bbdoc: Openas @file for writing.
    returns: A Stream where you can write in the file @file.
    EndRem
    Method OpenWriteStream:TStream(file:String)
        If (Not ready()) Or (Not openData()) Then Return Null

        If Not command("STOR "+file,150) Then Return Null

        Return datastream
    EndMethod

    Rem
    bbdoc: Closes the Stream opened by #OpenWriteStream
    about: You have to cal this function after Writing to a Stream from #OpenWriteStream.
    EndRem
    Method CloseWriteStream:Int()
        datastream.close()
        datastream = Null
        Return getcode() <> 226
    EndMethod

    Rem
    bbdoc: Changes the current Working Directory to @name.
    EndRem
    Method ChangeDir:Int(name:String)
        If Not ready() Then Return False
        If name = ".." Then
            Local retval:Int = command("CDUP",250)
            If retval Then Self.CurrentDir()
            Return retval
        Else
            Local retval:Int = command("CWD "+name,250)
            If retval Then Self.CurrentDir()
            Return retval
        EndIf
    EndMethod

    Rem
    bbdoc: Abourts the current Action.
    EndRem
    Method abort:Int()
        If Not ready() Then Return False
        Return command("ABOR",226)
    EndMethod

    Rem
    bbdoc: Returns the Current Working Dir.
    EndRem
    Method CurrentDir:String()
        If Not ready() Then Return False
        If Not command("PWD",257) Then Return Null
        Local str:String = infoString
        str = str[str.find("~q")+1..]
        str = str[..str.find("~q")]
        curDir = str
        Return str
    EndMethod

    Rem
    bbdoc: Returns a Stream to the file @name on the FTP-Server.
    EndRem
    Method GetFile:TStream(name:String)
        If (Not ready()) Or (Not openData()) Then Return Null

        If Not command("RETR "+name,150) Then datastream.close(); datastream = Null; Return Null

        Local tmpbankstrm:TBankStream = CreateBankStream(CreateBank())
        While Not datastream.Eof()
            tmpbankstrm.WriteByte(datastream.ReadByte())
        Wend
        tmpbankstrm.Seek(0)

        datastream.close()
        datastream = Null

        getCode()

        Return tmpbankstrm
    EndMethod

    Rem
    bbdoc: Internal Function to open a FTP-Data-Connection
    about: Passive Mode Only
    EndRem
    Method openData:Int()
        If (Not ready()) Or Not (command("PASV",227)) Then Return False

        Local str:String = infoString[infoString.findLast("(")+1..infoString.findLast(")")]

        Local val:Int[6],l:Int
        For Local i:Int = 0 Until 6
            l = str.find(",")
            If l = -1 Then
                val[i] = str.toInt()
            Else
                val[i] = str[..l].toInt()
            EndIf
            str = str[l+1..]
        Next

        datastream = TSocketStream.CreateClient(val[0]+"."+val[1]+"."+val[2]+"."+val[3],(val[4] Shl 8) | val[5])
        If Not datastream Then Return False

        Return True
    EndMethod

    Rem
    bbdoc: Holds the FTP-Connection(300Sec Timeout)
    EndRem
    Method Noop()
        If ready() Then cmdstream.WriteLine("NOOP")
    EndMethod

    Rem
    bbdoc: Internal Function
    EndRem
    Method ready:Int()
        If cmdstream And Not cmdstream.Eof() Then
            Return True
        Else
            Return connect()
        EndIf
    EndMethod

    Rem
    bbdoc: Internal Function
    about: Returns the Current FTP-Code! Please don't call!!!!!
    EndRem
    Method getCode:Int()
        If Not ready() Then Return -1
        Local tmpcode:Int = -9999,tmpinfostr:String=""
        While Not cmdstream.Eof()
            Local str:String = cmdstream.ReadLine()
            ?debug
                Print str
            ?
            Local i:Int = str[..3].toInt()

            If tmpcode <> -9999 And i <> tmpcode Then
                tmpinfostr :+ str+"~n"
                Continue
            Else
                tmpcode = -9999
            EndIf

            If str[3] = Asc("-") Then
                tmpcode = i
                tmpinfostr :+ str[4..]+"~n"
                Continue
            Endif

            If str[..3] = String(i) Then
                infoString = tmpinfostr+str[4..]
                lastCode = i
                If i > 400 Then lastErrorCode = i
                Return i
            EndIf
        Wend
        Return -1
    EndMethod
EndType




Type TFTPStreamFactory Extends TStreamFactory

    Method CreateStream:TStream(url:Object,proto:String,path:String,readable:Int,writeable:Int)
        If proto="ftpa" Or proto="ftpb" Or proto="ftp" Then
            If writeable And readable Then Return Null

            Local k:Int = path.find(":")
            Local user:String = path[..k]

            Local l:Int = path.find(":",k+1)
            Local pass:String = path[k+1..l]

            If user = "" Then
                user = "anonymous"
                pass = "nobody@blitzmax.com"
            EndIf

            k = path.find("/",l+1)
            Local server:String = path[l+1..k]

            Local file:String,dir:String = path[k+1..]
            If dir.find("/") = -1 Then
                file = dir
                dir = "/"
            Else
                file = dir[dir.findLast("/")+1..]
                dir = "/"+dir[..dir.findLast("/")]
            EndIf

            Local ftp:TFTP = (New TFTP).init(server,user,pass)

            If proto="ftpa" Then
                ftp.setAsciiMode(True)
            Else
                ftp.setAsciiMode(False)
            EndIf

            ftp.ChangeDir(dir)

            If readable Then
                Return ftp.GetFile(file)
            Else
                Return ftp.OpenWriteStream(file)
            EndIf
        EndIf
    End Method

End Type

New TFTPStreamFactory


Kritik und Verbesserungsvorschläge(Auch an der Dokumentation(Rechtschreibfehler und so)) sind willkommen.


Mfg
 

porcus

BeitragSo, Feb 15, 2009 23:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo ich habe heute mit diesem Modul versucht eine Datei von einem ftp zu ziehen aber ich kriege
nur einen "Unhandled Exception" Fehler (und zwar immer bei der Zeile: CopyStream(str,target)):

Code: [AUSKLAPPEN]
Framework brl.blitz
Import brl.stream
Import btbn.ftp

Local ftp:TFTP = (New TFTP).init("ibiblio.org")
ftp.connect()
ftp.ChangeDir("pub/Linux/distributions/damnsmall")
Print "Datei laden..."
Local str:TStream=ftp.GetFile("GPL_Sources.txt")
Local target:TStream=WriteStream("test.txt")
CopyStream(str,target)
CloseStream(target)
CloseStream(str)


Warum?
*Account deaktiviert*

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group