#!/bin/bash
#set -n		# read but do not execute commands (check on syntax errors)
#
# File: /usr/local/bin/update-multimedia
#
# Updates a users ~/.multimediarc
#
#    Copyright (C) 2008  Juergen Kaesmann (JK)
#
##############################################################################
# GPL NOTICE
#
#    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
#
##############################################################################
# FIND SAMPLES
#
##############################################################################
# FILTER SAMPLES
#
##############################################################################
# AWK SAMPLES
#
##############################################################################
# SED SAMPLES
#
##############################################################################
# RSYNC OPTIONS
#
##############################################################################
# DIALOG SAMPLES
#
##############################################################################
# REPLACE STRINGS
#
##############################################################################
# EXIT CODES

##############################################################################
# SOURCE FILES
#
. /usr/local/etc/main.conf				# config main
#. $LLIBDIR/libfuncerr-sh				# functions error
. $LLIBDIR/libfuncstd-sh				# functions standard
#. $LLIBDIR/libfuncmath-sh				# functions math
#. $LLIBDIR/libfuncip-sh				# functions IP
#. /usr/local/etc/multimedia.conf			# config multimedia
#
#if [ ! -e ~/.multimediarc ]; then			# install config user
#	cp /usr/local/share/ksm-sample/multimediarc ~/.multimediarc
#fi
#. ~/.multimediarc					# config user

##############################################################################
# DECLARATION OF STANDARD CONSTANTS AND VARIABLES
#
readonly package=Multimedia				# package name
readonly package_file=ksm-multimedia			# package file name
readonly vinfopath="/usr/local/share/$package_file"	# path to package dir
readonly version=$(/bin/cat $vinfopath/VERSION)		# package version
readonly release=$(/bin/cat $vinfopath/RELEASE)		# package release
readonly scriptname=$(basename $0)			# name of script
#readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp	# temporary file name
#tempfile=$(mktemp $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
#readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock	# lock file name
readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:"	# log dbg msg
readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:"		# log err msg
readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:"		# log inf msg
cmd=''							# sub command
debug=no						# debug=yes/no
verbose=''						# verbose=yes/''/no
err=0							# error code

##############################################################################
# USER FILL IN AT FIRST RUN

##############################################################################
# SYSTEM

##############################################################################
# USER-CONSTANTS

##############################################################################
# USER-VARIABLES
#
# STRINGS
# config file needs a version at first cnfvar!
cft=/usr/local/share/ksm-multimedia/multimediarc.templ	# conf file template
cf=$HOME/.multimediarc					# conf file
cnfvars=$(grep -v '^#' $cft | grep '[[:alnum:]]' | grep -v '\[' | cut -sd '=' -f1)
cnfvars=$(echo $cnfvars | cut -d ' ' -f2-)

#args=''				# all args from cmdline
#arg1=''				# 1. arg from cmdline
#opt_o=''				# option -o (yes)
					# option --output (yes)
#opt_i=''				# option -i (arg)
					# option --infile (arg)
#opt_o=''				# option -o (arg)
					# option --outfile (arg)
#opt_p=''				# option -p (arg)
					# option --pages (arg)

# NUMBERS
#p_first=0				# first page
#p_last=0				# last page

# ARRAYS
# Indexed arrays are always zero based string arrays.
# If index starts with 1 and all members are assigned then
# count of members of array = last index of array
#declare -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

##############################################################################
# SIGNAL HANDLING

##############################################################################
# FUNCTIONS
##############################################################################
#
##############################################################################
# HELP
#
#=============================================================================
function helptext ()
{
# Output helptext
# Uses cat, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG helptext: $# $@" >&2
	$debuglog helptext: $# $@
fi

cat <<EOT
NAME
$scriptname - Updates a users new ~/.multimediarc

SYNOPSIS
$scriptname [options]

DESCRIPTION
Updates a users new ~/.multimediarc with the previous values.
If the file does not exist then it is created. After update the user should
examine the values therin and correct them if necessary.

OPTIONS
Gnu style options:

  -h|--help    = Output help, then exit.
  -V|--version = Output version info, then exit.
  -d|--debug   = Turn on DEBUG mode.
  -q|--quiet   = Be quiet.
  -v|--verbose = Be verbose.
  --           = End of options.

EXIT STATUS
On program exit:

  Code 0 = OK

  See output of 'showerrmsg'.

FILES
Used directories and files:

  Config User          = ~/.multimediarc
  PKGDIR               = /usr/local/share/ksm-multimedia/
  Config User template = PKGDIR/multimediarc.templ

SEE ALSO
Related manpages:

  showerrmsg(1), replcnfvar(1).

AUTHORS
Juergen Kaesmann <juergen@kaesmann-online.de>
EOT
#  -o|--output  = Output to STDOUT.
#  -i f         = Input from file <f>.
#  --infile=f   = Input from file <f>.
#  -o f         = Output to file <f>.
#  --outfile=f  = Output to file <f>.
#  -p s,e       = Pages s=START e=END.
#  --pages=s,e  = Pages s=START e=END.

#ARGUMENTS
#Give if needed:
#
#  a = Arg a

#EXAMPLES
#For instance:
#
#  Do it:
#  $scriptname

return
}

