#!/bin/sh

# by probono at myrealbox dot com
# thanks to bfree
# GPL

# ok we need dialogs now
if [ -z "$DIALOG" ] ; then
# Determine which dialog to use in which situation:
# Xdialog (in all other cases)
export DIALOG=Xdialog
# kdialog (in case there is no console available and we are running KDE)
( ps -e 2>/dev/null | grep kdeinit >/dev/null 2>&1 ) && export DIALOG=kdialog 
# dialog (in case there is a console available)
GUIMODE=$(tty)
( echo $GUIMODE | grep /dev/tty[:digit:] >/dev/null ) && export DIALOG=dialog
fi

# Setup defaults for whatever dialog we are using
case $DIALOG in
 kdialog)
 DIALOG_OPTIONS=" --caption klik" ;
 KLIKDIR=":klikdir" ;;
 Xdialog|dialog)
 DIALOG_H=12
 DIALOG_W=60
 DIALOG_OPTIONS=" $DIALOG_H $DIALOG_W" ;
 KLIKDIR="~" ;;
esac

derror(){
 case $DIALOG in
 kdialog)
 $DIALOG --error "$1" $DIALOG_OPTIONS 
 ;;
 Xdialog|dialog)
 $DIALOG --msgbox "ERROR: $1" $DIALOG_OPTIONS 
 ;;
 esac
}
dmsgbox(){
 $DIALOG --msgbox "$1" $DIALOG_OPTIONS
}

# Setup our SU function
SU="su"
if [ $UID != 0 ]; then
  if [ -d /KNOPPIX ]; then
    SU="sudo"
  else
    if [ "$DIALOG" = "kdialog" ]; then
      if [ -f /usr/bin/kdesu -o -f /usr/kde/3.2/bin/kdesu ]; then
        SU="kdesu"
      fi
    fi
  fi
else
  SU="root"
fi

mysu(){
  SUREASON=$1
  shift
  _SUCMD=$@
  case $SU in
  kdesu)
  dmsgbox "You will need to supply the root password to $SUREASON"
  $SU -c "$_SUCMD"
  ;;
  su)
  dmsgbox "You will need to supply the root password to $SUREASON"
  $SU --command="$_SUCMD"
  ;;
  sudo)
  echo "#!/bin/bash" > klik.install
  echo "$_SUCMD" >> klik.install 
  chmod +x klik.install
  sudo ./klik.install
  rm klik.install
  ;;
  root)
  $_SUCMD
  ;;
  *)
  derror "I don't know how to become root"
  ;;
  esac
}

# rewrite cmdline to use absolute instead of relative paths, thanks bfree
NEWCMD=$(perl -e '$newcmd=shift(@ARGV);foreach $arg (@ARGV){ @part=split(/\=/,$arg); foreach $part (@part){ (-e "$ENV{PWD}/$part") && ($part="$ENV{PWD}/$part");}$newcmd.=" ".join ("=",@part);} print "$newcmd";' $@)
set -- $NEWCMD

# if no arguments are passed and 
# there is a .cmg in the same directory as this
# script, then use the .cmg
DIRNAME=$(dirname $0)
if [ -z $1 ]
then
  CMG=$(find "$DIRNAME" -iname '*.cmg'|head -n 1) || exit 1
  echo "Found $CMG, using it"
else
  CMG="$1"
  shift
fi

