#!/bin/sh
# vim:set sw=4 ts=4:
#
# $Id: alicerc,v 2.49 2005/04/14 18:39:41 fabian Exp $
#
# ALICE
# Automatic Linux Installation and Configuration Environment
#
#############################################################################
#
# Copyright (c) 2000 SuSE Linux Solutions AG, Eschborn, Germany
# All rights reserved.
#
# This file is part of ALICE, which was sponsored by
# T-Online International AG
#
# Author: Fabian Herschel
#
#############################################################################
#
# alicerc
# set the environment of alice
#
#if [ -d /mnt/var ]
#then
#   exec | tee -a /mnt/var/alice.log >/dev/tty2
#else
#   exec | tee -a /var/alice.log >/dev/tty2
#fi
#exec 2>&1 > /var/ALICE/log/alice.log

if [ -z "$alice_dir" ]; then
	alice_dir=$(cd $(dirname $0)/..; pwd)
	export alice_dir
fi
_self=$(basename $0)
alice_rc=0
if [ -e /etc/rc.config ]
then
	. /etc/rc.config
fi
if [ -e /etc/rc.config.d/alice.rc.config ]
then
   . /etc/rc.config.d/alice.rc.config
fi
#
if [ "$ALICE_CONFIG_MODE" = "dhcp" ]
then
   dhcp_mode=1
else if [ -z "$dhcp_mode" ]
     then
        dhcp_mode=0
     fi
fi
if [ -n "$ALICE_DHCP_CLASS" ]
then
   dhcp_class=$ALICE_DHCP_CLASS
fi

GET_CONFIGURATION()
{
    #
    # GET_CONFIGURATION config_section [--require | -r]
    #
    # config_section means the sort of the config_file
    # without the complete path and without the fqhn or
    # class name. get_config file will complete the pathname
    # by searching for a config_file. this mechanism can be used
    # to have specific, class and default config_files...
    #
    typeset require=0 section debug="" optional=0
    # debug="--debug"
    while [ $# -gt 0 ]
    do
	case $1 in
	    --require | -r ) # set the "require mode"
		require=1
		;;
	    --optional )     # if no config is found do not
		# print an error message
		optional=1
		;;
	    --debug )        # show the the search messages
		debug="--debug"
		;;
	    --dhcp )
		export get_config_option="--dhcp "
		;;
	    * )              section=$1
		;; 
	esac
	shift
    done
    #
    # if at leat one config file was found, set the variables
    # print a error message, if no file was found
    #
    typeset -i	my_return=0
    rm -f /tmp/al_cfg.$$ 
    $alice_dir/bin/alicetags.pl --alice_home=$ALICE_HOME \
	$debug \
	--section $section --script /tmp/al_cfg.$$ --host $fqhn 
    . /tmp/al_cfg.$$
    ALICE_TAGS_FOUND=$((awk -F= ' NF==2 { print $1 }' /tmp/al_cfg.$$) | sort -u)
    rm -f /tmp/al_cfg.$$ 
    #
    # TODO: How to handle --require config we have to check return codes
    #
    return $my_return
}


get_inst_server()
{
   typeset S_VAR_NAME SIS
   # 
   # figure out the installation server SIS
   #
   S_VAR_NAME=$(echo "SYS_INST_SERVER_${SYS_OS_VENDOR}_${SYS_OS}_${SYS_OS_VERSION}" | tr "." "_")
   eval SIS=\$\{$S_VAR_NAME\}
   if [ -z "$SIS" ]      # if no special entry go to the fallback value
   then
      if [ -n "$SYS_INST_SERVER" ]
      then
         SIS=$(expand_alice_var --mini $SYS_INST_SERVER)
      else
         (
	        echo "Can not figure out the installation server."
	         echo "Please define a server with a tag SYS_INST_SERVER"
	     ) >&2
         return_code=2
      fi
   fi
   echo $SIS
}

get_inst_directory()
{
   typeset S_VAR_NAME SID
   #
   # figure out the installation directory SID
   #
   S_VAR_NAME=$(echo "SYS_INST_DIR_${SYS_OS_VENDOR}_${SYS_OS}_${SYS_OS_VERSION}" | tr "." "_")
   eval SID=\$\{$S_VAR_NAME}
   if [ -z "$SID" ]      # if no special entry gp to the fallback value
   then
      if [ -n "$SYS_INST_DIR" ]
      then
         SID=$(expand_alice_var --mini "$SYS_INST_DIR")
      else
         (
		     echo "Can not figure out the installation directory."
		     echo "Please define a server with a tag SYS_INST_DIR"
	     ) >&2
         return_code=2
      fi
   fi
   echo $SID
}

WELCOME()
{
   MESSAGE HALLO $_self "$(date  +'%Y-%m-%d,%H:%M:%S,(%Z)')"
}

GOOD_BYE()
{
   MESSAGE BYE $_self "$(date  +'%Y-%m-%d,%H:%M:%S,(%Z)')"
   exit $alice_rc
}

