18. Internet Services

Simple DNS Lookups

Being an FTP Client

require 'net/ftp'

begin
    ftp = Net::FTP::new("ftp.host.com")
    ftp.login(username,password)
    ftp.chdir(directory)
    ftp.get(filename)
    ftp.put(filename)
rescue Net::FTPError
    $stderr.print "FTP failed: " + $!
ensure
    ftp.close() if ftp
end

# A better solution for a local use could be :
Net::FTP::new("ftp.host.com") do |ftp|
    ftp.login(username,password)
    ftp.chdir(directory)
    ftp.get(filename)
    ftp.put(filename)
end

# If you have only one file to get, there is a simple solution :
require 'open-uri'
open("ftp://www.ruby-lang.org/path/filename") do |fh|
    # read from filehandle fh
end 
#--------------------------------------------
# to wait a defined time for the connection, 
# use the timeout module
require 'timeout'
begin 
    timeout(30){
        ftp = Net::FTP::new("ftp.host.com")
        ftp.debug_mode = true
    }
rescue Net::FTPError
    $stderr.puts "Couldn't connect."
rescue Timeout::Error
    $stderr.puts "Timeout while connecting to server."
end

begin
    ftp.login()
rescue Net::FTPError
    $stderr.print "Couldn't authentificate.\n"
end

begin
    ftp.login(username)
rescue Net::FTPError
    $stderr.print "Still couldn't authenticate.\n"
end

begin
    ftp.login(username, password)
rescue Net::FTPError
    $stderr.print "Couldn't authenticate, even with explicit
    username and password.\n"
end

begin
    ftp.login(username, password, account)
rescue Net::FTPError
    $stderr.print "No dice. It hates me.\n"
end
#-----------------------------
ftp.put(localfile, remotefile)
#-----------------------------
# Sending data from STDIN is not directly supported 
# by the ftp library module. A possible way to do it is to use the 
# storlines method directly to send raw commands to the ftp server.
#-----------------------------
ftp.get(remotefile, localfile)
#-----------------------------
ftp.get(remotefile) { |data| puts data }
#-----------------------------
ftp.chdir("/pub/ruby") 
print "I'm in the directory ", ftp.pwd(), "\n"
#-----------------------------
ftp.mkdir("/pub/ruby/new_dir")
#-----------------------------
lines = ftp.ls("/pub/ruby/")
# => ["drwxr-xr-x 2 matz users 4096 July 17 1998 1.0", ... ]

latest = ftp.dir("/pub/ruby/*.tgz").sort.last

ftp.nlst("/pub/ruby")
# => ["/pub/ruby/1.0", ... ]
#-----------------------------
ftp.quit()

Sending Mail

Reading and Posting Usenet News Messages

Reading Mail with POP3

Simulating Telnet from a Program

require 'net/telnet'
t = Net::Telnet::new( "Timeout" => 10,
                      "Prompt"  => /%/,
                      "Host"    => host )
t.login(username, password)
files = t.cmd("ls")
t.print("top")
process_string = t.waitfor(/\d+ processes/)
t.close
#-----------------------------
/[$%#>] \z/n
#-----------------------------
# In case of an error, the telnet module throws an exception.
# For control of the behavior in case of an error,
# you just need to catch the exceptions and do your custom
# error handling.
#-----------------------------
begin
    telnet.login(username, password)
rescue TimeoutError
    fail "Login failed !\n"
end
#-----------------------------
telnet.waitfor('/--more--/')
#-----------------------------
telnet.waitfor(String => 'greasy smoke', Timeout => 30)

Pinging a Machine

require 'ping'

puts "#{host} is alive.\n" if Ping.pingecho(host);
#-----------------------------
# the ping module only use TCP ping, not ICMP even if we are root
if Ping.pingecho("kingkong.com")
    puts "The giant ape lives!\n";
else
    puts "All hail mighty Gamera, friend of children!\n";
end

Using Whois to Retrieve Information from the InterNIC

Program: expn and vrfy