#! /bin/bash

# Builds the MoviX initrd

echo "
This script will build the initrd.gz of MoviX from the compiled sources.

Press CTRL+C now if you don't want to start now.
"

# Constants and setup
targetname=movix
workdir=/home/movix/work
sourcedir=$workdir/source
targetdir=$workdir/target/$targetname
initrddir=$targetdir/initrd
configdir=$workdir/config
releasedir=$workdir/release/$targetname

# ------------- No need to change anything below ------------
# Work begins here

while getopts ":hsleuUmr:" opt; do
        case $opt in

		# help
		h )     echo "Usage:
  -h      this help

  -e      don't include em8300/DXR programs/modules
  -l      don't include LIRC programs/modules
  -s      don't include SCSI kernel modules

  -u      use the UPX packer to compress a few programs (probably good)
  -U      use the UPX packer to compress more programs (probably overkill)

  -m      before compressing the initrd, start mc for last minute changes
  -r      release name (subdirectory where release files are put)
"
			exit
		;;

		# don't include DXR/em8300
		e )	withoutEm8300=y
		;;

		# don't include LIRC
		l )	withoutLirc=y
		;;

		# don't include SCSI modules
		s )	withoutScsi=y
		;;

		# use UPX
		u )	useUpx=y
		;;

		# use UPX on more programs
		U )	useUpx=y
			useUpxHard=y
		;;

		# start mc before compressing the initrd
		m )	startMc=y
		;;

		# release name
		r )	releaseName="$OPTARG"
			shift
		;;

	esac
done

# Give the user some time 
sleep 1

echo "Creating initrd directory $initrddir..."
rm -rf $initrddir
mkdir -p $initrddir

pushd $initrddir

echo "Creating other directories..."
# Create the necessary directory structure
mkdir -p bin cdrom dev etc/devfs etc/terminfo floppy lib mnt proc \
	root/.mplayer sbin tag tmp \
	usr/bin usr/lib usr/libexec \
	usr/share/consolefonts usr/share/kbd usr/share/terminfo \
	usr/local/bin usr/local/lib usr/local/share \
	usr/local/alsa usr/local/mplayer \
	var/log/mount var/run
	
