chiark / gitweb /
dpkg (1.18.25) stretch; urgency=medium
[dpkg] / dselect / methods / multicd / install
1 #!/bin/sh
2 #
3 # Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk>
4 # Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de>
5 #
6 # This is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
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
19 set -e
20 vardir="$1"
21 method=$2
22 option=$3
23
24
25 cd "$vardir/methods/$method"
26
27 . ./shvar.$option
28
29
30 #debug() { echo "DEBUG: $@"; }
31 debug() { true; }
32 iarch=`dpkg --print-architecture`
33 ismulti() { test -e "$1/.disk/info" || test -e "$1$2/.disk/info"; }
34
35 # 1/ mountpoint
36 # 2/ hierarchy
37 getdisklabel () {
38     debug "$1" "$2"
39     if [ -f $1/.disk/info ]
40     then
41         echo -n `head -1 "$1/.disk/info"`
42     else
43         if [ -f $1$2/.disk/info ]
44         then
45             echo -n `head -1 "$1$2/.disk/info"`
46         else
47             echo -n 'Non-Debian disc'
48         fi
49     fi
50 }
51
52 xit=1
53
54 do_umount() {
55         if [ "$method" = "multi_mount" ]
56         then
57                 echo true
58                 return
59         fi
60         if [ -n "$umount" ]; then
61                 echo umount "$umount"
62                 #">/dev/null" "2>&1"
63         fi
64 }
65
66 do_mount() {
67
68         if [ "$method" = "multi_mount" ]
69         then
70                 echo true
71                 return
72         fi
73
74         if [ ! -b "$p_blockdev" ]
75         then
76                 loop=",loop"
77         fi
78
79         if [ -n "$p_blockdev" ]
80         then
81                 umount="$p_mountpoint"
82                 echo mount -rt iso9660 -o nosuid,nodev${loop} "$p_blockdev" "$p_mountpoint"\; umount="$p_mountpoint"
83         fi
84
85         if [ -n "$p_nfs" ]
86         then
87                 umount="$p_mountpoint"
88                 echo mount -rt nfs "$p_nfs" -o nosuid,nodev "$p_mountpoint"\; umount="$p_mountpoint"
89         fi
90
91         #if [ -n "$p_multi" -a -n "$p_multi_contentsfile" ]; then
92                 #echo "This is disk "
93                 #echo "    "`getdisklabel "${p_mountpoint}" "${p_hierbase}"`
94         #fi
95 }
96
97 trap 'eval `do_umount`; exit $xit' 0
98
99 eval `do_mount`
100
101 predep="$vardir/predep-package"
102 while true
103 do
104         thisdisk="`getdisklabel ${p_mountpoint} ${p_hierbase}`"
105         set +e
106         dpkg --predep-package >"$predep"
107         rc=$?
108         set -e
109         if test $rc = 1; then break; fi
110         test $rc = 0
111
112         perl -e '
113                 ($binaryprefix,$predep,$thisdisk) = @ARGV;
114                 open(P, "< $predep") or die "cannot open $predep: $!\n";
115                 while (<P>) {
116                         s/\s*\n$//;
117                         $package= $_ if s/^Package: //i;
118                         /^X-Medium:\s+(.*)\s*/ and $medium = $1;
119                         @filename= split(/ /,$_) if s/^Filename: //i;
120                         @msdosfilename= split(/ /,$_) if s/^MSDOS-Filename: //i;
121                 }
122                 die "internal error - no package" if length($package) == 0;
123                 die "internal error - no filename" if not @filename;
124                 die "internal error - mismatch >@filename< >@msdosfilename<"
125                         if @filename && @msdosfilename &&
126                            @filename != @msdosfilename;
127                 if ($medium && ($medium ne $thisdisk)) {
128                         print "
129
130 This is
131     $thisdisk
132 However, $package is expected on disc:
133     $medium
134 Please change the discs and press <RETURN>.
135
136 ";
137                         exit(1);
138                 }
139                 @invoke=(); $|=1;
140                 for ($i=0; $i<=$#filename; $i++) {
141                         $ppart= $i+1;
142                         print "Looking for part $ppart of $package ... ";
143                         if (-f "$binaryprefix$filename[$i]") {
144                                 $print= $filename[$i];
145                                 $invoke= "$binaryprefix$filename[$i]";
146                         } elsif (-f "$binaryprefix$msdosfilename[$i]") {
147                                 $print= $msdosfilename[$i];
148                                 $invoke= "$binaryprefix$msdosfilename[$i]";
149                         } else {
150                                 $base= $filename[$i]; $base =~ s,.*/,,;
151                                 $msdosbase= $msdosfilename[$i]; $msdosbase =~ s,.*/,,;
152                                 $c = open(X, "-|"));
153                                 if (not defined $c) {
154                                         die "failed to fork for find: $!\n";
155                                 }
156                                 if (!$c) {
157                                         exec("find", "-L",
158                                              length($binaryprefix) ? $binaryprefix : ".",
159                                              "-name",$base,"-o","-name",$msdosbase);
160                                         die "failed to exec find: $!\n";
161                                 }
162                                 while (chop($invoke= <X>)) { last if -f $invoke; }
163                                 $print= $invoke;
164                                 if (substr($print,0,length($binaryprefix)+1) eq
165                                     "$binaryprefix/") {
166                                         $print= substr($print,length($binaryprefix));
167                                 }
168                         }
169                         if (!length($invoke)) {
170                                 warn "
171
172 Oh dear, I need to install or upgrade $package, but I don'\''t see
173 the appropriate file(s) anywhere.  I'\''m expecting version $version or
174 later, as that is listed in the Packages.cd file.
175
176 Perhaps you downloaded it with an unexpected name, or something.
177 In any case, you must find the file(s) and then either place it with
178 the correct filename(s) (as listed in the Packages.cd file or in
179 /var/lib/dpkg/available) and rerun the installation, or upgrade the
180 package by using '\''dpkg --install --auto-deconfigure'\'' by hand.
181
182 ";
183                                 exit(1);
184                         }
185                         print "$print\n";
186                         push(@invoke,$invoke);
187                 }
188                 print "Running dpkg -iB for $package ...\n";
189                 exec("dpkg","-iB","--",@invoke);
190                 die "failed to exec dpkg: $!\n";
191         ' -- "$p_mountpoint$p_hierbase" "$predep" "$thisdisk"
192 done
193
194         perl -e '
195         $SIG{INT} = sub { cd $vardir; unlink <tmp/*>; exit 1; };
196         $| = 1;
197         my ($vardir, $mountpoint, $hierbase, $mount, $umount) = @ARGV;
198         my $line;
199         my $AVAIL = "$vardir/methods/multicd/available";
200         my $STATUS = "$vardir/status";
201         my %Installed, %Filename, %Medium;
202         print "Get currently installed package versions...";
203         open(IN, "$STATUS") or die "cannot open $STATUS: $!\n";
204         $line = 0;
205         { local $/ = "";
206         while (<IN>) {
207                 my %status;
208                 my @pstat;
209                 $line++ % 20 or print ".";
210                 s/\n\s+/ /g;
211                 %status =  ("", split /^(\S*?):\s*/m, $_);
212                 map { chomp $status{$_}; $status{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %status;
213                 @pstat = split(/ /, $status{Status});
214                 next unless ($pstat[0] eq "install");
215                 if ($pstat[2] eq "config-files" || $pstat[2] eq "not-installed") {
216                     $Installed{$status{Package}} = "0.0";
217                 } else {
218                     $Installed{$status{Package}} = $status{Version} || "" ;
219                 }
220         }; }
221         print "\nGot ", scalar keys %Installed, " installed/pending packages\n";
222         print "Scanning available packages...";
223         $line = 0;
224         open(IN, "$AVAIL") or die("Cannot open $AVAIL: $!\n");
225         { local $/ = "";
226         while (<IN>) {
227                 my $updated;
228                  $line++ % 20 or print ".";
229
230                  s/\n\s+/ /g;
231                  %avail   =  ("", split /^(\S*?):\s*/m, $_);
232                  map { chomp $avail{$_}; $avail{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %avail;
233
234                  next unless defined $Installed{$avail{Package}};
235
236                  system "dpkg", "--compare-versions", $avail{Version}, "gt", $Installed{$avail{Package}};
237                  $updated = ($? == 0);
238                  #print "$avail{Package}(" . ($updated ? "+" : "=") . ") ";
239                  $updated or next;
240
241                  $Filename{$avail{Package}} = $avail{Filename};
242
243                  next unless defined $avail{"X-Medium"};
244                  ${Medium{$avail{"X-Medium"}}} or ${Medium{$avail{"X-Medium"}}} = [];
245                  push @{${Medium{$avail{"X-Medium"}}}}, $avail{Package};
246         }; };
247         print "\n";
248
249         if (@_ = keys(%Medium)) {
250                     print "You will need the following distribution disc(s):\n",
251                         join (", ", @_), "\n";
252         }
253
254         foreach $need (sort @_) {
255                 if (-r "$mountpoint/.disk/info") {
256                         open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n");
257                 } else {
258                         open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n");
259                 }
260                 $disk = <IN>; chomp $disk; close(IN);
261
262                 print "Processing disc\n   $need\n";
263
264                 while ($disk ne $need) {
265                         print "Wrong disc.  This is disc\n    $disk\n";
266                         print "However, I need disc\n    $need\n";
267                         print "Please change the discs and press <RETURN>\n";
268                         system($umount);
269                         <STDIN>;
270                         system($mount);
271                         $? and warn("cannot mount $mount\n");
272                 } continue {
273                         if (-r "$mountpoint/.disk/info") {
274                             open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n");
275                         } else {
276                             open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n");
277                         }
278                         $disk = <IN>; chomp $disk; close(IN);
279                 }
280
281                 -d "tmp" || mkdir "tmp", 0755 or die("Cannot mkdir tmp: $!\n");
282                 unlink <tmp/*>;
283
284                 print "creating symlinks...\n";
285                 foreach (@{$Medium{$need}}) {
286                         ($basename = $Filename{$_}) =~ s/.*\///;
287                         symlink "$mountpoint/$hierbase/$Filename{$_}",
288                                 "tmp/$basename";
289                 }
290                 chdir "tmp" or die "cannot chdir to tmp: $!\n";
291                 system "dpkg", "-iGROEB", ".";
292                 unlink <*>;
293                 chdir "..";
294
295                 if ($?) {
296                         print "\nThe dpkg run produced errors.  Please tell me, if I should\n",
297                                   "continue with the next CD. [Y/n]: ";
298                         $ans = <STDIN>;
299                         exit 1 if $ans =~ /^n/i;
300                         $ouch = $?;
301                 }
302         }
303
304         exit $ouch;
305
306 ' "$vardir" "$p_mountpoint" "$p_hierbase" "`do_mount`" "`do_umount`"
307
308
309 echo -n 'Installation OK.  Hit RETURN.  '
310 read response
311
312 xit=0