#!/bin/sh

# Made by Yifan Lu (http://yifan.lu/)

JAILBREAK_PAYLOAD="/var/local/payload"
JAILBREAK_INIT_SCRIPT="${JAILBREAK_PAYLOAD}/jailbreak.init"
JAILBREAK_KEY="${JAILBREAK_PAYLOAD}/jailbreak.pem"
JAILBERAK_IMAGE="${JAILBREAK_PAYLOAD}/jailbreak.png"
JAILBREAK_DEV_KEYSTORE="${JAILBREAK_PAYLOAD}/jailbreak.keystore"
SCRIPT="/mnt/us/runme.sh"
ROOT=""

_FUNCTIONS=/etc/rc.d/functions
[ -f ${_FUNCTIONS} ] && . ${_FUNCTIONS}

MSG_SLLVL_D="debug"
MSG_SLLVL_I="info"
MSG_SLLVL_W="warn"
MSG_SLLVL_E="err"
MSG_SLLVL_C="crit"
MSG_SLNUM_D=0
MSG_SLNUM_I=1
MSG_SLNUM_W=2
MSG_SLNUM_E=3
MSG_SLNUM_C=4
MSG_CUR_LVL="/var/local/system/syslog_level"

logmsg()
{
    local _NVPAIRS
    local _FREETEXT
    local _MSG_SLLVL
    local _MSG_SLNUM

    _MSG_LEVEL=$1
    _MSG_COMP=$2

    { [ $# -ge 4 ] && _NVPAIRS=$3 && shift ; }

    _FREETEXT=$3

    eval _MSG_SLLVL=\${MSG_SLLVL_$_MSG_LEVEL}
    eval _MSG_SLNUM=\${MSG_SLNUM_$_MSG_LEVEL}

    local _CURLVL

    { [ -f $MSG_CUR_LVL ] && _CURLVL=`cat $MSG_CUR_LVL` ; } || _CURLVL=1

    if [ $_MSG_SLNUM -ge $_CURLVL ]; then
        /usr/bin/logger -p local4.$_MSG_SLLVL -t "jailbreak" "$_MSG_LEVEL def:$_MSG_COMP:$_NVPAIRS:$_FREETEXT"
    fi

    if [ "$_MSG_LEVEL" != "D" ]; then
      echo "jailbreak: $_MSG_LEVEL def:$_MSG_COMP:$_NVPAIRS:$_FREETEXT"
    fi
}

RW=
mount_rw() {
  if [ -z "$RW" ]; then
    RW=yes
    mount -o rw,remount /
  fi
}

mount_ro() {
  if [ -n "$RW" ]; then
    RW=
    mount -o ro,remount /
  fi
}

mount_root_rw()
{
	DEV=`rdev | awk '{ print $1 }'`
	if [ "${DEV}" != "/dev/mmcblk0p1" -a -n "${DEV}" ]; then # K4 doesn't have rdev on rootfs but does on diags, weird
		ROOT="/tmp/root"
		logmsg "I" "mount_root_rw" "We are not on rootfs, using ${ROOT}"
		[ -d "${ROOT}" ] || mkdir "${ROOT}"
		mount -o rw "/dev/mmcblk0p1" "${ROOT}"
	else
		logmsg "I" "mount_root_rw" "We are on rootfs"
		mount_rw
	fi
}

get_version()
{
    awk '/Version:/ { print $NF }' /etc/version.txt | \
        awk -F- '{ print $3 }' | \
        xargs printf "%s\n" | \
        sed -e 's#^0*##'
}

safesource()
{
    [ -f "${1}" ] && . "${1}"
}

install_nontouch_update_key()
{
	# Only required for Kindle 3.0 and below
	SLEVEL="64"
	KLEVEL="09"
	
	if [ -f "${ROOT}/etc/init.d/linkjail" ]; then
		logmsg "E" "install_nontouch_update_key" "Another jailbreak is already installed. Update not required."
		return 1
	fi
	
	logmsg "I" "install_nontouch_update_key" "Copying the jailbreak updater key"
	cp -a "${JAILBREAK_KEY}" "${ROOT}/etc/uks/pubprodkey01.hack.pem"
	
	logmsg "I" "install_nontouch_update_key" "Installing the key binding init script"
	cp -a "${JAILBREAK_INIT_SCRIPT}" "${ROOT}/etc/init.d/jailbreak"
	ln -sf "/etc/init.d/jailbreak" "${ROOT}/etc/rc5.d/S${SLEVEL}jailbreak"
	ln -sf "/etc/init.d/jailbreak" "${ROOT}/etc/rc3.d/K${KLEVEL}jailbreak"
	return 0
}

install_touch_update_key()
{
	# Only on Kindle 4.0+
	logmsg "I" "install_touch_update_key" "Copying the jailbreak updater key"
	cp -a "${JAILBREAK_KEY}" "${ROOT}/etc/uks/pubdevkey01.pem"
	return 0
}

install_kindlet_key()
{
	logmsg "I" "install_kindlet_key" "Copying the developer keystore"
	cp -a "${JAILBREAK_DEV_KEYSTORE}" "/var/local/java/keystore/developer.keystore"	
	return 0
}

clean_up_wan()
{
	[ -n "${WAN_INFO}" ] || WAN_INFO="/var/local/wan/info"
	
	logmsg "I" "install_kindlet_key" "Cleaning up waninfo file and generating new one"
	rm -f ${WAN_INFO}
	if [ -f "${WAN_INFO}" ]; then
		logmsg "E" "clean_up_mntus_params" "Cannot remove payload. Exiting to prevent boot-loop."
		return 1
	fi
	
	waninfo
	safesource ${WAN_INFO}
}

clean_up_mntus_params()
{
	[ -n "${MNTUS_PARAMS}" ] || MNTUS_PARAMS="/var/local/system/mntus.params"
	
	logmsg "I" "clean_up_mntus_params" "Cleaning up mntus.params file and generating new one"
	rm -f "${MNTUS_PARAMS}"
	if [ -f "${MNTUS_PARAMS}" ]; then
		logmsg "E" "clean_up_mntus_params" "Cannot remove payload. Exiting to prevent boot-loop."
		return 1
	fi
	
	if [ "${VERSION}" -ge "5" ]; then
		# Kindle 5, upstart
		${ROOT}/etc/upstart/userstore start
	else 
		# Kindle 4 or below, sysinit
		${ROOT}/etc/init.d/userstore start
	fi	
	safesource ${MNTUS_PARAMS}
}

clean_up()
{
	logmsg "I" "clean_up" "Removing payload files."
	rm -rf "${JAILBREAK_PAYLOAD}"
	clean_up_wan
	clean_up_mntus_params
	if [ -n "${ROOT}" ]; then
		logmsg "I" "clean_up" "Unmounting rootfs"
		umount "${ROOT}"
	fi
}

# Step 1, we put a pretty image on screen
eips -c
eips -f -g "${JAILBERAK_IMAGE}"

# Step 2, check device version
REVISION=`get_version`
VERSION=
logmsg "I" "jailbreak" "Kindle revision: ${REVISION}"
if [ "${REVISION}" -lt "29133" ]; then
	VERSION=1
elif [ "${REVISION}" -lt "51546" ]; then
	VERSION=2
elif [ "${REVISION}" -lt "130856" ]; then
	VERSION=3
elif [ "${REVISION}" -lt "137022" ]; then
	VERSION=4
else
	VERSION=5
fi
logmsg "I" "jailbreak" "Kindle version: ${VERSION}"

# Step 3, install updater key
mount_root_rw
if [ "${VERSION}" -ge "4" ]; then
	install_touch_update_key
else 
	# We are on Kindle 3.0 or below, use bind mounting key method
	install_nontouch_update_key
fi
mount_ro

# Step 3, install kindlet key
install_kindlet_key

# Step 4, wait a bit while our cool splash screen is up and then clean up
sleep 10
clean_up

# Step 5, run any custom scripts (must do this after cleanup so we have the userstore mounted)
if [ -f "${SCRIPT}" ]; then
	logmsg "I" "jailbreak" "Found script ${SCRIPT}, running it"
	[ -x "${SCRIPT}" ] || chmod +x "${SCRIPT}"
	${SCRIPT}
fi

# Step 6, leave a trace so the user knows they are jailbroken
echo "It is safe to delete this document." > "/mnt/us/documents/You are Jailbroken.txt"

exit 0 # required in case we have trailing junk data from a payload
