#!/bin/sh
#
# This 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; either version 2 of the License, or
# (at your option) any later version.
#
# It 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 IPCop; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
# Copyright 2005 Hacom - http://www.hacom.net/
#           Shamelessly copying the mkflash script of the IPCop software!
#

VERSION="0.0.1"
SIZE="$1"
CF="$2"
ORIGDIR=`pwd`
# PFSENSEVER="0.86.4"
PFSENSEVER="beta1"
PFSENSEFS=$ORIGDIR/'pfSense-'$PFSENSEVER
CF_MOUNT="/mnt/cf"
FLASHTMP=`pwd`

case "$SIZE" in
128)
        echo "`date '+%b %e %T'`: Creating 128MB Compact Flash"
        flash_MB=122
        boot_MB=10
        conf_MB=4
        root_MB=$(( $flash_MB - $conf_MB - $boot_MB ))
        heads=8
        sectors=32
        ;;
256)
        echo "`date '+%b %e %T'`: Creating 256MB Compact Flash"
        flash_MB=222
        boot_MB=10
        conf_MB=4
        root_MB=$(( $flash_MB - $conf_MB - $boot_MB ))
        heads=16
        sectors=32
        grub_PARMS="--force-lba"
        ;;
512)
        echo "`date '+%b %e %T'`: Creating 512MB Compact Flash"
        flash_MB=485
        boot_MB=10
        conf_MB=4
        root_MB=$(( $flash_MB - $conf_MB - $boot_MB ))
        heads=16
        sectors=32
        grub_PARMS="--force-lba"
        ;;
1gb)
        echo "`date '+%b %e %T'`: Creating 1 Gigabyte Compact Flash"
        flash_MB=978
        boot_MB=10
        conf_MB=4
        root_MB=$(( $flash_MB - $conf_MB - $boot_MB ))
        heads=128
        sectors=32
        grub_PARMS="--force-lba"
        ;;

*)
        echo "Usage: $0 {128|256|512|1gb} {hda|hdb|hdc|hdd|sda}"
        exit 1
        ;;
esac

case "$CF" in
hda)
        echo "`date '+%b %e %T'`: Creating hda Compact Flash"
        drive_ID=ad0
        ;;
hdb)
        echo "`date '+%b %e %T'`: Creating hdb Compact Flash"
        drive_ID=ad1
        ;;
hdc)
        echo "`date '+%b %e %T'`: Creating hdc Compact Flash"
        drive_ID=ad2
        ;;
hdd)
        echo "`date '+%b %e %T'`: Creating hdd Compact Flash"
        drive_ID=ad3
        ;;
sda)
        echo "`date '+%b %e %T'`: Creating hda Compact Flash"
        drive_ID=da0
        ;;
*)
        echo "Usage: $0 {128|256|512|1gb} {hda|hdb|hdc|hdd|sda}"
        exit 1
        ;;
esac

# Calculate all the required derived variables...
bs=512          # do not change!

flash_blocks=$(( $flash_MB * 1024 * 1024 / $bs ))

boot_blocks=$(( $boot_MB * 1024 * 1024 / $bs - 1 ))
root_blocks=$(( $root_MB * 1024 * 1024 / $bs ))
conf_blocks=$(( $conf_MB * 1024 * 1024 / $bs ))

boot_block_offset=1
root_block_offset=$(( $boot_block_offset + $boot_blocks ))
conf_block_offset=$(( $root_block_offset + $root_blocks ))

boot_byte_offset=$(( $boot_block_offset * $bs ))
root_byte_offset=$(( $root_block_offset * $bs ))
conf_byte_offset=$(( $conf_block_offset * $bs ))

cylinders=$(( $(( $flash_blocks )) /  $heads / $sectors )) 

echo "Flash size: $flash_MB MB"
echo "boot size: $boot_MB, boot blocks: $boot_blocks $boot_block_offset"
echo "root size: $root_MB, root blocks: $root_blocks $root_block_offset"
echo "conf size: $conf_MB, conf blocks: $conf_blocks $conf_block_offset"
echo "cylinders: $cylinders, heads: $heads, sectors: $sectors"

############################################################################
#                                                                          #
# Creating empty flash image in /usr/tmp-image                              #
#                                                                          #
############################################################################
echo "`date '+%b %e %T'`: Creating empty flash image in $FLASHTMP"
rm -f $FLASHTMP/flash.img
dd if=/dev/zero of=$FLASHTMP/flash.img bs=$bs count=$flash_blocks >/dev/null
dd if=/dev/zero of=$FLASHTMP/part1.img bs=$bs count=$boot_blocks  >/dev/null
dd if=/dev/zero of=$FLASHTMP/part4.img bs=$bs count=$(( $root_blocks + $conf_blocks )) >/dev/null

