update.pl 6.5 KB

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