#! /bin/sh
# cloneboot.sh v1.0 (2003-03-19)
# FreeBSD 4.x disk clone script
# Copyright Anders Nordby <anders@fix.no>, initial version created 2002-04-17

minfree=1
sourcedisk=ad0
destdisk=ad2
fstype="4.2BSD"
parttype="sysid 165"
newfsflags="-b 16384 -f 2048"

# requirements:
#
# run init once first, or set up matching slices
# /mnt must exist and be unused, it will be used temporarily in this script

runcmd() {
	echo "# $@"
	$@
}

listpart() {
	fdisk $sourcedisk -s | grep -A 1 '^The data for partition' | grep -v "^--$" | perl -pi -e "s@(^sysid.*),.*@\1@g;s@^The data for partition ([0-9]) is:\$@\1@g" | (
		while read line
		do
			read ptype
			if [ "`echo $ptype`" = "sysid 165" ]
			then
				echo $line
			fi
		done
	)
}

filtslice() {
	perl -e '$ok = 0; while (<>) { if ($_ =~ / partitions:$/) { $ok = 1; next; } next if not $ok; print $_; }' | tail +2 | grep "$fstype" | awk '{print $1}' | sed s/':'//g | xargs -n 1 echo
}

listslices() {
	partitions=`listpart`
	for part in $partitions; do
		disklabel -r "$sourcedisk"s$part | filtslice | (
			while read line
			do
				printf "s$part$line\n"
			done
		)
	done
}

lastchar() {
	perl -e "\$txt = \"$1\"; print substr(\$txt,length(\$txt)-1,1);"
}

case $1 in
'init')
	dd if=/dev/r$sourcedisk of=/dev/r$destdisk bs=64k
	;;
'list')
	printf "UFS slices on source disk $sourcedisk:\n\n`listslices`\n"
	;;
*)
	echo "[`date`]"
	for slice in `listslices`; do
		echo "== Clone slice $slice on disk $sourcedisk to $destdisk ==>"
		echo "* New filesystem on $destdisk$slice:"
		runcmd newfs $newfsflags /dev/r$destdisk$slice
		if [ "`lastchar $slice`" != "a" ]
		then
			echo "* Enable softupdates on $destdisk$slice:"
			runcmd tunefs -n enable /dev/r$destdisk$slice
			echo "* Set minfree to $minfree on $destdisk$slice:"
			runcmd tunefs -m $minfree /dev/r$destdisk$slice
		fi
		echo "* Mount filesystem $destdisk$slice on /mnt:"
		if !(runcmd mount /dev/$destdisk$slice /mnt)
		then
			echo "Error: Could not mount filesystem $destdisk$slice on /mnt. Exiting."
			exit 1
		fi
		if [ -z "`mount | awk '{print $3}' | grep '^/mnt$'`" ]
		then
			echo "Error: mount /mnt is not up. Exiting."
			exit 1
		fi
		echo "* Dump filesystem $sourcedisk$slice to $destdisk$slice:"
		echo "# dump 0f - /dev/r$sourcedisk$slice | (cd /mnt; restore -rf -)"
		dump 0f - /dev/r$sourcedisk$slice | (cd /mnt; restore -rf -)
		runcmd umount -f /mnt
	done
	runcmd disklabel -B "$destdisk"s1
	echo "[`date`]"
	;;
esac

