Class Net::FTP
In: net/ftp.rb
Parent: Object

This class implements the File Transfer Protocol. If you have used a command-line FTP program, and are familiar with the commands, you will be able to use this class easily. Some extra features are included to take advantage of Ruby’s style and strengths.

Example

  require 'net/ftp'

Example 1

  ftp = Net::FTP.new('ftp.netlab.co.jp')
  ftp.login
  files = ftp.chdir('pub/lang/ruby/contrib')
  files = ftp.list('n*')
  ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
  ftp.close

Example 2

  Net::FTP.open('ftp.netlab.co.jp') do |ftp|
    ftp.login
    files = ftp.chdir('pub/lang/ruby/contrib')
    files = ftp.list('n*')
    ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
  end

Major Methods

The following are the methods most likely to be useful to users:

Methods

abort   acct   chdir   close   closed?   connect   delete   dir   get   getbinaryfile   getdir   gettextfile   help   list   login   ls   mdtm   mkdir   mtime   new   nlst   noop   open   put   putbinaryfile   puttextfile   pwd   quit   rename   retrbinary   retrlines   return_code   return_code=   rmdir   sendcmd   set_socket   site   size   status   storbinary   storlines   system   voidcmd  

Included Modules

MonitorMixin

External Aliases

last_response_code -> lastresp

Attributes

binary  [RW]  When true, transfers are performed in binary mode. Default: true.
debug_mode  [RW]  When true, all traffic to and from the server is written to +$stdout+. Default: false.
last_response  [R]  The server’s last response.
last_response_code  [R]  The server’s last response code.
passive  [RW]  When true, the connection is in passive mode. Default: false.
resume  [RW]  Sets or retrieves the resume status, which decides whether incomplete transfers are resumed or restarted. Default: false.
welcome  [R]  The server’s welcome message.

Public Class methods

Creates and returns a new FTP object. If a host is given, a connection is made. Additionally, if the user is given, the given user name, password, and (optionally) account are used to log in. See login.

[Source]

# File net/ftp.rb, line 129
    def initialize(host = nil, user = nil, passwd = nil, acct = nil)
      super()
      @binary = true
      @passive = false
      @debug_mode = false
      @resume = false
      if host
        connect(host)
        if user
          login(user, passwd, acct)
        end
      end
    end

A synonym for FTP.new, but with a mandatory host parameter.

If a block is given, it is passed the FTP object, which will be closed when the block finishes, or when an exception is raised.

[Source]

# File net/ftp.rb, line 111
    def FTP.open(host, user = nil, passwd = nil, acct = nil)
      if block_given?
        ftp = new(host, user, passwd, acct)
        begin
          yield ftp
        ensure
          ftp.close
        end
      else
        new(host, user, passwd, acct)
      end
    end

Public Instance methods

Aborts the previous command (ABOR command).

[Source]

# File net/ftp.rb, line 742
    def abort
      line = "ABOR" + CRLF
      print "put: ABOR\n" if @debug_mode
      @sock.send(line, Socket::MSG_OOB)
      resp = getmultiline
      unless ["426", "226", "225"].include?(resp[0, 3])
        raise FTPProtoError, resp
      end
      return resp
    end

Sends the ACCT command. TODO: more info.

[Source]

# File net/ftp.rb, line 595
    def acct(account)
      cmd = "ACCT " + account
      voidcmd(cmd)
    end

Changes the (remote) directory.

[Source]

# File net/ftp.rb, line 665
    def chdir(dirname)
      if dirname == ".."
        begin
          voidcmd("CDUP")
          return
        rescue FTPPermError
          if $![0, 3] != "500"
            raise FTPPermError, $!
          end
        end
      end
      cmd = "CWD " + dirname
      voidcmd(cmd)
    end

Closes the connection. Further operations are impossible until you open a new connection with connect.

[Source]

# File net/ftp.rb, line 810
    def close
      @sock.close if @sock and not @sock.closed?
    end

