#! /bin/sh

# DIET-PC firmware assembly script

# Copyright (C) 2002-2011 Paul A. Whittaker <whitpa@users.sourceforge.net>

# This program 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.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

umask 022
PATH='/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin'
export PATH

IPK_LIST="/tmp/ipks.$$"
FWROOT="/tmp/fwroot.$$"
[ "$1" = '--upx' ] && USE_UPX=TRUE || USE_UPX=
trap "rm -rf $IPK_LIST $FWROOT; exit 255" 2

if [ "`id -u`" -ne 0 ]; then
    echo "`basename $0` must be run as root." 1>&2
    exit 1
elif [ ! -d $HOME/diet-pc/mdcache ]; then
   cat 1>&2 <<EOF
$HOME/diet-pc/mdcache not initialized - must run "dpc-mdcache refresh" first!
EOF
   exit 1
elif [ ! -s $HOME/diet-pc/.config ]; then
   cat 1>&2 <<EOF
$HOME/diet-pc/.config not initialized - must run "dpc-configure" first!
EOF
   exit 1
fi

compute_installation_order () {
    grep -v '^#' .config | sed 's/^CONFIG_\(.*\).*=y$/\1/' | tr '_[A-Z]' \
	    '\055[a-z]' | while read PKG; do
	[ ! -f "mdcache/$PKG" ] && continue
	grep '^Depends:' mdcache/$PKG | sed -e 's/^Depends://' -e \
		's/([^,]*)//g' | tr ' \t,' '\012' | while read DEP; do
	    [ "$DEP" ] && echo "$PKG $DEP"
	done
	ALIAS=`grep '^Provides:' mdcache/$PKG | sed 's/^Provides:\W*//'`
	[ "$ALIAS" ] && echo "$ALIAS $PKG"
    done | tsort | tac
}

cd $HOME/diet-pc
# Set *_DEST environment variables.
. ./.config
# Construct an ordered list ($IPK_LIST) of ipk files to be installed.
cat /dev/null >$IPK_LIST
compute_installation_order | while read PKG; do
    [ ! -f "mdcache/$PKG" ] && continue
    VERSION=`grep '^Version:' mdcache/$PKG | sed 's/^Version:\W*//'`
    ARCH=`grep '^Architecture:' mdcache/$PKG | sed 's/^Architecture:\W*//'`
    echo "$ARCH/${PKG}_${VERSION}_${ARCH}.ipk" >>$IPK_LIST
done

mkdir $FWROOT
/bin/echo -e '\tInstalling packages ... \c'
[ -f 'ipkg.conf' ] && ALTCONF='-f ipkg.conf' || ALTCONF=
while read IPK; do
    DEST_SYM="CONFIG_`basename $IPK | cut -f1 -d_ | tr '\055[a-z]' \
	    '_[A-Z]'`_DEST"
    eval 'DEST=$'"$DEST_SYM"
    [ "$DEST" != 'none' ] && ipkg $ALTCONF -V 0 -o $FWROOT -d ${DEST:-'root'} \
	    install $IPK
done <$IPK_LIST
echo 'done.'
rm -f $IPK_LIST

# Create /dev/console and /dev/null.  Init needs to be able to find these at
# boot, before mdev has initialized device nodes.
mknod -m 644 $FWROOT/dev/console c 5 1 2>/dev/null
mknod -m 666 $FWROOT/dev/null c 1 3 2>/dev/null

# Initialiase /etc/ld.so.cache
ldconfig -r $FWROOT 2>/dev/null

if [ "$USE_UPX" ]; then
    /bin/echo -e '\nUPXing executables ... \c'
    # Busybox find has neither "-exec" nor "-o".  Sigh.
    {
	find $FWROOT -type d -name bin -print
	find $FWROOT -type d -name sbin -print
    } | while read dir; do
	upx -q --best --overlay=skip $dir/* >/dev/null 2>&1
    done
    # Never UPX init or busybox - this will cause problems.
    upx -q -d $FWROOT/sbin/init $FWROOT/bin/busybox >/dev/null 2>&1
    echo 'done.'
fi

if [ "$CONFIG_SEPARATE_USRLOCAL" = 'y' ]; then
    sed -i '/^#LABEL=usrlocal/s/^#//' $FWROOT/etc/fstab
    (cd $FWROOT/usr/local; find . -print | cpio -o --quiet -H newc) \
	    >$HOME/diet-pc/usrlocal.cpio
    rm -rf $FWROOT/usr/local
    mkdir $FWROOT/usr/local
fi
if [ "$CONFIG_SEPARATE_USR" = 'y' ]; then
    sed -i '/^#LABEL=usr/s/^#//' $FWROOT/etc/fstab
    (cd $FWROOT/usr; find . -print | cpio -o --quiet -H newc) \
	    >$HOME/diet-pc/usr.cpio
    rm -rf $FWROOT/usr
    mkdir $FWROOT/usr
fi
(cd $FWROOT; find . -print | cpio -o --quiet -H newc) >$HOME/diet-pc/root.cpio

chown `ls -ld $HOME | awk '{printf "%s:%s\n", $3, $4}'` $HOME/diet-pc/*.cpio
sync

rm -rf $FWROOT
exit 0
