#!/bin/sh #set -x # C. Ostheimer 05-2006, 10-2006, 01-2007; usb_install framework by dynamic # 01-2008 dropbear-0.50, included libutil.so.0, only kernel 2.6 has been updated! # set stricter limits: MAX_AUTH_TRIES 3, MAX_UNAUTH_PER_IP 2, MAX_UNAUTH_CLIENTS 3 # disable shadow passwords (in dropbear and in passwd), no shadow support in avm uClibc # template cfg script addon=dropbear [ "$addon_bin" ] || addon_bin=$addon #put used defined post install commands into file cfg.customize # note: when using cfg_dropbear usb_install the config files # are COPIED from usb device (addons/dropbear/etc/dropbear) # to /var/tmp/dropbear because a vfat usb device does not allow chmod 600 # (changes made to /var/tmp are lost if not copied back to usb device) #server=http://192.168.222.10 server=http://www.spblinux.de/fbox # cfg.common and cfg.customize are downloaded from $server and # firmware version specific files are downloaded from $server$svr24 (or $svr26) # (kernel 2.4/uClibc-0.9.26 or kernel 2.6/uClibc-0.9.28); # default sub directories are /24[.zlib|.zlib16] and /26. # svr24=/24 # svr26=/26 # command line option parsing unset verbose quiet show_usage [ $# -eq 0 ] && show_usage=1 while [ x$1 != x ]; do case $1 in -z) [ "$svr24" ] || svr24=24.zlib;; -Z) [ "$svr24" ] || svr24=24.zlib16;; -v) verbose=1;; -q) quiet=1;; -h | -\? | --help) show_usage=1;; -*) echo "warning: unknown option $1";; *) break esac; shift; done # Source common functions for installation, (download if missing) f=cfg.common if [ -f ${0%cfg_*}$f ]; then . ${0%cfg_*}$f else wget $server/$f -O /var/$f || errorexit " Couldn't download $f from $server" . /var/$f fi modext=`_fct modext` svrsub=`_fct svrsub` export PATH=$PATH:/sbin:/usr/sbin:/var/$addon/bin usage() { echo -e "usage:\n" \ " [INST_DIR=installation_directory] ${0##*/} [-v] install\n" \ " (installs to ramdisk or to INST_DIR/addons if INST_DIR is given)\n" \ " ${0##*/} [-v] usb_install | remove\n" \ " (usb_install: installs to /addons of autodetected usb device or to INST_DIR)\n" \ " ${0##*/} [-v] start [onlykey] | [-v] stop \n" exit } is_addon_installed() { unset msg if mount |grep -q "on /var/$addon"; then msg="$addon is still mounted to /var/$addon" elif [ -L /var/$addon/bin/$addon_bin -a -x /var/$addon/bin/$addon_bin ]; then msg="(usb_install: `ls -l /var/${addon}_usb |sed 's/^[^\/]*//'`)" fi if [ x$1 != x-q -a "$msg" ]; then echo "$addon is still installed. Installation aborted. Run ${0##*/} [remove|usb_remove] first" errorexit "$msg" fi #create return value [ "$msg" ] } #echo TEST #echo "modext $modext, svrsub $svrsub." #get_inst_realdir_ $INST_DIR #get_inst_realdir_ #get_missing_file_ chroot #_fct rdsk@new:ramdev && echo "--$ramdev--" #echo END_TEST [ "$show_usage" ] && usage cd /var case $1 in usb_install | install) is_addon_installed unset is_usb [ $1 = usb_install ] && is_usb=1 free 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)" is_usb=1 else echo "warning: INST_DIR(=$INST_DIR) defined, but not a directory" echo " using default install to ramdisk (press ctrl+c to stop)" sleep 10 fi else echo "installing $addon ($server$svrsub) ..." fi [ -d $addon ] || mkdir $addon if [ "$is_usb" ]; then ############ USB-INSTALL #################################### # check for user defined installation directory given in $INST_DIR if [ "$INST_DIR" ]; then _fct instdir@`get_inst_realdir_ $INST_DIR`:addons/$addon:inst_dir:inst_fs_type else _fct instdir@/var/media/ftp:addons/$addon:inst_dir:inst_fs_type fi case $inst_fs_type in msdos | vfat | ntfs) cp_opts="" ;; *) cp_opts="-pd" esac ############ USB-INSTALL, EXTRACT TO USB IF NOT EXTRACTED YET ####### if ! [ -f $inst_dir/addons/$addon/bin/dropbearmulti ]; then echo "installing $addon on usb device (${inst_dir##*/})" # get $addon specific squashfs-archives from $server$svrsub _fct wgetx@$server$svrsub:$inst_dir/addons/$addon:$addon.sqf # get common install scripts / tools / modules from $server$svrsub file_path=`_fct path_abs@$0` if [ $file_path != $inst_dir/addons ];then # not called from $inst_dir/addons: install on $inst_dir/addons cp $cp_opts $file_path/cfg.common $inst_dir/addons cp $cp_opts $file_path/${0##*/} $inst_dir/addons fi _fct wgetx@$server$svrsub:$inst_dir/addons:freeramdisk:rd.$modext _fct wgetx@$server:$inst_dir/addons:cfg.customize chmod +x $inst_dir/addons/${0##*/} $inst_dir/addons/cfg.customize $inst_dir/addons/freeramdisk [ -d $addon.tmp ] || mkdir $addon.tmp mount |grep -q "on /var/$addon.tmp" && umount $addon.tmp if mount |grep -q "on /var/$addon.tmp"; then errorexit "error: /var/$addon.tmp already mounted; failed to unmount /var/$addon.tmp" else _fct rdsk@start:$inst_dir/addons # get free ramdisk and store device_name_and_path in variable ramdev _fct rdsk@new:ramdev:$inst_dir/addons echo -n "$addon.sqf -> $ramdev: " cat $inst_dir/addons/$addon/${addon}.sqf >$ramdev [ $? -eq 0 ] && mount $ramdev $addon.tmp || _fct fallback@$inst_dir/addons/$addon/$addon.sqf fi if mount |grep -q "on /var/$addon.tmp"; then echo "Start extracting files ... please wait!" fr=/var/$addon.tmp to=$inst_dir/addons/$addon # special treatment part1 (cpnL) of bin/, lib/, usr/bin/, usr/lib/ _fct cprs@$cp_opts:$fr:$to:bin:lib:usr:etc:dev:sys:proc _fct mkdr@$to:bin:lib:usr/bin:usr/lib:etc/$addon _fct cprs@$cp_opts:$fr/usr:$to/usr:bin:lib _fct cpnL@$cp_opts:$fr/etc:$to/etc:$addon _fct cpdf@$cp_opts:$fr/etc/$addon:$to/etc/$addon _fct cpnL@$cp_opts:$fr/bin:$to/bin _fct cpnL@-R${cp_opts#-}:$fr/lib:$to/lib _fct cpnL@$cp_opts:$fr/usr/bin:$to/usr/bin _fct cpnL@-R${cp_opts#-}:$fr/usr/lib:$to/usr/lib umount /var/$addon.tmp _fct rdsk@free:$ramdev:$inst_dir/addons rm -r $addon.tmp echo "$addon has been successfully installed to usb device ${inst_dir##*/}" else errorexit "error: failed to download and mount $addon (on /var/$addon.tmp)" fi else ############ USB-INSTALL, NO NEED TO EXTRACT FILES. ALREADY ON USB ##### echo "$addon already on USB-Device ... skipping extract phase." fi ########### CONTINUE USB-INSTALL AFTER REQUIRED FILES CONFIRMED ON USB-PATH ########### file_path=`_fct path_abs@$0` if [ $file_path = $inst_dir/addons ]; then # called from $inst_dir/addons: create copy in /var cp $cp_opts $inst_dir/addons/cfg.common /var cp $cp_opts $inst_dir/addons/${0##*/} /var fi [ -L ${addon}_usb ] || _fct lnsf@${addon}_usb:$inst_dir/addons/$addon #create links in /var/$addon pointing to /var/${addon}_usb #special treatment part2 (cpnL) of bin/, lib/, usr/bin/, usr/lib/ # - link all directories except bin/, ... # - in bin/, ... : link contents of these directories _fct lndfe@/var/$addon:/var/${addon}_usb:bin:lib:usr:etc:proc:sys:dev _fct mkdr@/var/$addon:bin:lib:usr/bin:usr/lib:etc:proc:sys:dev _fct lndfe@/var/$addon/lib:/var/${addon}_usb/lib _fct lndfe@/var/$addon/bin:/var/${addon}_usb/bin _fct lndfe@/var/$addon/usr:/var/${addon}_usb/usr:lib:bin _fct lndfe@/var/$addon/usr/lib:/var/${addon}_usb/usr/lib _fct lndfe@/var/$addon/usr/bin:/var/${addon}_usb/usr/bin # special treatment part3 (cpnL) of bin/, lib/, usr/bin/, usr/lib/ # - additional symlinks in bin/, usr/bin, lib ... # create symbolic links in /var/$addon for all files which have been skipped # when extracting to usb with _fct cpnL (=copy to usb but skip symbolic links) # (if installed to ramdisk ls -l /var/$addon/bin displays these links in bin/) if [ "$modext" = "o" ]; then d=/var/$addon/lib _fct lnsf2@$d:libutil.so:libutil.so.0:libutil-0.9.26.so else d=/var/$addon/usr/lib [ -f $d/libutil-0.9.28.so ] && _fct lnsf2@$d:libutil.so:libutil.so.0:libutil-0.9.28.so fi d=/var/$addon/bin _fct lnsf2@$d:dbclient:dropbear:dropbearconvert:dropbearkey:ssh:scp:dropbearmulti d=/var/$addon/usr/bin _fct lnsf2@$d:dbclient:dropbear:dropbearconvert:dropbearkey:ssh:scp:dropbearmulti # create devices in /var/$addon/dev if required # [ -d /var/$addon/dev ] || mkdir /var/$addon/dev # msdos/vfat does not have permissions: # copy config files from usb back to /var/tmp/$addon and adjust permissions # and link from /var/$addon/etc/$addon to /var/tmp/$addon # Create required directory structures _fct mkdr@/var:tmp/$addon:$addon/etc/$addon # Copy default conf files if not existing on target dir strcuture echo "Copying $addon configuration files from usb device addons/$addon/etc/$addon to /var/tmp/$addon" _fct cprs@$cp_opts:/var/${addon}_usb/etc/$addon:/var/tmp/$addon _fct lnsf@/var/$addon/etc:../../tmp/$addon chmod 600 /var/tmp/$addon/* cd /var else ########### RAM-INSTALL ############################################# _fct wgetx@$server$svrsub:/var:freeramdisk:rd.$modext _fct wgetx@$server:/var:cfg.customize chmod +x freeramdisk cfg.customize _fct rdsk@start _fct rdsk@new:ramdev echo -n "$addon.sqf -> $ramdev: " if [ -f $addon.sqf ]; then cat $addon.sqf > $ramdev else _fct wgetx@$server$svrsub:$ramdev:$addon.sqf fi mount $ramdev $addon || _fct fallback@$addon.sqf # Create required directory structures _fct mkdr@/var:tmp/$addon # Copy default conf files if not existing on target dir strcuture _fct cpdf@$cp_opts:/var/$addon/etc/$addon:/var/tmp/$addon # Remove symlinks which might be left over from last usb_install for f in /var/${addon}_usb ; do [ -L $f ] && rm $f done fi ########### COMMON-INSTALL (RAM and USB) ############################# # Create required directory structures _fct mkdr@/var:tmp/$addon/dev/pts if [ "$modext" = "ko" ]; then # allow write access to /dev/pts using mount -o bind for d in tmp/$addon tmp/$addon/dev tmp/$addon/dev/pts; do [ -d $d ] || mkdir $d done for i in 0 1 2 3 4 5 6 7; do [ -c $d/$i ] || mknod $d/$i c 136 $i done mount -o bind $d /dev/pts fi free echo "to use $addon (ssh server) type ./cfg_$addon start" if ! [ "$is_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/addons;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 ${0##*/} break fi done echo "(important: use /var/$addon/bin/passwd to set a root password;" echo "you might want to generate your own host key files in /var/tmp/$addon" echo "with /var/$addon/bin/dropbearkey)" ;; usb_remove | remove) [ $1 = usb_remove ] && is_usb=1 inst_dir=`get_inst_realdir_` [ "$inst_dir" ] && is_usb=1 && echo -e "default set to usb_remove\n(if this is not correct run: rm /var/${addon}_usb )\n" if ! is_addon_installed -q; then [ "$quiet" ] || echo "addon $addon is not installed (has already been removed?)" else free echo "removing $addon ..." $0 -q stop ask || exit sleep 1 if ! [ "$is_usb" ]; then _fct rdsk@get_device:ramdev:/var/$addon || unset ramdev umount /var/$addon [ "$ramdev" ] && _fct rdsk@free:$ramdev _fct rdsk@stop fi if ! mount |grep -q "on /var/$addon"; then f=$addon.sqf [ -f $f ] && rm $f if mount |grep -q "ramfs on /dev/pts"; then if umount /dev/pts; then rm -r /var/tmp/$addon/dev fi fi if [ "$is_usb" ]; then [ -d $addon ] && rm -r $addon [ -L ${addon_usb} ] && rm ${addon}_usb else # [ -d $addon ] && rmdir $addon # labor firmware 4883 busybox comes without rmdir if [ -d $addon ]; then for x in $addon/*; do [ -r $x ]; break; rm -r $addon; done; fi fi echo -n "done - (addon $addon has been removed" if [ "$is_usb" ]; then echo " from ram, not from usb)"; else echo ")"; fi fi free fi ;; start) d=/var/dropbear/etc/dropbear/dropbear_dss_host_key r=/var/dropbear/etc/dropbear/dropbear_rsa_host_key unset x [ "$2" = "onlykey" ] && x="-s" if [ -x $addon/bin/$addon_bin ]; then $addon/bin/$addon_bin -d $d -r $r $x else errorexit "error: executable /var/$addon/bin/$addon_bin not found (try to run ${0##*/} install)" fi ;; 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" ;; *) usage esac