echo "Copying busybox..."
# Copy the busybox stuff
cp --archive $targetdir/busybox/* .

echo "Copying /bin..."
# Copy original Debian stuff to bin
cp /usr/bin/setterm /usr/bin/comm /usr/bin/dialog \
	bin/

# Slackware scripts
cp $configdir/$targetname-lib/bin/* bin/
cp $configdir/$targetname-lib/sbin/* sbin/

echo "Copying /etc..."
# Copy MoviX /etc
cp --archive $configdir/$targetname-lib/etc/ .
# Debian's devfsd likes to have its config file in /etc/devfs/
ln -s ../devfsd.conf etc/devfs/devfsd.conf

echo "Copying Linux kernel modules..."
# Linux kernel modules to /lib
cp --archive $targetdir/lib/ .

echo "Compressing Linux kernel modules..."
pushd $initrddir/lib/modules
for module in `find . -type f -name '*.o'`; do 
	gzip -9 "$module"
done
# Of course, all the modules dependencies need to be updated
moddeps=`find . -type f -name 'modules.*'`
perl -pw -i -e 's/\.o\b/.o.gz/g' $moddeps

popd

echo "Copying /lib..."
# original Debian libs to /lib
cp --archive /lib/ld-linux*.so* /lib/ld-2.*.so \
	/lib/libBrokenLocale-*.so* /lib/libSegFault*.so* \
	/lib/libanl*.so* /lib/libcom_err*.so* \
	/lib/libc-*.so /lib/libc.so* /lib/libdl*.so* \
	/lib/libcrypt*.so* /lib/libdb*.so* \
	/lib/libm*.so* /lib/libncurses*.so* /lib/libnsl*.so* \
	/lib/libnss_[cf]*.so* \
	/lib/libproc*.so* /lib/libpthread* \
	/lib/libresolv*.so* /lib/librt*.so* \
	/lib/libss.so* /lib/libthread*.so* \
	/lib/libutil*.so* /lib/libuuid*.so* \
	lib/

echo "Copying /usr/lib..."
# the same for /usr/lib (Debian has some libs there)
cp --archive /usr/lib/libgpm*.so* \
	/usr/lib/libncurses*.so* /usr/lib/libform*.so* \
	/usr/lib/libgdbm*.so* /usr/lib/libpanel*.so* \
	/usr/lib/libtermcap*.so* \
	lib/

echo "Copying ALSA libs..."
if [ -d $targetdir/alsa/lib ]; then
	# Compiled libs for /usr/lib
	cp --archive $targetdir/alsa/lib/libasound*.so* usr/lib/
else
	# Debian libs
	cp --archive /usr/lib/libasound*.so* usr/lib/
fi

echo "Copying /sbin..."
cp --archive /sbin/depmod /sbin/lspci /sbin/pump sbin/
cp --archive /sbin/portmap sbin/rpc.portmap

# compiled or system devfsd
if [ -d $targetdir/devfsd/sbin ]; then
	cp --archive $targetdir/devfsd/sbin/devfsd sbin/
else
	cp --archive /sbin/devfsd sbin/
fi
# TODO: rpc.portmap agetty? chattr? lsattr? mkpv? (volume group)

# The original modutils versions work better - they have gzip support
cp --archive /sbin/insmod /sbin/modprobe /sbin/lsmod /sbin/rmmod \
	sbin/

echo "Copying /usr/bin..."
# /usr/bin: Debian files
cp --archive /usr/bin/eject /usr/bin/ldd /usr/bin/lsdvd \
	/usr/bin/consolechars /usr/bin/setfont /usr/bin/uuidgen \
	/usr/bin/iconv \
	usr/bin/
# TODO: nmixer

echo "Copying perl..."
if [ -d $targetdir/perl/bin ]; then
# Self-compiled perl
	cp --archive $targetdir/perl/bin/perl usr/bin/
elif [ -x $configdir/$targetname-lib/bin/perl ]; then
# Precompiled small perl
	cp --archive $configdir/$targetname-lib/bin/perl usr/bin/
else	
	# The normal Debian perl which also requires libcrypt
	cp --archive /usr/bin/perl usr/bin/
fi

# In either case, we will need lots of Perl modules.
cp --archive /usr/lib/perl* usr/lib
cp --archive /usr/share/perl* usr/share
cp --archive /usr/local/share/perl* usr/local/share

# Those are too large and not needed for MoviX
rm -rf usr/lib/perl/5.8.0/auto/Encode usr/lib/perl/5.8.0/auto/Unicode \
	   usr/share/perl5/Deb{conf,ian} usr/share/perl/5.8.0/Unicode \
	   usr/share/perl/5.8.0/Pod usr/share/perl/5.8.0/unicore

echo "Copying ALSA..."
if [ -d $targetdir/alsa/bin ]; then
	# /usr/bin: compiled ALSA stuff
	cp --archive $targetdir/alsa/bin/a*mixer usr/bin/
else
	cp --archive /usr/bin/a*mixer usr/bin/
fi

echo "Copying DXR/EM8300..."
if [ -d $targetdir/em8300/bin ]; then
	# /usr/bin: compiled em8300 stuff
	cp --archive $targetdir/em8300/bin/* usr/bin/
fi

echo "Copying LIRC..."
if [ -d $targetdir/lirc/bin ]; then
	cp --archive $targetdir/lirc/bin/{ir,rc}* usr/bin/
	cp --archive $targetdir/lirc/lib/*.so* usr/lib
fi

echo "Copying TV out and mixer programs..."
# /usr/bin: compiled tv out stuff
cp --archive $targetdir/nvtv/bin/nvtv $targetdir/usr/bin/* \
	$targetdir/nmixer/bin/nmixer $targetdir/rexima/bin/rexima \
	usr/bin/

echo "Copying /usr/lib..."
# /usr/lib: Debian stuff

cp --archive /usr/lib/terminfo /usr/lib/pt_chown usr/lib
# Debian libraries needed by mplayer => /usr/lib
cp --archive \
	/usr/lib/libcdda_*.so* /usr/lib/libdv*.so* \
	/usr/lib/libfaad*.so* /usr/lib/libfreetype*.so* \
	/usr/lib/libogg*.so* /usr/lib/libvorbis*.so* \
	/usr/lib/libmenu*.so* /usr/lib/libz*.so* \
	usr/lib

# libvorbisenc is only for encoding, neither libvorbisfile is needed
rm usr/lib/libvorbisenc* usr/lib/libvorbisfile*

echo "Copying SDL libraries..."
if [ -d $targetdir/sdl ]; then
	# Compiled version
	cp --archive $targetdir/sdl/lib/libSDL*.so* usr/lib
else
	# Those from Debian aren't good for Movix, but hey.
	cp --archive /usr/lib/libSDL*.so* usr/lib
fi

echo "Copying aalib libraries..."
if [ -d $targetdir/aalib ]; then
	# Compiled version (Debian's version depends on X)
	cp --archive $targetdir/aalib/lib/libaa*.so* usr/lib
fi

echo "Copying /usr/sbin..."
# /usr/sbin: some compiled stuff
if [ -d $targetdir/alsa/sbin ]; then
	cp --archive $targetdir/alsa/sbin/alsactl usr/sbin
else
	cp --archive /usr/sbin/alsactl usr/sbin
fi

if [ -d $targetdir/lirc/sbin ]; then
	cp --archive $targetdir/lirc/sbin/lircd usr/sbin
else
	cp --archive /usr/sbin/lircd usr/sbin
fi

# /usr/sbin: Debian stuff
cp --archive /bin/setserial /usr/sbin/gpm \
	usr/sbin

echo "Copying /usr/share..."
# /usr/share: Debian stuff
cp --archive /usr/share/consolefonts/lat1u-08.psf.gz usr/share/consolefonts/
cp --archive /usr/share/tabset usr/share
cp --archive /usr/share/terminfo/[l] usr/share/terminfo
# this also needs /etc/terminfo/(the same stuff)
cp --archive /etc/terminfo/[l] etc/terminfo

# save room by removing extended definitions
rm -f usr/share/terminfo/[l]/*-*

# /usr/local
# alsa - in usr/local/share or /usr/share (Debian)
cp --archive $targetdir/alsa/share/alsa usr/local/share/
ln -s /usr/local/share/alsa usr/share/alsa

echo "Copying MPlayer..."
# /usr/local/mplayer
cp --archive $targetdir/mplayer/usr/local/* usr/local/mplayer/
rm -rf usr/local/mplayer/man

echo "Creating symlinks..."
# create some necessary symlinks in /usr/bin
pushd usr/bin; ln -s ../local/bin/bugReport.sh debug; popd
pushd usr/bin; ln -s ../local/mplayer/bin/mplayer mplayer; popd
pushd usr/bin; ln -s ../local/bin/movix.pl movix; popd

# Check for libraries that aren't needed 
#(because MPlayer was compiled without them)
for lib in libSDL libaa libdvdread libfreetype libcdda_ \
		liblirc libogg libvorbis ; do
	if ldd usr/local/mplayer/bin/mplayer \
		| grep --silent $lib ; then
	# this lib is used in mplayer
		echo "$lib is compiled into mplayer, keeping it."
	else
		echo "Removing unused $lib*.so..."
		rm usr/lib/$lib*
	fi
done

if [ "X$withoutScsi" = "Xy" ]; then
	echo "Removing SCSI modules..."
	rm -rf lib/modules/*/kernel/drivers/scsi
