#!/bin/ash
LIVELABEL="SlackLive" #edit in build-slackware-live.sh script too
if [ -z "$livelabel" ]; then #(undocumented)
	livelabel=$LIVELABEL
fi

echo ""
echo "*** Live system initialization ***"
mount -n proc /proc -t proc
mount -n sysfs /sys -t sysfs
mount -n tmpfs /run -t tmpfs -o mode=0755
mount -n devtmpfs /dev -t devtmpfs
udevd --daemon --resolve-names=never
udevadm trigger --subsystem-match=block --action=add
udevadm settle --timeout=10
/load_kernel_modules 2>/dev/null
mkdir /tmp
mkdir /live

#mount live media
mkdir /live/media
mediadetected="none"
if [ ! -z "$nfsroot" ]; then
	mediadetected="nfs"
	address=`echo $ip | cut -f1 -d:`
	netmask=`echo $ip | cut -f4 -d:`
	gateway=`echo $ip | cut -f3 -d:`
	ifconfig eth0 $address netmask $netmask
	route add default gw $gateway
	mount -t nfs -o nolock $nfsroot /live/media
	echo "$livelabel found on $nfsroot"
else
	sleeptime=0
	while [ "$mediadetected" = "none" ] && [ "$sleeptime" != "10" ]; do #try each seconds, but don't wait (USB) more than 10 seconds
		if blkid | grep -q "LABEL=\"$livelabel\""; then
			livedevice=`blkid | grep "LABEL=\"$livelabel\"" | sed -n 1p | cut -f1 -d:`
			echo "$livelabel found on $livedevice"
			mount -o ro $livedevice /live/media
			if blkid | grep "LABEL=\"$livelabel\"" | sed -n 1p | grep -q "TYPE=\"iso9660\""
			then mediadetected="cd"
			else mediadetected="sd"
			fi
		else
			sleep 1
			let sleeptime+=1
		fi
	done
fi

if [ "$mediadetected" = "none" ]; then 
	echo -e "\nError: $livelabel not found"
	exec sh
fi

