#!/bin/bash

# defining some constants
OK="\r\033[72C[\033[32m ok \033[m]"
OK2="\r\033[1A\033[72C[\033[32m ok \033[m]\033[1B"
PROB="\r\033[72C[\033[33mprob\033[m]"
FAIL="\r\033[72C[\033[31mfail\033[m]"
TAB1="\r\033[30C"

# This function prints an introduction
function intro ()
{
  echo -e "\nThis script checks the environment on your system so that PBButtons would work"
  echo "with all features also if it was launched as normal user."
  echo "------------------------------------------------------------------------------"
  if [ "$user" = "root" ]; then
    echo "You started this script as superuser root. That means that all nessecary"
    echo "changes could be done automatically by this script."
    echo -n "-> Do you want to continue? (y/N): "; read answer
    if [ "$answer" != "Y" -a "$answer" != "y" ]; then user="test"; fi
  else
    echo "You started this script as normal user '$user' so that no adjustments"
    echo "of the system could be made. Instead of that all nessecary changes will be"
    echo "printed to console. To perform missing adjustments please restart this script"
    echo "as superuser root."
  fi
  echo
}

# This function split up a given string and assign each substring
# to a also given variable.
# Parameter: $1   = String to split
#            $2.. = names of variables to store the results
function splitstring ()
{
  for item in $1; do
    if [ "$2" = "" ]; then break; fi
    eval "$2=$item"
    shift;
  done
}

# This function prints advices to handle certain situations and explains
# the background.
# Parameter: $1   = no. of advice
#          : $2.. = advice dependent parameter
function printadvice ()
{
  if [ "$user" != "root" ]; then
    case "$1" in
      1)
        echo "   The group has the right permissions, but this will only work if"
        echo "   those users who wants to use PBButtons are members of '$4'. You"
        echo "   have the choice between adding those users to '$4' in /etc/groups"
        echo "   or setting the group permissions also to 'all users' with the"
        echo -e "   command: 'chmod o+$2 $3'.\n" 
        ;;
      2)
        echo "   Only root could access this device. This wouldn't work if you want"
        echo "   also normal user to use PBButtons. To solve this you could set (or"
        echo "   let this script do it for you) the nessecary permissions ($2) to"
        echo "   'all users'. This could be done with the command:"
        echo -e "   'chmod o+$2 $3'.\n"
        ;;
      3)
        echo "   The $3 $2 is nessecary for PBButtons to work"
        echo "   propperly. You could create it and set permissions by hand or let"
        echo -e "   this script do it for you.\n"
        ;;
      4)
        echo "   It seems that you are using a kernel without the new input layer."
        echo "   This input leyer with its event queues in /dev/input is fundamental"
        echo "   for PBButtons to work. Here are some hints that might help:"
        echo "    - Get a kernel for your system configured with the input layer"
        echo "    - or get the kernel source and compile it by yourself"
        echo "    - or you only have to load some kernel modules via modprobe."
        echo -e "   Please read the appropriate documentation for details.\n"
        ;;
    esac
  fi
}

# This function would set the permissions of a target, if it was called by root
# Parameter: $1 = target
#            $2 = permissions, 'r-' or 'rw'
function setpermissions ()
{
  if [ "$2" = "rw" ]; then local mode=666; else local mode=644; fi
  if [ -d $1 ]; then mode=$(($mode + 111)); fi
  if [ "$user" = "root" ]; then
    chmod $mode $1
    if [ "$2" = "r-" ]; then
       echo -e "  adjust permissions to 'user readable' ... done $OK2"
    else
       echo -e "  adjust permissions to 'user writable' ... done $OK2"
    fi
  fi
}

# This function would create a directory with correct permissions and owner,
# if it was called by root
# Parameter: $1 = directory
#            $2 = permissions, 'r-' or 'rw'
function createdir ()
{
  if [ "$2" = "rw" ]; then local mode=777; else local mode=755; fi
  if [ "$user" = "root" ]; then
    mkdir -p $1
    chmod $mode $1
    chown root.root $1
    if [ "$2" = "r-" ]; then
      echo -e "  create $1, user readable ... done $OK2"
    else
      echo -e "  create $1, user writable ... done $OK2"
    fi
    return 0
  fi
  return 1
}

# This function would create a character devce in /dev with correct
# permissions and owner, if it was called by root
# Parameter: $1 = device
#            $2 = permissions, 'r-' or 'rw'
#            $3 = major device number
#            $4 = minor device number
function createdev ()
{
  if [ "$2" = "rw" ]; then local mode=666; else local mode=644; fi
  if [ "$user" = "root" ]; then
    mknod -m $mode $1 c $3 $4
    chown root.root $1
    if [ "$2" = "r-" ]; then
      echo -e "  create $1, user readable ... done $OK2"
    else
      echo -e "  create $1, user writable ... done $OK2"
    fi
    return 0
  fi
  return 1
}

