#
# set -x
# C. Ostheimer and <dynamic>: 08-2008
#put user defined post install commands into file cfg.customize 
#maximal size of tar archive with asterisk config files
#which is written to /var/flash/cfg.configs
addon=dropbear
app_ver=0.51
script_ver=1.231
cfg_common_req=2.351
max_conf_size=100000
addon_bin=dropbear

#server=http://192.168.222.10 #or =ftp://user17:secret@1.2.3.4
server=http://www.spblinux.de/fbox.new/0.9.29
#server=http://c2a2b2.com/fbox/0.9.29
# cfg.common and cfg.customize are downloaded from $server and
# firmware version specific files are downloaded from $server$svr26 
# ( kernel 2.6/uClibc-0.9.28);
# default sub directories are /26, /26-ar7, /26-ur8.
# svr26=/26

##############################################################################
# Copyright (C) cfg_dropbear,  C. Ostheimer and <dynamic>, licensed under
# GNU General Public License version 2 (GPL v2.0)
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details; spblinux.de/fbox.new/gpl-2.0.txt

usage()
{
 echo -e "usage:\n" \
         "*******************************************************************************\n" \
	 " [INST_DIR=install_dir] ${0##*/} [-v] [-s alternate_sever ] install|usb_install\n" \
         "   install:     installs to ramdisk or to INST_DIR/addons if INST_DIR is given\n" \
         "   usb_install: installs to ./addons of autodetected usb device\n" \
         "   -v:          enables verbose mode for debugging purposes\n" \
         "   -s [ftp://[id:secret@]my_ftp_server.com|http://my_http_server.com]\n" \
         "\n" \
	 " ${0##*/} [-v] remove\n" \
         "\n" \
         " ${0##*/} [-v] disable | enable\n" \
         "   disable:     Application is put to maintenance mode to prevent installing\n" \
	 "                and starting of $addon\n" \
         "   enable:      Application is put to normal operations mode again\n" \
         "\n" \
         " ${0##*/} [-v] start [onlykey] |stop \n" \
         "\n" \
         " For RAM-Installations only:\n" \
         " ${0##*/} [-v] [-f] config2flash|flash2config|clearflash [minor]\n" \
         "   config2flash: save modified configuration files to non volatile (flash) memory\n" \
         "   flash2config: restore configuration files from non volatile (flash) memory\n" \
         "   clearflash:   clear $addon configuration files from flash memory\n" \
         "   -f:           forced mode - never prompt and always assume \"y\"\n" \
         "*******************************************************************************\n"
 exit
}
# command line option parsing
unset verbose forced disable downloaded_latest version_status
[ $# -eq 0 ] && usage
while [ x$1 != x  ]; do case $1 in
 -v) verbose=1;;
 -f) forced=1;;
 -s) echo $2 | grep -q -E "(http|ftp)://.*\..+" || (echo -e "\nParameter ERROR: Wrong \"-s ...\" Option usage!" && show_usage=1)
     server="$2";shift;;
 -h | -\? | --help) show_usage=1;;
 -*) echo "warning: unknown option $1";;
 *) break
esac; shift; done

# Check version of cfg.common required for installation and download latest version if required
f=cfg.common
cfg_common_script=${0%cfg_*}$f
while true;do
 if [ -x $cfg_common_script ];then
  version_status="`$cfg_common_script cmp_version $cfg_common_req`"
  [ "$verbose" ] && echo $version_status
  if echo $version_status | grep -q "\-> OK";then
   break;
  else
   if ! [ $downloaded_latest ];then
    echo -e "Fatal Error: Cannot locate version v$cfg_common_req of $f file"
    exit 1 
   fi 
  fi 
 fi 
 cfg_common_script=/var/$f
 if ! wget $server/$f -O $cfg_common_script;then
  echo -e "Fatal Error: Couldn't download $f from $server"
  exit 1 
 fi 
 chmod +x $cfg_common_script
 downloaded_latest=1
done

# Source common functions for installation from cfg.common
. $cfg_common_script

_fct cfgctl@${0##*/}:check:app_status

[ "$app_status" = "disabled" -a "$1" != "" ] && case $1 in
 stop|help|enable|remove|usb_remove);;
 *)
  echo "***************************************************************************" 
  echo "${0##*/} is currently in maintenance mode and will not allow"
  echo "any activities unless it is enabled via command line." 
  echo "Run: \"${0##*/} enable\", to activate normal operation mode again."
  echo "***************************************************************************" 
  exit
esac

modext=`_fct modext`
svrsub=`_fct svrsub`


