#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';

use Net::DNS;
use LWP::UserAgent;
use File::Basename;

# check we are root
if ($> != 0) {
    print "You must run $0 as root.\n";
    exit 2;
}

# Check our destination directory exists (or create) and is sane
# (i.e. avoid symlink attacks - CVE-2008-5379[0])
# 
# We cannot use mktemp as this path should be available to
# netdisco-mibs-install, invoked independently.
my $destdir = '/tmp/netdisco-mibs';
if (-e $destdir) {
    my @stat = stat($destdir);
    my $mode = sprintf('%04o', $stat[2] & 07777);
    my $maxmode = 0755;
    if (! -d $destdir or $stat[4] != 0 or $maxmode - $mode) {
	print "$destdir exists and is not a root-owned directory with " .
	    "permissions set to 0755 (or less)\n";
	exit 3;
    }
} else {
    unless (mkdir($destdir)) {
	print "Could not create destination directory $destdir\n";
	exit 3;
    }
}

my $site  = 'dl.sourceforge.net';
#my $source = 'audacity/audacity-src-1.2.6.tar.bz2'; # for testing
my $source = 'netdisco/netdisco-mibs-0.7.tar.gz';
my $target = [fileparse($source)]->[0]; # get file name part
my $destfile = "$destdir/$target";
my $homepage = 'http://sourceforge.net/project/showfiles.php?group_id=80033&package_id=135517';

unlink($destfile) if -e $destfile;

# get list of IPs for $site
my $res   = Net::DNS::Resolver->new;
my $query = $res->search($site);
my @sf_mirrors;

if ($query) {
    foreach my $rr ($query->answer) {
        next unless $rr->type eq "A";
        push @sf_mirrors, $rr->address;
    }
} else {
    warn "query failed: ", $res->errorstring, "\n";
}

# try to download $source from one of list of IPs
print "Trying ". (scalar @sf_mirrors) ." mirrors (10 seconds each)...\n";
foreach my $mirror (@sf_mirrors) {
    my $ua = LWP::UserAgent->new;
    $ua->timeout(10);
    $ua->env_proxy;
    my $request = HTTP::Request->new(GET =>
        "http://$mirror/sourceforge/$source");

    my $response = $ua->request($request, $destfile);

    if ($response->is_success) {
        print "Downloaded ok from [$mirror], please now run netdisco-mibs-install.\n";
        exit 0;
    }
    else {
        print $response->status_line, " from [$mirror]\n"
            if $ENV{MIBS_DEBUG};
        next;
    }
}

print "\nSorry, it has not been possible to download the Netdisco MIB bundle.\n";
print "Please go to the Netdisco Sourceforge page, and download $target:\n";
print "    $homepage\n";
print "\nSave this file to $destfile and then run netdisco-mibs-install.\n";

exit 1;
__END__

=head1 NAME

netdisco-mibs-download - Downloader for the Netdisco MIB bundle

=head1 VERSION

This document refers to version 1.0100 of netdisco-mibs-download

=head1 DESCRIPTION

Run this program to download the Netdisco MIB files bundle from Sourceforge.
It will try each of the Sourceforge mirror servers in turn, because quite
often some of them are not working.

If the download is successful, you can run the netdisco-mibs-install program
to unpack and install them.

If the download fails, you can visit the Netdisco Sourceforge downloads page,
details of which are given by this program on failure, and get the bundle
yourself.

=head1 ENVIRONMENT

Setting the environment variable C<MIBS_DEBUG> to a true value will display
information about failed mirror site downloads.

=head1 EXIT CODES

=over 4

=item 0 - Successful download

=item 1 - Failed download, possibly no available mirror

=item 2 - Program must be run as root, and you are not root

=item 3 - Error regarding the download directory

=back

=head1 AUTHOR

Oliver Gorwits C<< <oliver.gorwits@oucs.ox.ac.uk> >>

=head1 COPYRIGHT & LICENSE

Copyright (c) The University of Oxford 2007. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published by the
Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
St, Fifth Floor, Boston, MA 02110-1301 USA

=cut

