Listing 1. crawl_ftp
Recursive Traversal of an FTP Site
The Perl Journal, Winter 1999
 

Listing 1: crawl_ftp

#!/usr/bin/perl -w
# Crawls remote FTP directory.
#     usage: crawl_ftp [-D] host remotedir name password
#        -D  Turn on Net::FTP debug messages

use Getopt::Std;
use Net::FTP;

getopts("D");
defined($opt_D) or $opt_D = 0;

my $host     = shift;
my $dir      = shift;
my $name     = shift;
my $password = shift;

defined($host) and 
  defined($dir)  and 
  defined($name) and 
  defined($password) 
or die "usage: $0 [-D] host remotedir name password";

$ftp = Net::FTP->new($host, Debug => $opt_D ? 1 : 0);

$ftp->login($name, $password);

$ftp->cwd($dir);  # Go to the starting point in the remote tree.

print "DIRECTORY: ",$ftp->pwd,"\n";

crawl_tree(1);    # Crawl over the tree

$ftp->quit;

sub indent {
    # A utility to indent our file tree listing.
    my $num_levels = shift;
    foreach (1..$num_levels) { print "   " }
}

sub crawl_tree {
    my $level = shift;
    my @files = $ftp->dir;  # Make a listing of files and dirs.

    foreach my $i (@files) {
        my @items = split(/\s/, $i);
        my $item = $items[$#items];
        my $parent = $ftp->pwd;

        if ($i =~ /^d(.*)/) {     

            # Skip . and .. if present in the listing.
            # (Some FTP servers list these, some don't.)
            next if $item =~ /\.\.?$/;

            indent($level);  
            print "DIRECTORY: ", $parent, "/", $item, "\n";
            
            # Recursively crawl the subtree under this directory.
            $ftp->cwd($item);
            crawl_tree($level+1);

            # Restore location in remote tree.
            $ftp->cwd($parent);
        } elsif ($i =~ /^-(.*)/) {  
            # It's a file.
            indent($level);  print "FILE: ", $item, "\n";
        }
    }
}