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