ERROR()
{
   # parameter: message-id message-params
   MESSAGE -n ERR
   MESSAGE "$@"
   test $alice_rc -lt 2 && alice_rc=2
}

WARNING()
{
   MESSAGE -n WARN
   MESSAGE "$@"
   test $alice_rc -eq 0 && alice_rc=1
}

MESSAGE()
{
   #
   # -n says "no carr. return" after the message
   # -t <type>
   #
   typeset MSG MSGID RT="\n" TYPE=info MSGPAR FACILITY=local0
   while [ $# -gt 0 ]
   do
      case "$1" in
          -n )
              RT=""
              shift
              ;; 
          -t )
              TYPE="$2"
              shift 2
              ;;
           * ) 
              MSGID=$1
              shift
	          break;    # <-- the rest of params should be plain text
              ;;
      esac
   done

   #
   # Using LANG to get the correct error file (only C supported now)
   #
   if [ ! -f $alice_nls_dir/message_$LANG ]
   then
      export LANG=C
   fi
   MSG=$(grep ^$MSGID: $alice_nls_dir/message_$LANG)
   MSG=${MSG#$MSGID:}
#   printf "$MSG$RT" "$MSGPARAM"
   printf "$MSG$RT" "$@"
   if [ -n "$ALICE_LOGGER_FACILITY" ]
   then
      FACILITY="${ALICE_LOGGER_FACILITY%%[ \t]*}"
   fi
   logger -t ALICE -p ${FACILITY}.info "$(printf "$MSG$RT" "$@")"
}

FATAL()
{
   # parameter: message-id message-params
   MESSAGE -n FATAL
   MESSAGE "$@" 
   MESSAGE ERREXIT
   alice_rc=3
   GOOD_BYE
}

CHANGED()
{
    # CHANGED file
    # checks, if created temp file <file>.alice differs from
    # <file> and returns 1 if the file differs and 0 otherwise
    typeset file
    file="$1"
    diff -q ${file}.alice ${file} 2>/dev/null 1>&2 || return 1
    return 0
}

INSTALL()
{
    # INSTALL file [ user:group octal_mode ]
    typeset file owner mode
    file="$1" shift
    mv ${file}.alice ${file} || WARNING FREETEXT "failed to install $file"
    test "$#" -gt 0 && { 
	chown $1 ${file}; 
	shift 
    }
    test "$#" -gt 0 && { 
	chmod $1 ${file}; 
	shift 
    }
}

BACKUP()
{
   #
   # BACKUP [--require | -r | --error | -e] source {,..}
   #
   typeset rc=0 require=0 error_msg=0  
   if [ ! -d $alice_backup_dir ]
   then
       mkdir -p $alice_backup_dir
   fi
   while [ $# -gt 0 ]
   do
     case $1 in
         --require | -r ) # set require mode
                          require=1
                          ;;
         --error | -e )   # print an errpor message, if BACKUP fails
                          error_msg=1
                          ;;
         * )              # copy that ... 
                          cp -a --parents $1 $alice_backup_dir 2>/dev/null
                          if [ $? -ne 0 ]
                          then
                             rc=1
                             if [ $require -eq 1 ]
                             then
                                FATAL NOSAVE $1 $alice_backup_dir
                             elif [ $error_msg -eq 1 ]
                             then
                                ERROR NOSAVE $1 $alice_backup_dir
                             fi
                          fi
                          ;;
     esac
     shift
   done
   return $rc
}

