#!/bin/bash
# install-bootsplash-acritox.sh - Automatically install bootsplash
# (C) by Andreas Loibl (acritox) <andreas@andreas-loibl.de>, 2006
# License: GPL

INITRD=/boot/initrd.img-$(uname -r)
INITRD_SPLASH=/boot/initrd.img-$(uname -r)
DEFAULT_THEME=kanotix
DEFAULT_RESOLUTIONS="800x600, 1024x768"

function rcPatch()
{
cat <<"EOF_RCPATCH"
--- rc.orig	2005-12-28 18:12:59.000000000 +0100
+++ rc	2005-12-28 19:13:35.000000000 +0100
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! /bin/bash
 #
 # rc		This file is responsible for starting/stopping
 #		services when the runlevel changes.
@@ -16,6 +16,9 @@
 # Author:	Miquel van Smoorenburg <miquels@cistron.nl>
 #		Bruce Perens <Bruce@Pixar.com>
 #
+# Edited for bootsplash by Matthew A. Nicholson <debian@matt-land.com>, 2003
+# bootsplash patch changed by Andreas Loibl <andreas@andreas-loibl.de>, 2005
+#
 # Version:	@(#)rc  2.78  07-Nov-1999  miquels@cistron.nl
 #
 
@@ -26,6 +28,23 @@
 # Un-comment the following for debugging.
 # debug=echo
 
+# source the bootsplash config file
+test -f /etc/default/bootsplash && . /etc/default/bootsplash
+
+#
+# Update bootsplash stuff. (progress bar, animations...)
+#
+rc_splash() {
+   #test "$SPLASH" != "no" && test "$_rc_splash" -eq 1 && /sbin/splash "$1"
+   test "$SPLASH" != "no" && /sbin/splash.sh "$1"
+
+   # make sure we don't add unless we really made progress
+   if [ "$1" != "master" -a "$1" != "splash start" -a "$1" != "shutdown" ]
+   then
+      progress=$(( $progress + 1 ))
+   fi
+}
+
 # Specify method used to enable concurrent init.d scripts.  Valid
 # options are 'none', 'shell' and 'startpar'
 CONCURRENCY=none
@@ -63,6 +82,9 @@
     esac
 }
 
+
+
+
   # Ignore CTRL-C only in this shell, so we can interrupt subprocesses.
   trap ":" INT QUIT TSTP
 
@@ -72,6 +94,7 @@
   # Now find out what the current and what the previous runlevel are.
 
   runlevel=$RUNLEVEL
+
   # Get first argument. Set new runlevel to this argument.
   [ "$1" != "" ] && runlevel=$1
   if [ "$runlevel" = "" ]
@@ -84,6 +107,86 @@
 
   export runlevel previous
 
