## Functions for porteus init
## Author brokenman

# Export some color functions
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
BOLD='\033[1;37m'
RST='\033[0m' # Reset Color

# Find a parameter on boot line
param() {
if [ -e $CFGDEV/$FOLDER/$CFG ]; then
	egrep -qo "^${1}$" $CFGDEV/$FOLDER/$CFG || egrep -qo " $1( |\$)" /proc/cmdline
		else
	egrep -qo " $1( |\$)" /proc/cmdline
fi
}

value() {
if [ -e $CFGDEV/$FOLDER/$CFG ]; then
	egrep -o "^${1}=[^ ]+" $CFGDEV/$FOLDER/$CFG | cut -d= -f2
	egrep -o " $1=[^ ]+" /proc/cmdline | cut -d= -f2
		else
	egrep -o " $1=[^ ]+" /proc/cmdline | cut -d= -f2
fi
}

# Begin debug staggered prompt boot mode
debug() { param debug && { echo -e "\n=====\n: Debugging started. Here is the shell for you.\n: Type your desired commands, hit Ctrl+D to continue booting\n: or press Ctrl+Alt+Del to reboot."; setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'; echo -e "\n\n"; }; }

# Run fstab for setup
fstab() { rm -f /tmp/devices
param nocd || for x in /dev/sr*; do blkid $x >>/tmp/devices; done
param nohd || blkid | egrep -v '/dev/sr|/dev/loop|/dev/mapper' >>/tmp/devices
dev=`egrep -v 'TYPE="sw|TYPE="LVM|TYPE=".*_raid_member"' /tmp/devices 2>/dev/null | cut -d: -f1 | cut -d/ -f3 | sort | uniq`
cat > /etc/fstab << EOF
# Do not edit this file as fstab is recreated automatically during every boot.
# Please use /etc/rc.d/rc.local or sysvinit scripts if you want to mount/unmount
# drive, filesystem or network share.

# System mounts:
aufs / aufs defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devtmpfs /dev devtmpfs defaults 0 0
devpts /dev/pts devpts rw,mode=0620,gid=5 0 0

# Device partitions:
EOF
for x in $dev; do
    fs=`grep -w /dev/$x /tmp/devices | egrep -o ' TYPE=[^ ]+' | cut -d'"' -f2`
    [ $fs = vfat ] && echo "/dev/$x /mnt/$x vfat $MOPT,umask=0,check=s,utf8,uid=1000 0 0" >>/etc/fstab || echo "/dev/$x /mnt/$x $fs $MOPT 0 0" >>/etc/fstab
    if [ ! -d /mnt/$x ]; then
	mkdir /mnt/$x
	if [ $fs = ntfs ]; then
	    ntfs-3g /dev/$x /mnt/$x -o $MOPT,uid=1000,big_writes 2>/dev/null || { sed -i "/$x /d" /etc/fstab; rmdir /mnt/$x; }
	else
	    mount -n /mnt/$x 2>/dev/null || { modprobe $fs 2>/dev/null && mount -n /mnt/$x 2>/dev/null || { sed -i "/$x /d" /etc/fstab; rmdir /mnt/$x; }; }
	fi
    fi
done

if [ -z "`egrep -o " noswap( |\$)" /proc/cmdline`" -a -e /tmp/devices ]; then
	#echo -e "\n# Swap partitions:" >>/etc/fstab
	for x in `grep 'TYPE="swap"' /tmp/devices | cut -d: -f1`; do echo "$x none swap sw,pri=1 0 0" >>/etc/fstab; done
fi }

# Mount things
mount_device() {
fs=`blkid /dev/$1 | egrep -o ' TYPE=[^ ]+' | cut -d'"' -f2`
if [ "$fs" ]; then
    mkdir /mnt/$1
    if [ $fs = vfat ]; then
	mount -n /dev/$1 /mnt/$1 -o $MOPT,umask=0,check=s,utf8,uid=1000 2>/dev/null || rmdir /mnt/$1
    elif [ $fs = ntfs ]; then
	ntfs-3g /dev/$1 /mnt/$1 -o $MOPT,uid=1000,big_writes 2>/dev/null || rmdir /mnt/$1
    else
	mount -n /dev/$1 /mnt/$1 -o $MOPT 2>/dev/null || { modprobe $fs 2>/dev/null && mount -n /dev/$1 /mnt/$1 -o $MOPT || rmdir /mnt/$1; }
    fi
fi }

# Search for boot location
search() { FND=none; for x in `ls /mnt | tac`; do
[ $1 /mnt/$x/$2 ] && { DEV=$x; FND=y; break; }; done
[ $FND = y ]; }

# Delay booting a little until devices have settled
nap() { echo -en $i"device not ready yet? delaying [1;33m$SLEEP[0m seconds \r"; sleep 1; }
lazy() { SLEEP=10; while [ $SLEEP -gt 0 -a $FND = none ]; do nap; let SLEEP=SLEEP-1; fstab; search $*; done }

# Find location of Porteus files
locate() { LPATH=`echo $2 | cut -b-5 | sed s@/dev@/mnt@`
if [ $LPATH = /mnt/ ]; then
    DEV=`echo $2 | cut -d/ -f3`; LPTH=`echo $2 | cut -d/ -f4-`; SLEEP=6
    while [ $SLEEP -gt 0 -a ! -b /dev/$DEV ]; do nap; let SLEEP=SLEEP-1; fstab; done
    [ -d /mnt/$DEV ] || mount_device $DEV
    [ $1 /mnt/$DEV/$LPTH ]
elif [ $LPATH = UUID: -o $LPATH = LABEL ]; then
    ID=`echo $2 | cut -d: -f2 | cut -d/ -f1`; LPTH=`echo $2 | cut -d/ -f2-`; DEV=`blkid | grep -w $ID | cut -d: -f1 | cut -d/ -f3`; SLEEP=6
    while [ $SLEEP -gt 0 -a "$DEV" = "" ]; do nap; let SLEEP=SLEEP-1; fstab; DEV=`blkid | grep -w $ID | cut -d: -f1 | cut -d/ -f3`; done
    [ -d /mnt/$DEV ] || mount_device $DEV
    [ $1 /mnt/$DEV/$LPTH ]
else
    LPTH=$2; search $* || lazy $*
fi }

# Check if a location is writable
is_writable(){ touch $1/.test 2>/dev/null; [ -e $1/.test ] && rm $1/.test; }

# Booting failed. Failed to find porteus files. 
fail() { echo -e $i"couldn't find $1. Correct your from= cheatcode.\n Documentation in /usr/doc/porteus. Press 'enter' to continue booting."; read -s; }

# Failed to initiate changes. Creating temporary changes on tmpfs for this session.
fail_chn() { mount -nt tmpfs -o size=$RAMSIZE tmpfs /memory/changes; CHANGES=memory; CHNDEV=memory; }

# Just draw a line
draw() { echo "[1;33m""---------------------------------------------------------""[0m"; }

# Error checking a save file.
fsck_dat() { echo $i"checking $1 for errors"
fs=`blkid $1 | egrep -o ' TYPE=[^ ]+' | cut -b8-10`
if [ $fs = xfs ]; then
    echo $i"detected xfs - performing fsck at mount time"
elif [ $fs = ext ]; then
    draw; e2fsck -C 0 -p $1; wait; draw
else
    echo $i"detected unsupported fs - skipping fsck"
fi }

# Copy modules
cpmod() { NUM=`grep -c '.' $1`
modfile=$1
while read x; do
    echo -en "[1;33m""  ($NUM modules left)  \r""[0m"; let NUM=NUM-1; NAME=`basename "$x"`
    cp "$x" /memory/copy2ram 2>/dev/null
    if [ $? -eq 0 ]; then
	sed -i s@^.*/"$NAME"@/memory/copy2ram/"$NAME"@ /tmp/modules
    else
	rm /memory/copy2ram/"$NAME"; echo -e $i"[1;36m""Not enough memory to copy $NAME""[0m"; echo -e $i"[1;36m""Other modules will be skipped.""[0m"
	find /memory/copy2ram -name "*.xzm" | sort >/tmp/modules
	break
    fi
done < $modfile
echo -en "                       \r"
}

# If bootlog cheatcode is present then make log entry
blog(){
		param log && echo "$1" >> $LOGFILE
}

# Check for a boot param
chk_bootcfg(){ grep "^$1" /union/etc/bootcmd.cfg; }
