#!/bin/bash

# kernels we are sure we want to update
oldkern="\
3112d1782a90c2c87ae17a152a35deae \
b00a5d617f11366689488395b19411de \
aed218fe59ff93618bddd2b52b020014 \
"
newkern=53ca541a471f726eb1103f19d4306e61
currkern=$(md5sum /boot/uImage | cut -d" " -f1)

# u-boot versions we want to update
oldubootvers="\
U-Boot_2010.03_(May_19_2010_-_18:30:30) \
"

oldinterfaces=23f72750f2f7335b9c2ed3f55aaa5061
oldrcwl1251=7a6361e842f0f589418218436affbe07
newmmenu=270b2ef3aa8e92e913880fb313857b0a
oldmmenu="\
d15bf3ad29f12fa2325534b8fcd5c1f4 \
fa45e9bc91c48640a9ea592de5fbeb3c \
af66a5118a9bfef8eca5de13ee64c6a1 \
"
currmmenu=$(md5sum /usr/bin/mmenu | cut -d" " -f1)
currmmenuconf=$(md5sum /etc/pandora/conf/mmenu.conf | cut -d" " -f1)

rm /tmp/updater.log
rm /tmp/updreboot

log()
{
  echo "$@" >> /tmp/updater.log
  echo "$@" >&2
}

rm /tmp/updater_err.log

err()
{
  echo "$@" >> /tmp/updater_err.log
}

if zenity --question --title="Update Package 3" --text="\
This PND updates your Pandora OS. You can safely delete it after it has finished.\n\
This pack includes all updates from previous Hotfix Packs as well.\n\n\
Do you want to start the upgrade now? " --ok-label="Start now" --cancel-label="Don't do it" ; then