fi

if [ "X$withoutLirc" = "Xy" ]; then
	echo "Removing LIRC..."
	rm -f usr/bin/irpty usr/sbin/lircd \
		lib/modules/*/misc/lirc_*.o.gz
	# usr/lib/lirc* was already removed if mplayer was compiled without
fi

if [ "X$withoutEm8300" = "Xy" ]; then
	echo "Removing em8300/DXR..."
	rm -f usr/bin/em8300setup \
		lib/modules/*/kernel/drivers/video/em8300.o.gz \
		lib/modules/*/kernel/drivers/video/bt865.o.gz \
		lib/modules/*/kernel/drivers/video/adv717x.o.gz
fi

# Programs that aren't active during playback can be freely compressed
if [ "X$useUpx" = "Xy" ]; then
	for prog in \
		bin/comm \
		bin/dialog \
		bin/setterm \
		sbin/depmod \
		sbin/insmod \
		sbin/pump \
		sbin/rpc.portmap \
		usr/bin/amixer \
		usr/bin/atitvout \
		usr/bin/autocal \
		usr/bin/consolechars \
		usr/bin/dhc \
		usr/bin/dxr3view \
		usr/bin/eject \
		usr/bin/em8300setup \
		usr/bin/epiatvout \
		usr/bin/iconv \
		usr/bin/ir* \
		usr/bin/lsdvd \
		usr/bin/nvtv \
		usr/bin/rexima \
		usr/bin/s3switch \
		usr/sbin/alsactl \
		usr/sbin/setserial \
		; do

		upx -q --best "$prog"
	done
