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
16set -e
17vardir="$1"
18method=$2
19option=$3
20
21cd "$vardir/methods/disk"
22tp=/var/run/ddm$$
23
24iarch=`dpkg --admindir $vardir --print-architecture`
25
26xit=1
27trap '
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
36if ls -d "$tp.?" >/dev/null 2>&1
37then
38	rm $tp.?
39fi
40
41yesno () {
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
57print_partition_table()
58{
59	device="$1"
60
61	printf "p\nq\n" | fdisk "$device" 2>/dev/null
62}
63
64getblockdev () {
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 '
98next unless /^ *Device +Boot +Start +End +Blocks +Id +System *$/i .. !/\S/;
99next unless s:^/\S+::p && ${^MATCH} eq $ENV{proposeddevice};
100next unless s/^ +(\* +)?\d+ +\d+ +\d+\+? +//;
101next 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" );
104print $types{$1}; exit(0);	' <$tp.f >$tp.m
105			defaultfstype="`cat $tp.m`"
106			if [ -n "$defaultfstype" ]
107			then
108				cat <<END
109The partition table for $blockbase claims that $tryblockdevice
110contains filesystem type $defaultfstype.
111END
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 "
122Enter 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
142outputparam () {
143	echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3
144}
145
146intrkey="`stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p'`"
147echo "
148If you make a mistake, use the interrupt key ($intrkey) to abort.
149"
150
151# State variables, “best first”
152#  {main,ctb,nf,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
169if [ -f shvar.$option ]
170then
171	. ./shvar.$option
172	defaultdevice="$p_blockdev"
173	defaultnfsserver="$p_nfsserver"
174	defaultnfsrempath="$p_nfsrempath"
175fi
176
177if [ $option = cdrom ]
178then
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
242fi
243
244if [ $option = nfs ]
245then
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 "
282What is the pathname on the NFS server of the filesystem with
283the 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"
303fi
304
305if [ $option = harddisk ]
306then
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 '
315next unless /^ *Device +Boot +Start +End +Blocks +Id +System *$/i .. !/\S/;
316next unless / [146] +DOS \d+-bit \S+$/;
317next unless m:^/\S+:p;
318print ${^MATCH};		' <$tp.f >$tp.d
319	newdefaultdevice="`cat $tp.d`"
320	echo "
321I need to know which disk partition contains the distribution files;
322disk 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"
329fi
330
331if [ -n "$mountpoint" ]
332then
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
343filesystem, 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
351fi
352
353while true
354do
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
359distribution is (eg. 'dists/stable') - this directory usually contains the
360Packages-Master file.
361
362If the CD-ROM is badly organised and doesn't have a straightforward copy of
363the distribution you may answer 'none' and we'll go through the parts
364I need individually."
365	else
366		echo \
367"In order to make it easy for me to find the relevant files I'd ideally
368like to install from a straightforward copy of the Debian distribution.
369To use this I'll need to know where the top level of that copy of the
370distribution is (eg. 'debian/dists/stable') - this directory usually
371contains the Packages-Master file.
372
373If you do not have a straightforward copy of the distribution available
374just 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 "
384Last time you said '$p_hierbase', and that looks plausible."
385			defhierbase="$p_hierbase"
386		else
387			echo "
388Last time you said '$p_hierbase', but that doesn't look plausible,
389since '$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"
425done
426
427
428case "$hierbase" in
429/* )	;;
430'' )	;;
431* )	hierbase="/$hierbase" ;;
432esac
433
434check_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
454find_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 "
470Note: most CD-ROM distributions of Debian do not include programs
471available in the 'non-free' directory of the distribution site.
472This is because these programs have copyrights that prevent
473distribution for profit on a CD-ROM - ie they are not free software.
474If you wish to install these programs you'll have to get them from an
475alternative source."
476	elif [ $2 = lcl ] && [ -z "$this_binary" ]
477	then
478		echo "
479Note: By default there is no 'local' directory. It is intended for
480packages you made yourself."
481	fi
482	while [ -z "$this_binary" ]
483	do
484		defaultbinary="$4"
485		echo "
486Which directory contains the *.deb packages from the $1 distribution
487area (this directory is named '$3/binary-$iarch' on the distribution site) ?
488Say '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 "
524I can't find the $1 'Packages' file.  The information in the
525'Packages' file is important for package selection during new
526installations, and is very useful for upgrades.
527
528If you overlooked it when downloading you should do get it now and
529return to this installation procedure when you have done so: you will
530find one Packages file and one Packages.gz file -- either will do --
531in the 'binary-$iarch' subdirectory of each area on the FTP sites and
532CD-ROMs.  Alternatively (and this will be rather slow) I can scan the
533packages in the distribution area - say 'scan' if you want me to do so.
534
535You need a separate Packages file from each of the distribution areas
536you wish to install.
537
538Where 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
559find_area main main main "$p_main_binary" "$p_main_packages"
560find_area contrib ctb contrib "$p_ctb_binary" "$p_ctb_packages"
561find_area non-free nf non-free "$p_nf_binary" "$p_nf_packages"
562find_area local lcl local "$p_lcl_binary" "$p_lcl_packages"
563
564echo -n '
565Hit RETURN to continue.  '
566read response
567
568exec 3>shvar.$option.new
569
570outputparam p_blockdev "$blockdevice"
571outputparam p_fstype "$fstype"
572outputparam p_mountpoint "$mountpoint"
573outputparam p_nfsserver "$nfsserver"
574outputparam p_nfsrempath "$nfsrempath"
575outputparam p_nfs "$nfs"
576outputparam p_hierbase "$hierbase"
577
578outputparam p_main_packages "$main_packages"
579outputparam p_main_binary "$main_binary"
580outputparam p_ctb_packages "$ctb_packages"
581outputparam p_ctb_binary "$ctb_binary"
582outputparam p_nf_packages "$nf_packages"
583outputparam p_nf_binary "$nf_binary"
584outputparam p_lcl_packages "$lcl_packages"
585outputparam p_lcl_binary "$lcl_binary"
586
587mv shvar.$option.new shvar.$option
588
589xit=0
590