[ "$modext" = "o" ] && errorexit "ERROR: In this version of $addon only kernel 2.6 is supported." 
case $1 in
usb_install | install)
 is_addon_installed && errorexit "ERROR: $device installation of $addon detected.\nInstallation aborted. Run ${0##*/} [remove|usb_remove] first"
 free
 ### Set DEBUG to blank if not defined by external parameter
 DEBUG=${DEBUG-""}
 if [ "$INST_DIR" ];then 
  if [ -d "$INST_DIR" ]; then
   [ $1 = install ] && echo -n "defaulting to "
   echo "usb_install on $INST_DIR(="`get_inst_realdir_ $INST_DIR`") (given by variable INST_DIR)"
   echo "(if this is not correct run: unset INST_DIR)"
   device="USB"
   INST_DIR=$INST_DIR/addons
   [ -d $INST_DIR ] || mkdir $INST_DIR
   # check for user installation directory given in $INST_DIR
   _fct instdir@`get_inst_realdir_ $INST_DIR`:$addon:inst_dir:inst_fs_type
  else
   echo "WARNING:     INST_DIR(=$INST_DIR) defined, but not a directory"
   echo "             using default install to ramdisk"
   device="SQF"
   INST_DIR="/var"
   sleep 10
  fi
 else
  if [ "$1" = "usb_install" ];then
   device="USB"
   _fct instdir@/var/media/ftp:addons/$addon:inst_dir:inst_fs_type
   INST_DIR="$inst_dir/addons"
   [ -d $INST_DIR ] || mkdir $INST_DIR
  else
   device="SQF"
   INST_DIR="/var"
  fi 
  echo "INFORMATION: Installing $addon ($server$svrsub) to $INST_DIR ..."
 fi
 source_dir=$INST_DIR/$addon
 ############ CHECK WHETHER SOURCE FILES ARE ALREADY AVAILABLE ############
 if [ -f $source_dir/bin/$addon_bin ];then
  ############ SOURCE FILES ARE ALREADY AVAILABLE ############
  ############ USB-INSTALL, NO NEED TO EXTRACT FILES. ALREADY ON INST_DIR #####
  [ "$device" = "USB" ] && echo "INFORMATION: $addon already on USB-Device ... skipping extract phase."
 else 
  ############ SOURCE FILES NOT YET AVAILABLE      ############
  ############ COPY SQF-FILE TO RAMDISK AND MOUNT TO /var/$addon ###########
  [ -d /var/$addon ] || mkdir /var/$addon
  # get common install scripts / tools / modules from $server$svrsub
  _fct wgetx@$server$svrsub:$INST_DIR:freeramdisk:rd.$modext
  _fct wgetx@$server:$INST_DIR:cfg.customize
  chmod +x $INST_DIR/freeramdisk $INST_DIR/cfg.customize
  _fct rdsk@start
  _fct rdsk@new:ramdev
  echo "$addon.sqf -> $ramdev: "
  if [ -f $INST_DIR/$addon.sqf ]; then
   cat $addon.sqf > $ramdev
  else
   _fct wgetx@$server$svrsub:$ramdev:$addon.sqf
  fi 
  mount $ramdev /var/$addon || _fct fallback@$addon.sqf
  mount |grep -q "on /var/$addon" || errorexit "ERROR: failed to download and mount $addon (on /var/$addon)"
  if [ "$device" = "USB" ]; then 
   ############ USB-INSTALL, EXTRACT TO INST_DIR/$addon IF NOT EXTRACTED YET #######
   case $inst_fs_type in
    msdos | vfat | ntfs)
     cp_opts=""
     ;;
    *)
     cp_opts="-pd"
   esac
   echo "INFORMATION: Installing $addon on usb device (${inst_dir##*/})"
   file_path=`_fct path_abs@$0`
   if [ $file_path != $INST_DIR ];then
    # not called from $INST_DIR: install to $INST_DIR
    cp $cp_opts $file_path/cfg.common $INST_DIR
    cp $cp_opts $file_path/`basename $0` $INST_DIR
   fi
   echo "Start extracting files ... please wait!"
   cp -R $cp_opts /var/$addon/* $INST_DIR/$addon
   umount /var/$addon
   _fct rdsk@free:$ramdev:$inst_dir/addons
   rm -r /var/$addon
   _fct lnsf@/var/log/$addon_bin:$source_dir/log/$addon_bin
   _fct lnsf@/var/spool/$addon_bin:$source_dir/spool/$addon_bin
   echo "$addon has been successfully installed to usb device ${inst_dir##*/}"
  fi 
 fi 
 ########### COMMON ROOT INSTALL ( SQF and USB ) ###########
 ########### OVERLAYING ROOT DIRECTORIES ###########
 echo "#####################################################################"
 echo "Performing root install ... This may take a couple minutes."
 echo "Aborting during this period will render your system inoperable!!!"
 echo "#####################################################################"
 _fct cfgctl@`basename $0`:disable:SILENT
 [ "$verbose" ] || echo -n "Installation progress: "
 ################# HANDLING OF /bin DIRECTORY ####################### 
 _fct ovrly@RO,$device:$DEBUG/bin:$source_dir/bin
 ################# HANDLING OF /etc DIRECTORY #######################  
 _fct ovrly@RO,$device:$DEBUG/etc:$source_dir/etc
 ################# HANDLING OF /usr DIRECTORY #######################  
 _fct ovrly@RO,$device:$DEBUG/usr:$source_dir/usr
  # Newer FW with ctlmgr does not support symlinks to /usr/www 
  [ -L /usr/www ] && rm /usr/www && mkdir /usr/www && mount -o bind /var/_RO_/usr/www /usr/www
  # igdd has relative symlink references to /var and requires /var to be bound to /var/_RO_/var
 _fct mntif@-o:bind:/var:/var/_RO_/var
  echo ""
 _fct cfgctl@`basename $0`:enable:SILENT
 ########### OVERLAYING ROOT DIRECTORIES FINISH ###########
 
 ########### APPLICATION SPECIFIC ACTIVITIES    ###########
 # HANDLING OF /dev/pts DIRECTORY #######################                 
 # Create new pts device files that are RW ( can be chmod )                               
 if [ "$modext" = "ko" ]; then                                                            
  d=/dev/pts                                                                              
  _fct ovrly@NL,$device:$d                                                          
  for i in 0 1 2 3 4 5 6 7; do                                                            
   [ -c $d/$i ] || mknod $d/$i c 136 $i                                        
  done                                                                                    
 fi                                                                                                  
 # CREATE SYMLINKS TO DROPBEARMULTI ####################
 _fct lnsf2@$DEBUG/bin:dropbear:dbclient:dropbearconvert:dropbearkey:scp:ssh:dropbearmulti
 ########### APPLICATION INSTALLATION FINISHED  ########### 
 free
 echo "to use $addon type ./cfg_$addon start"
 if ! [ "$device" = "USB" ]; then
  [ "$0" != "./cfg_$addon" ] && echo "(or $0 start)"
 else
  echo "(or $inst_dir/addons/${0##*/} start)"
  echo
  echo "After a reboot you may reinstall $addon from usb with"
  echo "$inst_dir/addons/${0##*/} usb_install"
 fi
 # check for existence of "cfg.customize" to perform user specific cfg_xyz customizations
 for d in /var $INST_DIR;do
  if [ -f $d/cfg.customize -a -x $d/cfg.customize ];then
   [ "$verbose" ] && echo "Found addons customization script cfg.customize in $d. Will check & run customizations for $addon now."
   $d/cfg.customize allow `basename $0`
   break
  fi
 done  
 ;;