#copy live-media to RAM if requested
if [ "$copy2ram" = "yes" ]; then
	echo -n "Copying live system to RAM ..."
	mkdir /live/tmp
	mount --move /live/media /live/tmp
	mount -t tmpfs none /live/media
	
	mkdir /live/media/boot
	for bootfile in `find /live/tmp/boot -maxdepth 1 -type f`; do
		cp $bootfile /live/media/boot/
	done
	cp -r /live/tmp/boot/grub /live/media/boot/
	touch /live/media/boot/
	mkdir /live/media/boot/modules
	if [ `ls /live/tmp/boot/modules/ | wc -l` != 0 ]; then
		for module in /live/tmp/boot/modules/*; do #first copy main non excluded modules
			modulename=`basename $module`
			if ! echo $exclude | sed 's/:/\n/g' | grep -q "^$modulename$"; then
				cp /live/tmp/boot/modules/$modulename /live/media/boot/modules/
			fi
		done
	fi
	mkdir /live/media/boot/optional
	for modulename in `echo $include | sed 's/:/ /g'`; do #copy included optional modules
		if [ -f /live/tmp/boot/optional/$modulename ]; then
			cp /live/tmp/boot/optional/$modulename /live/media/boot/optional/
		fi
	done
	
	umount /live/tmp
	rmdir /live/tmp
	mount -o remount,ro /live/media
	if [ "$mediadetected" = "cd" ]; then
		eject $livedevice
	fi
	echo " done"
fi

#mount all modules in /live/modules/* except excluded ones
mkdir /live/modules
modulescount=0
if [ `ls /live/media/boot/modules/ | wc -l` != 0 ]; then
	for module in /live/media/boot/modules/*; do
		modulename=`basename $module`
		if ! echo $exclude | sed 's/:/\n/g' | grep -q "^$modulename$"; then #if module is not excluded by bootparam
			mkdir /live/modules/$modulename
			mount -o loop -t squashfs $module /live/modules/$modulename
			modulesbranches="/live/modules/$modulename=ro:$modulesbranches"
			echo "Loading SquashFS module $modulename"
			modulescount=$(($modulescount+1))
		fi
	done
fi

#load requested optional modules
for modulename in `echo $include | sed 's/:/ /g'`; do
	if [ -f /live/media/boot/optional/$modulename ]; then
		mkdir /live/modules/$modulename
		mount -o loop -t squashfs /live/media/boot/optional/$modulename /live/modules/$modulename
		modulesbranches="/live/modules/$modulename=ro:$modulesbranches"
		echo "Loading SquashFS module $modulename"
		modulescount=$(($modulescount+1))
	fi
done

if [ $modulescount = 0 ]; then 
	echo -e "\nError: no modules has been loaded"
	exec sh
fi

modulesbranches=`echo $modulesbranches | sed 's/:$//'`
unionfsmodulesbranches=$modulesbranches
overlaymodulesbranches=`echo $modulesbranches | sed 's/=ro//g'`

#mount (union) all modules in /live/system (ro)
mkdir /live/system
if [ $modulescount = 1 ]; then
	mount --bind $overlaymodulesbranches /live/system
else
	if [ "$mediadetected" != "nfs" ]
	then mount -t overlay -o ro,lowerdir=$overlaymodulesbranches overlay /live/system
	else unionfs -o ro,allow_other,suid,dev,use_ino,cow,max_files=524288 $unionfsmodulesbranches /live/system
	fi
fi

#setup persistent system changes
mkdir /live/changes
workdir=/live/changes/.workdir
upperdir=/live/changes/_
if [ ! -z "$changes" ] && [ "$mediadetected" != "cd" ]; then #TODO: 'changes' should be 'persist'
	echo "Using persistent system storage ($changes)"
	if [ "$mediadetected" = "nfs" ]; then
		mount -t nfs -o nolock $changes /live/changes #TODO: no auth / security
	else
		changesdevice=`blkid | grep "\"$changes\"" | cut -f1 -d:`
		if [ "$changesdevice" = "$livedevice" ]; then
			changes="/changes"
			changesdevice=""
		fi
		if [ -z "$changesdevice" ]; then #directory
			mount -o remount,rw,noatime /live/media
			sed 's@^\(.* /live/media .*\) ro@\1 rw,noatime@' -i /etc/mtab
			mkdir -p /live/media$changes
			workdir=/live/media$changes/.workdir
			upperdir=/live/media$changes/_
		else #device
			mount $changesdevice /live/changes
		fi
	fi
else
	mount -t tmpfs tmpfs /live/changes
fi

#mount (union) all modules (ro) and /live/changes (rw) in /live/union (rw)
if [ "$mediadetected" != "nfs" ]; then
	mkdir -p $workdir
	mkdir -p $upperdir
	mount -t overlay -o workdir=$workdir,upperdir=$upperdir,lowerdir=$overlaymodulesbranches overlay /mnt
else
	unionfs -o allow_other,suid,dev,use_ino,cow,max_files=524288, /live/changes=rw:$unionfsmodulesbranches /mnt
fi

#setup system tree
mkdir -p /mnt/tmp
mkdir -p /mnt/sys
mkdir -p /mnt/proc
mkdir -p /mnt/dev
mkdir -p /mnt/live
cat > /mnt/etc/fstab << END
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
none / tmpfs defaults 0 0
END

#system startup tweaking
if [ ! -z "$changes" ]; then
	cp -f /live/system/etc/rc.d/rc.S /mnt/etc/rc.d/ 2>/dev/null
	cp -f /live/system/etc/rc.d/rc.M /mnt/etc/rc.d/ 2>/dev/null
	cp -f /live/system/etc/rc.d/rc.modules /mnt/etc/rc.d/ 2>/dev/null
	rm -f /mnt/etc/udev/rules.d/70-persistent-net.rules
	rm -f /mnt/var/lib/alsa/asound.state
fi
touch /mnt/etc/fastboot

if [ "$fastboot" = "yes" ]; then #faster startup (actions already done by "build-slackware-live.sh --sysprep")
	echo "Enabling fast boot"
	sed	-e 's@^\( */usr/bin/fc-cache.*\)$@: #\1@' \
		-e 's@^\( */usr/bin/gtk-update.*\)$@: #\1@' \
		-e 's@^\( */usr/bin/update-gdk.*\)$@: #\1@' \
		-e 's@^\( */usr/bin/update-gtk.*\)$@: #\1@' \
		-e 's@^\( */usr/bin/update-mime-database.*\)$@: #\1@' \
		-e 's@^\( */usr/bin/glib-compile-schemas.*\)$@: #\1@' \
		-e 's@^\( */sbin/ldconfig.*\)$@: #\1@' \
		-i /mnt/etc/rc.d/rc.M
	sed	's@^\( */sbin/depmod.*\)$@: #\1@' -i /mnt/etc/rc.d/rc.modules
fi
if [ "$mediadetected" = "nfs" ] && [ -x /mnt/etc/rc.d/rc.networkmanager ]; then 
	chmod -x /mnt/etc/rc.d/rc.networkmanager #if enabled, system hangs
fi

#system shutdown tweaking
if [ ! -z "$changes" ]; then
	cp -f /live/system/etc/rc.d/rc.6 /mnt/etc/rc.d/ 2>/dev/null