RC_CONFIG_SET()
{
	if [ "$1" == "--no-backup" ]
	then
		NOBACKUP=1
		shift
	fi
	
	# RC_CONFIG_SET variable value
	typeset var value
	var=$1 
	value=$2
	#
    # remove leading and trailing double quotes
    #
    value=${value%\"}
    value=${value#\"}

	# first we try to find the variable in /etc/rc.config.d/*
	filename=`grep -Hl "^${var}" /etc/rc.config.d/*.rc.config`

	if [ `echo "$filename" | wc -l` -gt 1 ]
	then
		WARNING DOUBLEFLIE "^${var}" 
		# Just use the first
		filename=$( echo "$filename" | head -n 1 )
	fi

	if [ -z "$filename" ]
	then
		# if nothing is found we use /etc/rc.config
		filename=/etc/rc.config
	fi
	
   
   cat $filename | awk -F= '
        $1 == varname { found=1;
                        printf "%s=\"%s\"\n", varname, value }
        $1 != varname { print $0 }
        END           { if (found != 1 ) {
                            printf "%s=\"%s\"\n", varname, value
                        }
                      }' varname=$var value="$value" > $filename.$$
					  
	if [ "$NOBACKUP" == "1" ]
	then
		mv $filename.$$ $filename
	else
		diff -q $filename $filename.$$ 2>/dev/null
		if [ $? -ne 0 ]
		then
			BACKUP $filename
			mv $filename.$$ $filename
		fi
	fi
}

SYSCONFIG_SET()
{
	# path var value
	typeset path var value filename
	path="$1"
	var="$2"
	value="$3"
	
	filename="/etc/sysconfig/$path"
	cat $filename | awk -F= '
		$1 == varname { found=1;
						printf "%s=%s\n", varname, value }
		$1 != varname { print $0 }
		END           { if (found != 1 ) {
						printf "%s=%s\n", varname, value }
	}' varname=$var value="$value" > $filename.$$
	mv $filename.$$ $filename
}

expand_alice_var()
{
    # WILL BE OBSOLETE!
    # USE <tag expand="yes">....</tag> in the future  
    # expand_alice_var some_text_to_be_expanded
    #    note that in that standard string four markers are allowed:
    #
    # If you enhance_alice_expand here, please also
    # enhance lib/ALICE/aliceTags.pm (function alice_expand)
    # 
    # Expandable strings are:
    #
    #   x %arch
    #   x %hostname
    #   x %idir
    #   x %ip
    #   x %iproto
    #   x %iserver
    #   x %os
    #   x %vendor
    #
    #     %pct
    #
    if [ "$1" != "--mini" ]
    then
	export SYS_EXPANDED_INST_DIR=$(get_inst_directory)
	export SYS_EXPANDED_INST_SERVER=$(get_inst_server)
    else
	shift
    fi
    if [ -z "$SYS_EXPANDED_INST_IP" ]
    then
	export SYS_EXPANDED_INST_IP=$(echo "$NET_IP_CONFIG" | \
	awk '$1 == dev { print $2 }' dev=$NET_INST_DEV)
    fi
    echo "$*" | \
    sed \
        -e "s/%arch/$SYS_ARCH/g" \
	-e "s#%idir#$SYS_EXPANDED_INST_DIR#g" \
	-e "s/%hostname/$SYS_NAME/g" \
	-e "s/%ip/$SYS_EXPANDED_INST_IP/g" \
	-e "s/%iproto/$SYS_INST_PROTOCOL/g" \
	-e "s/%iserver/$SYS_EXPANDED_INST_SERVER/g" \
        -e "s/%os/$SYS_OS/g" \
        -e "s/%version/$SYS_OS_VERSION/g" \
	-e "s/%vendor/$SYS_OS_VENDOR/g" \
	-e "s/%pct/%/g" # %pct must the be last %-expand :-)
#
}

#
#  alice_configured is used to identify if alicerc has run before. so if make_all
#  has already configured alice, this part of alicerc need not to be rerun by each
#  script startd by make_all. so a little bit time is saved here. and i'm shure this
#  part will grow up very fast
#
if [ -z "$alice_configured" ]
then
    export alice_configured=yes
    if [ "$dhcp_mode" -eq 1 ]
    then
	export fqhn=dhcp
	export dhcp="--dhcp "
    fi
    if [ -z "$fqhn" ]
    then
       fqhn=$(hostname -f)
    fi
    if [ -d /etc/init.d ]            # first try the standard
    then
       rc_d_dir=/etc/init.d
    elif [ -d /etc/rc.d ]              
    then
       rc_d_dir=/etc/rc.d 
    elif  [ -d /sbin/init.d ]        # then the special
    then
       rc_d_dir=/sbin/init.d
    else 
       MESSAGE NOTFOUND /etc/rc.d 
       rc_d_dir=/etc/rc.d                 
    fi
    #
    # setup the alice directory structure
    #  there two MAIN parts:
    #   1) the shell scripts, libs and so on (program part)
    #   2) the configuration files (data part)
    # alice_dir   points to the root of the program part
    # alice_data  points to the root of the data part
    #
    # first comes the program part:
    #
    export alice_bin_dir=${alice_dir}/bin
    export alice_lib_dir=${alice_dir}/lib
    export alice_nls_dir=${alice_lib_dir}/nls
    #
    # now follows the data part:
    #
    if [ -n "$ALICE_HOME" ]
    then
       export alice_data=$ALICE_HOME
    fi
    export alice_info_dir=${alice_data}/info
    export alice_templates_dir=${alice_data}/templates
    export alice_classes_dir=${alice_data}/classes
    #
    # some "run time" directories
    #
    export alice_backup_dir=/var/alice/backup/$(date "+%Y-%m-%d-%H:%M")
    export alice_log_dir=/var/log
    export alice_log_file=$alice_log_dir/alice_log
    #
    # get the mac address of all network cards
    #
    mc_addrs=$(/sbin/ifconfig | awk '/HWaddr/ { print $NF}' | tr -d i: | tr [:lower:] [:upper:] )
    export alice_config_mode="sys_style"
    test -n "$DEBUG"  && DEBUG="set -x"
    if [ -z "$LANG" ]
    then
	export LANG=C
    fi
fi
export alice_dir alice_data alice_rc
export fqhn alice_mount alice_bin_dir alice_info_dir alice_lib_dir alice_templates_dir
export alice_backup_dir alice_classes_dir alice_log_file alice_log_dir
export alice_host_classes rc_d_dir alice_nls_dir
$DEBUG
