#!/bin/sh # set -x # C. Ostheimer and : 02-2009 #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 addon_bin=dropbear addon_bin_ver=0.51 addon_script_ver=1.0 core_script_ver=1.245 cfg_common_req=2.356 max_conf_size=100000 #server=http://192.168.222.10 #or =ftp://user17:secret@1.2.3.4 #server=http://www.spblinux.de/fbox.new server=http://demirel.biz/opensrc/fbox # cfg.common and cfg.customize are downloaded from $server and # firmware version specific files are downloaded from $server${uclibc#/0.9.28}$svrsub # ( kernel 2.6/uClibc-0.9.28 and 0.9.29 beta ); # default sub directories are /26, /26-ar7, /26-ur8. ############################################################################## # Copyright (C) cfg_asterisk16, C. Ostheimer and , 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!" && usage ) server="$2";shift;; -h | -\? | --help) usage;; -*) 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`" uclibc="/`ls /lib/libuClibc-* | sed "s/\(.*libuClibc-\)\(.*\)\(\.so\)/\2/"`" if [ "$verbose" ];then echo "INFORMATION: $version_status" echo "INFORMATION: $addon Version: $addon_bin_ver" echo "INFORMATION: uClibc: ${uclibc#/}" echo "INFORMATION: Install-Script Version: $core_script_ver" echo "INFORMATION: FW specific modules will be downloaded from: $server${uclibc#/0.9.28}$svrsub" fi 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` export PATH=$PATH:/sbin:/usr/sbin [ "$modext" = "o" ] && errorexit "Error: In this version of cfg_$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${uclibc#/0.9.28}$svrsub) to $INST_DIR ..." fi _fct mkdr@/var:log:run:spool:log/asterisk:spool/asterisk 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 and $server${uclibc#/0.9.28}$svrsub _fct wgetx@$server${uclibc#/0.9.28}$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:$INST_DIR _fct rdsk@new:ramdev # WORKAROUND FOR HANDLING COMPATIBILITY ISSUES WITH uClibc > 0.9.28 # a) cp does not do proper dereferencing of symlinks when copying # -> use cp from customized busybox coming in $addon # b) recursive mutex not properly supported for > 0.9.28 therefore no thread safety # -> enforce use of old uClibc 0.9.28 via LD_LIBRARY_PATH if [ -f /lib/libuClibc-0.9.29.so ];then CP="/var/$addon/bin/cp" else CP="cp" fi SQF_FILE=${addon}.sqf echo "$SQF_FILE -> $ramdev: " if [ -f $INST_DIR/$SQF-FILE ]; then cat $SQF_FILE > $ramdev else _fct wgetx@$server${uclibc#/0.9.28}$svrsub:$ramdev:$SQF_FILE fi mount $ramdev /var/$addon || _fct fallback@$SQF_FILE 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 eval ${CP} $cp_opts $file_path/cfg.common $INST_DIR eval ${CP} $cp_opts $file_path/`basename $0` $INST_DIR fi echo "Start extracting files ... please wait!" # WORKAROUND FOR HANDLING COMPATIBILITY ISSUES WITH uClibc > 0.9.28 # SPECIAL WORKAROUND FOR FAT32 FS old_IFS=$IFS IFS=' ' for cp_error in `eval ${CP} -R $cp_opts /var/$addon/* $INST_DIR/$addon 2>&1`;do if echo $cp_error | grep -q "cp: cannot create symlink";then cp_to=`echo $cp_error | sed "s/\(.*'\)\(.*\addons\\)\(.*\)\('.*\)/\3/"` cp_from=`ls -l /var/$cp_to` cp_from=${cp_from#*-> } eval ${CP} $cp_opts /var${cp_to%/*}/$cp_from $INST_DIR$cp_to [ "$verbose" ] && echo "INFO: Fixed FAT32 symlink dereferncing issue for: $cp_to" else echo $cp_error fi done IFS=$old_IFS # WORKAROUND END umount /var/$addon _fct rdsk@free:$ramdev:$INST_DIR 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 "COMPLETED: $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 && _fct mntif@-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 "($0 start or simply $addon)" else echo "($INST_DIR/${0##*/} start or simply $addon)" echo echo "After a reboot you may reinstall $addon from usb with" echo "$INST_DIR/${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_ rm -rf /var/log/asterisk /var/spool/asterisk 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