fi
sed 's/\(\/rc.[06]\)\( fast\)*/\1 fast/' -i /mnt/etc/inittab #to prevent system hang at shutdown
sed -e 's@^\( *\)\([a-z/]*sleep.*\)@\1: #\2@' \
	-e 's@^\( *\)\([a-z/]*sync\)@\1: #\2@' \
	-e 's@^\(.* -t no,.*\)$@#\1\
for m in `mount -t no,proc,sysfs | cut -f3 -d" " | sed -e /^.live/d -e /^.home/d -e /^.$/d`; do umount $m; done@' \
	-i /mnt/etc/rc.d/rc.6 #umounts everything but live system, /home and /
if [ ! -z "$home" ] && [ "$mediadetected" != "cd" ]; then
	if [ -z "$home" ]; then
		sed 's@^\(.*-o remount.*\)$@\1 2>/dev/null\
mount -n -o remount,ro /live/media@' \
		-i /mnt/etc/rc.d/rc.6
	else
		sed 's@^\(.*-o remount.*\)$@while ! umount /home 2>/dev/null; do echo -n "."; sync; sleep 1; done; echo ""\
\1 2>/dev/null\
mount -n -o remount,ro /live/media@' \
		-i /mnt/etc/rc.d/rc.6
	fi
fi
if [ "$mediadetected" = "nfs" ]; then
	sed -e 's@^\( *\)\([a-z/]*fuser -k.*\)@\1: #\2@' \
		-e 's@^\( *\)\([a-z/]*dhcpcd -k.*\)@\1: #\2@' \
		-e 's@^\( *\)\(\. /etc/rc\.d/rc\.inet1 stop\)@\1: #\2@' \
		-e 's@-t \(nfs,\)\(.*\)@-t \2 #\1@' \
		-i /mnt/etc/rc.d/rc.6
fi
if [ "$mediadetected" = "cd" ] && [ "$copy2ram" != "yes" ]; then
	sed	-e "s@\(/sbin/reboot\)@reboot -w; shutdown -k now \>/dev/null\n  cdrecord --eject dev=$livedevice \>/dev/null 2\>\&1\n  sleep 5\n  \1@" \
		-e "s@\(/sbin/poweroff\)@poweroff -w; shutdown -k now \>/dev/null\n  cdrecord --eject dev=$livedevice \>/dev/null 2\>\&1\n  sleep 5\n  \1@" \
		-i /mnt/etc/rc.d/rc.6
fi

#setup persistent homedir
if [ ! -z "$home" ] && [ "$mediadetected" != "cd" ]; then
	echo "Setting up persistent home directory ($home)"
	if [ "$mediadetected" = "nfs" ]; then
		mount -t nfs -o nolock $home /mnt/home
		echo "$home /home nfs nolock 0 0" >> /mnt/etc/fstab
	else
		homedevice=`blkid | grep "\"$home\"" | cut -f1 -d:`
		if [ "$homedevice" = "$livedevice" ]; then
			home="/home"
			homedevice=""
		fi
		if [ -z "$homedevice" ]; then #directory
			mount -o remount,rw,noatime /live/media
			sed 's@^\(.* /live/media .*\) ro@\1 rw,noatime@' -i /etc/mtab
			mkdir -p /live/media/$home
			mount --bind /live/media/$home /mnt/home
			echo "/live/media$home /home none bind 0 0" >> /mnt/etc/fstab
		else #device
			mount $home /mnt/home
			fstype=`cat /etc/fstab | grep $home | cut -f3 -d' '`
			echo "$home /home $fstype defaults 0 0" >> /mnt/etc/fstab
		fi
	fi
	for entry in `cat /mnt/etc/passwd | grep /home | sed /^ftp/d`; do
		uid=`echo $entry | cut -f3 -d:`
		gid=`echo $entry | cut -f4 -d:`
		homedir=`echo $entry | cut -f6 -d:`
		if [ ! -d /mnt/$homedir ]; then
			mkdir /mnt/$homedir
			cp -dpR /mnt/etc/skel/.??* /mnt/$homedir
			cp -dpR /mnt/etc/skel/* /mnt/$homedir
			chown -R $uid:$gid /mnt/$homedir
		fi
	done
	umount /mnt/home
fi

#fstab
cat /etc/mtab | sed '/fusectl/d' > /mnt/etc/mtab.live
sed 's@overlay /mnt@overlay /@' -i /mnt/etc/mtab.live
mount -o rbind /live /mnt/live
cat >> /mnt/etc/rc.d/rc.S << EOF
cat /etc/mtab.live >> /etc/mtab
rm -f /etc/mtab.live
sed -e 's@^none / @none /live @' -i /etc/mtab
EOF

#runlevel boot parameter handling
if [ ! -z "$runlevel" ]; then
	echo "Setting up runlevel ($runlevel)"
	sed s/^id:[1-5]:initdefault:$/id:$runlevel:initdefault:/ -i /mnt/etc/inittab
fi

#autologin (runlevel 5)
runlevel=`cat /mnt/etc/inittab | sed -n /^id:[1-5]:initdefault:$/p | cut -f2 -d:`
if [ $runlevel = 5 ]; then
	login=`cat /mnt/etc/passwd | grep ":1000:" | cut -f1 -d:`
	if [ -z "$login" ]; then login="root"; fi
	echo "Setting up autologin (login=$login)"
	sed "s/^c1:.*$/c1:5:respawn:\/sbin\/agetty -a $login 38400 tty1 linux/" -i /mnt/etc/inittab
	
	if [ -x /mnt/usr/bin/startx ]; then
	cat  > /mnt/etc/profile.d/x.sh << END
if [ -z "\$DISPLAY" ] && [ "\`id -u\`" != "0" ] && [ "\`tty\`" = "/dev/tty1" ]; then
	startx
	logout
fi
END
		chmod +x /mnt/etc/profile.d/x.sh
	fi
fi

#system i18n setup
if [ ! -z "$locale" ]; then
	echo "Setting up locale ($locale)"
	if [ -f /mnt/etc/profile.d/lang.sh ] && grep -q "^export LANG=" /mnt/etc/profile.d/lang.sh
	then sed s/^export\ LANG=.*/export\ LANG=$locale/ -i /mnt/etc/profile.d/lang.sh
	else echo "export LANG=$locale" >> /mnt/etc/profile.d/lang.sh
	fi
