#! /bin/bash
# vim:set sw=4 ts=4:
#! /bin/bash -x
#
##############################################################################
#
# $Id: make_boot_server,v 1.3 2005/04/11 14:14:34 fabian Exp $
#
#############################################################################
#
# ALICE
# Automatic Linux Installation and Configuration Environment
#
# Copyright (c) 2000-2002 SuSE Linux Solutions AG, Eschborn, Germany
#               2002-2004 SuSE Linux AG, Eschborn, Germany
#               2005           SUSE GmbH, Nuernberg, Germany
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#############################################################################
#
# Author: 
#
##############################################################################
#
#
# NAME
#	make_boot_server - Create a directory hierarchy for an ALICE tftp server
#
# SYNTAX
#   make_boot_server <options>
#
# DESCRIPTION
#
# OPTIONS
#   -a <arch>
#       Create a tftp-tree for architecture <arch>
#       This option can be used multiple
#
#   -h	
#       Print a short help menu.
#
#   -s <path>
#       Set the tftp root server path. The default is (and should be)
#       /srv/tftp
#
# TODO: -v Not implemented yet
#   -v <level>
#       Set the verbosity to <level>.
#       Default level is 1, i.e. only very limited verbosity -- Use 0 for no verbosity.
#
# ARGUMENTS
#	None required nor accepted.
#
# FILES
#	None.
#
# SEE ALSO
#	bash(1),
#	AutoYaST(8), YaST(8)
#
# EXAMPLES
#	<Something useful to illustrate how this script works>
#
# AUTHOR
#	Created on 2004-Jul-21 by Fabian Herschel, SUSE Linux AG <fabian.herschel@suse.com>
#
# RELEASED
#	make_boot_server - Create a directory hierarchy for an ALICE tftp server
#
#	This program is released under the GPL Version 2 (or later), and is
#	Copyright (c) 2004 Dennis Olsson, SUSE Linux AG <DOlsson@SUSE.com>
#	All rights reserved.
#
#	This program is free software; you can redistribute it and/or
#	modify it under the terms of the GNU General Public License
#	as published by the Free Software Foundation; either version 2
#	of the License, or (at your option) any later version.
#
#	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.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#	The creation of this script was sponsored in 2004 by
#	T-Mobile Deutschland GmbH, Bonn, Germany, EU.
#
# REVISION HISTORY
#	$Id: make_boot_server,v 1.3 2005/04/11 14:14:34 fabian Exp $
#
#	Use 'cvs log' to view the history log for this script.
# -------------------------------------------------------------------------------------------------
#
# TODO:
#
# -------------------------------------------------------------------------------------------------
# Initialization
 
set -o privileged		# Do not inherit functions.
set -o nounset			# Raise error on unset variable.
set -o errexit			# Exit on first error.
set +o noglob			# Expand wildcards.
set +o noclobber		# Overwrite files.
set -o allexport		# Export all variables.
shopt -s expand_aliases		# Expand aliases, even if non interactive.
# set -o verbose		# List commands as they are read.
# set -o xtrace			# List commands after parameter expansion.
 
alias echo="echo -e"		# Allow the usage of escape sequences.

# Set our name:)
typeset -r PROG="${0##*/}"

# Default exit value
typeset -i _exit=0

# Where to create temporary working files
typeset -r TMP="/var/tmp/TMP-$$"


# -------------------------------------------------------------------------------------------------
# Default values for option changable values

########## CHANG begins here
# Default verbose level
typeset -i INFOlevel=1

# Initialize the product related variables:
#
# - ProductIndex is used an index pointer into the following arrays
# - ProductName array (-p,-c) contains the CD/DVD product name
# - ProductPath array (-p,-c) contains the alternative path where to find the product files
#
# In case a "ProductName" entry does not have an entry in either of "Product{CD,DVD}s", it
# means that the product sources are to be found relative to the "SourceDir" path, or alternatively
# relative to the path given by "ProductPath[${ProductIndex}]", if this has been set, under
# where a directory structure of "${ProductName[${ProductIndex}]}/{CD,DVD}[0-9]*" for the product
# files are expected to be found.  If not, this is an error.
declare -i ACount=0
declare -a ArchitectureName

# Initialize the default values for the installation and source directories:
#
# - InstallDir (-i) contains the path to the directory where to create the install server dir
# - SourceDir (-s) containt the the path to the directory where to find the product files
declare ServerDir="/srv/tftp"
#
# read the alice sysconfig
#
if [[ -r /etc/sysconfig/alice ]]
then
	. /etc/sysconfig/alice
fi
#
# -------------------------------------------------------------------------------------------------
# Function defintions

