update.pl 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #!/usr/bin/perl
  2. #
  3. # Copyright © 1996 Andy Guy <awpguy@acs.ucalgary.ca>
  4. # Copyright © 1998 Martin Schulze <joey@infodrom.north.de>
  5. # Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; version 2 of the License.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. use strict;
  19. use warnings;
  20. eval q{
  21. pop @INC if $INC[-1] eq '.';
  22. use Net::FTP;
  23. };
  24. if ($@) {
  25. warn "Please install the 'perl' package if you want to use the\n" .
  26. "FTP access method of dselect.\n\n";
  27. exit 1;
  28. }
  29. use Dselect::Ftp;
  30. # deal with arguments
  31. my $vardir = $ARGV[0];
  32. my $method = $ARGV[1];
  33. my $option = $ARGV[2];
  34. if ($option eq 'manual') {
  35. print "Enter package file names or a blank line to finish\n";
  36. while(1) {
  37. print 'Enter package file name:';
  38. my $fn = <STDIN>;
  39. chomp $fn;
  40. if ($fn eq '') {
  41. exit 0;
  42. }
  43. if ( -f $fn ) {
  44. system('dpkg', '--merge-avail', $fn);
  45. } else {
  46. print "Could not find $fn, try again\n";
  47. }
  48. };
  49. };
  50. #print "vardir: $vardir, method: $method, option: $option\n";
  51. my $arch = qx(dpkg --print-architecture);
  52. $arch='i386' if $?;
  53. chomp $arch;
  54. my $exit = 0;
  55. # get info from control file
  56. read_config("$vardir/methods/ftp/vars");
  57. chdir "$vardir/methods/ftp";
  58. print "Getting Packages files...(stop with ^C)\n\n";
  59. my @pkgfiles;
  60. my $ftp;
  61. my $packages_modified = 0;
  62. sub download {
  63. foreach (@{$CONFIG{site}}) {
  64. my $site = $_;
  65. $ftp = do_connect ($_->[0], # Ftp server
  66. $_->[4], # username
  67. $_->[5], # password
  68. $_->[1], # ftp dir
  69. $_->[3], # passive
  70. $CONFIG{use_auth_proxy},
  71. $CONFIG{proxyhost},
  72. $CONFIG{proxylogname},
  73. $CONFIG{proxypassword});
  74. my @dists = @{$_->[2]};
  75. PACKAGE:
  76. foreach my $dist (@dists) {
  77. my $dir = "$dist/binary-$arch";
  78. my $must_get = 0;
  79. my $newest_pack_date;
  80. # check existing Packages on remote site
  81. print "\nChecking for Packages file... ";
  82. $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
  83. if (defined $newest_pack_date) {
  84. print "$dir/Packages.gz\n";
  85. } else {
  86. $dir = "$dist";
  87. $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
  88. if (defined $newest_pack_date) {
  89. print "$dir/Packages.gz\n";
  90. } else {
  91. print "Couldn't find Packages.gz in $dist/binary-$arch or $dist; ignoring.\n";
  92. print "Your setup is probably wrong, check the distributions directories,\n";
  93. print "and try with passive mode enabled/disabled (if you use a proxy/firewall)\n";
  94. next PACKAGE;
  95. }
  96. }
  97. # we now have $dir set to point to an existing Packages.gz file
  98. # check if we already have a Packages file (and get its date)
  99. $dist =~ tr/\//_/;
  100. my $file = "Packages.$site->[0].$dist";
  101. # if not
  102. if (! -f $file) {
  103. # must get one
  104. # print "No Packages here; must get it.\n";
  105. $must_get = 1;
  106. } else {
  107. # else check last modification date
  108. my @pack_stat = stat($file);
  109. if($newest_pack_date > $pack_stat[9]) {
  110. # print "Packages has changed; must get it.\n";
  111. $must_get = 1;
  112. } elsif ($newest_pack_date < $pack_stat[9]) {
  113. print " Our file is newer than theirs; skipping.\n";
  114. } else {
  115. print " Already up-to-date; skipping.\n";
  116. }
  117. }
  118. if ($must_get) {
  119. -f 'Packages.gz' and unlink 'Packages.gz';
  120. -f 'Packages' and unlink 'Packages';
  121. my $size = 0;
  122. TRY_GET_PACKAGES:
  123. while (1) {
  124. if ($size) {
  125. print ' Continuing ';
  126. } else {
  127. print ' Getting ';
  128. }
  129. print "Packages file from $dir...\n";
  130. eval {
  131. if ($ftp->get("$dir/Packages.gz", 'Packages.gz', $size)) {
  132. if (system('gunzip', 'Packages.gz')) {
  133. print " Couldn't gunzip Packages.gz, stopped";
  134. die 'error';
  135. }
  136. } else {
  137. print " Couldn't get Packages.gz from $dir !!! Stopped.";
  138. die 'error';
  139. }
  140. };
  141. if ($@) {
  142. $size = -s 'Packages.gz';
  143. if (ref($ftp)) {
  144. $ftp->abort();
  145. $ftp->quit();
  146. };
  147. if (yesno ('y', "Transfer failed at $size: retry at once")) {
  148. $ftp = do_connect ($site->[0], # Ftp server
  149. $site->[4], # username
  150. $site->[5], # password
  151. $site->[1], # ftp dir
  152. $site->[3], # passive
  153. $CONFIG{use_auth_proxy},
  154. $CONFIG{proxyhost},
  155. $CONFIG{proxylogname},
  156. $CONFIG{proxypassword});
  157. if ($newest_pack_date != do_mdtm ($ftp, "$dir/Packages.gz")) {
  158. print ("Packages file has changed !\n");
  159. $size = 0;
  160. }
  161. next TRY_GET_PACKAGES;
  162. } else {
  163. die 'error';
  164. }
  165. }
  166. last TRY_GET_PACKAGES;
  167. }
  168. if (!rename 'Packages', "Packages.$site->[0].$dist") {
  169. print " Couldn't rename Packages to Packages.$site->[0].$dist";
  170. die 'error';
  171. } else {
  172. # set local Packages file to same date as the one it mirrors
  173. # to allow comparison to work.
  174. utime $newest_pack_date, $newest_pack_date, "Packages.$site->[0].$dist";
  175. $packages_modified = 1;
  176. }
  177. }
  178. push @pkgfiles, "Packages.$site->[0].$dist";
  179. }
  180. $ftp->quit();
  181. }
  182. }
  183. eval {
  184. local $SIG{INT} = sub {
  185. die "interrupted!\n";
  186. };
  187. download();
  188. };
  189. if($@) {
  190. $ftp->quit() if (ref($ftp));
  191. if($@ =~ /timeout/i) {
  192. print "FTP TIMEOUT\n";
  193. } else {
  194. print "FTP ERROR - $@\n";
  195. }
  196. $exit = 1;
  197. };
  198. # Don't clear if nothing changed.
  199. if ($packages_modified) {
  200. print <<'EOM';
  201. It is a good idea to clear the available list of old packages.
  202. However if you have only downloaded a Package files from non-main
  203. distributions you might not want to do this.
  204. EOM
  205. if (yesno ('y', 'Do you want to clear available list')) {
  206. print "Clearing...\n";
  207. if (system('dpkg', '--clear-avail')) {
  208. print 'dpkg --clear-avail failed.';
  209. die 'error';
  210. }
  211. }
  212. }
  213. if (!$packages_modified) {
  214. print "No Packages files was updated.\n";
  215. } else {
  216. foreach my $file (@pkgfiles) {
  217. if (system('dpkg', '--merge-avail', $file)) {
  218. print "Dpkg merge available failed on $file";
  219. $exit = 1;
  220. }
  221. }
  222. }
  223. exit $exit;