fi

if [ ! -z "$keymap" ]; then
	echo "Setting up keymap ($keymap)"
	cat > /mnt/etc/rc.d/rc.keymap <<END
#!/bin/sh
if [ -x /usr/bin/loadkeys ]; then
	/usr/bin/loadkeys $keymap
fi
END
	chmod +x /mnt/etc/rc.d/rc.keymap
	
	if [ -d /mnt/etc/X11/xorg.conf.d ]; then #Xorg UDev keyboard configuration
		xkblayout=`echo $keymap | cut -c1-2`
		echo "Setting up Xorg keymap layout ($xkblayout)"
		cat > /mnt/etc/X11/xorg.conf.d/20-keyboard.conf << END
Section "InputClass"
	Identifier "keyboard-all"
	Driver "evdev"
	Option "XkbLayout" "$xkblayout"
	MatchIsKeyboard "on"
EndSection
END
	fi
fi

if [ ! -z "$tz" ]; then
	if [ -f /mnt/usr/share/zoneinfo/$tz ]; then
		echo "Setting up timezone ($tz)"
		cat /mnt/usr/share/zoneinfo/$tz > /mnt/etc/localtime
		ln -sf /usr/share/zoneinfo/$tz /mnt/etc/localtime-copied-from
	fi
fi
if [ ! -z "$hwc" ]; then
	if [ "$hwc" = "UTC" ] || [ "$hwc" = "localtime" ]; then
		echo "Setting up hardware clock ($hwc)"
		echo "$hwc" > /mnt/etc/hardwareclock
	fi
fi

#detect fixed partitions
blkid | grep "/dev/sd" | while read line; do
	partition=`echo $line | cut -f1 -d: | cut -c 6-`
	device=`echo $partition | cut -c1-3`
	type=`echo $line | sed 's/^.*TYPE=\"\([^\"]*\)\".*$/\1/'`
	if [ "`cat /sys/block/$device/removable`" = "0" ]; then
		if [ "$type" = "swap" ]; then
			if [ "$useswap" = "yes" ]; then
				echo "Enabling swap on /dev/$partition"
				echo "/dev/$partition none swap defaults 0 0" >> /mnt/etc/fstab
			else
				echo "/dev/$partition none swap defaults,noauto 0 0" >> /mnt/etc/fstab
			fi
		else
			echo "Detected /dev/$partition ($type)"
			echo "/dev/$partition /mnt/$partition $type defaults,noauto,user 0 0" >> /mnt/etc/fstab
			mkdir -p /mnt/mnt/$partition
		fi
	fi
done

#setup root password
if [ ! -z "$rootpw" ]; then
	echo "Setting up root password"
	echo "root:$rootpw" > /mnt/tmp/chpasswd.tmp
	chroot /mnt /usr/sbin/chpasswd < /mnt/tmp/chpasswd.tmp
	rm -f /mnt/tmp/chpasswd.tmp
fi

#chroot to live system
/sbin/udevadm settle --timeout=10
/sbin/udevadm info --cleanup-db
/sbin/udevadm control --exit
mount -o move /proc /mnt/proc
mount -o move /sys /mnt/sys
mount -o move /run /mnt/run
mount -o move /dev /mnt/dev
mount -o remount,ro /mnt #remount root directory read-only for normal startup

echo "*** Live system ready ***"
echo ""

exec switch_root /mnt /sbin/init || exec sh
