#!/bin/ksh93
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r714 src/43haes/lib/ksh93/ihs/KLIB_IHS_ch_httpd_directive.sh 1.1 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2009,2010 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)55	1.1  src/43haes/lib/ksh93/ihs/KLIB_IHS_ch_httpd_directive.sh, hacmp, 61haes_r714 11/28/11 15:14:48
#
#=head1 NAME
#
# KLIB_IHS_ch_httpd_directive - Change the httpd.conf directive to a new value
#
#=head1 SYNOPSIS
#
# KLIB_IHS_ch_httpd_directive "/usr/IBMIHS/conf/httpd.conf" "Listen" \
#		 "10.10.11.107:80" KLIB_IHS_ch_httpd_directive_port_equals
# echo "Number of replacements: $?"
#
#=head1 DESCRIPTION
#
# This function changes the specified directive in httpd.conf formatted files.
#
# The 4th argument to this function is a comparison function, which is passed
# four arguments, the return code from that function determines whether the current
# value is replaced.
#
# A backup of the original file is created as filename.backup -- in the same path
# as the original.
#
# The four arguments to the comparitor function are:
#	1: Directive (current directive name - Listen)
#	2: Current value in httpd.conf file
#	3: Value we've been asked to use as a replacement
#	4: Section name <SectionName SectionArgs> from config file, IfDefine, etc.
#	5: Section arguments example: IfDefine HAVE_SSL, args=HAVE_SSL
# If the return code from the function is 0, then a replacement will occur
# If the return code is any value other than 0, then a replacement will not occur
#
# If the above function is not specified, then all values are replaced
#
# If a directive with the same name cannot be found, then a new entry is added
# to the bottom of the httpd.conf file
#
#=head1 ARGUMENTS
#
#   1: [scalar] httpd.conf filename (required)
#   2: [scalar] directive to search for (required)
#   3: [scalar] new value for directive (required)
#   4: [by ref] function to perform comparison (not required)
#
#=head1 RETURN
#
#   returns the number of replacements / or additions performed
#
#=head1 COPYRIGHT
#
#(C) COPYRIGHT International Business Machines Corp. 2005
#All Rights Reserved
#
#=cut
#
function KLIB_IHS_ch_httpd_directive
{
	[[ "$VERBOSE_LOGGING" == "high" ]] && set -x
	typeset filename=$1
	typeset directive=$2
	typeset newvalue=$3
	typeset regexp_function=$4
	typeset tmpname
	typeset changed=false
	typeset -i ch_count=0

	[[ -z $filename || ! -f $filename ]] && return 0
	[[ -z $directive ]] && return -1

	IFS="
"
	while read -r line; do
		tmpname=${line/\#*/}
		[[ -n $tmpname ]] && {

			# Did we find the start of an httpd.conf section?
			if [[ $tmpname != ${tmpname#\<} ]]; then
				section=${tmpname/\<\//}
				args=${section/*[[:space:]]/}
				args=${args/\>/}
				section=${section/[[:space:]]*/}
				section=${section/\>*/}
				section=${section//[[:space:]]/}

				# If this is the start of a new section
				if [[ ${section:0:1} == "<" ]]; then
					section=${section/\</}
					in_section=$section
					in_section_args=$args

				# else this is the end of a section
				else
					in_section=
					in_section_args=
				fi
			else
				this_directive=${line/[[:space:]]*/}

				# If the directive matches, then check to see if we should do a replacement
				[[ "$this_directive" == "$directive" ]] && {
					typeset this_val=${line/*[[:space:]]/}
					typeset ip_val=${this_val/:*/}
					typeset port_val=${this_val/*:/}

					# If ip_val = port_val, then ip_val should be ""
					if [[ "$ip_val" == "$port_val" ]] ; then
					    ip_val=""
					fi

					# Execute the provided regular expression match to determine
					# if we should replace this value
					if [[ -n $regexp_function ]]; then
						$($regexp_function $directive $this_val $newvalue $in_section $in_section_args)
						(( $? == 0 )) && {
							line="$directive $newvalue"
							(( ch_count += 1 ))
							changed=true
						}

					else 
						# If the caller didn't provide a function for determining
						# If we should change the entry, then just change every entry
						# we come across.
						if [[ -z ${newvalue} ]] ;  then
						    line="$directive ${port_val}"
						else
						    line="$directive ${newvalue}:${port_val}"
						fi
						(( ch_count += 1 ))
						changed=true
					fi
				}
			fi
		}
		echo $line
	done < $filename > $filename.new

	# If we couldn't change the value in the above logic, then
	# create a new entry at the end of the httpd.conf file for
	# our directive.
	$changed || { 
		echo "$directive $newvalue" >> $filename.new
		(( ch_count += 1 ))
	}
	
	# Backup the file if a backup doesn't already exist
	[[ ! -f $filename.backup ]] && mv $filename $filename.backup
	[[ -f $filename ]] && rm -f $filename
	mv $filename.new $filename

	return $ch_count
}