# This function checks if a given caracter device exists and if is
# has the right permissions to be usefull for PBButtons.
# Parameter: $1 = device including path
#            $2 = nessecary permissions: "r-"=read, "rw"=read/write
#            $3 = major device number
#            $4 = minor device number
# Return   : true if the device exists, false if not 
function checkdevice ()
{
  echo -en "checking $1: $TAB1"
  if [ -c $1 ]; then
    echo -n "exists"
    splitstring "`ls -l $1`" devmode t devuser devgroup
    if [[ "$2" == "rw" ]] && [[ $devmode == ???????rw? ]]; then
      echo -e ", user writable $OK"
    elif [[ "$2" == "r-" ]] && [[ $devmode == ???????r-? ]]; then
      echo -e ", user readable $OK"
    else
      if [[ "$2" == "rw" ]] && [[ $devmode == ????rw???? ]]; then
	echo -e ", group writable $PROB"
	printadvice "1" "$2" "$1" "$devgroup"
      elif [[ "$2" == "r-" ]] && [[ $devmode == ????r-???? ]]; then
	echo -e ", group readable $PROB"
	printadvice "1" "$2" "$1" "$devgroup"
      else
	echo -e ", root access only $FAIL"
	printadvice "2" "$2" "$1"
      fi
      setpermissions $1 $2
    fi
    return 0
  else
    echo -e "does not exist $FAIL"
    printadvice "3" "$1" "device"
    if (createdev $1 $2 $3 $4); then return 0; else return 1; fi
  fi
}

# This function checks if a given directory exists and if is has the right
# permissions to be usefull for PBButtons.
# Parameter: $1 = directorye including path
#            $2 = nessecary permissions: "r-"=read, "rw"=read/write
# Return   : true if the directory exists, false if not 

function checkdir ()
{
  if [ "$2" = "rw" ]; then mode=777; else mode=755; fi

  echo -en "checking $1: $TAB1"
  if [ -d $1 ]; then
    echo -n "exists"
    splitstring "`ls -ld $1`" dirmode t diruser dirgroup
    if [[ "$2" == "rw" ]] && [[ $dirmode == ???????rw? ]]; then
      echo -e ", user writable $OK"
    elif [[ "$2" == "r-" ]] && [[ $dirmode == ???????r-? ]]; then
      echo -e ", user readable $OK"
    else
      if [[ "$2" == "rw" ]] && [[ $dirmode == ????rw???? ]]; then
	echo -e ", group writable $PROB"
	printadvice "1" "$2" "$1" "$dirgroup"
      elif [[ "$2" == "r-" ]] && [[ $dirmode == ????r-???? ]]; then
	echo -e ", group readable $PROB"
	printadvice "1" "$2" "$1" "$dirgroup"
      else
	echo -e ", root access only $FAIL"
	printadvice "2" "$2" "$1"
      fi
      setpermissions $1 $2
    fi
    return 0
  else
    echo -e "does not exist $FAIL"
    printadvice "3" "$1" "directory"
    if (createdir $1 $2); then return 0; else return 1; fi
  fi
}

user=`whoami`
intro

procmountpoint=`mount | grep "^proc" | sed -e "s/.*on //" | sed -e "s/ .*//"`
if [ "$procmountpoint" = "" ]; then
  echo "Sorry, this script needs a mounted proc-device to work properly."
  exit 1
else
  echo -ne "checking new input layer: $TAB1"
  if [ ! "`cat $procmountpoint/devices | grep " *[0-9]* *input.*"`" = "" ]; then
    echo -e "active $OK"
    if (checkdir "/dev/input" "r-"); then
      for dev in 0 1 2 3; do
        checkdevice "/dev/input/event$dev" "r-" 13 $((64 + $dev))
      done
    fi
  else
    echo -e "not configured in kernel $FAIL"
    printadvice "4"
  fi
fi

checkdevice "/dev/pmu"   "rw" 10 154
checkdevice "/dev/mixer" "rw" 14 0
checkdevice "/dev/adb"   "rw" 56 0
checkdevice "/dev/fb0"   "rw" 29 0

if [ $user != "root" ]; then
  echo -e "\nNo changes to the system have been made."
else
  echo -e "\nThe 'problematic' and 'failed' issues have been tried to set correctly."
  echo "Start this script again to check if it was completely successfull."
fi  
