The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/local/bin/perl
#	This example demonstrates how to spawn an ftp process, have it
#log in to a host, and grab a file off the host. This should give you a
#general idea of how to spawn processes and talk to them.
#	The first thing I do when attempting to automate a process is do it
#by hand, so you know what interaction with the process should look like.
#	I highly recommend you read the information on debugging in chapter
#3 before actually trying this yourself.
#
#	Usage: script  ftphost file1 [file2 file3.. ]


use Expect;

# Optional debugging, explained later.
# $Expect::Debug=1
# $Expect::Exp_Internal=1;
# $Expect::Log_Stdout=0; # On by default.

$host = shift @ARGV; # Let the host be the first argument we are given.

@files = @ARGV; # Let the names of the files be the remaining arguments.

# Make sure we're trying to get something.
unless ($host ne '' && @files  > 0) {
  print STDERR <<EOM
Usage: $0 hostname ftphost file1 [file2 file3.. ]
EOM
;
  exit -1;
}

# Start the ftp process.
($ftp = Expect->spawn("ftp $hostname")) || die "Couldn't spawn ftp, $!";


# Look for a username prompt. On my box this looks like:
# "Name (ftp.cdrom.com:tex): "
# So, let's see what our username is.
$username = $ENV{'USER'};
# Time out if we don't get it within 30 seconds.
unless ($ftp->expect(30,"Name ($hostname:$username): ")) {
  die "Never got username prompt on $hostname, ".$ftp->exp_error()."\n";
}

# Ok, so we have the username prompt. Let's send it "anonymous".
# Note how I follow with a \r.
print $ftp "anonymous\r";

# And we want a password prompt now.
# On my box this looks like:
# 331 Guest login ok, send your complete e-mail address as password.
# Password:
# Where there are no spaces after the password. This is important to note
# since, if there were a space, we might try sending a password before
# the ftp server finished giving us a prompt or if we were looking for a space
# and there wasn't one we might end up not matching.

# To save time I cut and pasted most of the line above where we grabbed the
# username prompt.
unless ($ftp->expect(30,"Password:")) {
  die "Never got password prompt on $hostname, ".$ftp->exp_error()."\n";
}

# Grabbing our actual domain would be the better thing to do here but is
# outside the scope of this example.
print $ftp "$username\@mycompany.com\r";

# Now we look for a prompt, having (we hope) successfully logged in.
unless ($ftp->expect(30,"ftp> ")) {
  die "Never got ftp prompt after sending username, ".$ftp->exp_error()."\n";
}

# Ok. We have a prompt on the foreign machine, so let's get the files.
# Notice that at the end of each loop we are at an ftp> prompt.
foreach $file (@files) {
  print $ftp "get $file\r";
  unless ($ftp->expect(30,"ftp> ")) {
    die "Never got ftp prompt after attempting to get $file, ".$ftp->exp_error()."\n";
  }
}

# We should have all the files. If this is the end of the script we can
# quit without bothering to close the process. Perl will take care of it
# for us. Later examples will demonstrate the differences between
# close(), soft_close(), and hard_close().