# Net::FTP (Class)

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:

- FTP::open
- getbinaryfile
- gettextfile
- putbinaryfile
- puttextfile
- chdir
- nlst
- size
- rename
- delete

## 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

## 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.

## Included Modules

MonitorMixin

## Public Class methods

open(host, user = nil, passwd = nil, acct = nil) {|ftp| ...}

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

new(host = nil, user = nil, passwd = nil, acct = nil)

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

## Public Instance methods

return_code()

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

return_code=(s)

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

connect(host, port = FTP_PORT)

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

set_socket(sock, get_greeting = true)

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

sendcmd(cmd)

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

voidcmd(cmd)

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

login(user = "anonymous", passwd = nil, acct = nil)

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

retrbinary(cmd, blocksize, rest_offset = nil) {|data| ...}

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

retrlines(cmd) {|line| ...}

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

storbinary(cmd, file, blocksize, rest_offset = nil) {|data| ...}

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

storlines(cmd, file) {|line| ...}

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

getbinaryfile(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE) {|data| ...}

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

gettextfile(remotefile, localfile = File.basename(remotefile)) {|line| ...}

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

get(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE) {|data| ...}

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

putbinaryfile(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE) {|data| ...}

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

puttextfile(localfile, remotefile = File.basename(localfile)) {|line| ...}

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

put(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE, &block)

Tranfers `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

acct(account)

Sends the ACCT command. TODO: more info.

[Source]

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

nlst(dir = nil)

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

list(*args) {|line| ...}

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

ls(*args)

Alias for list

dir(*args)

Alias for list

rename(fromname, toname)

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

delete(filename)

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

chdir(dirname)

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

size(filename)

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

mtime(filename, local = false)

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

mkdir(dirname)

Creates a remote directory.

[Source]

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

rmdir(dirname)

Removes a remote directory.

[Source]

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

pwd()

Returns the current remote directory.

[Source]

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

getdir()

Alias for pwd

system()

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

abort()

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

status()

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

mdtm(filename)

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

help(arg = nil)

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

quit()

Exits the FTP session.

[Source]

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

noop()

Issues a NOOP command.

[Source]

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

site(arg)

Issues a SITE command.

[Source]

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

close()

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

closed?()

Returns `true` iff the connection is closed.

[Source]

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

[Validate]