eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'FTPClient':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: FTPClient


Inheritance:

   Object
   |
   +--NVTClient
      |
      +--FTPClient

Package:
stx:goodies/communication
Category:
Net-Communication-FTP
Version:
rev: 1.69 date: 2022/01/06 18:57:11
user: cg
file: FTPClient.st directory: goodies/communication
module: stx stc-classLibrary: communication

Description:


Client interface to an ftp server.


[instance variables:]
    partnersTransferMode    mode of the connected-to partner
                            (nil initially - could be initialized by parsing some startup message)

    transferMode            wanted mode (can be changed before logging in)

    passiveMode             controls data connection setup - either I connect to the partners data port,
                            or he connects to my data port (req'd for firewalls / outgoing connection blockers)
                                passiveMode == false        -> I am actively connecting to partners data port
                                passiveMode == true         -> I am passively awaiting partner to connect to my data port

copyright

COPYRIGHT (c) 2003 by eXept Software AG All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

Signal constants
o  fileErrorSignal
return the signal raised if some file-get or chdir fails

o  fileNotFoundErrorSignal
return the signal raised if some file-get or chdir fails

o  filePutErrorSignal
return the signal raised if some file-put fails

o  ftpErrorSignal
return the parent of all ftp errors

o  transferInformationSignal
return the notification raised to transfer info information (such as speed etc.)
Currently never raised, but provided for later extension and compatibility with HTTPInterface.

o  transferProgressNotificationSignal
return the notification raised to provide progress (percentage) information.
Currently never raised, but provided for later extension and compatibility with HTTPInterface.

class initialization
o  initialize
self initialize.
Verbose := true


Instance protocol:

compatibility - squeak
o  changeDirectoryTo: dirName

o  getDirectory

o  getFileNamed: fileName

o  loginUser: user password: pw
login using userName and password. Squeak compatibility.
After successful login, set transfer mode

o  putFileStreamContents: aStream as: remoteFileName

defaults
o  defaultPassword
the anonymous's default password

o  defaultPort
Socket portOfService:'ftp'

o  defaultUser

error handling
o  fileNotFoundError

o  filePermissionError

o  noPort: errMsg

initialization
o  initialize
means: unknown

operations
o  ascii
send a 'type a' command (switch to text-mode transfer).

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp binary.
     ftp ascii.
     ftp close

o  binary
send a 'type i' command (switch to binary-mode transfer)

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp binary.
     ftp close

o  cd: aDirectoryPath
send a changeDirectory command

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp cd:'/pub'.
     ftp close

o  cdUp
send a changeDirectory-up command

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     Transcript showCR:(ftp pwd).
     ftp cdUp.
     Transcript showCR:(ftp pwd).
     ftp close

o  delete: aFilePath
send a delete file command

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp delete:'testfile'.
     ftp close

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'foo.bar.com' user:'anonymous' password:'fooBarBaz'.
     ftp delete:'testfile'.
     ftp close

o  get: aFileNameString
send a get command; return the result as either a string
or a byteArray (depending on the transfer mode).
Raise connectFailedSignal if data connection cannot be established

Usage example(s):

     |ftp text|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp ascii.
     text := ftp get:'welcome.msg'.
     ftp close.
     TextView openWith:text.

Usage example(s):

     |ftp text|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp binary.
     text := ftp get:'welcome.msg'.
     ftp close.
     text inspect.

o  getStreamFor: aFilenameString
send a get command; return a stream on the files contents.
Raise a signal if connection cannot be established

Usage example(s):

     |ftp s t|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     s := ftp getStreamFor:'welcome.msg'.
     t := s contents.
     TextView openWith:t.
     s close.
     ftp close.

Usage example(s):

     |ftp s t|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     s := ftp getStreamFor:'fooBar'.
     t := s contents.
     TextView openWith:t.
     s close.
     ftp close.

o  help
send a 'HELP' command to ask about the partners capabilities.
Return a collection of help lines.

Usage example(s):

     |ftp|

     ftp := FTPClient new.
     ftp connectTo:'alt.exept.de' user:'anonymous'.
     Transcript showCR:(ftp help).
     ftp close

o  list
send a list command; return the result as a collection of
strings (containing the listing)

Usage example(s):

     |ftp list|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     list := ftp list.
     ftp close.
     list do:[:line | Transcript showCR:line].

Usage example(s):

     |ftp list|

     ftp := FTPClient new.
     ftp connectTo:'aix' user:'anonymous'.
     ftp cd:'/'.
     list := ftp list.
     ftp close.
     list do:[:line | Transcript showCR:line].

Usage example(s):

     |ftp list|

     FTPClient ftpErrorSignal handle:[:ex |
         self warn:'ftp failed'
     ] do:[
         ftp := FTPClient new.
         ftp connectTo:'ftp.mozilla.org' user:'anonymous'.
         ftp cd:'/'.
         list := ftp list.
         ftp close.
         list do:[:line | Transcript showCR:line].
     ]

o  list: aFileName
send a list command; return the result as a collection of
strings (containing the listing)

o  listStream
send a list command; return a stream on the listing

Usage example(s):

     |ftp s t|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     s := ftp listStream.
     t := s contents.
     TextView openWith:t.
     s close.
     ftp close.

Usage example(s):

     |ftp s1 s2 t|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     s1 := ftp listStream.
     ftp cd:'bin'.
     s2 := ftp listStream.
     t := s1 contents.
     TextView openWith:t.
     s1 close.
     t := s2 contents.
     TextView openWith:t.
     s2 close.
     ftp close.

o  listStream: listCommand
send a list command; return a stream on the listing

o  listWithCommand: listCommand
send a list command; return the result as a collection of
strings (containing the listing)

o  mkdir: aDirectoryNameString
send a make Directory command

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp cd:'/tmp'.
     ftp mkdir:'test12345'.
     ftp close

o  nlist
send an nlist command; return the result as a collection of
strings (containing the listing)

Usage example(s):

     |ftp list|

     ftp := FTPClient new.
     ftp connectTo:'ftp.mozilla.org' user:'anonymous'.
     list := ftp nlist.
     ftp close.
     list do:[:line | Transcript showCR:line].

o  passiveMode: aBoolean
set passiveMode to aBoolean.
In passive mode, the server instead of the client creates an extra socket to transmit the data.
Answer the prevoius status of passiveMode

o  put: aStringOrByteArrayOrStream as: remoteFileName
send a put command;
send aStringOrbyteArray

Usage example(s):

     |ftp s|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp ascii.
     (ftp put:'hello world' as:'testfile') ifFalse:[
        self warn:'File transfer failed'
     ].
     ftp close.

o  putFile: localFileName as: remoteFileName
send a put command;
send a local file

Usage example(s):

     |ftp s|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp ascii.
     (ftp putFile:'..\bmake.bat' as:'testfile') ifFalse:[
        self warn:'File transfer failed'
     ].
     ftp close.

o  putStreamFor: aFilenameString
send a put command; return a stream for writing the file

Usage example(s):

     |ftp s|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp ascii.
     s := ftp putStreamFor:'newfile'.
     s nextPutLine:'line1'.
     s nextPutLine:'line2'.
     s nextPutLine:'line3'.
     s close.
     ftp close.

o  pwd
send an XPWD (print current dir) command; return the directory or nil
if the partner does not support the XPWD command

Usage example(s):

     |ftp|

     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     Transcript showCR:(ftp pwd).
     ftp cd:'/pub'.
     Transcript showCR:(ftp pwd).
     ftp close

o  recursiveMkDir: aDirectoryNameString
recursively create all required directories and change to

o  rename: fromFilename to: toFilename
rename a file

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'hippo' user:'stefan' password:'pass'.
     ftp rename:'/tmp/bla1' to:'/tmp/bla2'.
     ftp close

o  rmdir: aDirectoryNameString
send a make Directory command

Usage example(s):

     |ftp|
     ftp := FTPClient new.
     ftp connectTo:'porty' user:'anonymous'.
     ftp cd:'/tmp'.
     ftp mkdir:'test12345'.
     ftp rmdir:'test12345'.
     ftp close

o  sizeOf: aFileName
send an SIZE (print size) command; return the size or nil
if the partner does not support the SIZE command

Usage example(s):

     |ftp|

     ftp := FTPClient new.
     ftp connectTo:'www.exept.de' user:'anonymous'.
     Transcript showCR:(ftp sizeOf:'download/wartungsvertrag.pdf').
     ftp close

o  systemStatus
send a 'STAT' command to ask about the partner systems status.
Return a collection of status lines.

Usage example(s):

     |ftp|

     ftp := FTPClient new.
     ftp connectTo:'alt.exept.de' user:'anonymous'.
     Transcript showCR:(ftp systemStatus).
     ftp close

o  systemType
send a 'SYST' command to ask about the partner system

Usage example(s):

     |ftp|

     ftp := FTPClient new.
     ftp connectTo:'www.exept.de' user:'anonymous'.
     Transcript showCR:(ftp systemType).
     ftp close

private - commands & responses
o  getResponseForPORTCommand

o  handleReplyCode: replyCode
(comment from inherited method)
intermediate message; final reply code follows

o  handleReplyCodeOfPORTCommand: replyCode

private - connection setup
o  close
means: unknown

o  getInitialConnectResponse
(comment from inherited method)
invoked right after the socket connection has been setup;
subclass implementation should read all initial hello-bla

o  login: userName password: passwordOrNil
login using userName and password.
After successful login, set transfer mode

o  openActiveDataConnection: mode for: command
open & retrieve a data connection.
Raise connectFailedSignal if data connection can't be established

o  openDataConnection: mode for: command
open & retrieve a data connection

o  openDataConnectionFor: command
open & retrieve a data connection

o  openPassiveDataConnection: mode for: command
open & retrieve a data connection.
Raise connectFailedSignal if data connection can't be established

o  performLoginSequence
login using userName and password iff userName is not nil.
This is invoked automatically by doConnect.
If userName is nil, manual login is required.

o  sendGoodByeCommand
(comment from inherited method)
invoked before the socket connection is shutDown.
A subclass implementation may want to redefine this for a graceful goodBy
(typically sending a quit-command)

o  setModeTo: mode


Examples:


login/pwd/close:
   |host ftpClient|

   host := Dialog request:'host:' initialAnswer:'ftp.informatik.uni-stuttgart.de'.

   ftpClient := FTPClient new.
   ftpClient connectToHost:host.
   ftpClient login:'anonymous' password:'foo@bar.com'.
   Transcript showCR:(ftpClient pwd).
   ftpClient close.
getting a list from some other machine:
   |host ftp list|

   host := Dialog request:'host:' initialAnswer:'ftp.informatik.uni-stuttgart.de'.

   ftp := FTPClient new.
   ftp connectTo:host user:'anonymous' password:'foo@bar.com'.
   list := ftp list.
   ftp close.
   list do:[:line | Transcript showCR:line].
getting a list from some other machine (passive mode):
   |host ftp list|

   host := Dialog request:'host:' initialAnswer:'ftp.informatik.uni-stuttgart.de'.

   ftp := FTPClient new.
   ftp passiveMode:true.   
   ftp connectTo:host user:'anonymous' password:'foo@bar.com'.
   list := ftp list.
   ftp close.
   list do:[:line | Transcript showCR:line].
getting list from some other machine:
   |host user passwd fn ftp data|

   host := Dialog request:'host:' initialAnswer:'localhost'.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.

   ftp := FTPClient new.
   ftp connectTo:host user:user password:passwd.
   data := ftp list.
   ftp close.
   data inspect.
on a special port:
   |host port user passwd fn ftp data|

   FTPClient verbose:true.
   host := Dialog request:'host:' initialAnswer:'localhost'.
   port := Dialog request:'port:' initialAnswer:(Socket portOfService:'ftp') printString.
   port := Integer readFrom:port onError:nil.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.

   ftp := FTPClient new.
   ftp connectTo:host port:port user:user password:passwd.
   data := ftp list.
   ftp close.
   data inspect.
getting a (text) file from some other machine:
   |host user passwd fn ftp data|

   host := Dialog request:'host:' initialAnswer:'localhost'.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.
   fn := Dialog request:'file:'.

   ftp := FTPClient new.
   ftp connectTo:host user:user password:passwd.
   data := ftp get:fn.
   ftp close.
   data asString inspect.
getting a (binary) file from some other machine:
   |host user passwd fn ftp data|

   host := Dialog request:'host:' initialAnswer:'localhost'.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.
   fn := Dialog request:'file:'.

   ftp := FTPClient new.
   ftp connectTo:host user:user password:passwd.
   ftp binary.   
   data := ftp get:fn.
   ftp close.
   data inspect.
putting some data onto some other machine:
   |host user passwd fn ftp data|

   host := Dialog request:'host:' initialAnswer:'localhost'.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.
   fn := Dialog request:'local file:'.

   ftp := FTPClient new.
   ftp connectTo:host user:user password:passwd.
   ftp binary.   
   data := ftp put:'hello world' as:'testfile'.
   ftp close.
   data inspect.
putting a (binary) file onto some other machine:
   |host user passwd fn ftp data|

   host := Dialog request:'host:' initialAnswer:'localhost'.
   user := Dialog request:'user:' initialAnswer:'anonymous'.
   passwd := Dialog requestPassword:'password:'.
   fn := Dialog request:'local file:'.

   ftp := FTPClient new.
   ftp connectTo:host user:user password:passwd.
   ftp binary.   
   data := ftp putFile:'Makefile' as:'testfile'.
   ftp close.
   data inspect.
handling errors:
   |host ftp list|

   host := Dialog request:'host:' initialAnswer:(OperatingSystem getHostName).

   FTPClient ftpErrorSignal handle:[:ex |
       self warn:('ftp error:\\' , ex signal errorString) withCRs
   ] do:[
       ftp := FTPClient new.
       ftp connectTo:host user:'anonymous'.
       list := ftp list.
       ftp close.
       list do:[:line | Transcript showCR:line].
   ]
chdir & get a list from some other machine:
   |ftp list|

   FTPClient ftpErrorSignal handle:[:ex |
       self warn:('ftp error:\\' , ex signal errorString) withCRs
   ] do:[
       ftp := FTPClient new.
       ftp connectTo:'aix' user:'anonymous'.
       ftp cd:'/'.
       list := ftp list.
       ftp close.
       list do:[:line | Transcript showCR:line].
   ]
dialog with user & password:
   |ftp dlg hostHolder userHolder passHolder list|

   hostHolder := OperatingSystem getHostName asValue.
   userHolder := OperatingSystem getLoginName asValue.
   passHolder := '' asValue.

   dlg := DialogBox new.
   dlg addTextLabel:'host:'.
   dlg addInputFieldOn:hostHolder tabable:true.
   dlg addTextLabel:'user:'.
   dlg addInputFieldOn:userHolder tabable:true.
   dlg addTextLabel:'password:'.
   (dlg addInputFieldOn:passHolder tabable:true) passwordCharacter:$*.
   dlg addAbortButton; addOkButton.
   dlg open.

   dlg accepted ifTrue:[
       FTPClient ftpErrorSignal handle:[:ex |
           self warn:('ftp error:\\' , ex signal errorString) withCRs
       ] do:[
           ftp := FTPClient new.
           ftp connectTo:hostHolder value
               user:userHolder value
               password:passHolder value.
           ftp cd:'/'.
           list := ftp list.
           ftp close.
           list do:[:line | Transcript showCR:line].
       ]
   ]
   |host port user passwd fn ftp data|

   FTPClient verbose:true.

   host := 'data'.
   port := 12345.
   user := 'anonymous'.
   passwd := nil.

   ftp := FTPClient new.
   ftp connectTo:host port:port user:user password:passwd.
   ftp ascii.
   data := ftp list.
   ftp close.
   data inspect.
   |host port user passwd fn ftp data|

   FTPClient verbose:true.

   host := 'data'.
   port := 12345.
   user := 'anonymous'.
   passwd := nil.

   ftp := FTPClient new.
   ftp connectTo:host port:port user:user password:passwd.
   ftp ascii.
   data := ftp list.
   ftp close.
   data inspect.


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 04 May 2024 01:16:42 GMT