# make path to CMG absolute, thanks bfree
case $CMG in
/*) ;; 
*) CMG=$(pwd)/$CMG ;; 
esac

# determine which filesystem is used as .cmg
[ "$(head --bytes=4 $CMG)" = "sqsh" ] && FS="squashfs"
[ "$(head --bytes=4 $CMG)" = "E=(" ] && FS="cramfs" && [ -n "$(which fusecram)" ] && FUSE="fusecram"
[ "$(head --bytes=32774 $CMG | tail --bytes=5)" = "CD001" ] && FS="iso9660" && [ -n "$(which fuseiso)" ] && FUSE="fuseiso"

if [ -n "$FS" ]
then
  MOUNT=""
  if [ -n "$FUSE" ]
  then
    SAFEFUSE="$FUSE"
    FUSEMNT="$HOME/.fuse/$(basename $CMG)"
    # make mount point and use fuse to mount it
    mkdir -p $FUSEMNT
    $FUSE $CMG $FUSEMNT || FUSE=""
    if [ -x "$FUSEMNT/wrapper" ]
    then
      MOUNT="$FUSEMNT"
    else
      if [ -z "$FUSE" ]
      then
        fusermount -u $FUSEMNT
      else
        FUSE=""
      fi
    fi
    if [ -z "$MOUNT" ]
    then
      rmdir $FUSEMNT
      #derror "Sorry but your Fuse mount (by $SAFEFUSE) failed, falling back to normal mounting" &
    fi
  fi
  if [ -z "$MOUNT" ]
  then
    # Find the first available space in /mnt/app
    NUMBERS="7 6 5 4 3 2 1"		
    for NUMBER in $NUMBERS
    do
      [ -e "/mnt/app/$NUMBER" ] || MNTNUM=$NUMBER
    done
    # Set the mount point
    case $FS in
      squash) MOUNT=/mnt/squash/$MNTNUM ;;
      *) MOUNT=/mnt/app/$MNTNUM ;;
    esac
    # Check /mnt/app exists and is writable
    if [ ! -w /mnt/app ]
    then
      if [ ! -d /mnt/app ]
      then
        SUDESC="make the /mnt/app directory,"
        SUCMD="mkdir -p /mnt/app "
      fi
      SUDESC="$SUDESC prepare the /mnt/app directory, "
      if [ -n "$SUCMD" ]
      then
        SUCMD="$SUCMD ; "
      fi
      SUCMD="$SUCMD chmod ugo+w /mnt/app "
    fi

    # better use /media/klik according to FSH?
    if [ -z "$(cat /etc/fstab | grep app/7)" ]
    then
      SUDESC="$SUDESC prepare /etc/fstab to mount .cmg files."
      if [ -n "$SUCMD" ]
      then
        SUCMD="$SUCMD ; "
      fi
      SUCMD="$SUCMD echo \"#Added by klik (klik.atekon.de)\" >> /etc/fstab  "
      for i in 1 2 3 4 5 6 7; do
        SUCMD="$SUCMD ; echo \"/mnt/app/$i/image /mnt/app/$i cramfs,iso9660 user,noauto,ro,loop,exec 0 0\" >> /etc/fstab";
      done
    fi

    if [ -n "$SUCMD" ]
    then
      mysu "$SUDESC" $SUCMD
    fi

    (mkdir -p $MOUNT && ln -s $CMG $MOUNT/image) || (MNTAPP=fail && rmdir $MOUNT >/dev/null 2>/dev/null)
    if [ -n "$MNTAPP" ]
    then
      derror "Klik was unable to make the neccessary changes in /mnt/app.
Have you (as root) created /mnt/app and made it writable by all klik users?"
      exit 1
    fi

    if [ -n "$(cat /etc/fstab | grep app/7)" ]
    then
      mount $MOUNT || MOUNTSTAT="Unable to mount $MOUNT"
    else
      rm $MOUNT/image
      rmdir $MOUNT
      derror "Failed to make the changes to /etc/fstab, did you supply the correct password?"
      exit 1
    fi

    if [ ! -x $MOUNT/wrapper ]
    then
      rm $MOUNT/image
      rmdir $MOUNT
      derror "You seem to be unable to mount .cmg images correctly.
Either configure fuse with fusecram and fuseiso or
you can setup your /etc/fstab to allow users to mount .cmg images.

To prepare your fstab:
As root, please make /mnt/app writeable and add the following lines:
  
#######################################################################
/mnt/app/1/image /mnt/app/1 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/2/image /mnt/app/2 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/3/image /mnt/app/3 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/4/image /mnt/app/4 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/5/image /mnt/app/5 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/6/image /mnt/app/6 cramfs,iso9660 user,noauto,ro,loop,exec 0 0
/mnt/app/7/image /mnt/app/7 cramfs,iso960 user,noauto,ro,loop,exec 0 0
#######################################################################"
      exit 1
    fi
  fi
else
  # NOTE: exit now cause our cmg isn't mounted
  derror "$CMG does not appear to be either a squashfs, iso9660 or a cramfs file"
  exit 1
fi

  #
  # execute the wrapper
  # the wrapper should take care to keep running until its app closes
  #
  
  # we need this so that on the cmdline, pipes etc work
  CMDLINE="yes"
  ( tty | grep ^/dev/tty >/dev/null ) && CMDLINE=""
  ( tty | grep ^/dev/pts >/dev/null ) && CMDLINE=""
  if [ "$CMDLINE" = "yes" ] ; then
    RESULT=$($MOUNT/wrapper $@ 2>&1) || error "$RESULT" 
  else
    $MOUNT/wrapper $@
  fi

  # kill all child processes
  kill $(pidof -x -o %PPID) 2>/dev/null


# unmount and clean up
if [ -n "$FUSE" ]
then
  fusermount -u $MOUNT
  rmdir $MOUNT
else
  if [ -n "$(cat /etc/fstab | grep app/7)" ]
  then
  umount $MOUNT
  else
  mysu "unmount the .cmg image" "umount $MOUNT"
  fi
  rm -f $MOUNT/cramfs
  rm -r $MOUNT/
fi