usb_remove | remove)
 if is_addon_installed;then
  if [ "$forced" ];then
   echo "Forced uninstall requested ... trying!"
   for mount_point in /var/_RO_/var /bin /lib /etc /usr/www /usr /dev/pts;do
    mount |grep -q " on $mount_point" && umount $mount_point
   done
   if [ $device = "SQF" ];then
    _fct rdsk@get_device:ramdev:/var/$addon || unset ramdev
    umount /var/$addon
    [ "$ramdev" ] && _fct rdsk@free:$ramdev
    _fct rdsk@stop
   fi
   cd /
   umount /var/_RO_
   echo "Leaving contents of \"/var/_RW_\" as is. rm -rf as needed." 
  else 
   free
   $0 -q stop ask || exit
   echo "*************************************************************************"
   echo "Due to $addon installation being mapped to \"/\" ( root directories ) a removal"
   echo "requires a System Reboot for clean completion of the de-installation."
   _fct cfgctl@`basename $0`:disable
   echo "A potential automatic re-installation of $addon after reboot was disabled."
   echo "Reboot your system now via \"reboot\" to complete the de-installation of $addon"
   [ "$device" = "USB" ] && echo "Your $addon files that were stored on your usb will not be deleted."
   echo "*************************************************************************"
   free
   exit
  fi 
 else
  [ "$verbose" ] && echo "addon $addon is not installed (has already been removed?)"
  free
 fi
 ;;
start)
 is_addon_installed || errorexit "ERROR: executable /bin/$addon_bin not found. You need to run first\n \"${0##*/} usb_install | install\""
 unset x
 [ "$2" = "onlykey" ] && x="-s"
 /bin/$addon_bin -E $x
 ;;

stop)
 unset do_ask
 [ "x$2" = "xask" ] && do_ask=1 && shift
 f1=$addon
  for x in TERM KILL result; do
   unset is_running
   for f in $f1; do
    [ "$f" ] || continue 
    if ps |grep -v grep |grep -v ${0##*/} |grep -q "$f "; then
     case $x in
      result)
       errorexit "ERROR: cannot terminate process $f"
       ;;
      *)
       is_running=1
       key=y
       if [ "$do_ask" ]; then
        echo "$addon is running; do you want to terminate process $f (Y/n)"
	read key
	[ "n" = "$key" ] && errorexit "script terminated by user"
	echo "(to reset a terminal use command: stty sane)"
       fi
       killall -$x $f
       sleep 2
     esac
    fi
   done
   [ "$is_running" ] || break
  done
  [ "$quiet" ] || echo "run ${0##*/} remove to free memory by removing addon $addon from the system"
 ;;

disable | enable )
 if [ "$1" = "disable" ];then
  _fct cfgctl@`basename $0`:disable
 else
  _fct cfgctl@`basename $0`:enable
 fi 
 ;;   

config2flash)
 conf_in_flash_ $1 ${2-"101"} /etc/dropbear
 ;;
flash2config|clearflash) 
 conf_in_flash_ $1 ${2-"101"} 
 ;;
 
*)
 usage
esac