#=============================================================================
function upd_conf_norm ()
{
# updates normal variables of the configuration file with previous values
# uses echo, logger, replcnfvar
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG upd_conf_norm: $# $@" >&2
	$debuglog upd_conf_norm: $# $@
fi

local c='' s='' t=''
local ret=0

if [ -x /usr/local/bin/replcnfvar ]; then
	for c in $cnfvars; do
		t="\$$c"
		eval s="$t"
		s=\"$s\"
		/usr/local/bin/replcnfvar $cf $c "$s"
		ret=$?
	done
else							# error
	if [ "$verbose" != no ]; then
		Show_Err 1 "cmd replcnfvar not found or not executable!"
	else
		$errlog cmd replcnfvar not found or not executable
	fi
	ret=1
fi

return $ret
}

#=============================================================================
function upd_conf_arr ()
{
# updates array variables of the configuration file with previous values
# uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG upd_conf_arr: $# $@" >&2
	$debuglog upd_conf_arr: $# $@
fi

local s=''
local i=0 cnt=0 ret=0

# array workarr
cnt="${#workarr[@]}"					# num usr
i=0
while [ "$i" -lt $cnt ]; do
	let ++i
	s="workarr[$i]=${workarr[$i]}"
	echo "$s" >> $cf				# append to conf file
done

return $ret
}

#=============================================================================
function update_cnf ()
{
# updates both types of variables
# uses cp, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG update_cnf: $# $@" >&2
	$debuglog update_cnf: $# $@
fi

local ret=0

if [ "$verbose" != no ]; then
	echo "Update $cf"
else
	$infolog Update $cf
fi
cp $cf ${cf}.o						# backup conf file
ret=$?
if [ "$ret" -eq 0 ]; then				# backup ok
	cp $cft $cf					# get new conf file
	. ${cf}						# source new conf
	. ${cf}.o					# source conf.o
	ret=$?
	if [ "$ret" -eq 0 ]; then
		upd_conf_norm				# update normal vars
		ret=$?
		#if [ "$ret" -eq 0 ]; then
		#	upd_conf_arr			# update array vars
		#	ret=$?
		#fi
		if [ "$ret" -eq 0 ]; then
			diff ${cf} ${cf}.o &>/dev/null
			ret=$?
			if [ "$ret" -eq 0 ]; then
				rm ${cf}.o
			fi
		fi
	else						# error
		if [ "$verbose" != no ]; then
			Show_Err 1 "While providing $cf"
		else
			$errlog While providing $cf
		fi
		ret=1
	fi
else							# error
	if [ "$verbose" != no ]; then
		Show_Err 1 "During backup of $cf"
	else
		$errlog During backup of $cf
	fi
	ret=1
fi

return $ret
}

#=============================================================================
function install_cnf ()
{
# installs a new configuration file
# uses cp, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG install_cnf: $# $@" >&2
	$debuglog install_cnf: $# $@
fi

local ret=0

if [ "$verbose" != no ]; then
	echo "Install new $cf"
else
	$infolog Install new $cf
fi
cp $cft $cf						# instal new conf file
ret=$?
if [ "$ret" -eq 0 ]; then				# ok
	if [ "$verbose" != no ]; then
		echo "New $cf installed. Needs to configure!"
	else
		$infolog New $cf installed. Needs to configure
	fi
else							# error
	if [ "$verbose" != no ]; then
		Show_Err 1 "Installation of new $cf failed!"
	else
		$errlog Installation of new $cf failed
	fi
	ret=1
fi

return $ret
}

