123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #!/usr/bin/perl
- #
- # Copyright © 1996 Andy Guy <awpguy@acs.ucalgary.ca>
- # Copyright © 1998 Martin Schulze <joey@infodrom.north.de>
- # Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; version 2 of the License.
- #
- # 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, see <https://www.gnu.org/licenses/>.
- use strict;
- use warnings;
- eval q{
- pop @INC if $INC[-1] eq '.';
- use Net::FTP;
- };
- if ($@) {
- warn "Please install the 'perl' package if you want to use the\n" .
- "FTP access method of dselect.\n\n";
- exit 1;
- }
- use Dselect::Ftp;
- # deal with arguments
- my $vardir = $ARGV[0];
- my $method = $ARGV[1];
- my $option = $ARGV[2];
- if ($option eq 'manual') {
- print "Enter package file names or a blank line to finish\n";
- while(1) {
- print 'Enter package file name:';
- my $fn = <STDIN>;
- chomp $fn;
- if ($fn eq '') {
- exit 0;
- }
- if ( -f $fn ) {
- system('dpkg', '--merge-avail', $fn);
- } else {
- print "Could not find $fn, try again\n";
- }
- };
- };
- #print "vardir: $vardir, method: $method, option: $option\n";
- my $arch = qx(dpkg --print-architecture);
- $arch='i386' if $?;
- chomp $arch;
- my $exit = 0;
- # get info from control file
- read_config("$vardir/methods/ftp/vars");
- chdir "$vardir/methods/ftp";
- print "Getting Packages files...(stop with ^C)\n\n";
- my @pkgfiles;
- my $ftp;
- my $packages_modified = 0;
- sub download {
- foreach (@{$CONFIG{site}}) {
- my $site = $_;
- $ftp = do_connect ($_->[0], # Ftp server
- $_->[4], # username
- $_->[5], # password
- $_->[1], # ftp dir
- $_->[3], # passive
- $CONFIG{use_auth_proxy},
- $CONFIG{proxyhost},
- $CONFIG{proxylogname},
- $CONFIG{proxypassword});
- my @dists = @{$_->[2]};
- PACKAGE:
- foreach my $dist (@dists) {
- my $dir = "$dist/binary-$arch";
- my $must_get = 0;
- my $newest_pack_date;
- # check existing Packages on remote site
- print "\nChecking for Packages file... ";
- $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
- if (defined $newest_pack_date) {
- print "$dir/Packages.gz\n";
- } else {
- $dir = "$dist";
- $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
- if (defined $newest_pack_date) {
- print "$dir/Packages.gz\n";
- } else {
- print "Couldn't find Packages.gz in $dist/binary-$arch or $dist; ignoring.\n";
- print "Your setup is probably wrong, check the distributions directories,\n";
- print "and try with passive mode enabled/disabled (if you use a proxy/firewall)\n";
- next PACKAGE;
- }
- }
- # we now have $dir set to point to an existing Packages.gz file
- # check if we already have a Packages file (and get its date)
- $dist =~ tr/\//_/;
- my $file = "Packages.$site->[0].$dist";
- # if not
- if (! -f $file) {
- # must get one
- # print "No Packages here; must get it.\n";
- $must_get = 1;
- } else {
- # else check last modification date
- my @pack_stat = stat($file);
- if($newest_pack_date > $pack_stat[9]) {
- # print "Packages has changed; must get it.\n";
- $must_get = 1;
- } elsif ($newest_pack_date < $pack_stat[9]) {
- print " Our file is newer than theirs; skipping.\n";
- } else {
- print " Already up-to-date; skipping.\n";
- }
- }
- if ($must_get) {
- -f 'Packages.gz' and unlink 'Packages.gz';
- -f 'Packages' and unlink 'Packages';
- my $size = 0;
- TRY_GET_PACKAGES:
- while (1) {
- if ($size) {
- print ' Continuing ';
- } else {
- print ' Getting ';
- }
- print "Packages file from $dir...\n";
- eval {
- if ($ftp->get("$dir/Packages.gz", 'Packages.gz', $size)) {
- if (system('gunzip', 'Packages.gz')) {
- print " Couldn't gunzip Packages.gz, stopped";
- die 'error';
- }
- } else {
- print " Couldn't get Packages.gz from $dir !!! Stopped.";
- die 'error';
- }
- };
- if ($@) {
- $size = -s 'Packages.gz';
- if (ref($ftp)) {
- $ftp->abort();
- $ftp->quit();
- };
- if (yesno ('y', "Transfer failed at $size: retry at once")) {
- $ftp = do_connect ($site->[0], # Ftp server
- $site->[4], # username
- $site->[5], # password
- $site->[1], # ftp dir
- $site->[3], # passive
- $CONFIG{use_auth_proxy},
- $CONFIG{proxyhost},
- $CONFIG{proxylogname},
- $CONFIG{proxypassword});
- if ($newest_pack_date != do_mdtm ($ftp, "$dir/Packages.gz")) {
- print ("Packages file has changed !\n");
- $size = 0;
- }
- next TRY_GET_PACKAGES;
- } else {
- die 'error';
- }
- }
- last TRY_GET_PACKAGES;
- }
- if (!rename 'Packages', "Packages.$site->[0].$dist") {
- print " Couldn't rename Packages to Packages.$site->[0].$dist";
- die 'error';
- } else {
- # set local Packages file to same date as the one it mirrors
- # to allow comparison to work.
- utime $newest_pack_date, $newest_pack_date, "Packages.$site->[0].$dist";
- $packages_modified = 1;
- }
- }
- push @pkgfiles, "Packages.$site->[0].$dist";
- }
- $ftp->quit();
- }
- }
- eval {
- local $SIG{INT} = sub {
- die "interrupted!\n";
- };
- download();
- };
- if($@) {
- $ftp->quit() if (ref($ftp));
- if($@ =~ /timeout/i) {
- print "FTP TIMEOUT\n";
- } else {
- print "FTP ERROR - $@\n";
- }
- $exit = 1;
- };
- # Don't clear if nothing changed.
- if ($packages_modified) {
- print <<'EOM';
- It is a good idea to clear the available list of old packages.
- However if you have only downloaded a Package files from non-main
- distributions you might not want to do this.
- EOM
- if (yesno ('y', 'Do you want to clear available list')) {
- print "Clearing...\n";
- if (system('dpkg', '--clear-avail')) {
- print 'dpkg --clear-avail failed.';
- die 'error';
- }
- }
- }
- if (!$packages_modified) {
- print "No Packages files was updated.\n";
- } else {
- foreach my $file (@pkgfiles) {
- if (system('dpkg', '--merge-avail', $file)) {
- print "Dpkg merge available failed on $file";
- $exit = 1;
- }
- }
- }
- exit $exit;
|