#!/bin/bash

kernel=2.6.18-92.1.13.el5

if [ "$1" -a -f "fset/$1.fset" ]; then
   template=$1
else
   template=siplinux
fi

root=$(mktemp -d /dev/shm/$template.XXXXX)

function copy() {
    local file=$1

    ### Handle comments
    if [ "${file:0:1}" == "#" ]; then
        return
    fi

    ### Already processed file
    if [ -f "$root/$file" ]; then
        return
    fi

    mkdir -p $(dirname $root/$file)

    if [ -L "$file" ]; then
        cp -Pp $file $root/$file
	copy $(readlink -f $file)
    elif [ -d "$file" ]; then
        ### FIXME: handle directories recursively too
        cp -ap $file $root/$file
    elif [ -x "$file" ]; then
        cp -p $file $root/$file
        strip -s $root/$file &>/dev/null
        chmod 0755 $root/$file

        ### Copy dependencies
        ldd $file | while read -a list; do
            if [ "${list[2]}" -a -r "${list[2]}" ]; then
                copy ${list[2]}
            elif [ "${list[0]}" -a -r "${list[0]}" ]; then
                copy ${list[0]}
#            elif [ "${list[0]:0:13}" == "linux-gate.so" ]; then
#                :
#            else
#                echo "ldd: something wrong with ${list[@]}" >&2
            fi
        done
    elif [ -r "$file" ]; then
        ### Copy file
        cp -p $file $root/$file
    else
	location="$(which $(basename $file) 2>/dev/null)"
	if [ $? -eq 0 ]; then
            echo "copy: relocation $file to $location" >&2
            copy $location
        else
            echo "copy: Cannot find file $file" >&2
        fi
    fi
}

### Clean up existing directories first
rm -rf /dev/shm/$template.*

echo "Creating tree in $root"
cp -a $(pwd)/skelroot/$template/ $root/
find $root/ -name '.svn' -type d -exec rm -rf {} \;

### Start of with a list of files to include
echo "Processing fileset $template"
cat $(pwd)/fset/$template.fset | while read file; do
    for f in $file; do
        copy $f
    done
done

echo "Creating empty directories."
mkdir -p $root/boot/
mkdir -p $root/etc/cron.{daily,hourly,monthly,weekly}/
mkdir -p $root/etc/skel/
mkdir -p $root/dev/{pts,shm}/
mkdir -p $root/home/
mkdir -p $root/mnt/
mkdir -p $root/proc/
mkdir -p $root/sys/
mkdir -p $root/var/empty/sshd/
mkdir -p $root/var/lib/
mkdir -p $root/var/lock/subsys/
mkdir -p $root/var/log/
mkdir -p $root/var/run/
mkdir -p $root/var/spool/{at,cron}/
mkdir -p -m1777 $root/tmp/
mkdir -p -m1777 $root/var/tmp/

echo "Making empty files."
touch $root/etc/gshadow
touch $root/etc/fstab
touch $root/etc/modprobe.conf
touch $root/etc/modules.conf
touch $root/etc/mtab
touch $root/etc/resolv.conf
touch $root/etc/shadow
touch $root/var/log/messages

if [ -x $root/sbin/MAKEDEV ]; then
    echo "Make devices."
    chroot $root /sbin/MAKEDEV std mem ram tty raid pty fuse usb input cpu
    chroot $root /sbin/MAKEDEV console root cdrom generic mouse fb sound
fi

if [ -x $root/sbin/depmod ]; then
    echo "Make kernel module dependencies."
    chroot $root /sbin/depmod $kernel
fi

if [ -x $root/usr/bin/apt-get ]; then
    echo "Configuring apt."
    mkdir -p $root/var/lib/apt/lists/partial/
    mkdir -p $root/var/cache/apt/archives/partial/
    mkdir -p $root/var/lib/rpm/
    mkdir -p $root/etc/apt/sources.list.d/
    cp -av /etc/apt/sources.list.d/os.list $root/etc/apt/sources.list.d/os.list
    cp -av /etc/apt/sources.list.d/rpmforge.list $root/etc/apt/sources.list.d/rpmforge.list

    mkdir -p $root/usr/lib/rpm/
    cp -av /usr/lib/rpm/rpmrc $root/usr/lib/rpm/rpmrc
    cp -av /usr/lib/rpm/macros $root/usr/lib/rpm/macros

fi

if [ -x $root/sbin/busybox ]; then
    echo "Create busybox links."
    for cmd in $($root/sbin/busybox | grep -E '.*, .*, .*' | tr ',' ' ' | grep -v busybox ); do
        ln -sf busybox $root/bin/$cmd
        ln -sf busybox $root/sbin/$cmd
    done
    ln -sf bash $root/bin/sh
    rm -f $root/etc/inittab

    mkdir -p $root/etc/init.d
    cat <<EOF >$root/etc/init.d/rcS
export PATH=/bin:/sbin

echo "Make devices."
mdev -s

echo "Mount proc and sys."
mount -t proc proc /proc
mount -t sysfs sys /sys
EOF
fi

echo "Symlink files."
ln -sf sbin/init $root/init
ln -sf rc.d/init.d $root/etc/
ln -sf rc.d/rc{0,3,6}.d $root/etc/
ln -sf /proc/self/fd $root/dev/fd

if [ "$(which upx 2>/dev/null)" ]; then
    echo "Compress binaries. (this may take a few minutes)"
    upx -q --no-progress --best --ultra-brute $root/bin/* $root/sbin/* $root/usr/bin/* $root/usr/sbin/* &>$(pwd)/upx.log
else
    echo "Warning: upx binary not found, not compressing binaries." >&2
fi

echo "Creating the initrd."
pwd="$(pwd)"
cd $root && find . | cpio --quiet -o -H newc | gzip -9 >$pwd/$template.cgz
#cd $root && find . | afio -o -Z $pwd/$template.cgz

echo "See $root if you like it."

# vim:ts=4:sw=4:et
