#!/bin/bash

function del_partitions(){
	echo "d"
	echo "1"
	echo "d"
	echo "2"
	echo "d"
	echo "3"
	echo "d"
	[ "$SPECIAL4" = "4" ] || echo "4"
}

function enable_errcheck(){
	echo "v"
}

function add_partition(){
	echo "n"
	echo "$1"
	[ "$1" != "l" -a "$2" != "$SPECIAL4" ] && echo "$2"
	echo
	echo "$3"
	if [ "$4" != "" ]; then
		echo "t"
		echo "$2"
		echo "$4"
	fi
}

function make_partitions(){
	del_partitions
	enable_errcheck
	[ "$UNITS" = "K" ] && echo "u"
	add_partition e 1 "+$SZ_HDA1$UNITS"
	add_partition l 5 "+$SZ_HDA5$UNITS" 83
	add_partition l 6 ""                82
	add_partition p 2 "+$SZ_HDA2$UNITS" 83
	add_partition p 3 "+$SZ_HDA3$UNITS" 10
	add_partition p 4 ""                83
	echo "a"
	echo "5"
	echo "p"
	echo $COMMIT
}

function errcheck(){
	DOECHO=0
	ERRCHECK=0
	while read x ; do
		[[ "$x" == Disk\ ${DEV}:*             ]] && DOECHO=1
		[[ "$x" == Command\ \(m\ for\ help\): ]] && DOECHO=0
		[ $DOECHO -eq 1 ] && [[ "$x" != *does\ not\ end\ on* ]] && echo "$x" >&2
		[[ "$x" == *\ unallocated\ sectors    ]] && ERRCHECK=1
		if [ $ERRCHECK -eq 1 ]; then
			if [[ "$x" == *out\ of\ range.		\
			   || "$x" == *got\ EOF\ thrice*	\
			   || "$x" == *No\ free\ sectors*	\
			   || "$x" == *unknown\ command*	\
			   ]]
			then
				echo "ERROR: fdisk: $x" 1>&2
				exit 1
			fi
		fi
	done
	exit 0
}

## First parameter is the device path, eg. /dev/hda:
[ "$1" = "" ] && echo "missing device path" && exit 1
DEV=$1

## The default is to "just pretend", and not actually do anything for real.
## Supply "COMMIT" on the command line to actually write the new partition info.
COMMIT=q
[ "$2" = "COMMIT" ] && COMMIT=w

## Figure out how big $DEV is, in kilobytes:
DEV_KB=`sed -n -e"s/  *[0-9][0-9]*  *[0-9][0-9]* *\([0-9]*\) ${DEV##*/}\$/\1/p" < /proc/partitions`
if [ "$DEV_KB" = "" ]; then
	echo "$DEV: not found"
	exit 1
fi

## Newer fdisk versions don't always prompt for partition number 4, but the empeg does:
SPECIAL4="4"
[ "`fdisk -v`" = "fdisk v2.10d" ] && SPECIAL4=NONE	## empeg

## minimum partition sizes, in $UNITS (defined below):
SZ_HDA5=16	## root
SZ_HDA6=64	## swap
SZ_HDA1=$(( SZ_HDA5 + SZ_HDA6 ))
SZ_HDA2=32	## spare
SZ_HDA3=32	## dynamic data
SZ_HDA4=	## FIDs, use all remaining space

## allocation units, normally "M" (megabytes), or possibly "K" (kilobytes):
UNITS=M

## "K" kilobytes: only for testing here on a tiny drive I have:
SZ_TOTAL=$(( SZ_HDA1 + SZ_HDA2 + SZ_HDA3 + 128 ))
[ $(( SZ_TOTAL * 1024 )) -ge $DEV_KB ] && UNITS=K

echo
[ "$SPECIAL4" = "4" ] || echo "$DEV: ${DEV_KB} KB"
make_partitions $COMMIT | fdisk $DEV 2>&1 | errcheck || exit 1
echo "Success"
