#! /bin/bash

# Builds the eMoviX initrd

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

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

# Constants and setup
targetname=emovix
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 ":hielsSbuUmr:" opt; do
        case $opt in

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

  -e      don't include em8300/DXR programs/modules
  -i      don't include iconv character set conversion
  -l      don't include LIRC programs/modules
  -s      don't include SCSI kernel modules
  -S      include only a few SCSI kernel modules (for popular adapters)

  -b      don't include the bootsplash files

  -u      use the UPX packer to compress a few programs
  -U      use the UPX packer to compress more programs

  -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 iconv
		i )	withoutIconv=y
		;;

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

		# don't include all SCSI modules, just a few
		S )	withoutAllScsi=y
		;;

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

		# don't include bootsplash images
		b )	withoutBootsplash=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/lib/gconv usr/libexec \
	usr/share/consolefonts usr/share/kbd usr/share/terminfo \
	usr/local/bin usr/local/lib usr/local/share \
	usr/local/alsa \
	var/lock 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 \
	bin/

echo "Copying /etc..."
# Copy eMoviX /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

if [ "X$withoutBootsplash" != "Xy" ]; then

	# bootsplash configs
	if ! [ -e $configdir/bootsplash/themes/current ]; then
	# there is no "current" symlink to the MoviX directory because 
	# CVS doesn't understand symlinks - so create it now
		ln -s MoviX $configdir/bootsplash/themes/current
	fi

	# Copy the distribution-specific bootsplash images to the central directory
	cp $configdir/bootsplash/alt-pics/$targetname/* $configdir/bootsplash/themes/current/images/

	# Copy the bootsplash stuff to  the initrd
	mkdir -p etc/bootsplash/themes
	cp --archive /etc/bootsplash/themes/* etc/bootsplash/themes
	# but remove the progress images because they are not needed 
	# on the booted *MoviX* system
	rm etc/bootsplash/themes/current/images/movix.*.jpg
fi

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

echo "Copying /lib..."
# original Debian libs to /lib
cp --archive /lib/ld-linux*.so* /lib/ld-2.*.so \
	/lib/libc-*.so /lib/libc.so* /lib/libdl*.so* \
	/lib/libm*.so* /lib/libncurses*.so* /lib/libnsl*.so* \
	/lib/libproc*.so* /lib/libpthread* \
	/lib/libgcc*.so* \
	/lib/libconsole* /lib/libcfont* /lib/libctutils* \
	lib/

echo "Copying /usr/lib..."
# the same for /usr/lib (Debian has some libs there)
cp --archive /usr/lib/libgpm*.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/hdparm sbin/
# compiled or system devfsd
if [ -d $targetdir/devfsd/sbin ]; then
	cp --archive $targetdir/devfsd/sbin/devfsd sbin/
else
	cp --archive /sbin/devfsd sbin/
fi

# 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/find \
	/usr/bin/ldd /usr/bin/lsdvd \
	/usr/bin/consolechars /usr/bin/iconv \
	/usr/bin/kbd_mode \
	/usr/bin/ogginfo /usr/bin/setfont \
	usr/bin/

# Debian's ldd script wants to use bash. It is changed to sh on the initrd.
perl -pw -i -e 's!/bin/bash!/bin/sh!' usr/bin/ldd

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 without libcrypt dependency
	cp --archive $configdir/$targetname-lib/bin/perl usr/bin/
else	
	# The "bloated" Debian perl which also requires libcrypt
	cp --archive /usr/bin/perl usr/bin/
	cp --archive /lib/libcrypt*.so* lib/
fi

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/em8300setup usr/bin/
else
	cp --archive /usr/bin/em8300setup usr/bin/
fi

echo "Copying LIRC..."
if [ -d $targetdir/lirc/bin ]; then
	# /usr/bin: compiled lirc stuff
	#cp --archive $targetdir/lirc/bin/irpty usr/bin/
	cp --archive $targetdir/lirc/lib/liblirc_client.so* usr/lib
else
	#cp --archive /usr/bin/irpty usr/bin/
	cp --archive /usr/lib/liblirc_client.so* usr/lib
fi

echo "Copying TV out programs..."
# /usr/bin: compiled tv out stuff
cp --archive $targetdir/nvtv/bin/nvtv $targetdir/usr/bin/* \
	usr/bin/
# nvtv requires libpci.so
cp --archive /usr/lib/libpci.so* usr/lib

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/libdvdread*.so* \
	/usr/lib/libfaad*.so* /usr/lib/libz*.so* \
	/usr/lib/libogg*.so* /usr/lib/libvorbis*.so* \
	/usr/lib/libfreetype*.so* /usr/lib/libstdc++.so* \
	usr/lib

# ICONV plugins
cp --archive \
	/usr/lib/gconv/lib* /usr/lib/gconv/gconv-modules \
	/usr/lib/gconv/ISO* /usr/lib/gconv/CP*  \
	usr/lib/gconv

# 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 eMovix, 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: compiled stuff
cp --archive $targetdir/usr/sbin/* \
	usr/sbin

# /usr/sbin: Debian stuff
cp --archive /bin/setserial /usr/sbin/fbset \
	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/consolefonts/LatArCyrHeb-14.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..."
# Formerrly /usr/local/mplayer
cp --archive $targetdir/mplayer/usr/local/* usr/local/
rm -rf usr/local/man
# symlink for compatibility with scripts that want /usr/local/mplayer/bin etc.
ln -s /usr/local usr/local/mplayer

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/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_ \
		libogg libvorbis libstdc ; do
	if ldd usr/local/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$withoutAllScsi" = "Xy" ]; then
	echo "Removing some SCSI modules..."
	for module in lib/modules/*/kernel/drivers/scsi/*.o \
			lib/modules/*/kernel/drivers/scsi/*/*.o ; do

		case $module in 
			# Don't delete those modules
			*/aic*.o ) ;;
			*/atp*.o ) ;;
			*/fdomain*.o ) ;;
			*/ide-scsi*.o ) ;;
			*/ncr53*.o ) ;;
			*/*NCR53*.o ) ;;
			*/pci200*.o ) ;;
			*/qlogic*.o ) ;;
			*/sym53*.o ) ;;
			*/sim*.o ) ;;
			*/scsi_mod*.o ) ;;
			*/sr_mod*.o ) ;;
			*/tmscsim*.o ) ;;
			*/ultrastor*.o ) ;;
			*/wd7000*.o ) ;;

			# delete the rest
			*) rm $module
			   echo $module removed
			   ;;
		esac
	done
