| #!/bin/sh |
| # |
| # The `multicd' package was initially written by Heiko Schlittermann |
| # <heiko@lotte.sax.de> based on builtin access methods written by Ian |
| # Jackson <ian@chiark.greenend.org.uk>. The final packaging as well as |
| # cleanups were made by Martin Schulze <joey@infodrom.north.de> who also |
| # put this package together for the slink release (Debian GNU/Linux |
| # 2.1). |
| |
| # Copyright © 1995-1998 Ian Jackson <ian@chiark.greenend.org.uk> |
| # Copyright © 1998 Heiko Schlittermann <heiko@lotte.sax.de> |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; version 2 dated June, 1991. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| |
| set -e |
| vardir="$1" |
| method=$2 |
| option=$3 |
| |
| test -d "$vardir/methods/$method" || mkdir "$vardir/methods/$method" |
| cd "$vardir/methods/$method" |
| tp=/tmp/ddm$$ |
| |
| iarch=`dpkg --print-architecture` |
| dist=stable |
| |
| xit=1 |
| trap ' |
| rm -f $tp.? |
| if [ -n "$umount" ] |
| then |
| umount "$umount" >/dev/null 2>&1 |
| fi |
| exit $xit |
| ' 0 |
| |
| if ls -d "$tp.?" >/dev/null 2>&1 |
| then |
| rm $tp.? |
| fi |
| |
| #debug() { echo "DEBUG: $@"; } |
| debug() { true; } |
| ismulti() { debug $1 $2; test -e "$1/.disk/info" || test -e "$1$2/.disk/info"; } |
| |
| # 1/ mountpoint |
| # 2/ hierarchy |
| getdisklabel () { |
| debug "$1" "$2" |
| if [ -f $1/.disk/info ] |
| then |
| echo -n `head -1 "$1/.disk/info"` |
| else |
| if [ -f $1$2/.disk/info ] |
| then |
| echo -n `head -1 "$1$2/.disk/info"` |
| else |
| echo -n 'Non-Debian disc' |
| fi |
| fi |
| } |
| |
| yesno () { |
| while true |
| do |
| echo -n "$2 [$1] " |
| read response |
| if [ -z "$response" ] |
| then |
| response="$1" |
| fi |
| case "$response" in |
| [Nn]*) yesno=no ; return ;; |
| [Yy]*) yesno=yes ; return ;; |
| esac |
| done |
| } |
| |
| getblockdev () { |
| mountpoint="$vardir/methods/mnt" |
| if [ -z "$defaultdevice" ] |
| then |
| defaultdevice="$newdefaultdevice" |
| elif [ "$defaultdevice" != "$newdefaultdevice" ] |
| then |
| echo \ |
| "Last time you specified installation from $defaultdevice." |
| fi |
| promptstring="$1" |
| while [ -z "$blockdevice" ] |
| do |
| echo -n "$promptstring [$defaultdevice]: " |
| read response |
| if [ -z "$response" ] |
| then |
| response="$defaultdevice" |
| fi |
| if [ ! -b "$response" ] |
| then |
| echo "$response is not a block device - will try as loopback."; |
| loop=",loop" |
| fi |
| tryblockdevice="$response" |
| if [ $option = multi_cd ] |
| then |
| fstype=iso9660 |
| elif [ $option = harddisk2 ] |
| then |
| blockbase="`echo \"$tryblockdevice\" | sed -e 's/[0-9]\{1,\}$//'`" |
| set +e |
| printf 'p\nq\n' | fdisk "$blockbase" 2>/dev/null >$tp.f |
| set -e |
| proposeddevice="$tryblockdevice" perl -ne ' |
| next unless /^ *Device +Boot +Begin +Start +End +Blocks +Id +System *$/i .. !/\S/; |
| next unless s:^/\S+:: && $& eq $ENV{"proposeddevice"}; |
| next unless s/^ +(\* +)?\d+ +\d+ +\d+ +\d+\+? +//; |
| next unless m/^([0-9a-f]{1,2}) /i; |
| %types= ( "1","msdos", "4","msdos", "6","msdos", "7","hpfs", "80","minix", |
| "81","minix", "83","ext2" ); |
| print $types{$1}; exit(0); ' <$tp.f >$tp.m |
| defaultfstype="`cat $tp.m`" |
| if [ -n "$defaultfstype" ] |
| then |
| cat <<END |
| The partition table for $blockbase claims that $tryblockdevice |
| contains filesystem type $defaultfstype. |
| END |
| if ! grep " $defaultfstype$" /proc/filesystems >/dev/null |
| then |
| echo \ |
| "Your kernel does not appear to support that filesystem type." |
| defaultfstype="" |
| fi |
| fi |
| echo -n "Supported filesystems: " |
| sed -e 's/^.* / /' /proc/filesystems | tr '\n' ' ' |
| echo -n " |
| Enter filesystem type (for $tryblockdevice) [$defaultfstype]: " |
| read fstype |
| if [ -z "$fstype" ] |
| then |
| fstype="$defaultfstype" |
| fi |
| fi |
| umount="$mountpoint" |
| if mount -rt "$fstype" -o nosuid,nodev$loop "$tryblockdevice" "$mountpoint" |
| then |
| echo |
| blockdevice="$tryblockdevice" |
| else |
| umount="" |
| echo \ |
| "Unable to mount $tryblockdevice on $mountpoint, type $fstype." |
| fi |
| done |
| } |
| |
| outputparam () { |
| echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3 |
| } |
| |
| ## MAIN |
| intrkey="`stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p'`" |
| echo " |
| If you make a mistake, use the interrupt key ($intrkey) to abort. |
| " |
| |
| # State variables, `best first' |
| # {main,ctb,nf,nonus,nonusctb,nonusnf,lcl}_{packages,binary} |
| # Empty before we've found them or if they're not available, |
| # set to the relevant bit under mountpoint otherwise. |
| # hierbase |
| # A directory containing a Debian FTP site mirror tree. |
| # mountpoint |
| # The mountpoint for the filesystem containing the stuff |
| # empty or unset if we don't know yet, or if we haven't mounted anything; |
| # may also be empty if `directory' was set. |
| # blockdevice |
| # The actual block device to mount. |
| # fstype |
| # The filesystem type to use. |
| # defaultdevice |
| # The default block device to mount. |
| |
| p_usedevel=no |
| if [ -f shvar.$option ] |
| then |
| . ./shvar.$option |
| defaultdevice="$p_blockdev" |
| defaultnfsserver="$p_nfsserver" |
| defaultnfsrempath="$p_nfsrempath" |
| usedevel="$p_usedevel" |
| fi |
| |
| if [ $option = multi_cd ] |
| then |
| mount >$tp.m |
| sed -n 's/ ([^)]*)$//; s/^[^ ]* on //; s/ type iso9660$//p' <$tp.m >$tp.l |
| ncdroms=`wc -l <$tp.l` |
| if [ $ncdroms -gt 1 ] |
| then |
| response="" |
| while [ -z "$response" ] |
| do |
| echo \ |
| 'Several CD-ROMs (or other ISO9660 filesystems) are mounted:' |
| egrep 'type iso9660 \([^)]*\)$' <$tp.m | nl |
| echo -n \ |
| 'Is it any of these ? Type a number, or `n'\'' for none. ' |
| read response |
| response="`echo \"$response\" | sed -e 's/[ ]*$//'`" |
| if expr "$response" : '[0-9][0-9]*$' >/dev/null && \ |
| [ $response -ge 1 -a $response -le $ncdroms ] |
| then |
| mountpoint="`sed -n $response'p' <$tp.l`" |
| echo |
| elif expr "$response" : '[Nn]' >/dev/null |
| then |
| mountpoint="" |
| else |
| response="" |
| fi |
| done |
| elif [ $ncdroms = 1 ] |
| then |
| mountpoint="`cat $tp.l`" |
| perl -ne 'print if s/ type iso9660 \([^)]*\)$// && s/ on .*$//;' \ |
| <$tp.m >$tp.d |
| blockdevice="`cat $tp.d`" |
| yesno yes \ |
| "I see a CD-ROM: $blockdevice, mounted on $mountpoint. Is it the right one ?" |
| if [ $yesno = no ] |
| then |
| echo 'Unmounting it ...' |
| umount="$mountpoint" |
| while true |
| do |
| echo -n \ |
| 'Please insert the right disc, and hit return: ' |
| read response |
| if mount -rt iso9660 -o nosuid,nodev \ |
| "$blockdevice" "$mountpoint" |
| then |
| echo |
| break |
| fi |
| done |
| fi |
| fi |
| if [ -z "$mountpoint" ] |
| then |
| if [ -b /dev/cdrom ] |
| then |
| echo \ |
| 'I see that /dev/cdrom exists and is a block device.' |
| newdefaultdevice=/dev/cdrom |
| fi |
| getblockdev 'Insert the CD-ROM and enter the block device name' |
| fi |
| fi |
| |
| if [ $option = multi_nfs ] |
| then |
| mountpoint="$vardir/methods/mnt" |
| while [ -z "$nfsserver" ] |
| do |
| echo -n \ |
| "What is the name of the NFS server ? [$defaultnfsserver] " |
| read response |
| if [ -z "$response" -a -n "$defaultnfsserver" ] |
| then |
| response="$defaultnfsserver" |
| fi |
| if [ -z "$response" ]; then continue; fi |
| if [ -x /usr/bin/rpcinfo ] |
| then |
| if rpcinfo -u "$response" mountd >/dev/null |
| then |
| nfsserver="$response" |
| else |
| echo "$response appears not to be an NFS server." |
| fi |
| elif [ -x /bin/ping ] |
| then |
| if ping -q -c 1 "$response" | grep -q ', 1 packets received' |
| then |
| nfsserver="$response" |
| else |
| echo "$response appears to be down or nonexistent." |
| fi |
| else |
| echo \ |
| "(I can't check that now because there is no /usr/bin/rpcinfo or /bin/ping.)" |
| nfsserver="$response" |
| fi |
| done |
| while [ -z "$nfsrempath" ] |
| do |
| echo -n " |
| What is the pathname on the NFS server of the filesystem with |
| the Debian files ? [$defaultnfsrempath] " |
| read response |
| if [ -z "$response" -a -n "$defaultnfsrempath" ] |
| then |
| response="$defaultnfsrempath" |
| else |
| response="`echo \"$response\" | sed -e 's:/$::; s:^/*:/:'`" |
| fi |
| umount="$mountpoint" |
| if mount -rt nfs -o nosuid,nodev "$nfsserver:$response" "$mountpoint" |
| then |
| echo |
| nfsrempath="$response" |
| else |
| umount="" |
| echo \ |
| "Unable to mount NFS filesystem $nfsserver:$response." |
| fi |
| done |
| nfs="$nfsserver:$nfsrempath" |
| fi |
| |
| if [ $option = harddisk2 ] |
| then |
| set +e |
| printf 'p\nq\n' | fdisk /dev/hda 2>/dev/null >$tp.f |
| if [ $? != 0 ] |
| then |
| printf 'p\nq\n' | fdisk /dev/sda 2>/dev/null >$tp.f |
| fi |
| set -e |
| perl -ne ' |
| next unless /^ *Device +Boot +Begin +Start +End +Blocks +Id +System *$/i .. !/\S/; |
| next unless / [146] +DOS \d+-bit \S+$/; |
| next unless m:^/\S+:; |
| print $&; ' <$tp.f >$tp.d |
| newdefaultdevice="`cat $tp.d`" |
| echo " |
| I need to know which disk partition contains the distribution files; |
| disk partitions are specified by the block device name in Linux." |
| if [ -n "$newdefaultdevice" ] |
| then |
| echo \ |
| "By the way, $newdefaultdevice looks like a DOS partition." |
| fi |
| getblockdev "Enter the partition's block device name" |
| fi |
| |
| if [ -n "$mountpoint" ] |
| then |
| # We must have $mountpoint |
| if [ $option = multi_cd ] |
| then |
| echo \ |
| 'All directory names should be entered relative to the root of the CD-ROM. |
| ' |
| elif [ $option = multi_nfs ] |
| then |
| echo \ |
| "All directory names should be entered relative to the root of the NFS |
| filesystem, ie relative to $nfsrempath on the server. |
| " |
| else |
| echo \ |
| "All directory names should be entered relative to the root of the |
| $fstype filesystem on $blockdevice. |
| " |
| fi |
| fi |
| |
| # now try to get the users idea where the debian |
| # hierarchy start below the mointpoint |
| |
| debug "mountpoint: $mountpoint" |
| while true |
| do |
| if ismulti "${mountpoint}" "${hierbase}"; then |
| multi=yes |
| fi |
| |
| if [ $option = multi_cd ] |
| then |
| echo \ |
| "I would like to know where on the CD-ROM the top level of the Debian |
| distribution is - this will usually contain the \`dists' directory. |
| |
| If the CD-ROM is badly organized and doesn't have a straightforward copy of |
| the distribution you may answer \`none' and we'll go through the parts |
| I need individually." |
| else |
| echo \ |
| "In order to make it easy for me to find the relevant files I'd ideally |
| like to install from a straightforward copy of the Debian distribution. |
| To use this I'll need to know where the top level of that copy of the |
| distribution is - this directory usually contains the Packages-Master file. |
| |
| If you do not have a straightforward copy of the distribution available |
| just answer \`none' and we'll go through the parts I need individually." |
| fi |
| |
| defhierbase=none |
| if [ -n "$p_hierbase" ]; then |
| if [ -d "$mountpoint/$p_hierbase/dists/$dist/main/binary-$iarch" \ |
| -o -n "$multi" ]; then |
| echo "Last time you said \`$p_hierbase', and that looks plausible." |
| defhierbase="$p_hierbase" |
| else |
| echo " |
| Last time you said \`$p_hierbase', but that doesn't look plausible, |
| since \`$p_hierbase/dists/$dist/main/binary-$iarch' doesn't seem to exist. |
| And I can't get the impression that you're using a multi-CD set." |
| fi |
| fi |
| |
| # at this point defhierbase is set if it looks plausible |
| # if `none' was entered, we assume a CD with a debian/ directory |
| |
| if [ none = "$defhierbase" -a -d "$mountpoint/debian/dists/$dist/main/binary-$iarch" ] |
| then |
| echo "\`/debian' exists and looks plausible, so that's the default." |
| defhierbase=/debian |
| fi |
| |
| echo -n "Distribution top level ? [$defhierbase] " |
| read response |
| if [ -z "$response" ]; then response="$defhierbase"; fi |
| if [ none = "$response" ]; then |
| hierbase="" |
| break |
| elif ismulti "$mountpoint" "$response" && [ -z "$multi" ]; then |
| multi=yes |
| fi |
| |
| if ! [ -d "$mountpoint/$response/dists/$dist/main/binary-$iarch" \ |
| -o -n "$multi" ]; then |
| echo \ |
| "Neither $response/dists/$dist/main/binary-$iarch does not exist, |
| nor are you using a multi-CD set" |
| break |
| fi |
| |
| hierbase="`echo \"$response\" | sed -e 's:/$::; s:^/*:/:; s:/\+:/:g;'`" |
| debug "hierbase: [$hierbase]" |
| |
| if [ -n "$multi" ]; then |
| disklabel=`getdisklabel "$mountpoint" "/$response"` |
| echo "Ok, this is disc" |
| echo " $disklabel" |
| #echo "Updating multi CD contents file cache ..." |
| #multi_contentsfile="${mountpoint}/${response}/.disk/contents.gz" |
| #zcat "$multi_contentsfile" > disk-contents.$option |
| fi |
| |
| break; |
| done |
| |
| distribution=$dist |
| if [ -n "$hierbase" ] |
| then |
| if [ -d "$mountpoint/$hierbase/dists/unstable/binary-$iarch" ] |
| then |
| echo \ |
| ' |
| Both a stable released distribution and a work-in-progress |
| development tree are available for installation. Would you like to |
| use the unreleased development tree (this is only recommended for |
| experts who like to live dangerously and want to help with testing) ?' |
| yesno "$p_usedevel" 'Use unreleased development distribution ?' |
| usedevel="$yesno" |
| if [ "$usedevel" = yes ] |
| then |
| distribution=development |
| fi |
| else |
| usedevel=no |
| fi |
| echo |
| fi |
| |
| case "$hierbase" in |
| /* ) ;; |
| '' ) ;; |
| * ) hierbase="/$hierbase" ;; |
| esac |
| |
| check_binary () { |
| # args: area-in-messages directory |
| debug "check_binary($@)" |
| |
| if [ ! -d "${mountpoint}$2" -a -z "$multi" ] |
| then |
| echo "\`$2' does not exist." |
| return |
| fi |
| |
| # In this special case it is ok for a sub-distribution to not contain any |
| # .deb files. Each CD should contain all Packages.cd files but doesn't |
| # need to contain the .deb files. |
| # |
| # if ! { find -L "$mountpoint$2" -name '*.deb' -print \ |
| # | head -1 | grep . ; } >/dev/null 2>&1 && [ -z "$multi" ]; |
| # then |
| # echo "\`$2' does not contain any *.deb packages." |
| # return |
| # fi |
| |
| this_binary="$2" |
| echo -n "Using \`$this_binary' as $1 binary dir" |
| |
| if [ -n "$multi" ]; then |
| this_disk=`getdisklabel ${mountpoint} "/$hierbase"` |
| echo " from disc" |
| echo " \`$this_disk'" |
| else |
| echo "" |
| fi |
| } |
| |
| find_area () { |
| # args: area-in-messages area-in-vars subdirectory-in-hier |
| # last-time-binary last-time-packages |
| debug "find_area($@)" |
| this_binary='' |
| this_packages='' |
| this_disk='' |
| if [ -n "$hierbase" ] |
| then |
| check_binary $1 `echo "$hierbase/dists/$3/$1/binary-$iarch" | sed 's:/\+:/:g'` |
| debug "THIS_BINARY $this_binary" |
| fi |
| if [ $option = multi_cd -a $2 = nf -a -z "$this_binary" ] |
| then |
| echo ' |
| Note: most CD-ROM distributions of Debian do not include programs |
| available in the `non-free'\'' directory of the distribution site. |
| This is because these programs have copyrights that prevent |
| distribution for profit on a CD-ROM - ie they are not free software. |
| If you wish to install these programs you'\''ll have to get them from an |
| alternative source.' |
| fi |
| while [ -z "$this_binary" ] |
| do |
| defaultbinary="$4" |
| echo " |
| Which directory contains the *.deb packages from the $1 distribution |
| area (this directory is named \`$3/binary' on the distribution site) ? |
| Say \`none' if this area is not available." |
| if [ $2 != main -a -z "$defaultbinary" ] |
| then |
| defaultbinary=none |
| fi |
| echo -n \ |
| "Enter _$1_ binary dir. [$4] |
| ? " |
| read response |
| if [ -z "$response" -a -n "$defaultbinary" ] |
| then |
| response="$defaultbinary" |
| fi |
| if [ none = "$response" ] |
| then |
| break |
| fi |
| case "$response" in |
| '' | none) continue ;; |
| esac |
| check_binary $1 "`echo \"$response\" | sed -e 's:/$::; s:^/*:/:'`" |
| done |
| if [ -n "$this_binary" ] |
| then |
| if [ "$multi" = "yes" ]; then |
| for f in Packages.cd.gz packages.cd.gz Packages.cd packages.cd |
| do |
| if [ -f "$mountpoint/$this_binary/$f" ] |
| then |
| this_packages="$this_binary/$f" |
| echo "Using \`$this_packages' for $1." |
| break |
| fi |
| done |
| else |
| if [ -f "${mountpoint}${hierbase}/.disk/packages/$1/Packages.gz" ]; then |
| this_packages=`echo "${hierbase}/.disk/packages/$1/Packages.gz"|sed 's:/\+:/:g'` |
| echo "Using \`${this_packages}' for $1." |
| fi |
| fi |
| while [ -z "$this_packages" ] |
| do |
| echo -n " |
| I can't find the $1 \`Packages.cd' file. The information in the |
| \`Packages.cd' file is important for package selection during new |
| installations, and is very useful for upgrades. |
| |
| If you overlooked it when downloading you should do get it now and |
| return to this installation procedure when you have done so: you will |
| find one Packages.cd file and one Packages.cd.gz file -- either will do -- |
| in the \`binary' subdirectory of each area on the FTP sites and |
| CD-ROMs. Alternatively (and this will be rather slow) I can scan the |
| packages in the distribution area - say \`scan' if you want me to do so. |
| |
| You need a separate Packages.cd file from each of the distribution areas |
| you wish to install. |
| |
| Where is the _$1_ \`Packages.cd' file (if none is available, say \`none') |
| [$5] |
| ? " |
| read response |
| if [ -z "$response" -a -n "$5" ] |
| then |
| response="$5" |
| fi |
| case "$response" in |
| '') break ;; |
| none) break ;; |
| scan) this_packages=scan ;; |
| /*) this_packages="$response" ;; |
| *) this_packages="/$response" ;; |
| esac |
| done |
| fi |
| eval $2'_binary="$this_binary"' |
| eval $2'_packages="$this_packages"' |
| eval $2'_disk="$this_disk"' |
| } |
| |
| find_area main main "$distribution" "$p_main_binary" "$p_main_packages" |
| find_area contrib ctb "$distribution" "$p_ctb_binary" "$p_ctb_packages" |
| find_area non-free nf "$distribution" "$p_nf_binary" "$p_nf_packages" |
| find_area non-US/main nonus "$distribution" "$p_nonus_binary" "$p_nonus_packages" |
| find_area non-US/contrib nonusctb "$distribution" "$p_nonusctb_binary" "$p_nonusctb_packages" |
| find_area non-US/non-free nonusnf "$distribution" "$p_nonusnf_binary" "$p_nonusnf_packages" |
| find_area local lcl local "$p_lcl_binary" "$p_lcl_packages" |
| |
| echo -n ' |
| Hit RETURN to continue. ' |
| read response |
| |
| exec 3>shvar.$option.new |
| |
| outputparam p_blockdev "$blockdevice" |
| outputparam p_fstype "$fstype" |
| outputparam p_mountpoint "$mountpoint" |
| outputparam p_nfsserver "$nfsserver" |
| outputparam p_nfsrempath "$nfsrempath" |
| outputparam p_nfs "$nfs" |
| outputparam p_hierbase "$hierbase" |
| outputparam p_usedevel "$usedevel" |
| outputparam p_main_packages "$main_packages" |
| outputparam p_main_binary "$main_binary" |
| outputparam p_main_disk "$main_disk" |
| outputparam p_ctb_packages "$ctb_packages" |
| outputparam p_ctb_binary "$ctb_binary" |
| outputparam p_ctb_disk "$ctb_disk" |
| outputparam p_nf_packages "$nf_packages" |
| outputparam p_nf_binary "$nf_binary" |
| outputparam p_nf_disk "$nf_disk" |
| outputparam p_nonus_binary "$nonus_binary" |
| outputparam p_nonus_packages "$nonus_packages" |
| outputparam p_nonus_disk "$nonus_disk" |
| outputparam p_nonusctb_binary "$nonusctb_binary" |
| outputparam p_nonusctb_packages "$nonusctb_packages" |
| outputparam p_nonusctb_disk "$nonusctb_disk" |
| outputparam p_nonusnf_binary "$nonusnf_binary" |
| outputparam p_nonusnf_packages "$nonusnf_packages" |
| outputparam p_nonusnf_disk "$nonusnf_disk" |
| outputparam p_lcl_packages "$lcl_packages" |
| outputparam p_lcl_binary "$lcl_binary" |
| outputparam p_multi "$multi" |
| outputparam p_multi_contentsfile "$multi_contentsfile" |
| |
| mv shvar.$option.new shvar.$option |
| |
| xit=0 |
| |
| # vim:ts=4:sw=4:aw:ai: |