#!/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 compatibility gets broken in ways that require # regenerating the configuration files OLPC_CONFIGURE_VERSION=16 OLPC_HOME=/home/olpc XO_VERSION=0 # control variable so that we only generate the library homepage a maximum of # 1 time per boot LIBRARY_INDEX_BUILT=0 source /usr/share/olpc-utils/olpc-utils-functions initialize_ptmode() { # the hgpk driver for the "old" ALPS touchpads has a # means of switching between capacitive "finger" mode and # stylus-only tablet mode. make it possible for the user # to switch it back and forth. PTMODE=/sys/devices/platform/i8042/serio1/ptmode test -e $PTMODE && chmod a+rw $PTMODE } configure_hw_1_0() { # load alsa configuration here since doing it at module load time wasn't working /usr/sbin/alsactl restore # workaround activities lowering PCM level amixer -q sset PCM "90%" unmute amixer -q sset 'Capture' '100%' # 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 if [ -x /sbin/rfkill -a -e $OLPC_HOME/.rfkill_block_wifi ] then /sbin/rfkill block wifi fi initialize_ptmode } configure_hw_1_5() { amixer -q sset Master -- "-10.0dB" amixer -q sset PCM "100%" amixer -q sset "DC Input Bias" Off amixer -q sset "DC Mode Enable" mute amixer -q sset 'Analog Mic Boost' '30dB' amixer -q sset 'Capture' '100%' cap if [ -x /sbin/rfkill -a -e $OLPC_HOME/.rfkill_block_wifi ] then /sbin/rfkill block wifi fi initialize_ptmode } configure_hw_1_75() { # FIXME - nothing to do yet echo XO-1.75 } # Dynamically determine the boot device and mount it mount_boot() { local bootpath=$(get_ofw_file /chosen/bootpath) local bootdev local tmp case $bootpath in /pci/sd@c/disk@?:*) # XO-1.5 SD tmp=${bootpath#/pci/sd@c/disk@} tmp=${tmp%%:*} ((tmp--)) bootdev="/dev/disk/mmc/mmc${tmp}p1" ;; /sd@d4280000/disk@?:*) # XO-1.75 tmp=${bootpath#/sd@d4280000/disk@} tmp=${tmp%%:*} ((tmp--)) bootdev="/dev/disk/mmc/mmc${tmp}p1" ;; esac [[ -n "$bootdev" && -d "/bootpart" && -e "$bootdev" ]] || return mount -o noatime "$bootdev" /bootpart } mount_boot_1_0() { local link link=$(readlink /dev/root) || return 0 # If using UBIFS root, assume JFFS2 boot if [ "$link" = "ubi0_0" ]; then mount -t jffs2 -o noatime mtd2 /bootpart fi } configure_hw() { [ "${XO_VERSION}" == "0" ] && return echo "olpc-configure: configuring hardware..." # disable tap-to-click and extra scrolling areas on AVC touchpads if [ -e /sys/bus/serio/drivers/psmouse/serio*/vscroll ]; then echo -n 0 > /sys/bus/serio/drivers/psmouse/serio*/vscroll echo -n 0 > /sys/bus/serio/drivers/psmouse/serio*/hscroll echo -n c > /sys/bus/serio/drivers/psmouse/serio*/flags fi if [ "${XO_VERSION}" == "1.5" ] ; then configure_hw_1_5 mount_boot elif [ "${XO_VERSION}" == "1.75" ] ; then configure_hw_1_75 mount_boot else configure_hw_1_0 mount_boot_1_0 fi } 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" [ "${XO_VERSION}" == "0" ] && return # test if we can get mfg data reading it local KM=`get_xo_mfg_tag KM` if [ -n "$KM" ]; then XKB_MODEL="$KM" XKB_LAYOUT="`get_xo_mfg_tag_stripspaces KL`" XKB_VARIANT="`get_xo_mfg_tag KV`" SYS_LANG="`get_xo_mfg_tag LO`" if [ "$XKB_LAYOUT" = "en" ] ; then # Some units have invalid KL 'en' tags (e.g. SKU104, #10711) XKB_LAYOUT="us" fi if [ "$SYS_LANG" = "es_MX.UTF-8" \ -a "$XKB_LAYOUT" = "us" \ -a "$XKB_VARIANT" = "olpc" ] ; then # We have some XO-1 machines in Peru with US(Intl) membrane keyboards # and they need some modifications to the standard layout # See http://dev.laptop.org/ticket/9126 XKB_LAYOUT="es" XKB_VARIANT="olpc2" fi elif [ "${XO_VERSION}" == "1" ] ; 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 if ! locale -a | grep -qx "${SYS_LANG/UTF-8/utf8}"; then echo "olpc-configure: Locale $SYS_LANG is not supported;" SYS_LANG="en_US.UTF-8" # better fallback than "C" echo "olpc-configure: Falling back to locale $SYS_LANG" fi } rebuild_library_index() { [ "$LIBRARY_INDEX_BUILT" = "1" ] && return 0 LIBRARY_INDEX_BUILT=1 if [ -x /usr/share/library-common/make_index.py ]; then echo '* olpc-configure: Rebuilding the library index.' rm -rf $OLPC_HOME/.library_pages [ -n "$SYS_LANG" ] || read_config /usr/bin/env - LANG=$SYS_LANG /usr/share/library-common/make_index.py chown -R olpc:olpc $OLPC_HOME/.library_pages fi } # see dev.laptop.org trac #6432 for use case and spec. install_customization_packages () { # we'd like to look on USB/SD here, but udev/sugar hasn't mounted # them yet =( for pkgdir in $OLPC_HOME/.custom/rpms ; do # other paths? if [ ! -d "$pkgdir" ]; then continue; fi pkgs=$(find "$pkgdir" -name '*.rpm' -a ! -name '*.src.rpm' ) if [ -n "$pkgs" ]; then echo '* olpc-configure: Installing customization packages:' echo "$pkgs" rpm -Uvh $pkgs fi unset pkgs done unset pkgdir } # 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="`get_xo_mfg_tag SN`" UUID="`get_xo_mfg_tag U#`" if [ -e /etc/olpc-configure/devkey.html ];then sed -e "s/REPLACE_WITH_SERIALNUMBER/$SERNUM/" \ -e "s/REPLACE_WITH_UUID/$UUID/" > /home/.devkey.html.tmp < /etc/olpc-configure/devkey.html else sed -e "s/REPLACE_WITH_SERIALNUMBER/$SERNUM/" \ -e "s/REPLACE_WITH_UUID/$UUID/" > /home/.devkey.html.tmp <<__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__ fi chmod a+r,a-w /home/.devkey.html.tmp mv /home/.devkey.html.tmp /home/.devkey.html rebuild_library_index # ensure /home/root exists (#6700) mkdir -p /home/root chmod 750 /home/root # version 11: switch from batterymon to batti (#10436) rm -f /home/olpc/.config/autostart/batterymon.desktop # version 12: create default unencrypted keyring (#10290) if [ ! -e /home/olpc/.gnome2/keyrings/default.keyring ]; then mkdir -p /home/olpc/.gnome2/keyrings echo 'default' > /home/olpc/.gnome2/keyrings/default TIME=$(/bin/date +%s) cat >/home/olpc/.gnome2/keyrings/default.keyring.tmp <<EOF [keyring] display-name=default ctime=$TIME mtime=$TIME lock-on-idle=false lock-timeout=0 EOF mv /home/olpc/.gnome2/keyrings/default.keyring{.tmp,} chown -R olpc:olpc /home/olpc/.gnome2/keyrings fi # version 13: get rid of old ~/Activities/.groups from gg-802-1 (#10582) # activity group changed for XO-1, and this is now specified in /etc if [ -e /home/olpc/Activities/.groups ]; then ACTGROUPS=$(</home/olpc/Activities/.groups) if [ "$ACTGROUPS" = "http://wiki.laptop.org/go/Activities/G1G1" ]; then rm -f /home/olpc/Activities/.groups fi fi } update_home_permissions_to_v6() { 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 a+rX,u+w,go-w } set_home_permissions() { # 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 if [ -d "$OLPC_HOME/.ssh" ]; then find $OLPC_HOME/.ssh -print0 | xargs -0 chmod u+rwX,go-rwx fi # .sugar contains plenty of confidential data chmod 700 $OLPC_HOME/.sugar 2>/dev/null } clean_previews() { echo "olpc-configure: cleaning the previews directory..." /usr/bin/olpc-clean-previews } # determine presence of USB-VGA adapter on boot, switch Xorg config # appropriately configure_xorg() { # TODO: put this all in a hal callout or something similar if [ -e /dev/sisusbvga0 ]; then ln -s /usr/share/olpc-utils/xorg.conf.d/sisusb.conf \ /etc/X11/xorg.conf.d/ rm -f /etc/X11/xorg.conf.d/xo$XO_VERSION.conf else rm -f /etc/X11/xorg.conf.d/sisusb.conf [ -e /etc/X11/xorg.conf.d/xo$XO_VERSION.conf ] || \ ln -s /usr/share/olpc-utils/xorg.conf.d/xo$XO_VERSION.conf /etc/X11/xorg.conf.d/ fi } # 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` # Some keyboards come with a special OLPC variant for the console if [ -f /lib/kbd/keymaps/i386/olpc/$KERN_KEYTABLE-olpc.map.gz ]; then KERN_KEYTABLE=$KERN_KEYTABLE-olpc fi # 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" # set olpc-dm as desktop manager echo "DISPLAYMANAGER=/usr/sbin/olpc-dm" > /etc/sysconfig/desktop # Update library index rebuild_library_index if [ -x /usr/sbin/rainbow-replay-spool ]; then echo "olpc-configure: replaying rainbow spool..." /usr/sbin/rainbow-replay-spool fi # developer customizations. if /usr/bin/olpc-test-devkey -q ; then install_customization_packages fi # version 10: use xorg.conf.d instead of xorg.conf rm -f /etc/X11/xorg.conf # version 15: set hostname via /etc/hosts and /etc/sysconfig/network if [ -e "/sys/class/net/eth0/address" ]; then local addr=$(</sys/class/net/eth0/address) if [ "${#addr}" == 17 ]; then addr=${addr:9} local hname=xo-${addr//:/-} cat <<EOF >/etc/sysconfig/network NETWORKING=yes NETWORKING_IPV6=no HOSTNAME=$hname.localdomain NM_IGNORE_HOSTNAME_LOCALHOST=yes EOF hostname ${hname}.localdomain sed -c -i -e "s/^127\.0\.0\.1.*/127.0.0.1 ${hname}.localdomain ${hname} localhost/g" /etc/hosts fi 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) XO_VERSION=$(get_xo_version) 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 # unconditionally configure xorg for USB2VGA configure_xorg # create directories needed by screen, lockdev and minicom (#11078) # temporary until we move to F15+ where this is solved already if ! [ -e /var/lock/lockdev ]; then mkdir -p /var/lock/lockdev chmod 775 /var/lock/lockdev chgrp lock /var/lock/lockdev fi if ! [ -e /var/run/screen ]; then mkdir -p /var/run/screen chmod 775 /var/run/screen # screen group only exists after installing screen, so this chgrp # call may (harmlessly) fail chgrp screen /var/run/screen 2>/dev/null || : fi # check whether /home configuration is necessary. if [ "$olpc_home_version" != "$OLPC_CONFIGURE_VERSION" ]; then if [ -n "$olpc_home_version" ]; then ### ### upgrades only ### ## trigger activity upgrade (dlo trac #7495 #9747) touch "$OLPC_HOME/.sugar-update" if [ "0$olpc_home_version" -le "6" ]; then # run it *before* set_home_permissions update_home_permissions_to_v6 fi if [ "0$olpc_home_version" -le "7" ]; then clean_previews fi fi set_home_permissions 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 # check whether we need to reconfigure in response to usb-driven customizations if [ -f "$OLPC_HOME/.usb-customizations" ]; then olpc_usb_version="`cat $OLPC_HOME/.usb-customizations 2>/dev/null`" if [ -n "$olpc_usb_version" ] && [ "$olpc_usb_version" -ge "1" ]; then rebuild_library_index fi # we've done whatever we can; remove the customization flag # XXX: This choice means that whichever image is booted after usb-based # customizations gets to decide what customizations it wants to do. <MS> rm -rf "$OLPC_HOME/.usb-customizations" fi ;; stop|status) ;; *) echo $"Usage: $0 {start|stop|restart|status}" ;; esac