fi

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

if [ "X$withoutIconv" = "Xy" ]; then
	echo "Removing Iconv..."
	rm -rf usr/bin/iconv usr/lib/gconv
fi

if [ "X$withoutLirc" = "Xy" ]; then
	echo "Removing LIRC..."
	rm -f usr/bin/irpty usr/sbin/lircd \
		lib/modules/*/misc/lirc_*.o \
		usr/lib/liblirc*
fi

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

echo "Compressing Linux kernel modules..."
pushd $initrddir/lib/modules
for module in `find . -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

# Programs that aren't active during playback can be freely compressed
if [ "X$useUpx" = "Xy" ]; then
	for prog in \
		bin/setterm \
		sbin/depmod \
		sbin/insmod \
		usr/bin/amixer \
		usr/bin/atitvout \
		usr/bin/epiatvout \
		usr/bin/find \
		usr/bin/lsdvd \
		usr/bin/nvtv \
		usr/bin/ogginfo \
		usr/bin/s3switch \
		usr/sbin/fbtruetype \
		usr/sbin/progress \
		; 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/bin/mplayer \
		; do

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

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

find initrd -name CVS -type d | xargs rm -rf

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 + 128`
size=$[ $size * 101 / 100 ] # one percent more

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/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/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/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

if [ "X$withoutBootsplash" != "Xy" ]; then

	echo "Appending bootsplash to the initrd.gz..."
	for conf in 1400x1050 1280x1024 1024x768 800x600 640x480; do
		$sourcedir/splashutils/splash -s \
			-f "/etc/bootsplash/themes/current/config/bootsplash-$conf.cfg" \
			>> "$releasedir/initrd.gz"
	done
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 eMoviX kernel and initrd.gz are now in $releasedir:"
ls -la $releasedir

# one last popd
popd
