#! /usr/pkg/bin/perl -w

# simpleftp - Rudimentary FTP client.
#
# Author: David Lawrence <tale@isc.org>.
#         Rewritten by Julien Elie to use Net::FTP.
#
# Fetch files to the local machine based on URLs on the command line.
# INN's configure searches for ncftp, wget, linx, et caetera,
# but they're all system add-ons, so this is provided.
#
# Perl 5 is already required by other parts of INN; it only took a half hour
# to write this, so this was the easiest way to go for a backup plan.
#
# This script is nowhere near as flexible as libwww.  If you really need
# that kind of power, get libwww and use it.  This is just sufficient for what
# INN needed.

use strict;
use Net::FTP;
use Sys::Hostname;

$0 =~ s(.*/)();

my $usage = "Usage: $0 ftp-URL ...\n";

@ARGV
  or die $usage;

for (@ARGV) {
    m(^ftp://)
      or die $usage;
}

my ($lasthost, $ftp);

# This will keep track of how many _failed_.
my $exit = @ARGV;

for (@ARGV) {
    my ($host, $path) = m%^ftp://([^/]+)(/.+)%;
    my $user = 'anonymous';
    my $pass = (getpwuid($<))[0] . '@' . hostname;
    my $port = 21;

    unless (defined $host && defined $path) {
        warn "$0: bad URL: $_\n";
        next;
    }

    if ($host =~ /(.*):(.*)\@(.*)/) {
        $user = $1;
        $pass = $2;
        $host = $3;
    }

    if ($host =~ /(.*):(.*)/) {
        $port = $1;
        $host = $2;
    }

    if (defined $lasthost && $host ne $lasthost) {
        $ftp->quit;
        $lasthost = undef;
    }

    unless (defined $lasthost) {
        $ftp = Net::FTP->new($host, Port => $port)
          or next;
        $ftp->login($user, $pass)
          or next;
    }

    my $localfile = $path;
    $path =~ s([^/]+$)();
    $localfile =~ s(.*/)();

    $ftp->binary
      or next;

    $ftp->cwd($path)
      or next;
    $ftp->get($localfile)
      or next;

    $exit--;
    $lasthost = $host;
}

$ftp->quit
  if defined $lasthost;

exit $exit;
