chiark / gitweb /
dpkg (1.18.25) stretch; urgency=medium
[dpkg] / dselect / methods / disk / setup
1 #!/bin/sh
2 #
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16 set -e
17 vardir="$1"
18 method=$2
19 option=$3
20
21 cd "$vardir/methods/disk"
22 tp=/var/run/ddm$$
23
24 iarch=`dpkg --admindir $vardir --print-architecture`
25
26 xit=1
27 trap '
28         rm -f $tp.?
29         if [ -n "$umount" ]
30         then
31                 umount "$umount" >/dev/null 2>&1
32         fi
33         exit $xit
34 ' 0
35
36 if ls -d "$tp.?" >/dev/null 2>&1
37 then
38         rm $tp.?
39 fi
40
41 yesno () {
42         while true
43         do
44                 echo -n "$2 [$1]  "
45                 read response
46                 if [ -z "$response" ]
47                 then
48                         response="$1"
49                 fi
50                 case "$response" in
51                 [Nn]*)  yesno=no ; return ;;
52                 [Yy]*)  yesno=yes ; return ;;
53                 esac
54         done
55 }
56
57 print_partition_table()
58 {
59         device="$1"
60
61         printf "p\nq\n" | fdisk "$device" 2>/dev/null
62 }
63
64 getblockdev () {
65         mountpoint="$vardir/methods/mnt"
66         if [ -z "$defaultdevice" ]
67         then
68                 defaultdevice="$newdefaultdevice"
69         elif [ "$defaultdevice" != "$newdefaultdevice" ]
70         then
71                 echo \
72         "Last time you specified installation from $defaultdevice."
73         fi
74         promptstring="$1"
75         while [ -z "$blockdevice" ]
76         do
77                 echo -n "$promptstring [$defaultdevice]:  "
78                 read response
79                 if [ -z "$response" ]
80                 then
81                         response="$defaultdevice"
82                 fi
83                 if ! [ -b "$response" ]
84                 then
85                         echo "$response is not a block device."; continue
86                 fi
87                 tryblockdevice="$response"
88                 if [ $option = cdrom ]
89                 then
90                         fstype=iso9660
91                 elif [ $option = harddisk ]
92                 then
93                         blockbase="`echo \"$tryblockdevice\" | sed -e 's/[0-9]\{1,\}$//'`"
94                         set +e
95                         print_partition_table "$blockbase" >$tp.f
96                         set -e
97                         proposeddevice="$tryblockdevice" perl -ne '
98 next unless /^ *Device +Boot +Start +End +Blocks +Id +System *$/i .. !/\S/;
99 next unless s:^/\S+::p && ${^MATCH} eq $ENV{proposeddevice};
100 next unless s/^ +(\* +)?\d+ +\d+ +\d+\+? +//;
101 next unless m/^([0-9a-f]{1,2}) /i;
102 %types= ( "1","msdos", "4","msdos", "6","msdos", "7","hpfs", "80","minix",
103           "81","minix", "83","ext2" );
104 print $types{$1}; exit(0);      ' <$tp.f >$tp.m
105                         defaultfstype="`cat $tp.m`"
106                         if [ -n "$defaultfstype" ]
107                         then
108                                 cat <<END
109 The partition table for $blockbase claims that $tryblockdevice
110 contains filesystem type $defaultfstype.
111 END
112                                 if ! grep "     $defaultfstype$" /proc/filesystems >/dev/null
113                                 then
114                                         echo \
115         "Your kernel does not appear to support that filesystem type."
116                                         defaultfstype=""
117                                 fi
118                         fi
119                         echo -n "Supported filesystems: "
120                         sed -e 's/^.*   / /' /proc/filesystems | tr '\n' ' '
121                         echo -n "
122 Enter filesystem type (for $tryblockdevice) [$defaultfstype]:  "
123                         read fstype
124                         if [ -z "$fstype" ]
125                         then
126                                 fstype="$defaultfstype"
127                         fi
128                 fi
129                 umount="$mountpoint"
130                 if mount -rt "$fstype" -o nosuid,nodev "$tryblockdevice" "$mountpoint"
131                 then
132                         echo
133                         blockdevice="$tryblockdevice"
134                 else
135                         umount=""
136                         echo \
137         "Unable to mount $tryblockdevice on $mountpoint, type $fstype."
138                 fi
139         done
140 }
141
142 outputparam () {
143         echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3
144 }
145
146 intrkey="`stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p'`"
147 echo "
148 If you make a mistake, use the interrupt key ($intrkey) to abort.
149 "
150
151 # State variables, “best first”
152 #  {main,ctb,nf,nus,lcl}_{packages,binary}
153 #   Empty before we've found them or if they're not available,
154 #   set to the relevant bit under mountpoint otherwise.
155 #  hierbase
156 #   A directory containing a Debian FTP site mirror tree for ONE distribution.
157 #       eg /pub/debian/dists/stable
158 #  mountpoint
159 #   The mountpoint for the filesystem containing the stuff
160 #   empty or unset if we don't know yet, or if we haven't mounted anything;
161 #   may also be empty if ‘directory’ was set.
162 #  blockdevice
163 #   The actual block device to mount.
164 #  fstype
165 #   The filesystem type to use.
166 #  defaultdevice
167 #   The default block device to mount.
168
169 if [ -f shvar.$option ]
170 then
171         . ./shvar.$option
172         defaultdevice="$p_blockdev"
173         defaultnfsserver="$p_nfsserver"
174         defaultnfsrempath="$p_nfsrempath"
175 fi
176
177 if [ $option = cdrom ]
178 then
179         mount >$tp.m
180         sed -n 's/ ([^)]*)$//; s/^[^ ]* on //; s/ type iso9660$//p' <$tp.m >$tp.l
181         ncdroms=`wc -l <$tp.l`
182         if [ $ncdroms -gt 1 ]
183         then
184                 response=""
185                 while [ -z "$response" ]
186                 do
187                         echo \
188         'Several CD-ROMs (or other ISO9660 filesystems) are mounted:'
189                         grep 'type iso9660 ([^)]*)$' <$tp.m | nl
190                         echo -n \
191         "Is it any of these ?  Type a number, or 'n' for none.  "
192                         read response
193                         response="`echo \"$response\" | sed -e 's/[     ]*$//'`"
194                         if expr "$response" : '[0-9][0-9]*$' >/dev/null && \
195                            [ $response -ge 1 ] && [ $response -le $ncdroms ]
196                         then
197                                 mountpoint="`sed -n $response'p' <$tp.l`"
198                                 echo
199                         elif expr "$response" : '[Nn]' >/dev/null
200                         then
201                                 mountpoint=""
202                         else
203                                 response=""
204                         fi
205                 done
206         elif [ $ncdroms = 1 ]
207         then
208                 mountpoint="`cat $tp.l`"
209                 perl -ne 'print if s/ type iso9660 \([^)]*\)$// && s/ on .*$//;' \
210                         <$tp.m >$tp.d
211                 blockdevice="`cat $tp.d`"
212                 yesno yes \
213         "I see a CD-ROM: $blockdevice, mounted on $mountpoint.  Is it the right one ?"
214                 if [ $yesno = no ]
215                 then
216                         echo 'Unmounting it ...'
217                         umount="$mountpoint"
218                         while true
219                         do
220                                 echo -n \
221         'Please insert the right disc, and hit return:  '
222                                 read response
223                                 if mount -rt iso9660 -o nosuid,nodev \
224                                         "$blockdevice" "$mountpoint"
225                                 then
226                                         echo
227                                         break
228                                 fi
229                         done
230                 fi
231         fi
232         if [ -z "$mountpoint" ]
233         then
234                 if [ -b /dev/cdrom ]
235                 then
236                         echo \
237         'I see that /dev/cdrom exists and is a block device.'
238                         newdefaultdevice=/dev/cdrom
239                 fi
240                 getblockdev 'Insert the CD-ROM and enter the block device name'
241         fi
242 fi
243
244 if [ $option = nfs ]
245 then
246         mountpoint="$vardir/methods/mnt"
247         while [ -z "$nfsserver" ]
248         do
249                 echo -n \
250 "What is the name of the NFS server ? [$defaultnfsserver]  "
251                 read response
252                 if [ -z "$response" ] && [ -n "$defaultnfsserver" ]
253                 then
254                         response="$defaultnfsserver"
255                 fi
256                 if [ -z "$response" ]; then continue; fi
257                 if [ -x "`which rpcinfo`" ]
258                 then
259                         if rpcinfo -u "$response" mountd | grep -q 'ready'
260                         then
261                                 nfsserver="$response"
262                         else
263                                 echo "$response appears not to be an NFS server."
264                         fi
265                 elif [ -x "`which ping`" ]
266                 then
267                         if ping -q -c 1 "$response" | grep -q ', 1 packets received'
268                         then
269                                 nfsserver="$response"
270                         else
271                                 echo "$response appears to be down or nonexistent."
272                         fi
273                 else
274                         echo \
275 "(I can't check that now because there is no rpcinfo or ping.)"
276                         nfsserver="$response"
277                 fi
278         done
279         while [ -z "$nfsrempath" ]
280         do
281                 echo -n "
282 What is the pathname on the NFS server of the filesystem with
283 the Debian files? [$defaultnfsrempath]  "
284                 read response
285                 if [ -z "$response" ] && [ -n "$defaultnfsrempath" ]
286                 then
287                         response="$defaultnfsrempath"
288                 else
289                         response="`echo \"$response\" | sed -e 's:/$::; s:^/*:/:'`"
290                 fi
291                 umount="$mountpoint"
292                 if mount -rt nfs -o nosuid,nodev "$nfsserver:$response" "$mountpoint"
293                 then
294                         echo
295                         nfsrempath="$response"
296                 else
297                         umount=""
298                         echo \
299 "Unable to mount NFS filesystem $nfsserver:$response."
300                 fi
301         done
302         nfs="$nfsserver:$nfsrempath"
303 fi
304
305 if [ $option = harddisk ]
306 then
307         set +e
308         print_partition_table /dev/hda >$tp.f
309         if [ $? != 0 ]
310         then
311                 print_partition_table /dev/sda >$tp.f
312         fi
313         set -e
314         perl -ne '
315 next unless /^ *Device +Boot +Start +End +Blocks +Id +System *$/i .. !/\S/;
316 next unless / [146] +DOS \d+-bit \S+$/;
317 next unless m:^/\S+:p;
318 print ${^MATCH};                ' <$tp.f >$tp.d
319         newdefaultdevice="`cat $tp.d`"
320         echo "
321 I need to know which disk partition contains the distribution files;
322 disk partitions are specified by the block device name in Linux."
323         if [ -n "$newdefaultdevice" ]
324         then
325                 echo \
326 "By the way, $newdefaultdevice looks like a DOS partition."
327         fi
328         getblockdev "Enter the partition's block device name"
329 fi
330
331 if [ -n "$mountpoint" ]
332 then
333         # We must have $mountpoint
334         if [ $option = cdrom ]
335         then
336                 echo \
337 'All directory names should be entered relative to the root of the CD-ROM.
338 '
339         elif [ $option = nfs ]
340         then
341                 echo \
342 "All directory names should be entered relative to the root of the NFS
343 filesystem, ie relative to $nfsrempath on the server.
344 "
345         else
346                 echo \
347 "All directory names should be entered relative to the root of the
348 $fstype filesystem on $blockdevice.
349 "
350         fi
351 fi
352
353 while true
354 do
355         if [ $option = cdrom ]
356         then
357                 echo \
358 "I would like to know where on the CD-ROM the top level of the Debian
359 distribution is (eg. 'dists/stable') - this directory usually contains the
360 Packages-Master file.
361
362 If the CD-ROM is badly organised and doesn't have a straightforward copy of
363 the distribution you may answer 'none' and we'll go through the parts
364 I need individually."
365         else
366                 echo \
367 "In order to make it easy for me to find the relevant files I'd ideally
368 like to install from a straightforward copy of the Debian distribution.
369 To use this I'll need to know where the top level of that copy of the
370 distribution is (eg. 'debian/dists/stable') - this directory usually
371 contains the Packages-Master file.
372
373 If you do not have a straightforward copy of the distribution available
374 just answer 'none' and we'll go through the parts I need individually."
375         fi
376         defhierbase=none
377 # maybe ask for debian/dists and then show and ask for available dists
378 # eg. {stable,frozen,unstable,bo,hamm,slink}
379         if [ -n "$p_hierbase" ]
380         then
381                 if [ -d "$mountpoint/$p_hierbase/main/binary-$iarch" ]
382                 then
383                         echo "
384 Last time you said '$p_hierbase', and that looks plausible."
385                         defhierbase="$p_hierbase"
386                 else
387                         echo "
388 Last time you said '$p_hierbase', but that doesn't look plausible,
389 since '$p_hierbase/main/binary-$iarch' doesn't seem to exist."
390                 fi
391         fi
392         if [ none = "$defhierbase" ]
393         then
394                 if [ -d "$mountpoint/debian/dists/stable/main/binary-$iarch" ]
395                 then
396                         echo "
397 '/debian/dists/stable' exists and looks plausible, so that's the default."
398                         defhierbase=/debian/dists/stable
399                 elif [ -d "$mountpoint/dists/stable/main/binary-$iarch" ]
400                 then
401                         echo "
402 '/dists/stable' exists and looks plausible, so that's the default."
403                         defhierbase=/dists/stable
404                 fi
405         fi
406         echo -n \
407 "Distribution top level ? [$defhierbase]  "
408         read response
409         if [ -z "$response" ]
410         then
411                 response="$defhierbase"
412         fi
413         if [ none = "$response" ]
414         then
415                 hierbase=""
416                 break
417         elif [ -d "$mountpoint/$response/main/binary-$iarch" ]
418         then
419                 hierbase="`echo \"$response\" | sed -e 's:/*$::; s:^/*:/:'`"
420                 break
421         fi
422         echo \
423 "$response/main/binary-$iarch does not exist.
424 "
425 done
426
427
428 case "$hierbase" in
429 /* )    ;;
430 '' )    ;;
431 * )     hierbase="/$hierbase" ;;
432 esac
433
434 check_binary () {
435         # args: area-in-messages directory
436         # eg:   main             "$hierbase/main/binary-$iarch"
437         # checks whether $2 contains *.deb
438         if ! [ -d "$mountpoint$2/" ]
439         then
440                 echo "'$2' does not exist."
441                 return
442         fi
443
444         if ! ( find -L "$mountpoint$2/" -name '*.deb' -print \
445                 | head -n 1 ) 2>/dev/null  | grep . >/dev/null
446         then
447                 echo "'$2' does not contain any *.deb packages.  Hmmpf."
448                 return
449         fi
450         echo "Using '$2' as $1 binary dir."
451         this_binary="$2"
452 }
453
454 find_area () {
455         # args: area-in-messages area-in-vars subdirectory-in-hier
456         #       last-time-binary last-time-packages
457         # eg:   main             main         main
458         #       "$p_main_binary" "$p_main_packages"
459
460         this_binary=''
461         this_packages=''
462         if [ -n "$hierbase" ]
463         then
464                 check_binary $1 "$hierbase/$3/binary-$iarch"
465         fi
466
467         if [ $option = cdrom ] && [ $2 = nf ] && [ -z "$this_binary" ]
468         then
469                 echo "
470 Note: most CD-ROM distributions of Debian do not include programs
471 available in the 'non-free' directory of the distribution site.
472 This is because these programs have copyrights that prevent
473 distribution for profit on a CD-ROM - ie they are not free software.
474 If you wish to install these programs you'll have to get them from an
475 alternative source."
476         elif [ $2 = lcl ] && [ -z "$this_binary" ]
477         then
478                 echo "
479 Note: By default there is no 'local' directory. It is intended for
480 packages you made yourself."
481         fi
482         while [ -z "$this_binary" ]
483         do
484                 defaultbinary="$4"
485                 echo "
486 Which directory contains the *.deb packages from the $1 distribution
487 area (this directory is named '$3/binary-$iarch' on the distribution site) ?
488 Say 'none' if this area is not available."
489                 if [ $2 != main ] && [ -z "$defaultbinary" ]
490                 then
491                         defaultbinary=none
492                 fi
493                 echo -n \
494 "Enter _$1_ binary dir. [$4]
495  ?  "
496                 read response
497                 if [ -z "$response" ] && [ -n "$defaultbinary" ]
498                 then
499                         response="$defaultbinary"
500                 fi
501                 if [ none = "$response" ]
502                 then
503                         break
504                 fi
505                 case "$response" in
506                 '' | none)      continue                ;;
507                 esac
508                 check_binary $1 "`echo \"$response\" | sed -e 's:/$::; s:^/*:/:'`"
509         done
510         if [ -n "$this_binary" ]
511         then
512                 for f in Packages.gz packages.gz Packages packages
513                 do
514                         if [ -f "$mountpoint/$this_binary/$f" ]
515                         then
516                                 echo "Using '$this_binary/$f' for $1."
517                                 this_packages="$this_binary/$f"
518                                 break
519                         fi
520                 done
521                 while [ -z "$this_packages" ]
522                 do
523                         echo -n "
524 I can't find the $1 'Packages' file.  The information in the
525 'Packages' file is important for package selection during new
526 installations, and is very useful for upgrades.
527
528 If you overlooked it when downloading you should do get it now and
529 return to this installation procedure when you have done so: you will
530 find one Packages file and one Packages.gz file -- either will do --
531 in the 'binary-$iarch' subdirectory of each area on the FTP sites and
532 CD-ROMs.  Alternatively (and this will be rather slow) I can scan the
533 packages in the distribution area - say 'scan' if you want me to do so.
534
535 You need a separate Packages file from each of the distribution areas
536 you wish to install.
537
538 Where is the _$1_ 'Packages' file (if none is available, say 'none')
539 [$5]
540  ?  "
541                         read response
542                         if [ -z "$response" ] && [ -n "$5" ]
543                         then
544                                 response="$5"
545                         fi
546                         case "$response" in
547                         '')             continue                        ;;
548                         none)           break                           ;;
549                         scan)           this_packages=scan              ;;
550                         /*)             this_packages="$response"       ;;
551                         *)              this_packages="/$response"      ;;
552                         esac
553                 done
554         fi
555         eval $2'_binary="$this_binary"'
556         eval $2'_packages="$this_packages"'
557 }
558
559 find_area main main main "$p_main_binary" "$p_main_packages"
560 find_area contrib ctb contrib "$p_ctb_binary" "$p_ctb_packages"
561 find_area non-free nf non-free "$p_nf_binary" "$p_nf_packages"
562 find_area non-US nus non-US "$p_nus_binary" "$p_nus_packages"
563 find_area local lcl local "$p_lcl_binary" "$p_lcl_packages"
564
565 echo -n '
566 Hit RETURN to continue.  '
567 read response
568
569 exec 3>shvar.$option.new
570
571 outputparam p_blockdev "$blockdevice"
572 outputparam p_fstype "$fstype"
573 outputparam p_mountpoint "$mountpoint"
574 outputparam p_nfsserver "$nfsserver"
575 outputparam p_nfsrempath "$nfsrempath"
576 outputparam p_nfs "$nfs"
577 outputparam p_hierbase "$hierbase"
578
579 outputparam p_main_packages "$main_packages"
580 outputparam p_main_binary "$main_binary"
581 outputparam p_ctb_packages "$ctb_packages"
582 outputparam p_ctb_binary "$ctb_binary"
583 outputparam p_nf_packages "$nf_packages"
584 outputparam p_nf_binary "$nf_binary"
585 outputparam p_nus_packages "$nus_packages"
586 outputparam p_nus_binary "$nus_binary"
587 outputparam p_lcl_packages "$lcl_packages"
588 outputparam p_lcl_binary "$lcl_binary"
589
590 mv shvar.$option.new shvar.$option
591
592 xit=0