Returns true iff the connection is closed.

[Source]

# File net/ftp.rb, line 817
    def closed?
      @sock == nil or @sock.closed?
    end

Establishes an FTP connection to host, optionally overriding the default port. If the environment variable SOCKS_SERVER is set, sets up the connection through a SOCKS proxy. Raises an exception (typically Errno::ECONNREFUSED) if the connection cannot be established.

[Source]

# File net/ftp.rb, line 170
    def connect(host, port = FTP_PORT)
      if @debug_mode
        print "connect: ", host, ", ", port, "\n"
      end
      synchronize do
        @sock = open_socket(host, port)
        voidresp
      end
    end

Deletes a file on the server.

[Source]

# File net/ftp.rb, line 651
    def delete(filename)
      resp = sendcmd("DELE " + filename)
      if resp[0, 3] == "250"
        return
      elsif resp[0] == ?5
        raise FTPPermError, resp
      else
        raise FTPReplyError, resp
      end
    end
dir(*args)

Alias for list

Retrieves remotefile in whatever mode the session is set (text or binary). See gettextfile and getbinaryfile.

[Source]

# File net/ftp.rb, line 531
    def get(remotefile, localfile = File.basename(remotefile),
            blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      unless @binary
        gettextfile(remotefile, localfile, &block)
      else
        getbinaryfile(remotefile, localfile, blocksize, &block)
      end
    end

Retrieves remotefile in binary mode, storing the result in localfile. If a block is supplied, it is passed the retrieved data in blocksize chunks.

[Source]

# File net/ftp.rb, line 490
    def getbinaryfile(remotefile, localfile = File.basename(remotefile),
                      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      if @resume
        rest_offset = File.size?(localfile)
        f = open(localfile, "a")
      else
        rest_offset = nil
        f = open(localfile, "w")
      end
      begin
        f.binmode
        retrbinary("RETR " + remotefile, blocksize, rest_offset) do |data|
          f.write(data)
          yield(data) if block
        end
      ensure
        f.close
      end
    end
getdir()

Alias for pwd

Retrieves remotefile in ASCII (text) mode, storing the result in localfile. If a block is supplied, it is passed the retrieved data one line at a time.

[Source]

# File net/ftp.rb, line 515
    def gettextfile(remotefile, localfile = File.basename(remotefile), &block) # :yield: line
      f = open(localfile, "w")
      begin
        retrlines("RETR " + remotefile) do |line|
          f.puts(line)
          yield(line) if block
        end
      ensure
        f.close
      end
    end

Issues the HELP command.

[Source]

# File net/ftp.rb, line 776
    def help(arg = nil)
      cmd = "HELP"
      if arg
        cmd = cmd + " " + arg
      end
      sendcmd(cmd)
    end

Returns an array of file information in the directory (the output is like `ls -l`). If a block is given, it iterates through the listing.

[Source]

# File net/ftp.rb, line 619
    def list(*args, &block) # :yield: line
      cmd = "LIST"
      args.each do |arg|
        cmd = cmd + " " + arg
      end
      if block
        retrlines(cmd, &block)
      else
        lines = []
        retrlines(cmd) do |line|
          lines << line
        end
        return lines
      end
    end

Logs in to the remote host. The session must have been previously connected. If user is the string "anonymous" and the password is nil, a password of user@host is synthesized. If the acct parameter is not nil, an FTP ACCT command is sent following the successful login. Raises an exception on error (typically Net::FTPPermError).

[Source]

# File net/ftp.rb, line 371
    def login(user = "anonymous", passwd = nil, acct = nil)
      if user == "anonymous" and passwd == nil
        passwd = getaddress
      end
      
      resp = ""
      synchronize do
        resp = sendcmd('USER ' + user)
        if resp[0] == ?3
          resp = sendcmd('PASS ' + passwd)
        end
        if resp[0] == ?3
          resp = sendcmd('ACCT ' + acct)
        end
      end
      if resp[0] != ?2
        raise FTPReplyError, resp
      end
      @welcome = resp
    end
ls(*args)

Alias for list

Issues the MDTM command. TODO: more info.

[Source]

# File net/ftp.rb, line 766
    def mdtm(filename)
      resp = sendcmd("MDTM " + filename)
      if resp[0, 3] == "213"
        return resp[3 .. -1].strip
      end
    end

Creates a remote directory.

[Source]

# File net/ftp.rb, line 707
    def mkdir(dirname)
      resp = sendcmd("MKD " + dirname)
      return parse257(resp)
    end

Returns the last modification time of the (remote) file. If local is true, it is returned as a local time, otherwise it’s a UTC time.

[Source]

# File net/ftp.rb, line 698
    def mtime(filename, local = false)
      str = mdtm(filename)
      ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
      return local ? Time.local(*ary) : Time.gm(*ary)
    end

Returns an array of filenames in the remote directory.

[Source]

# File net/ftp.rb, line 603
    def nlst(dir = nil)
      cmd = "NLST"
      if dir
        cmd = cmd + " " + dir
      end
      files = []
      retrlines(cmd) do |line|
        files.push(line)
      end
      return files
    end

Issues a NOOP command.

[Source]

# File net/ftp.rb, line 794
    def noop
      voidcmd("NOOP")
    end

Transfers localfile to the server in whatever mode the session is set (text or binary). See puttextfile and putbinaryfile.

[Source]

# File net/ftp.rb, line 583
    def put(localfile, remotefile = File.basename(localfile),
            blocksize = DEFAULT_BLOCKSIZE, &block)
      unless @binary
        puttextfile(localfile, remotefile, &block)
      else
        putbinaryfile(localfile, remotefile, blocksize, &block)
      end
    end

Transfers localfile to the server in binary mode, storing the result in remotefile. If a block is supplied, calls it, passing in the transmitted data in blocksize chunks.

[Source]

# File net/ftp.rb, line 545
    def putbinaryfile(localfile, remotefile = File.basename(localfile),
                      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      if @resume
        begin
          rest_offset = size(remotefile)
        rescue Net::FTPPermError
          rest_offset = nil
        end
      else
        rest_offset = nil
      end
      f = open(localfile)
      begin
        f.binmode
        storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
      ensure
        f.close
      end
    end

Transfers localfile to the server in ASCII (text) mode, storing the result in remotefile. If callback or an associated block is supplied, calls it, passing in the transmitted data one line at a time.

[Source]

# File net/ftp.rb, line 570
    def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
      f = open(localfile)
      begin
        storlines("STOR " + remotefile, f, &block)
      ensure
        f.close
      end
    end

Returns the current remote directory.

[Source]

# File net/ftp.rb, line 722
    def pwd
      resp = sendcmd("PWD")
      return parse257(resp)
    end

Exits the FTP session.

[Source]

# File net/ftp.rb, line 787
    def quit
      voidcmd("QUIT")
    end

Renames a file on the server.

[Source]

# File net/ftp.rb, line 640
    def rename(fromname, toname)
      resp = sendcmd("RNFR " + fromname)
      if resp[0] != ?3
        raise FTPReplyError, resp
      end
      voidcmd("RNTO " + toname)
    end

Puts the connection into binary (image) mode, issues the given command, and fetches the data returned, passing it to the associated block in chunks of blocksize characters. Note that cmd is a server command (such as "RETR myfile").

[Source]

# File net/ftp.rb, line 398
    def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
      synchronize do
        voidcmd("TYPE I")
        conn = transfercmd(cmd, rest_offset)
        loop do
          data = conn.read(blocksize)
          break if data == nil
          yield(data)
        end
        conn.close
        voidresp
      end
    end

Puts the connection into ASCII (text) mode, issues the given command, and passes the resulting data, one line at a time, to the associated block. If no block is given, prints the lines. Note that cmd is a server command (such as "RETR myfile").

[Source]

# File net/ftp.rb, line 418
    def retrlines(cmd) # :yield: line
      synchronize do
        voidcmd("TYPE A")
        conn = transfercmd(cmd)
        loop do
          line = conn.gets
          break if line == nil
          if line[-2, 2] == CRLF
            line = line[0 .. -3]
          elsif line[-1] == ?\n
            line = line[0 .. -2]
          end
          yield(line)
        end
        conn.close
        voidresp
      end
    end

Obsolete

[Source]

# File net/ftp.rb, line 144
    def return_code
      $stderr.puts("warning: Net::FTP#return_code is obsolete and do nothing")
      return "\n"
    end

Obsolete

[Source]

# File net/ftp.rb, line 150
    def return_code=(s)
      $stderr.puts("warning: Net::FTP#return_code= is obsolete and do nothing")
    end

Removes a remote directory.

[Source]

# File net/ftp.rb, line 715
    def rmdir(dirname)
      voidcmd("RMD " + dirname)
    end

Sends a command and returns the response.

[Source]

# File net/ftp.rb, line 261
    def sendcmd(cmd)
      synchronize do
        putline(cmd)
        return getresp
      end
    end

WRITEME or make private

[Source]

# File net/ftp.rb, line 183
    def set_socket(sock, get_greeting = true)
      synchronize do
        @sock = sock
        if get_greeting
          voidresp
        end
      end
    end

Issues a SITE command.

[Source]

# File net/ftp.rb, line 801
    def site(arg)
      cmd = "SITE " + arg
      voidcmd(cmd)
    end

Returns the size of the given (remote) filename.

[Source]

# File net/ftp.rb, line 683
    def size(filename)
      voidcmd("TYPE I")
      resp = sendcmd("SIZE " + filename)
      if resp[0, 3] != "213" 
        raise FTPReplyError, resp
      end
      return resp[3..-1].strip.to_i
    end

Returns the status (STAT command).

[Source]

# File net/ftp.rb, line 756
    def status
      line = "STAT" + CRLF
      print "put: STAT\n" if @debug_mode
      @sock.send(line, Socket::MSG_OOB)
      return getresp
    end

Puts the connection into binary (image) mode, issues the given server-side command (such as "STOR myfile"), and sends the contents of the file named file to the server. If the optional block is given, it also passes it the data, in chunks of blocksize characters.

[Source]

# File net/ftp.rb, line 443
    def storbinary(cmd, file, blocksize, rest_offset = nil, &block) # :yield: data
      if rest_offset
        file.seek(rest_offset, IO::SEEK_SET)
      end
      synchronize do
        voidcmd("TYPE I")
        conn = transfercmd(cmd, rest_offset)
        loop do
          buf = file.read(blocksize)
          break if buf == nil
          conn.write(buf)
          yield(buf) if block
        end
        conn.close
        voidresp
      end
    end

Puts the connection into ASCII (text) mode, issues the given server-side command (such as "STOR myfile"), and sends the contents of the file named file to the server, one line at a time. If the optional block is given, it also passes it the lines.

[Source]

# File net/ftp.rb, line 467
    def storlines(cmd, file, &block) # :yield: line
      synchronize do
        voidcmd("TYPE A")
        conn = transfercmd(cmd)
        loop do
          buf = file.gets
          break if buf == nil
          if buf[-2, 2] != CRLF
            buf = buf.chomp + CRLF
          end
          conn.write(buf)
          yield(buf) if block
        end
        conn.close
        voidresp
      end
    end

Returns system information.

[Source]

# File net/ftp.rb, line 731
    def system
      resp = sendcmd("SYST")
      if resp[0, 3] != "215"
        raise FTPReplyError, resp
      end
      return resp[4 .. -1]
    end

Sends a command and expect a response beginning with ‘2’.

[Source]

# File net/ftp.rb, line 271
    def voidcmd(cmd)
      synchronize do
        putline(cmd)
        voidresp
      end
    end

[Validate]