# Function to extract and print a nice self documenting help menu
function Usage()
{
    sed -e 's/^# \?//' -e '/^SYNTAX/,/^DESCRIPTION/!d' -e '/^DESCRIPTION/q' "${0}" | sed -e '$d'
    sed -e 's/^# \?//' -e '/^OPTIONS/,/^FILES/!d' -e '/^FILES/q' "${0}" | sed -e '$d'
    _exit 1
    # NEVER REACHED!
}

# Functions used to exit from script
function _exit()
{
    [[ -n "${1:-}" ]] && _exit=${1}
    # Ignore catching of script ending
    trap EXIT

    # Clean up after our selfs, if need be
    [[ -d "${TMP}" ]] && rm -rf "${TMP}"

    # Exit with set error code
    exit ${_exit}
    # NEVER REACHED!
}

trap _exit EXIT 1 2 3 15

function info()
{
    set +o errexit			# Suspend: Exit on first error.
    local -i level=${1-0}
    shift
    if [[ ${INFOlevel} -ge ${level} ]]
    then
	if [[ $# -eq 0 ]]
	then
	    echo
	else
	    for text in "${@}"
	    do
		echo "${PROG}: ${text}"
	    done
	fi
    fi
    set -o errexit			# Restore: Exit on first error.
}

function error()
{
    set +o errexit			# Suspend: Exit on first error.
    _exit=${1}
    shift
    if [[ "${1}" == "-c" ]]
    then
	continue=true
	shift
    fi
    for text in "${@}"
    do
	echo "${PROG}: ${text}"
    done

    if [[ -z "${continue:-}" ]]
    then
	_exit
	# NEVER REACHED!
    fi
}

# Function to set an integer value to a variable
#
#	setInteger <var> <value> [ <default value, if not 0> ]
function setInteger()
{
    declare var="${1}" value="${2}"
    declare -i defval="${3:-0}" result=0

    integer=$(expr match "${value}" '0*\([0-9]\+\)$')
    result=$?
	[[ ${result} -eq 1 && "${integer}" == "0" ]] && result=0
    [[ -z "${integer}" ]] && integer="${defval}"

    eval "${var}"="${integer}"
    return ${result}
}

function split()
{
	declare tmpDelim="${1}"
	declare tmpList="${2}"
	declare tmpPos="${3}"
	declare tmpDef="${4}"
	tmpElem=$(echo "${tmpList}" | awk -F"${tmpDelim}" '{ printf "%s", $i} ' i="${tmpPos}" )
	if [[ -z "$tmpElem" ]]
	then
		tmpElem="${tmpDef}"
	fi
	echo "${tmpElem}"
}

# -------------------------------------------------------------------------------------------------
# Recognized options -- make use of "silent error" reporting from "getopts" (the first ":")!!
typeset -r OPTIONS="a:hs:v:"

# Decode the options
ArgMissing=""
while getopts "${OPTIONS}" opt
do
    case "${opt}" in
	a ) # Add a tree for architecture <arch>
		#
		ArchitectureName[$ACount]="${OPTARG}"
		(( ACount++ ))
		;;

	h)	# Print a short help menu.
	    Usage
	    # NEVER REACHED!
	;;

	s)	# Set server dir
	    ServerDir="${OPTARG}"
	;;

	v)	# Change the verbosity
	    opt_v=true
	    setInteger INFOlevel "${OPTARG}" "${INFOlevel}" ||
		error 2 -c "Option ${opt}: Passed value '${OPTARG}' is not an integer."
	;;

	:)	# Option requiring argument is missing its argument
	    echo "${PROG}: Option '${OPTARG}' requires an argument!"
	    ArgMissing=true
	;;

	?)	# Unknown option found
	    echo "${PROG}: Option '${OPTARG}' is unknown -- Ignored!"
	;;
    esac
done
# Shift any options off the argument stack
shift $((${OPTIND} - 1))

# Complain, if an option is missing its parameter
[[ -n "${ArgMissing}" ]] && Usage

# Cannot continue, if an error was detected!
[[ ${_exit} -ne 0 ]] && exit

# Write protect the fetched values
typeset -r InstallDir SourceDir ProductIndex ProductName ProductCDs ProductDVDs ProductPath
typeset -r opt_v INFOlevel

# debug some arrays
#typeset -a -p

# -------------------------------------------------------------------------------------------------
# Decode arguments...

# None to decode and none expected!
[[ $# -gt 0 ]] && Usage

declare -i ANo=0

while [[ "${ANo}" -lt "${ACount}" ]]
do
	tmpArch="${ArchitectureName[$ANo]}"
	mkdir -p "${ServerDir}/${tmpArch}"
	cd "${ServerDir}/${tmpArch}"
	for dir in grub nbi pxe pxe/pxelinux.cfg yast.cfg
	do
		mkdir -p "$dir"
	done
	cd -
	(( ANo++ ))
done

#
# end of script