fi

# Those programs are active while playing. Compressing them means that they
# use /tmp and therefore RAM. This is not good with little RAM.
if [ "X$useUpxHard" = "Xy" ]; then
	for prog in \
		sbin/devfsd \
		usr/bin/alsamixer \
		usr/bin/perl \
		usr/local/mplayer/bin/mplayer \
		; do

		upx -q --best "$prog"
	done
fi

# OK, everything is now in the initrd directory.
# Create the initrd image file.
cd $targetdir

if [ "X$startMc" = "Xy" ]; then
	mc initrd
fi

echo "Calculating size for initrd..."
# Determine the size of the initrd file
size=`du -ks initrd/ | awk '{print $1}'`
# add a bit additional room for files that will be copied at runtime
size=`expr $size + 512`

echo "Creating initrd image with $size kibibytes..."
# Create an empty image file with this size
dd if=/dev/zero of=initrd.img bs=1024 count=$size
# Create the filesystem
/sbin/mke2fs -Fq initrd.img 
# This fs doesn't need to be fscked
/sbin/tune2fs -c 0 -i 0 initrd.img 

echo "Mounting the initrd image..."
# Create a mountpoint and mount the initrd image
mkdir -p initrd.mnt
sudo /bin/mount -o loop initrd.img initrd.mnt

echo "Copying everything to the initrd image..."
# Copy everything from the initrd directory to the mounted image.
# This is done as root because only root can write on the last X kB.
sudo /bin/cp --archive initrd/* initrd.mnt/

echo "Adjusting file ownership..."
# "movix" is currently the owner of all files. But they should belong to root.
sudo /bin/chown -R root.root initrd.mnt/*

echo "Compressing the initrd image..."
# Umount and gzip the image
sudo /bin/umount initrd.img
gzip -9 initrd.img
mv initrd.img.gz initrd.gz

echo "Making release..."
# Copy stuff from all over to the release directory
mkdir -p $releasedir
cp $targetdir/initrd.gz $releasedir
cp $targetdir/vmlinuz $releasedir/vmlinuz

echo "Adjusting the isolinux config file..."
perl -pwe "s/(ramdisk_size)=\\d+ /\$1=$size /" \
	$configdir/$targetname-lib/isolinux/isolinux.cfg \
	> $releasedir/isolinux.cfg

if ldd $targetdir/initrd/usr/local/mplayer/bin/mplayer \
	| grep --silent libaa ; then
# mplayer was compiled with aa support
	echo -n
else
	echo "Removing aa boot labels from isolinux.cfg..."
	ssed -i '/^label aa/,+2d' $releasedir/isolinux.cfg
fi

if ldd $targetdir/initrd/usr/local/mplayer/bin/mplayer \
	| grep --silent libSDL ; then
# mplayer was compiled with SDL support
	echo -n
else
	echo "Removing sdl boot label from isolinux.cfg..."
	ssed -i '/^label sdl/,+2d' $releasedir/isolinux.cfg
fi

if ldd $targetdir/initrd/usr/local/mplayer/bin/mplayer \
	| grep --silent libfreetype ; then
# mplayer was compiled with freetype support
	echo "MPlayer has freetype support, you can use TrueType fonts."
else
	echo "Remember: MPlayer was compiled without freetype support, you "
	echo "can't use TrueType fonts."
fi

# Copy the release into a named subdirectory if a name was given
if [ "X$releaseName" != "X" ]; then
	mkdir -p "$releasedir/$releaseName"
	cp "$releasedir/initrd.gz" "$releasedir/vmlinuz" \
	   "$releasedir/isolinux.cfg" \
		"$releasedir/$releaseName/"
fi

echo "Your MoviX kernel and initrd.gz are now in $releasedir:"
ls -la $releasedir

# one last popd
popd
