]> pere.pagekite.me Git - homepage.git/blob - linux/ftp-upgrade
Generated.
[homepage.git] / linux / ftp-upgrade
1 #!/usr/bin/perl
2 #
3 # ftp-upgrade - fetch redhat package manager updates from the network
4 #
5 # usage: ftp-upgrade [-n] [-u uname]
6 #
7 # -u - specify a username to use - will be prompted for a password
8 # -n - identify packages that are "new" (e.g. not yet installed)
9 #
10 # ftp-upgrade queries the set of installed packages on the local machine. It
11 # then connects to the redhat repository of your choice via ftp, examines
12 # the list of available updates there, and informs you of any packages that
13 # have had their patch level increased or version number changed. You can
14 # then choose to have all of the indicated packages downloaded, or
15 # individually select which packages to download. The transferred RPMs are
16 # placed in the current working directory. They can then be installed on
17 # your system by using the command rpm -u <file>, where <file> is one of
18 # the downloaded RPMs.
19 #
20 # Note that if there is an update to RPM or GLINT, these should be updated
21 # first!
22 #
23 # $Header: /storage/cvsroot/user/www/homepage/linux/ftp-upgrade,v 1.1 2003/06/02 13:01:37 pere Exp $
24 #
25 # $Log: ftp-upgrade,v $
26 # Revision 1.1 2003/06/02 13:01:37 pere
27 # Add all my patches to CVS.
28 #
29 # Revision 1.10-pr 1998/05/28 10:00:00 pere
30 # Lost of changes. Added handling of many directories, etc.
31 #
32 # Revision 1.10 1995/11/27 11:01:33 ahby
33 # Changed default path to be for the 2.1 RPMS directory.
34 #
35 # Revision 1.9 1995/11/22 09:38:21 ahby
36 # Removed some debugging code.
37 #
38 # Revision 1.8 1995/11/20 19:27:58 ahby
39 # Added ability to get packages that are not yet installed.
40 #
41 # Revision 1.7 1995/11/14 21:53:41 ahby
42 # Fixed an erroneously anchored string.
43 # Improved package recognition.
44 # Fixed a stupid array reference (I really am a better programmer
45 # than this!).
46 #
47 # Revision 1.6 1995/11/14 19:09:35 ahby
48 # Added list of mirror sites and username option.
49 # Changed handling on connection error.
50 #
51 # Revision 1.5 1995/11/14 15:59:07 ahby
52 # Changed it so if there are no changes it just terminates.
53 #
54 # Revision 1.4 1995/11/14 15:51:16 ahby
55 # Cleaned up some comments.
56 #
57 # Revision 1.3 1995/11/09 23:15:46 ahby
58 # CHanged revision tracking strategy to be smarter and use associative
59 # array instead of a flat array and a search.
60 #
61 # Revision 1.2 1995/11/09 17:27:01 ahby
62 # Fixed RCS headers.
63 #
64 #
65 sub get_redhat_version {
66 my($tmp) = `rpm -q redhat-release`;
67 my($ver) = $tmp =~ m/^.+-([\d\.]+)-\d+/;
68 if ($ver) {
69 return $ver;
70 } else {
71 print "Unable to determine RedHat version. Exiting.\n";
72 exit(1);
73 }
74 }
75
76 sub get_redhat_architecture {
77 my($tmp) = `uname -m`;
78 chomp($tmp);
79 my($arch);
80 if ($tmp =~ m/i?86/) {
81 $arch = 'i386';
82 } else {
83 $arch = $tmp;
84 }
85 return $arch;
86 }
87
88 $version = get_redhat_version();
89 $arch = get_redhat_architecture();
90 @rpm_dirs = ("redhat-$version/$arch/RedHat/RPMS",
91 "updates/$version/$arch",
92 "powertools-$version/$arch");
93
94 # Popular RedHat mirrors sites
95 #$host = "ftp.nvg.unit.no";
96 #$path = "/pub/linux/redhat";
97 $host = "sunsite.uio.no";
98 $path = "/pub/unix/linux/redhat";
99 #$host = "ftp.caldera.com";
100 #$path = "/pub/mirrors/redhat";
101 #$host = "ftp.cc.gatech.edu";
102 #$path = "/pub/linux/distributions/redhat";
103 #$host = "ftp.pht.com";
104 #$path = "/pub/linux/redhat";
105 #$host = "ftp.cms.uncwil.edu";
106 #$path = "/linux/redhat";
107 #$host = "ftp.wilmington.net";
108 #$path = "/linux/redhat";
109 #$host = "ftp.caldera.com";
110 #$path = "/pub/mirrors/redhat";
111 #$host = "ftp.lasermoon.co.uk";
112 #$path = "/pub/distributions/RedHat";
113 #$host = "sunsite.unc.edu";
114 #$path = "/pub/Linux/distributions/redhat";
115 #$host = "sunsite.doc.ic.ac.uk";
116 #$path = "/packages/linux/sunsite.unc-mirror/distributions/redhat";
117 #$host = "ftp.cc.gatech.edu";
118 #$path = "/pub/linux/distributions/redhat";
119 #$host = "uiarchive.cso.uiuc.edu";
120 #$path = "/pub/systems/linux/distributions/redhat";
121 #$host = "ftp.ibp.fr";
122 #$path = "/pub/linux/distributions/redhat";
123 #$host = "ftp.gwdg.de";
124 #$path = "/pub/linux/install/redhat";
125 #$host = "ftp.uoknor.edu";
126 #$path = "/linux/redhat";
127 #$host = "ftp.msu.ru";
128 #$path = "/pub/Linux/RedHat";
129 #$host = "linux.ucs.indiana.edu";
130 #$path = "/pub/linux/redhat";
131 #$host = "ftp.cvut.cz";
132 #$path = "/pub/linux/redhat";
133 #$host = "ftp.ton.tut.fi";
134 #$path = "/pub/Linux/RedHat";
135 #$host = "ftp.funet.fi";
136 #$path = "/pub/Linux/images/RedHat";
137
138 BEGIN {
139 # Find Net::FTP if it is in an nonstandard place
140 push(@INC, "/store/lib/perl5", "/store/lib/perl5/site_perl" );
141
142 # Workaround for a bug in early RedHat 5 perl distributions.
143 eval 'require "ftp.pl"; import ftp;';
144 return unless ( $@ );
145
146 # Make backup include files
147 mkdir "/tmp/perl-fix", 0777;
148 mkdir "/tmp/perl-fix/gnu", 0777;
149 my($tmp) = `echo '1;' > /tmp/perl-fix/gnu/stubs.ph`;
150 $tmp = `echo '1;' > /tmp/perl-fix/stddef.ph`;
151 push(@INC, "/tmp/perl-fix");
152 }
153
154 # compare versions - needs more work
155 # 1.9.1 is newer then 1.9 and 3.19 is newer then 3.2
156 # Return true if v2 is newer then v1
157 sub version_newer {
158 my ($v1, $v2) = @_;
159 my($r1, $r2);
160 ($v1,$r1) = $v1 =~ m/^(.+)-(\d+).+rpm/;
161 ($v2,$r2) = $v2 =~ m/^(.+)-(\d+).+rpm/;
162 if ($v1 eq $v2) {
163 return ($r1 < $r2);
164 }
165 my @v1 = split(/\./, $v1);
166 my @v2 = split(/\./, $v2);
167 if ($v1[0] < $v2[0] ||
168 ($v1[0] == $v2[0] && $v1[1] < $v2[1]) ||
169 ($v1[0] == $v2[0] && $v1[1] == $v2[1] && $v1[2] lt $v2[2])) {
170 # print "Comparing $v1 and $v2 - true\n";
171 return 1;
172 }
173 # print "Comparing $v1 and $v2 - false\n";
174 return 0;
175 }
176
177 use Getopt::Std;
178
179 # XXX use Net::FTP;
180 require "ftp.pl";
181 import ftp;
182
183
184 $uname = "anonymous";
185 $pword = "upgrade-user@";
186
187 &getopts('nu:');
188
189 if ($opt_u) {
190 $uname = $opt_u;
191 system "stty -echo";
192 print "Password: ";
193 chop($pword = <STDIN>);
194 print "\n";
195 system "stty echo";
196 }
197
198 # subroutine to get y/n answer
199
200 sub getyn {
201 local($prompt) = @_;
202 local($answer) = "";
203 local($a) = "";
204
205 do {
206 print "$prompt (y/n)? ";
207 $answer = <STDIN>;
208 $a = substr($answer, 0, 1);
209 } while (($a ne "Y") && ($a ne "y") && ($a ne "N") && ($a ne "n"));
210 return (($a eq "Y") || ($a eq "y"));
211 }
212
213
214 # get the local list of installed packages
215
216 print "Getting list of installed packages\n";
217 @llist = `rpm -qa`;
218 chop(@llist);
219 sort(@llist);
220
221 # now connect to the remote host
222
223 print ("Getting the list of updated packages from $host.\n");
224
225 # make the connection and fetch the directory
226
227 print "Opening connection to $host\n";
228
229 # XXX $ftp = Net::FTP->new($host, Timeout => '30');
230 ftp::set_timeout(30);
231 $ftp = ftp::open($host,21,0,10);
232
233 if ( ! $ftp ) {
234 die("open of $host failed");
235 }
236 print "Logging in to $host as $uname\n";
237
238 # XXX $ftp->login($uname,$pword) || die("login failed");
239 ftp::login($uname,$pword) || die("login failed");
240
241 for $dir (@rpm_dirs) {
242 fetch_subdir_list($dir);
243 }
244
245 ##
246 # Exports: @templist, %rlist
247 sub fetch_subdir_list {
248 my($dir) = @_;
249 my($curpath) = $path . "/" . $dir;
250
251 print "Changing to directory $curpath on $host\n";
252
253 # XXX $ftp->cwd($curpath);
254 if ( ! ftp::cwd($curpath) ) {
255 return;
256 }
257
258 print "Fetching directory list\n";
259
260 # XXX my(@longlist) = $ftp->ls();
261 ftp::dir_open("");
262 @longlist = <ftp::NS>;
263 ftp::dir_close();
264
265 push(@templist, grep(/\.rpm/, @longlist));
266 undef @longlist;
267
268 chomp(@templist);
269 sort (@templist);
270
271 my(@temp);
272 for (@templist) {
273 @temp = m/([^ ]*)-([^- ]*-[0-9]*[^ ]*rpm).*/;
274 ($file) = m/(\S+rpm)/;
275 # Only add newer package
276 if ( (! $rlist{$temp[0]} ) ||
277 ($rlist{$temp[0]} && version_newer($rlist{$temp[0]},$temp[1])) ) {
278 $rlist{$temp[0]} = $temp[1];
279 $directory{$file} = $curpath;
280 }
281 }
282 }
283
284 # XXX $ftp->type("I");
285 ftp::type("I");
286
287 # XXX $ftp->debug(1);
288 #ftp::debug(1);
289
290 if ($opt_n) { # if we are looking for new packages
291
292 for (@llist) {
293 @temp = m/([^ ]*)-([^-]*-[0-9]*)/;
294 $ilist{$temp[0]} = $temp[1];
295 }
296
297 $uindex = 0; #initialize index for uninstalled package array
298
299 for (@templist) {
300 $fname = $_;
301 $fname =~ s/.*\s([^ ]*rpm).*/$1/;
302 @pname = ($fname =~ m/^(.*)-([^-]*)-([0-9]*)/);
303 if (! $ilist{$pname[0]}) { # if this not package already installed
304 @ulist[$uindex] = $fname;
305 $uindex++;
306 }
307 }
308 @ulist = sort(@ulist);
309 if (@ulist) {
310 print "Uninstalled packages:\n";
311 for (@ulist) {
312 print " $_\n";
313 }
314 $all = getyn("Fetch all?");
315
316 for (@ulist) {
317 if (! $all) {
318 if (!getyn("Fetch $_")) { next };
319 }
320 getfile($ftp, $_);
321 }
322 } else {
323 print ("No new packages are available on $host\n");
324 }
325
326 } else { # check for updated packages
327
328 $nindex = 0; #initialize index for new version array
329 $cindex = 0; #initialize index for changed patch array
330
331 for (@llist) {
332 @lname = m/^(.*)-([^-]*)-([0-9]*$)/;
333 if ($rlist{$lname[0]}) { # if this package has an update
334 @temp = ($rlist{$lname[0]} =~ m/([^-]*)-([0-9]*).*rpm/);
335 if ($lname[1] eq $temp[0]) { # if versions equal
336 if ($lname[2] < $temp[1]) { # if patch level has increased
337 @clist[$cindex] = $lname[0] . '-' . $rlist{$lname[0]};
338 $cindex++;
339 };
340 } else { # if different version
341 if (version_newer($lname[1], $temp[0])) {
342 @nlist[$nindex] = $lname[0] . '-' . $rlist{$lname[0]};
343 $nindex++;
344 }
345 }
346 }
347 }
348 if (@clist || @nlist) {
349 @clist = sort(@clist);
350 @nlist = sort(@nlist);
351 print "New patches:\n\n";
352 for (@clist) {
353 print " $_\n"
354 }
355 print "\nDifferent versions:\n\n";
356 for (@nlist) {
357 print " $_\n"
358 }
359
360 $all = getyn("Fetch all?");
361
362 for (@clist) {
363 if (! $all) {
364 if (!getyn("Fetch $_")) { next };
365 }
366 getfile($ftp, $_);
367 }
368 for (@nlist) {
369 if (! $all) {
370 if (!getyn("Fetch $_")) { next };
371 }
372 getfile($ftp, $_);
373 }
374 print "\nTo upgrade, run 'rpm -Uvh *.rpm' as root.\n"
375 } else {
376 print ("No new updates are available on $host\n");
377 }
378 }
379
380
381 #$ftp->debug(0);
382 # XXX $ftp->quit();
383 ftp::close();
384
385 sub getfile {
386 my($ftphandle, $filename) = @_;
387 my($dir) = $directory{$filename};
388 print "Fetching $dir/$filename\n";
389 # XXX $ftphandle->cwd($dir);
390 ftp::cwd($dir);
391
392 # XXX $ftphandle->get($filename);
393 ftp::get($filename);
394 }