############################################################################
#                                                                          #
# Making filesystems                                                       #
#                                                                          #
############################################################################
echo "`date '+%b %e %T'`: Making filesystems"
MD=`mdconfig -a -t vnode -f $FLASHTMP/part4.img`

TMPFILE1=`mktemp -t freesbie`
cat >$TMPFILE1 <<-EOF
# /dev/md0:
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   $root_blocks  *    4.2BSD     1024  8192 16
  c:   $(( $root_blocks + $conf_blocks )) *    unused        0     0         # "raw" part, don't edit
  d:   $conf_blocks  * 4.2BSD     1024  8192   16
EOF
cat $TMPFILE1
bsdlabel -R /dev/${MD} $TMPFILE1
bsdlabel /dev/${MD} 
newfs /dev/${MD}a
newfs /dev/${MD}d
rm $TMPFILE1

mdconfig -d -u $MD

MD=`mdconfig -a -t vnode -f $FLASHTMP/flash.img`
fdisk -f - /dev/${MD} <<-EOF
g c$cylinders h$heads s$sectors
p 1 4 $boot_block_offset $boot_blocks
p 2 0 0 0
p 3 0 0 0
p 4 165 $root_block_offset $(( $root_blocks + $conf_blocks ))
a 1
EOF
fdisk /dev/${MD}
mdconfig -d -u $MD

dd if=$FLASHTMP/part1.img of=$FLASHTMP/flash.img seek=$boot_block_offset  bs=$bs
dd if=$FLASHTMP/part4.img of=$FLASHTMP/flash.img seek=$root_block_offset  bs=$bs
rm -f $FLASHTMP/part?.img

MD=`mdconfig -a -t vnode -f $FLASHTMP/flash.img`
newfs_msdos -F 12 -S 512 -h $heads -u 16 -o 0 -s 20448 /dev/${MD}s1
bsdlabel /dev/${MD}s4 
newfs -O1 /dev/${MD}s4a
newfs -O1 /dev/${MD}s4d
mdconfig -d -u ${MD}

############################################################################
#                                                                          #
# Creating and partitioning Compact Flash image                            #
#                                                                          #
############################################################################
echo "`date '+%b %e %T'`: Creating and partitioning Compact Flash image"
MD=`mdconfig -a -t vnode -f $FLASHTMP/flash.img`
fdisk -f - /dev/${MD} <<-EOF
g c$cylinders h$heads s$sectors
p 1 4 $boot_block_offset $boot_blocks
p 2 0 0 0
p 3 0 0 0
p 4 165 $root_block_offset $(( $root_blocks + $conf_blocks ))
a 1
EOF
fdisk /dev/${MD}
# newfs_msdos -F 12 -S 512 -h $heads -u 16 -o 0 -s $boot_blocks /dev/md0s1
newfs_msdos -F 12 -S 512 -h $heads -u 16 -o 0 -s $boot_blocks /dev/${MD}s1

TMPFILE1=`mktemp -t freesbie`
cat >$TMPFILE1 <<-EOF
# /dev/${MD}:
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   $root_blocks  *    4.2BSD     1024  8192 16
  c:   $(( $root_blocks + $conf_blocks )) *    unused        0     0         # "raw" part, don't edit
  d:   $conf_blocks  * 4.2BSD     1024  8192   16
EOF
cat $TMPFILE1
bsdlabel -R /dev/${MD}s4 $TMPFILE1
bsdlabel /dev/${MD}s4 
newfs /dev/${MD}s4a
newfs /dev/${MD}s4d
rm $TMPFILE1

echo "Building the pfSense filesystem ... ${PFSENSEFS}.tar.gz "

