#!/bin/sh
#-
# $FreeWRT$
#-
# This file is part of the FreeWRT project. FreeWRT is copyrighted
# material, please see the LICENCE file in the top-level directory
# or at http://www.freewrt.org/licence for details.

# Copyright (c) Waldemar Brodkorb <wbx@freewrt.org>
# image builder script (version 0.1)

# change here the base variables
basedir=/srv/apache2/downloads
toolsdir=/var/ib/bin
database=/srv/database/wib_dev.db
usetmpfs=0

# do not change anything below

usage() {
	echo "Usage: `basename $0` -a <arch> -b <board> -k <kernelversion> -f <filesystem> -d <device> -o <outputfile> -p <packagelist>"
	echo "		-a cpu architecture, f.e. mipsel"
	echo "		-b board type, f.e. brcm"
	echo "		-k kernel version, 2.4 or 2.6"
	echo "		-f root filesystem type, f.e. jffs2"
	echo "		-d specific device, f.e. asus-wl500g"
	echo "		-p package list filename"
	echo "		-o output file for the firmware image"
	exit 1
}

# check for needed applications
tools="mksquashfs-lzma trx addpattern mkfs.jffs2 ipkg"

for t in ${tools}
  do 
   [ -x ${toolsdir}/${t} ] || echo "${t} application missing or not executable" 
done

# check for sqlite 
sqlite=$(which sqlite)
[ -x ${sqlite} ] || "sqlite application is missing"

# simple sql functions
sql() {
	sqlite $database "select $1 from $2"
}
sqlw() {
	sqlite $database "select $1 from $2 where $3=\"$4\""
}

allowed_fs=$(sql name filesystems)
allowed_archs=$(sql name arches)
allowed_boards=$(sql name boards)
allowed_devices=$(sql name devices)
allowed_os_kernels=$(sql name os_kernels)

while getopts a:b:f:k:d:o:p: option
do
  case $option in
	a)
		archs=$OPTARG
		for a in $allowed_archs
		do
			if [ $archs = $a ]
			then
				arch=$a
			fi
		done
		if [ -z $arch ]
		  then
			echo "unsupported architecture: $archs"
			exit 1
		fi
		;;
	b)
		boards=$OPTARG
		for b in $allowed_boards
		do
			if [ $boards = $b ]
			then
				board=$b
			fi
		done
		if [ -z $board ]
		  then
			echo "unsupported board: $boards"
			exit 1
		fi
		;;
	f)
		filesystems=$OPTARG
		for f in $allowed_fs 
		  do
			if [ $filesystems = $f ]
			then 
				fs=$f
			fi
		done
		if [ -z $fs ]
		  then
			echo "unsupported filesystem: $filesystems"
			exit 1
		fi
		;;
	k)
		kernels=$OPTARG
		for k in $allowed_os_kernels
		  do
			if [ $kernels = $k ]
			then 
				kernel=$k
			fi
		done
		if [ -z $kernel ]
		  then
			echo "unsupported kernel version: $kernels"
			exit 1
		fi
		;;
	d)
		devices=$OPTARG
		for d in $allowed_devices
		  do
			if [ $devices = $d ]
			then 
				device=$d
			fi
		done
		if [ -z $device ]
		  then
			echo "unsupported device: $devices"
			exit 1
		fi
		;;
	o)
		outputfile=$OPTARG
		if [ -z $outputfile ] 
		then
			echo "You need to set an output file"
			exit 1
		fi
		;;
	p)
		packagelist=$OPTARG
		if [ -z $packagelist ] 
		then
			echo "You need to set a package list file"
			exit 1
		fi
		;;
 	*)
		echo "$0: unknown option: $option"
		usage
		exit 1
		;;
  esac
done

if [ -z $1 ]
  then
    usage
    exit 1
fi

if [ $usetmpfs = 1 ]
  then
   tmpdir=$(mktemp -d /dev/shm/fwrt.XXXXXX)
else
   tmpdir=$(mktemp -d)
fi
mkdir -p ${tmpdir}/tmp
mkdir -p ${tmpdir}/root
echo "creating temporary dir: ${tmpdir}"

echo -e "dest root /\noption offline_root ${tmpdir}/root" > ${tmpdir}/ipkg.conf
ipkg_command="env IPKG_TMP=${tmpdir}/tmp IPKG_INSTROOT=${tmpdir}/root IPKG_CONF_DIR=${tmpdir} ${toolsdir}/ipkg -force-defaults -force-depends"

for p in $(grep -v '^#' $packagelist)
  do
  	$ipkg_command install $(ls ${basedir}/${board}-${kernel}/packages/${p}_*)
done

erase_size=$(sqlw erase_size devices name ${device})

if [ $fs = "squashfs-symlinks" -o $fs = "squashfs-overlay" ]
  then 
	align=1024
else
	align=${erase_size}
fi

case $device in 
	asus-wl500g)
		device_opts="-p WL500g -v 1.9.6.0"
		image_command="${toolsdir}/trx ${device_opts} -o ${outputfile} -a ${align} ${tmpdir}/root.${fs}"
		;;
	asus-wl500g-deluxe)
		device_opts="-p WL500gx -v 1.9.6.0"
		image_command="${toolsdir}/trx ${device_opts} -o ${outputfile} -a ${align} ${tmpdir}/root.${fs}"
		;;
	asus-wl500g-premium)
		device_opts="-p WL500gp -v 1.9.7.0"
		image_command="${toolsdir}/trx ${device_opts} -o ${outputfile} -a ${align} ${tmpdir}/root.${fs}"
		;;
esac

jffs_opts="--little-endian --pad --squash-uid"
squashfs_opts="-le -nopad -noappend -root-owned"

case $fs in
	jffs2)
		fs_command="${toolsdir}/mkfs.jffs2 -e ${erase_size} -o ${tmpdir}/root.${fs} -d ${tmpdir}/root"
		;;
	squashfs-*)
		fs_command="${toolsdir}/mksquashfs-lzma ${tmpdir}/root ${tmpdir}/root.${fs} ${squashfs_opts}"
		;;
esac

echo "create root filesystem image" 
$fs_command || echo "creating the root filesystem image failed"

echo "create firmware image"
$image_command || echo "failed to create firmware image"

[ -n $tmpdir ] && rm -rf $tmpdir
echo "successfully build firmware image: ${outputfile}"