(

# Kernel Update

echo "7"
echo "# Updating kernel if needed"


update_kernel()
{
     have_error=false

     rm /boot/uImage.old 
     needfree=$(ls -lk uImage | grep uImage | cut -d" " -f5)
     currfree=$(df /boot | grep boot | awk '{print $4}')
     if [ $currfree -lt $needfree ]; then
        err "There is not enough diskspace on /boot/ to update the kernel.\nKernel couldn't be updated."
        log "Kernel not updated - not enough diskspace on /boot/"
        have_error=true
     else
        cp uImage /boot/uImage.new 
        sync
        bad_checksum=false
        currkern=$(md5sum /boot/uImage.new | cut -d" " -f1)
          if [ "$currkern" = "$newkern" ]; then
            mv /boot/uImage /boot/uImage.old 
            mv /boot/uImage.new /boot/uImage 
            currkern=$(md5sum /boot/uImage | cut -d" " -f1)
            if [ "$currkern" != "$newkern" ]; then
               rm /boot/uImage 
               mv /boot/uImage.old /boot/uImage 
               bad_checksum=true
            fi
          else
            rm /boot/uImage.new 
            bad_checksum=true
          fi
          if $bad_checksum; then
            err "There was a checksum error while copying the kernel.\nKernel couldn't be updated. Please check your SD-Card and try to recopy the PND-File."
            log "Kernel not updated - checksum error"
            have_error=true
          fi
     fi

     if ! $have_error; then
       log "Kernel successfully updated"
       echo "The kernel has been updated. You need to restart your system." > /tmp/updreboot
     fi
     sync
}

kernel_known=false
for oknl in $oldkern $newkern; do
  if [ "$oknl" = "$currkern" ]; then
    kernel_known=true
    break
  fi
done

if [ "$kernel_known" = "true" -o -z "$currkern" ]; then
  if [ "$currkern" != "$newkern" ]; then
    update_kernel
  else
    log "Kernel already up-to-date"
  fi
else
  if zenity --question --title="Custom kernel?" --text="\
You seem to have custom or newer kernel in flash.\n\n\
Update it anyway?\n\
(if unsure, select Yes)" --ok-label="Yes" --cancel-label="No" ; then
    update_kernel
  else
    log "Kernel update skipped"
  fi
fi
  

# u-boot Update

echo "15"
echo "# U-Boot if needed"

update_uboot()
{
  if flash_eraseall /dev/mtd1 && nandwrite -p /dev/mtd1 u-boot.bin; then
    # XXX: perhaps we need to check if write went ok?
    log "u-boot.bin flashed."
  else
    log "u-boot.bin flashing failed."
  fi
}

if [ -f u-boot.bin ]; then

  rm /tmp/u-boot.bin.nand 2> /dev/null
  nanddump -o -b -q -f /tmp/u-boot.bin.nand /dev/mtd1
  uboot_nand_ver=`strings /tmp/u-boot.bin.nand | grep 'U-Boot 20' | head -n 1 | sed 's/ /_/g'`
  uboot_ver=`strings u-boot.bin | grep 'U-Boot 20' | head -n 1 | sed 's/ /_/g'`
  uboot_size=`stat -c %s u-boot.bin`

  dd if=/tmp/u-boot.bin.nand of=/tmp/u-boot.bin.nand.cmp bs=$uboot_size count=1
  if ! cmp u-boot.bin /tmp/u-boot.bin.nand.cmp
  then
    uboot_need_to_ask=true
    for oldver in $oldubootvers; do
      if [ "$oldver" = "$uboot_nand_ver" ]; then
	uboot_need_to_ask=false
	break
      fi
    done

    if $uboot_need_to_ask; then
      if zenity --question --title="Custom u-boot?" --text="\
      You seem to have custom or newer u-boot in flash.\n\n\
      Update it anyway?\n\
      (if unsure, select Yes)" --ok-label="Yes" --cancel-label="No" ; then
	update_uboot
      else
	log "u-boot update skipped\n(nand has $uboot_nand_ver)"
      fi
    else
      update_uboot
    fi
  else
    log "u-boot already up-to-date\n($uboot_nand_ver)"
  fi
fi

# Libraries and Programs
  
echo "20"
echo "# Installing missing Python libraries"
if [ "`opkg list-installed | grep python-shell`" ]; then
   log "Python libraries were already installed."
else 
  opkg install 1/gnome-vfs-plugin-ftp_2.24.1-r2.5_armv7a.ipk 1/gnome-vfs-plugin-http_2.24.1-r2.5_armv7a.ipk 1/python-pycairo_1.4.0-ml3.5_armv7a.ipk 1/python-pygtk_2.16.0-r1.5_armv7a.ipk 1/python-shell_2.6.4-ml9.1.5_armv7a.ipk 
  log "Python libraries installed"
  sync
fi

# Libraries and programs

echo "35"
echo "# Installing Boost Library"
if [ "`opkg list-installed | grep boost-system`" ]; then
  log "Boost library was already installed"
else  
  opkg install 2/boost_1.41.0-r8.1.5_armv7a.ipk 2/boost-filesystem_1.41.0-r8.1.5_armv7a.ipk 2/boost-graph_1.41.0-r8.1.5_armv7a.ipk 2/boost-iostreams_1.41.0-r8.1.5_armv7a.ipk 2/boost-program-options_1.41.0-r8.1.5_armv7a.ipk 2/boost-python_1.41.0-r8.1.5_armv7a.ipk 2/boost-regex_1.41.0-r8.1.5_armv7a.ipk 2/boost-serialization_1.41.0-r8.1.5_armv7a.ipk 2/boost-signals_1.41.0-r8.1.5_armv7a.ipk 2/boost-system_1.41.0-r8.1.5_armv7a.ipk 2/boost-test_1.41.0-r8.1.5_armv7a.ipk 
  log "Boost library installed"
  sync
fi

echo "50"
echo "# Installing Lua5.1"
if [ "`opkg list-installed | grep lua5.1`" ]; then
  log "Lua5.1 was already installed"
else  
  opkg install 2/lua5.1_5.1.4-r5.5_armv7a.ipk 
  log "Lua5.1 installed"
  sync
fi

echo "65"
echo "# Installing Evince"
if [ "`opkg list-installed | grep evince`" ]; then
  log "Evince was already installed"
else  
  opkg install 2/libpoppler-glib4_0.12.3-r0.5_armv7a.ipk 2/libpoppler5_0.12.3-r0.5_armv7a.ipk 2/espgs_8.15.3-r1.5_armv7a.ipk 2/poppler-data_0.4.0-r1.5_all.ipk 2/poppler_0.12.3-r0.5_armv7a.ipk 2/libcupsimage_1.4.3-r2.5_armv7a.ipk 2/evince_2.30.0-r0.5_armv7a.ipk
  log "Evince installed"
  sync
fi

# MiniMenu Update

echo "80"
echo "# Installing updated MiniMenu"

update_mmenu()
{
     bad_mmenu=false
     mmenu_error=false
     rm /usr/bin/mmenu.old 
     cp 3/mmenu /usr/bin/mmenu.new 
     cp 3/mmenu.conf /etc/pandora/conf/mmenu.conf.new 
        sync
        currmmenu=$(md5sum /usr/bin/mmenu.new | cut -d" " -f1)
          if [ $currmmenu = $newmmenu ]; then
            mv /usr/bin/mmenu /usr/bin/mmenu.old 
            mv /etc/pandora/conf/mmenu.conf /etc/pandora/conf/mmenu.conf.old 
            mv /usr/bin/mmenu.new /usr/bin/mmenu 
            mv /etc/pandora/conf/mmenu.conf.new /etc/pandora/conf/mmenu.conf 
            currmmenu=$(md5sum /usr/bin/mmenu | cut -d" " -f1)
            if [ $currmmenu != $newmmenu ]; then
               rm /usr/bin/mmenu 
	       rm /etc/pandora/conf/mmenu.conf 
               mv /etc/pandora/conf/mmenu.conf.old /etc/pandora/conf/mmenu.conf 
               mv /usr/bin/mmenu.old /usr/bin/mmenu 
               bad_mmenu=true
            fi
          else
            rm /usr/bin/mmenu.new 
            rm /etc/pandora/conf/mmenu.conf.new 
	    bad_mmenu=true
	  fi
	  if $bad_mmenu; then
            err "There was a checksum error while copying MiniMenu.\n\nMiniMenu couldn't be updated. Please check your SD-Card and try to recopy the PND-File."
            log "MiniMenu not updated - checksum error"
            mmenu_error=true
          fi    
     if ! $mmenu_error; then
       log "MiniMenu successfully updated"
     fi
     sync
}


mmenu_known=false
for ommenu in $oldmmenu $newmmenu; do
  if [ "$ommenu" = "$currmmenu" ]; then
    mmenu_known=true
    break
  fi
done

if [ "$mmenu_known" = "true" -o -z "$currmmenu" ]; then
  if [ "$currmmenu" != "$newmmenu" ]; then
    update_mmenu
  else
    log "MiniMenu already up-to-date"
  fi
else
  if zenity --question --title="Custom MiniMenu?" --text="\
You seem to have custom or newer MiniMenu on your OS.\n\n\
Update it anyway?\n\
(if unsure, select Yes)" --ok-label="Yes" --cancel-label="No" ; then
    update_mmenu
  else
    log "MiniMenu update skipped"
  fi
fi

# Bugfixes in Scripts

echo "85"
echo "# Installing updated scripts"
if [ ! -f /usr/bin/stopmmenu ]; then
  cp 2/op_calibrate.sh /usr/pandora/scripts/ 
  cp 2/op_datetime.sh /usr/pandora/scripts/ 
  cp 2/op_lcdsettings.sh /usr/pandora/scripts/ 
  cp 2/op_nubmode.sh /usr/pandora/scripts/ 
  cp 2/op_switchgui.sh /usr/pandora/scripts/ 
  cp 2/op_usermanager.sh /usr/pandora/scripts/ 
  cp 2/op_lcdrate.sh /usr/pandora/scripts/ 
  chmod +x /usr/pandora/scripts/op_lcdrate.sh
  cp 2/gui.conf /etc/pandora/conf/ 
  cp 2/op_bluetooth.desktop /usr/share/applications/    
  cp 2/rc.wl1251 /etc/init.d/wl1251-init 
  cp 2/interfaces /etc/network/ 
  cp 2/stopmmenu /usr/bin/stopmmenu 
  mkdir /usr/pandora/mmenu
  rm /usr/share/applications/op_wifi.desktop
  cp 2/abiword.pnd /usr/pandora/mmenu/
  cp 2/arora.pnd /usr/pandora/mmenu/
  cp 2/claws-mail.pnd /usr/pandora/mmenu/
  cp 2/evince.pnd /usr/pandora/mmenu/
  cp 2/gigolo.pnd /usr/pandora/mmenu/
  cp 2/gnumeric.pnd /usr/pandora/mmenu/
  cp 2/midori.pnd /usr/pandora/mmenu/
  cp 2/mousepad.pnd /usr/pandora/mmenu/
  cp 2/pidgin.pnd /usr/pandora/mmenu/
  cp 2/ristretto.pnd /usr/pandora/mmenu/
  cp 2/squeeze.pnd /usr/pandora/mmenu/
  cp 2/thunar.pnd /usr/pandora/mmenu/
  cp 2/xchat.pnd /usr/pandora/mmenu/
  
  log "The HotFix 2 scripts have been updated"
  sync
  chmod 666 /etc/pointercal 
  log "Permissions updated"
else
 log "HotFix 2 scripts were already installed."
fi

echo "90"
echo "# Installing updated scripts"
mountmd5=$(md5sum /usr/pandora/scripts/op_storage.sh | cut -d" " -f1)
if [  "23c0cd2ef0197e1a1e512ce48014311e" != "$mountmd5" ]; then
  update-rc.d -f pandora-lcd-state remove
  rm /etc/init.d/pandora-lcd-state
  cp 3/op_bluetooth.sh /usr/pandora/scripts/ 
  cp 3/rc.pandora-state /etc/init.d/pandora-state
  cp 3/50_openpandora /etc/sudoers.d/ 
  cp 3/mount.sh /etc/udev/scripts/mount.sh
  cp 3/op_startupmanager.sh /usr/pandora/scripts/
  cp 3/op_storage.sh /usr/pandora/scripts/
  cp 3/pandorascripts.pnd /usr/pandora/apps/
  cp 3/dirty_expire_centisecs /etc/pandora/conf/
  cp 3/service.conf /etc/pandora/conf/
  cp 3/eventmap /etc/pandora/conf/
  cp 3/op_runfbapp /usr/bin/
  cp 3/pnd_run.sh /usr/pandora/scripts/
  update-rc.d -f pandora-state start 39 S . stop 31 0 1 6 .
  log "The HotFix 3 scripts have been updated"
  sync
else
 log "HotFix 3 scripts were already installed."
fi

echo "94"
echo "# Installing new Modules"
if [ ! -f /lib/modules/2.6.27.46-omap1/kernel/drivers/net/tun.ko  ]; then
  cp 3/snd-usb-audio.ko /lib/modules/2.6.27.46-omap1/kernel/sound/usb/
  cp 3/snd-usb-lib.ko /lib/modules/2.6.27.46-omap1/kernel/sound/usb/
  cp 3/snd-hwdep.ko /lib/modules/2.6.27.46-omap1/kernel/sound/core/
  cp 3/snd-rawmidi.ko /lib/modules/2.6.27.46-omap1/kernel/sound/core/
  cp 3/tun.ko /lib/modules/2.6.27.46-omap1/kernel/drivers/net/
  depmod
  log "New modules installed"
  sync
else
 log "All Modules were already installed."
fi

echo "95"
echo "# Disabling unneeded services"
if [ -f /etc/rc5.d/S20apmd ]; then
  update-rc.d -f samba remove
  update-rc.d -f xinetd
  update-rc.d -f avahi-daemon
  update-rc.d -f apmd
  update-rc.d -f usb-gadget
  update-rc.d -f banner
  update-rc.d -f portmap
  update-rc.d -f mountnfs
  update-rc.d -f blueprobe
  update-rc.d -f dropbear
  log "Unneeded services have been disabled"
  sync
else
  log "Unneeded sevices were already disabled"
fi

echo "100"
echo "# Update finished"

# Zenity Progress goes here
) |
        zenity --progress \
          --title="Installing Updates..." \
          --text="Updating System..." \
          --percentage=0

err=`cat /tmp/updater_err.log`
if [ -z "$err" ]; then
  err="Your system has been updated without any errors."
fi
update=$(cat /tmp/updater.log)
zenity --info --title="Update finished" --text "$err\n\n${update}"

fi

if [ -f /tmp/updreboot ]; then
  reboot=`cat /tmp/updreboot`
  zenity --info --title="You need to reboot" --text "${reboot}"
  rm /tmp/updreboot
fi