#!/bin/dash
#
# Minimal init to start Fatdog on User Mode Linux
# Copyright (C) James Budiono 2013, 2014
# License: GNU GPL Version 3 or later.
#
# Note: This is UML init script - pid 1
# Version 2 for Fatdog64 700
#
# Requirement: UML kernel must be compiled with the support:
# - loopback, ext4, squashfs, aufs and devtmpfs

### config
OLD_ROOT=initrd
AUFS_ROOT=/aufs
NEW_ROOT=$AUFS_ROOT/new_root
BASE_SFS_MOUNT=$AUFS_ROOT/pup_ro
SAVEFILE_MOUNT=$AUFS_ROOT/pup_save
BASE_SFS_DEVICE=/dev/ubda
SAVEFILE_DEVICE=	# filled in later
#SAVEFILE_PATH		# set by caller
AUFS_ROOT_ID=		# filled in later
CONFIGURED_NET=eth0:ip # hardcoded - sign that network is already setup on boot

############ main ##########

### critical
export TERM=rxvt-unicode # our console is urxvt
/bin/busybox mkdir -p /proc /sys /dev
/bin/busybox mount -t proc proc /proc
mount -t sysfs sysfs /sys

# earlyshell
grep -q earlyshell /proc/cmdline && echo "Starting early shell. Type 'exit' to continue, 'halt -f' to stop." && 
setsid cttyhack ash

# mount basesfs and savefile (use tmpfs if not exist)
mkdir -p $BASE_SFS_MOUNT $SAVEFILE_MOUNT $NEW_ROOT
mount -o ro $BASE_SFS_DEVICE $BASE_SFS_MOUNT
if [ -e $SAVEFILE_PATH ]; then
	! [ -c /dev/null ] && mount -t devtmpfs devtmpfs /dev # perhaps devtmpfs wasn't attached
	SAVEFILE_DEVICE=$(losetup -f)
	if ! { losetup $SAVEFILE_DEVICE $SAVEFILE_PATH && mount $SAVEFILE_DEVICE $SAVEFILE_MOUNT; } then
		losetup -d $SAVEFILE_DEVICE
		mount -t tmpfs tmpfs $SAVEFILE_MOUNT
		SAVEFILE_DEVICE=tmpfs
	fi
else
	mount -t tmpfs tmpfs $SAVEFILE_MOUNT
	SAVEFILE_DEVICE=tmpfs
fi

# prepare aufs root - union basesfs and savefile
mount -t aufs aufs $NEW_ROOT -o br:$SAVEFILE_MOUNT=rw:$BASE_SFS_MOUNT=rr
AUFS_ROOT_ID=$(ls /sys/fs/aufs) 

# setup init system
if ! cmp /bin/busybox $NEW_ROOT/sbin/init >/dev/null; then
	rm $NEW_ROOT/sbin/init 
	cp /bin/busybox $NEW_ROOT/sbin/init # use static busybox as init
fi
# use host provided inittab and init files
cp rc.*.uml $NEW_ROOT/etc/rc.d
cp inittab $NEW_ROOT/etc

# switch to $NEW_ROOT, keep old one in $OLD_ROOT
mkdir -p $NEW_ROOT/$OLD_ROOT
pivot_root $NEW_ROOT $NEW_ROOT/$OLD_ROOT

#####################################
###### RUNNING IN NEW ROOT NOW ######
#####################################

# move the mounts to the new root
for p in /dev /sys /proc $SAVEFILE_MOUNT $BASE_SFS_MOUNT; do
	busybox mkdir -p $p
	busybox mount -o move /$OLD_ROOT/$p $p
done

# create /etc/BOOTSTATE
for p in AUFS_ROOT BASE_SFS_MOUNT SAVEFILE_MOUNT BASE_SFS_DEVICE SAVEFILE_DEVICE CONFIGURED_NET AUFS_ROOT_ID; do
	eval echo $p=\\\'\$$p\\\'
done > /etc/BOOTSTATE

# patch files
echo "DISPLAY='$DISPLAY'" > /etc/X11/host-x11 # save DISPLAY from host
sed -i -e '\_xinit $HOME/.xinitrc_ s|xinit|. /etc/X11/host-x11; export DISPLAY;|' /usr/bin/xwin
#sed -i -e 's|xinit|. /etc/X11/host-x11; export DISPLAY;|' /usr/bin/xwin
! grep -q UML /etc/shinit && echo 'PS1="UML $PS1"' >> /etc/shinit
cp /$OLD_ROOT/wmexit /usr/bin 

# remove services not supported in UML
rm -f /etc/init.d/50-Wpagui /etc/init.d/85-bluetooth /etc/init.d/99-alsa \
      /etc/xdg/Startup/WpaGui /etc/xdg/Startup/Batterymeter \
      /etc/xdg/Startup/load-touchpad-settings /etc/xdg/Startup/bluetooth-applet
ln -sf /bin/true /usr/bin/radeon-dpm-control.sh

# preparation for rc.sysinit
ln -sf /tmp /run
busybox mkdir -p /dev/pts /dev/shm /tmp # rc.sysinit expects these
busybox umount -l -r /$OLD_ROOT; rmdir /$OLD_ROOT # make unaccessible

# lateshell - lateshell running in NEW_ROOT
grep -q lateshell /proc/cmdline && 
echo "Starting late shell. Type 'exit' to continue, 'halt -f' to stop." && 
setsid cttyhack ash

# done, now lets run our real init
exec /sbin/init

#exec setsid cttyhack ash
#exec setsid ash -c 'exec sh </dev/tty0 >/dev/tty0 2>&1'
#chroot $NEW_ROOT /usr/bin/setsid /bin/cttyhack /bin/sh -login $START_CMD
