#!/bin/bash
#
# olpc-configure       Perform one-time configuration
#
# chkconfig: 345 01 01
# description: olpc-configure performs one-time configuration
# processname: olpc-configure

# Bump this version each time comatibility gets broken in ways that require
# regenerating the configuration files
OLPC_CONFIGURE_VERSION=7

OLPC_HOME=/home/olpc
MFG_DATA=/ofw/mfg-data

configure_hw() {
	echo "olpc-configure: configuring hardware..."

	# load alsa configuration here since doing it at module load time wasn't working
	/usr/sbin/alsactl restore

	if [ "`cut -c 7-8 /ofw/openprom/model 2>/dev/null`" = "Q2" ] ; then
		# Libertas Marvell LED configuration
		# map LED1 to GPIO1, LED2 to GPIO12, LED3 to GPIO16
		/sbin/iwpriv eth0 ledgpio 1 1 2 12 3 16 > /dev/null
	fi
}

# Read a manufacturing data tag and strip the leading NUL
mfgtag () {
	cat $MFG_DATA/$1 | tr -d '\000' 2>/dev/null
}

read_nvram() {
	dd if=/dev/nvram bs=1 skip=$(($1)) count=$2 2>/dev/null
}

read_config() {
	# Some defaults
	XKB_MODEL="olpc"
	XKB_LAYOUT="us"
	SYS_LANG="en_US.UTF-8"

	if X -version 2>&1 | grep -q 'Version 1.3'; then
		XVER='-1.3'
	fi
	XORG_CONF=xorg-emu${XVER}.conf

	if grep -q Geode /proc/cpuinfo; then
		# TODO: put this all in a hal callout or something similar
		XORG_CONF=xorg-dcon${XVER}.conf

		if [ -f $MFG_DATA/KL ]; then
			XKB_MODEL="`mfgtag KM`"
			XKB_LAYOUT="`mfgtag KL`"
			XKB_VARIANT="`mfgtag KV`"
			SYS_LANG="`mfgtag LO`"
		elif [ "`cut -c 7-8 /ofw/openprom/model 2>/dev/null`" = "Q2" ] ; then
			KB_HEADER=`read_nvram 0x44 2`
			if [ "x$KB_HEADER" = "xKB" ] ; then
				KB_CODE=`read_nvram 0x46 10`
				if [ "x$KB_CODE" = "xus_INTL" ] ; then
					XKB_LAYOUT="us"
				elif [ "x$KB_CODE" = "xes" ] ; then
					XKB_LAYOUT="es"
					SYS_LANG="es_AR.UTF-8"
				elif [ "x$KB_CODE" = "xpt_BR" ] ; then
					XKB_LAYOUT="br"
					SYS_LANG="pt_BR.UTF-8"
				elif [ "x$KB_CODE" = "xara" ] ; then
					XKB_LAYOUT="us(olpc2),ara(olpc)"
					SYS_LANG="ar_LY.UTF-8"
				elif [ "x$KB_CODE" = "xth" ] ; then
					XKB_LAYOUT="us(olpc2),th(olpc)"
					SYS_LANG="th_TH.UTF-8"
				elif [ "x$KB_CODE" = "xng" ] ; then
					XKB_LAYOUT="ng(olpc)"
				elif [ "x$KB_CODE" = "xpk" ] ; then
					XKB_LAYOUT="us(olpc2),ur(olpc)"
					SYS_LANG="ur_PK.UTF-8"
				elif [ "x$KB_CODE" = "xet" ] ; then
					XKB_LAYOUT="us(olpc2),et"
					SYS_LANG="am_ET.UTF-8"
				fi
			fi
		fi
	fi
}

# configurations which happen in /home
# these don't need to be repeated when we upgrade.
configure_home() {
	echo "olpc-configure: reconfiguring home..."

	rm -f $OLPC_HOME/.i18n
	cat >$OLPC_HOME/.i18n <<__EOF__
LANG="$SYS_LANG"
__EOF__
	chown olpc:olpc $OLPC_HOME/.i18n

	# can't live in $OLPC_HOME because activities can't read this dir.
	SERNUM="`mfgtag SN`"
	UUID="`mfgtag U#`"
	sed -e "s/REPLACE_WITH_SERIALNUMBER/$SERNUM/" \
	    -e "s/REPLACE_WITH_UUID/$UUID/" > /home/.devkey.html <<__EOF__
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Developer key request</title>
<style type="text/css" media="all">@import "https://activation.laptop.org/devkey/stylesheet/";</style>
</head>
<body>
<iframe src="https://activation.laptop.org/devkey/content/"
        width="100%" height="450" >
<p>Use the button below to request a developer key for your
        machine.</p>
</iframe>
<form action="https://activation.laptop.org/devkey/post/"
        method="post" id="devkeyform" >
<input type="hidden" name="serialnum" value="REPLACE_WITH_SERIALNUMBER" />
<input type="hidden" name="uuid" value="REPLACE_WITH_UUID" />
<input type="submit" />
</form>
</body>
</html>
__EOF__
	chmod a+r,a-w /home/.devkey.html

	if [ -x /usr/share/library-common/make_index.py ]; then
		echo "olpc-configure: running make_index..."
		rm -rf $OLPC_HOME/.library_pages
		/usr/share/library-common/make_index.py
		chown -R olpc:olpc $OLPC_HOME/.library_pages
	fi
}