mount /dev/${MD}s4a $CF_MOUNT/a
mount /dev/${MD}s4d $CF_MOUNT/d
cd $CF_MOUNT/a
tar xzvf ${PFSENSEFS}.tar.gz >/dev/null 2>&1
cd $ORIGDIR
cd $CF_MOUNT/d
# tar xzvf ${PFSENSEFS}-d.tar.gz >/dev/null 2>&1
cp -R $CF_MOUNT/a/cf/* $CF_MOUNT/d
cd $ORIGDIR

############################################################################
#                                                                          #
# Fix the fstab to mount the first IDE master drive                        #
#                                                                          #
############################################################################

# sed -i .bak -e 's/ad2a/ad0a/' -e 's/ad2d/ad0d/' $CF_MOUNT/a/etc/fstab
# rm $CF_MOUNT/a/etc/fstab.bak
cat >$CF_MOUNT/a/etc/fstab <<-EOF
/dev/${drive_ID}s4a / ufs ro 1 1
/dev/${drive_ID}s4d /cf ufs ro 1 1
md /tmp mfs rw,-s16m 1 0
EOF

cat >$CF_MOUNT/a/etc/platform <<-EOF
embedded
EOF

#TMPFILE=`mktemp -t freesbie`
#cat >$TMPFILE <<-EOF
#diff -u pfSense-0.84.orig/etc/rc.firmware_auto pfSense-0.84/etc/rc.firmware_auto
#--- pfSense-0.84.orig/etc/rc.firmware_auto      Wed Sep  7 13:21:25 2005
#+++ pfSense-0.84/etc/rc.firmware_auto   Wed Sep 14 20:01:17 2005
#@@ -49,10 +49,21 @@
#         if [ "$PLATFORM" = "wrap" ]; then
#             /usr/local/bin/php /etc/rc.conf_mount_rw
#         fi
#+        if [ "$PLATFORM" = "hacom" ]; then
#+            /usr/local/bin/php /etc/rc.conf_mount_rw
#+        fi
#         if [ -r "/tmp/custom.tgz" ]; then
#             sh /etc/rc.firmware pfSenseupgrade /tmp/latest.tgz /tmp/custom.tgz
#         else
#             sh /etc/rc.firmware pfSenseupgrade /tmp/latest.tgz
#+        fi
#+        if [ "$PLATFORM" = "hacom" ]; then
#+            /bin/sync
#+            sleep 5
#+            /usr/local/bin/php /etc/rc.conf_mount_ro
#+            if [ -e /etc/init_bootloader.sh ]; then
#+                    sh /etc/init_bootloader.sh
#+            fi
#         fi
#         if [ "$PLATFORM" = "wrap" ]; then
#             /bin/sync
#EOF
#
#cd $CF_MOUNT/a
#patch -p1 <$TMPFILE
#rm $TMPFILE
#cd $ORIGDIR
#
#TMPFILE=`mktemp -t freesbie`
#cat >$TMPFILE <<-EOF
#diff -u pfSense-0.86.4.orig/etc/inc/config.inc pfSense-0.86.4/etc/inc/config.inc
#--- pfSense-0.86.4.orig/etc/inc/config.inc	Sat Oct  8 17:34:29 2005
#+++ pfSense-0.86.4/etc/inc/config.inc	Mon Oct 17 23:55:20 2005
#@@ -298,7 +298,7 @@
# 	 *    compact flash cards root.
#          */
# 	if(\$g['platform'] == "wrap" or \$g['platform'] == "net45xx"
#-	   or \$g['platform'] == "embedded") {
#+	   or \$g['platform'] == "embedded" or \$g['platform'] == "hacom") {
# 		mwexec("/sbin/umount -f /");
# 		$status = mwexec("/sbin/mount -w /");
# 		/* we could not mount this correctly.  kick off fsck */
#@@ -336,7 +336,7 @@
# 	 *    compact flash card.
#          */
# 	if(\$g['platform'] == "wrap" or \$g['platform'] == "net45xx"
#-	   or \$g['platform'] == "embedded") {
#+	   or \$g['platform'] == "embedded" or \$g['platform'] == "hacom") {
# 		mwexec("/sbin/umount -f /");
# 		mwexec("/sbin/mount -f -r /");
# 	}
#EOF
#
#cd $CF_MOUNT/a
#patch -p1 <$TMPFILE
#rm $TMPFILE
#cd $ORIGDIR

umount /dev/${MD}s4a
umount /dev/${MD}s4d

mount -t msdosfs /dev/${MD}s1 $CF_MOUNT

##########################################################################t#
#                                                                          #
# Create the Grub.conf file with our parameters                            #
#                                                                          #
############################################################################
mkdir $CF_MOUNT/grub
cat > $CF_MOUNT/grub/menu.lst <<EOF
timeout 5
foreground = 16064e
background = ffffff
title pfSense
  root (hd0,3,a)
  kernel /boot/loader
  boot
EOF

cp /usr/local/share/grub/i386-freebsd/stage1 $CF_MOUNT/grub
cp /usr/local/share/grub/i386-freebsd/stage2 $CF_MOUNT/grub

umount /dev/${MD}s1

############################################################################
#                                                                          #
# Installing grub                                                          #
#                                                                          #
############################################################################
echo "`date '+%b %e %T'`: Installing Grub"

/usr/local/sbin/grub --batch <<EOF
device (hd0) $FLASHTMP/flash.img
geometry (hd0)
root (hd0,0)
makeactive
install $grub_PARMS (hd0,0)/grub/stage1 (hd0) (hd0,0)/grub/stage2 0x8000 p /grub/menu.lst
quit
EOF

############################################################################
#                                                                          #
# Cleaning up                                                              #
#                                                                          #
############################################################################
echo "`date '+%b %e %T'`: Cleaning up"

mdconfig -d -u ${MD}
HACOMIMG='pfSense-'${PFSENSEVER}'-'${SIZE}'-'${drive_ID}'.img'
mv $FLASHTMP/flash.img $ORIGDIR/$HACOMIMG
gzip $HACOMIMG
md5 $HACOMIMG'.gz' >$ORIGDIR/$HACOMIMG'.gz.md5'
echo "Done! ..."