+#
+# initialize boosplash progressbar variables
+#
+if [ S = "$runlevel" ]
+then
+	# we are booting up, so initialize bootsplash for this
+	runrcS=/etc/rcS.d
+	runrc=/etc/rc2.d  # assume we will boot into runlevel 2
+	
+	SSC=($(echo $runrcS/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=${#SSC[*]} ;;
+	esac
+	
+	SSC=($(echo $runrc/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=$((${#SSC[*]} + $sscripts)) ;;
+	esac
+	
+	progress=0
+	kscripts=0
+else
+	# we are not booting up, so initialize bootsplash for that
+	runrcS=/etc/rcS.d
+	runrc=/etc/rc$runlevel.d
+	prerc=/etc/rc$previous.d
+	
+	SSC=($(echo $runrc/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=${#SSC[*]} ;;
+	esac
+	
+	if [ "$previous" != "N" ]; then
+	KSC=($(echo $runrc/K*))
+	case "$KSC" in
+	*\*)
+	kscripts=0
+	;;
+	
+	*)
+	kscripts=${#KSC[*]}
+	;;
+	esac
+	fi
+	
+	if [ "$previous" = "N" ]; then
+	SSC=($(echo $runrcS/S*))
+	case "$SSC" in
+	*\*)
+	sscripts=0
+	;;
+	
+	*)
+	progress=${#SSC[*]}
+	sscripts=$((${#SSC[*]} + $sscripts))
+	;;
+	esac
+	else
+	progress=0
+	fi
+fi
+export sscripts progress kscripts
+
+#
+# let bootsplash know if we are booting up or shutting down
+#
+if [ "$runlevel" = "0" -o "$runlevel" = "6" ]
+then
+   # shutting down
+   rc_splash "splash start"
+   rc_splash "shutdown"
+elif [ S = "$runlevel" ]
+then
+   # booting up
+   rc_splash "splash start"
+fi
+
   if [ S = "$runlevel" ]
   then
 	#
@@ -137,6 +240,7 @@
 
                     # Stop the service.
                     SCRIPTS="$SCRIPTS $i"
+                    rc_splash "$i stop"          # handle bootsplash stuff
                 done
                 startup stop $SCRIPTS
             done
@@ -151,6 +255,11 @@
 			;;
 	esac
 
+	if [ "$runlevel" != "0" -a "$runlevel" != "6" ]
+	then
+		rc_splash "master"
+	fi
+
         # Now run the START scripts for this runlevel.
         # Run all scripts with the same level in parallel
         CURLEVEL=""
@@ -184,6 +293,7 @@
                     [ -f $previous_start ] && [ ! -f $stop ] && continue
 		fi
 		SCRIPTS="$SCRIPTS $i"
+		rc_splash "$i $ACTION"           # handle bootsplash stuff
 	    done
 	    startup $ACTION $SCRIPTS
         done
@@ -205,4 +315,7 @@
 		/sbin/setup.sh
 	fi
   fi
+
+rc_splash "master"   # finish up bootsplash
+
 # eof /etc/init.d/rc
EOF_RCPATCH
}

function rcPatchAlternative()
{
cat <<"EOF_RCPATCH"
--- rc.neu	2006-01-31 17:29:00.000000000 +0100
+++ rc.neu-changed	2006-01-31 17:28:23.000000000 +0100
@@ -12,6 +12,8 @@
 # Authors:
 # 	Miquel van Smoorenburg <miquels@cistron.nl>
 # 	Bruce Perens <Bruce@Pixar.com>
+#
+# Edited for bootsplash by Andreas Loibl <andreas@andreas-loibl.de>, 2005
 
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
 export PATH
@@ -19,6 +21,23 @@
 # Un-comment the following for debugging.
 # debug=echo
 
+# source the bootsplash config file
+test -f /etc/default/bootsplash && . /etc/default/bootsplash
+
+#
+# Update bootsplash stuff. (progress bar, animations...)
+#
+rc_splash() {
+   #test "$SPLASH" != "no" && test "$_rc_splash" -eq 1 && /sbin/splash "$1"
+   test "$SPLASH" != "no" && /sbin/splash.sh "$1"
+
+   # make sure we don't add unless we really made progress
+   if [ "$1" != "master" -a "$1" != "splash start" -a "$1" != "shutdown" ]
+   then
+      progress=$(( $progress + 1 ))
+   fi
+}
+
 # Specify method used to enable concurrent init.d scripts.
 # Valid options are 'none', 'shell' and 'startpar'
 CONCURRENCY=none
@@ -58,6 +77,7 @@
 				$debug "$script" $action
 				;;
 			esac
+			rc_splash "$script $action"           # handle bootsplash stuff
 		done
 	}
 	;;
@@ -89,6 +109,7 @@
 				backgrounded=1
 				;;
 			esac
+			rc_splash "$script $action"           # handle bootsplash stuff
 		done
 		[ 1 = "$backgrounded" ] && wait
 	}
@@ -118,6 +139,7 @@
 					newscripts="$newscripts $script"
 					;;
 				esac
+				rc_splash "$script $action"           # handle bootsplash stuff
 			done
 			scripts="$newscripts"
 		fi
@@ -155,6 +177,89 @@
 
 export runlevel previous
 
+#
+# initialize boosplash progressbar variables
+#
+if [ S = "$runlevel" ]
+then
+	# we are booting up, so initialize bootsplash for this
+	runrcS=/etc/rcS.d
+	runrc=/etc/rc2.d  # assume we will boot into runlevel 2
+	
+	SSC=($(echo $runrcS/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=${#SSC[*]} ;;
+	esac
+	
+	SSC=($(echo $runrc/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=$((${#SSC[*]} + $sscripts)) ;;
+	esac
+	
+	progress=0
+	kscripts=0
+else
+	# we are not booting up, so initialize bootsplash for that
+	runrcS=/etc/rcS.d
+	runrc=/etc/rc$runlevel.d
+	prerc=/etc/rc$previous.d
+	
+	SSC=($(echo $runrc/S*))
+	case "$SSC" in
+	*\*) sscripts=0 ;;
+	*) sscripts=${#SSC[*]} ;;
+	esac
+	
+	if [ "$previous" != "N" ]; then
+	KSC=($(echo $runrc/K*))
+	case "$KSC" in
+	*\*)
+	kscripts=0
+	;;
+	
+	*)
+	kscripts=${#KSC[*]}
+	;;
+	esac
+	fi
+	
+	if [ "$previous" = "N" ]; then
+	SSC=($(echo $runrcS/S*))
+	case "$SSC" in
+	*\*)
+	sscripts=0
+	;;
+	
+	*)
+	progress=${#SSC[*]}
+	sscripts=$((${#SSC[*]} + $sscripts))
+	;;
+	esac
+	else
+	progress=0
+	fi
+fi
+export sscripts progress kscripts
+
+#
+# let bootsplash know if we are booting up or shutting down
+#
+if [ "$runlevel" = "0" -o "$runlevel" = "6" ]
+then
+   # shutting down
+   rc_splash "splash start"
+   rc_splash "shutdown"
+elif [ S = "$runlevel" ]
+then
+   # booting up
+   rc_splash "splash start"
+   rc_splash "master"
+else
+   rc_splash "master"
+fi
+
 if [ S = "$runlevel" ]
 then
 	#
@@ -281,14 +386,6 @@
 			SCRIPTS="$SCRIPTS $i"
 		done
 		startup $ACTION $SCRIPTS
-
-		# Use 50% of the progress bar for rcS and the rest for the
-		# runlevel we want to end up in
-		step=$(($step + $step_change))
-		progress=$(($step * $progress_size / $num_steps + $first_step))
-		if type usplash_write >/dev/null 2>&1; then
-			usplash_write "PROGRESS $progress" || true
-		fi
 	done
 fi
 
@@ -313,3 +410,4 @@
 
 exit 0
 
+rc_splash "master"   # finish up bootsplash

EOF_RCPATCH
}

if test $(id -u) != 0; then
    echo Error: You must be root to run this script!
    exit 4
fi

if [ "uninstall" = "$1" ]; then
    echo "Uninstalling bootsplash and all its themes..."

    echo "Reverse-patching files..."
    if rcPatch | patch /etc/init.d/rc --dry-run -Rfs; then
        echo "Patching files..."
        rcPatch | patch /etc/init.d/rc -R
    elif rcPatchAlternative | patch /etc/init.d/rc --dry-run -Rfs; then
        echo "Patching files..."
        rcPatchAlternative | patch /etc/init.d/rc -R
    else
        echo "Patches would not apply cleanly. (Perhaps it is already patched?)"
        echo "Not patching start up files..."
    fi

    yes | DEBIAN_FRONTEND=noninteractive apt-get --purge remove bootsplash

    echo "Reverse-patching /boot/grub/menu.lst..."
    perl -pi -e 's/^(# kopt=.*)splash=silent(.*)$/\1\2/g' /boot/grub/menu.lst
    
    echo "Updating Grub..."
    update-grub
    
    echo "Bootsplash is uninstalled."
    exit 0
fi

if ! zgrep -q CONFIG_BOOTSPLASH=y /proc/config.gz; then
    echo Error: Your kernel $(uname -r) doesn\'t support Bootsplash!
    exit 5
fi

# add bootsplash.de sources if neccessary
if ! grep -q 'deb http://bootsplash.de unstable main' /etc/apt/sources.list; then
echo "Adding bootsplash.de sources to /etc/apt/sources.list ..."
echo "
# bootsplash
deb http://bootsplash.de unstable main
deb-src http://bootsplash.de unstable main
" >> /etc/apt/sources.list
fi

if ! ( dpkg -l bootsplash 2>/dev/null | egrep -q '^ii' ); then
    # install deb-packages
    echo "Updating package lists..."
    apt-get update
    echo "Installing packages..."
    # we need "yes" here because bootsplash.de doesn't sign its packages
    yes | DEBIAN_FRONTEND=noninteractive apt-get install bootsplash-theme-$DEFAULT_THEME bootsplash 2>/dev/null
    echo "Setting default values..."
    echo set shared/bootsplash-bootloader grub | debconf-communicate bootsplash
    echo set shared/bootsplash-initrd none | debconf-communicate bootsplash
    echo set shared/bootsplash-initscript true | debconf-communicate bootsplash
    echo set shared/bootsplash-theme bootsplash-theme-$DEFAULT_THEME | debconf-communicate bootsplash-theme-$DEFAULT_THEME
    echo set bootsplash-theme-$DEFAULT_THEME/resolutions "$DEFAULT_RESOLUTIONS" | debconf-communicate bootsplash-theme-$DEFAULT_THEME
    echo set bootsplash-theme-$DEFAULT_THEME "" | debconf-communicate bootsplash-theme-$DEFAULT_THEME
    echo set shared/bootsplash-bootloader-info "" | debconf-communicate bootsplash
    echo set shared/bootsplash-custom-initrd "" | debconf-communicate bootsplash
    echo "Reconfiguring bootsplash..."
    yes | DEBIAN_FRONTEND=noninteractive apt-get -f install
    DEBIAN_FRONTEND=noninteractive dpkg-reconfigure bootsplash
else
    echo "Package \"bootsplash\" is already installed, skipping its installation..."
fi
# test if patch applies cleanly:
echo "Testing if patches apply cleanly..."
rcPatch | patch /etc/init.d/rc --dry-run -bfs

if [ $? -eq 0 ]; then
    echo "Patching files..."
    rcPatch | patch /etc/init.d/rc -b
elif rcPatchAlternative | patch /etc/init.d/rc --dry-run -bfs; then
    echo "Patching files..."
    rcPatchAlternative | patch /etc/init.d/rc -b
else
    echo "Patches would not apply cleanly. (Perhaps it is already patched?)"
    echo "Not patching start up files..."
fi

# Get resolution from debconf
THEME="$(echo get shared/bootsplash-theme | debconf-communicate bootsplash | cut -d\  -f2)"
echo "Selected bootsplash-theme: $THEME"
RESOLUTION="$(echo get $THEME/resolutions | debconf-communicate bootsplash | tr ' ' '\n' | tail -n1 )"
echo "Using resolution: $RESOLUTION"
SPLASH="/etc/bootsplash/themes/current/config/bootsplash-$RESOLUTION.cfg"

# create initrd.splash
echo "Creating $INITRD_SPLASH ..."
initrd_dir=$(mktemp -t -d initrd.XXXXXX)
backdir="$PWD"
cd "$initrd_dir"
if [ -f "$INITRD" ]; then
    echo "Using old initrd..."
    gzip -cd "$INITRD" | cpio -i
else
    echo "Creating a new initrd..."
fi
if [ -f "$SPLASH" ]; then
    echo "Adding Bootsplash from $SPLASH ..."
    splash -s -f "$SPLASH" > bootsplash
fi
find . | cpio --quiet -o -H newc > "$INITRD_SPLASH.tmp"
gzip -9 < "$INITRD_SPLASH.tmp" > "$INITRD_SPLASH"
rm -f "$INITRD_SPLASH.tmp"
echo "$INITRD_SPLASH has been written."
cd "$backdir"
rm -rf "$initrd_dir"

# patch /boot/grub/menu.lst
if ! grep -q "splash" /boot/grub/menu.lst; then
    echo "Patching /boot/grub/menu.lst to use 'splash=silent'..."
    cp -a /boot/grub/menu.lst /boot/grub/menu.lst.bak
    perl -pi -e 's/(# kopt=.*$)/\1 splash=silent/' /boot/grub/menu.lst
fi

echo "Updating Grub..."
update-grub