update_home_permissions() {
	echo "olpc-configure: fixing permissions on home (dlo#4928, dlo#5626)..."

	# Our first attempt at fixing dlo#4928 assumed that home was totally
        # private and public data would be explicitly made available.
	# Since it's inpractical, we relax this requirement and undo the
	# changes made by earlier versions of this script.
	# However, we must be careful not to mess with the rainbow isolation
	# scheme which is intentionally 770.
	find $OLPC_HOME -type d -perm 770 -name isolation -prune -o -print0 | xargs -0 chmod 755

	# Home must be world aXessible so that activities installed
	# in ~/Activities can reach their bundles
	# We make the home also listable because we expect that confidential
	# data will be explicitly isolated in nested subdirectories.
	chmod 755 $OLPC_HOME

	# SSH would bitch if permissions on .ssh happens to be too lax
	chmod 700 $OLPC_HOME/.ssh 2>/dev/null

	# .sugar contains plenty of confidential data
	chmod 700 $OLPC_HOME/.sugar 2>/dev/null
}

# configurations which happen in the root fs 
# these need to be repeated when we upgrade.
configure_root() {
	echo "olpc-configure: reconfiguring root..."

	# First X layout used also as kernel keytable
	KERN_KEYTABLE=`echo "$XKB_LAYOUT" |  cut -d , -f 1`

	cd /etc/X11
	rm -f xorg.conf
	ln -sf $XORG_CONF xorg.conf

	cat >/etc/sysconfig/i18n <<__EOF__
# LANG=C considerably speeds up boot (measured 5sec) -- bernie
LANG=C
SYSFONT=sun12x22
__EOF__

	# We keep keyboard settings here to avoid users from messing around
	# with them in their home and maybe shut themselves out
	cat >/etc/sysconfig/keyboard <<__EOF__
KEYTABLE="$KERN_KEYTABLE"
XKB_MODEL="$XKB_MODEL"
XKB_LAYOUT="$XKB_LAYOUT"
XKB_VARIANT="$XKB_VARIANT"
__EOF__
	# Keyboard is being loaded early in rc.sysint, reset it now
	loadkeys "$KERN_KEYTABLE"

	# Update library index
	echo "olpc-configure: updating library index..."
	cd /usr/share/library-common
	./make_index.py
	chown -R olpc:olpc $OLPC_HOME/.library_pages

	if [ -x /usr/sbin/rainbow-replay-spool ]; then
		echo "olpc-configure: replaying rainbow spool..."
		/usr/sbin/rainbow-replay-spool
	fi
}

#
# Main entry point
#
# This is organized to minimize boot time by bailing out early
# in the common case of an already configured system
#
case "$1" in
  start|restart)
	olpc_home_version="`cat $OLPC_HOME/.olpc-configured 2>/dev/null`"
	olpc_root_version="`cat /.olpc-configured 2>/dev/null`"

	# unconditionally configure the hardware
	configure_hw

	# check whether /home configuration is necessary.
	if [ "$olpc_home_version" != "$OLPC_CONFIGURE_VERSION" ]; then
		if [ "0$olpc_home_version" -le "6" ]; then
			update_home_permissions
		fi
		read_config
		configure_home
		echo "$OLPC_CONFIGURE_VERSION" >$OLPC_HOME/.olpc-configured
	fi

	# check whether / configuration is necessary.
	if [ "$olpc_root_version" != "$OLPC_CONFIGURE_VERSION" ]; then
		[ -n "$XKB_MODEL" ] || read_config
		configure_root
		echo "$OLPC_CONFIGURE_VERSION" >/.olpc-configured
	fi
	;;
  stop|status)
  	;;
  *)
        echo $"Usage: $0 {start|stop|restart|status}"
  	;;
esac