##############################################################################
# GET OPTIONS
##############################################################################
# Give 2 strings and all cmdline_args to func GetOpt
# (POSIX_options Gnu_long_options cmdline_args):
# GetOpt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@
#
# A ':' after a POSIX option means this option needs an arg.
# A '=' after a Gnu long option means this option needs an arg.
#
# All cmd/options have to be initialised to ''!
#
# POSIX options are classified in 2 categories:
#   a) cmds (mutually exclusive). All cmds are given to var 'cmd'.
#   b) options (as many as you like). Each option is given to it's own var.
# As a general rule: If cmds/options are given multiple then last given wins.
#
# Options can take 1 argument (no whitespace in arg). If you want to give more
# than 1 arg or want to use multiple strings as 1 arg then concatenate them
# together with a delimiter like ',' or ';' or '.'
# Use a delimiter which will not be part of the arg:
# sampleprog -m val1,val2
# sampleprog --myval=val1,val2
# It's at the programmers responsibility to do meaningfull things with the
# content of the options.
#
# If err != 0 then all args are processed, else continue to look for options.
# When GetOpt finishes then all options are removed from cmdline.
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Parse Commandline: $# $@" >&2
	$debuglog Parse Commandline: $# $@
fi
#
err=${_ERR_OK_}
while [ "$err" -eq 0 ]; do
	GetOpt 'hVdqv' 'help version debug quiet verbose' $@
	err=$?
	#echo "DEBUG GET OPTIONS: err=${err}  _OPTNAME_=${_OPTNAME_}  _OPTVAL_=${_OPTVAL_}  _OPTPOS_=${_OPTPOS_}  _OPTIDX_=${_OPTIDX_}" >&2
	if [ $err -eq 0 ]; then
		case "$_OPTNAME_" in
		    h|help)	cmd="-h";;
		    V|version)	cmd="-V";;
#		    a)		cmd="-${_OPTNAME_}";;
		    d|debug)	debug=yes;;
		    q|quiet)	verbose=no;;
		    v|verbose)	verbose=yes;;
#		    o|output)	opt_o=yes;;
#		    i|infile)	opt_i="${_OPTVAL_}";;
#		    o|outfile)	opt_o="${_OPTVAL_}";;
#		    p|pages)	opt_p="${_OPTVAL_}";;
		    --)		break;;
		    :)	Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_MISSING_ARG_FOR_OPT_};;
		    ?)	Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_OPT_};;
		    *)	Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_ERR_};;
		esac
	fi
done
err=${_ERR_OK_}
shift ${_OPTIDX_}				# rm all opts from cmdline
#
# Uncomment if giving a cmd is mandatory
#if [ -z "$cmd" ]; then					# error no cmd given
#	Show_Err ${_ERR_MISSING_SUB_CMD_} ""
#	exit ${_ERR_MISSING_SUB_CMD_}
#fi

##############################################################################
# CHECK LINK NAMES

##############################################################################
# CHECK OPTIONS

##############################################################################
# CHECK VERSION

##############################################################################
# CHECK ARGUMENTS
#
case "$cmd" in
#    '')
#	if [ "$#" -eq 1 ]; then				# parameter count ok
#		arg1="$1"
#		shift
#		#args="$@"
#		#shift $#
#	else						# error in param count
#		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
#		exit ${_ERR_WRONG_PAR_COUNT_}
#	fi
#	;;
    *)
	if [ "$#" -ne 0 ]; then				# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
esac

##############################################################################
# LOCK

##############################################################################
# MAINPROGRAM
##############################################################################
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Main: $# $@" >&2
	$debuglog Main: $# $@
fi

# Check what to do (sub commands, options and args are removed from cmdline)
case "$cmd" in
    '')
	#mainproc
	if [ -e $cf ]; then
		update_cnf
		err=$?
	else
		install_cnf
		err=$?
	fi
	;;
    -h)
	helptext
	exit 0
	;;
    -V)
	echo "${scriptname}: (${package}) $package_file ${version}-${release}"
	exit 0
	;;
    *)							# error
	Show_Err ${_ERR_SUB_CMD_NOT_FOUND_} ""
	err=${_ERR_SUB_CMD_NOT_FOUND_}
	;;
esac

#rm -f $lockfile

exit $err
