#! /bin/sh
# Copyright (c) 2004-2014 SUSE Linux GmbH, Nuernberg, Germany.
# All rights reserved.
#
# Author: Lars Mueller <lmuelle@suse.com>
#
# /etc/init.d/lwresd
#   and its symbolic link
# /(usr/)sbin/rclwresd
#
#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
### BEGIN INIT INFO
# Provides:          lwresd
# Required-Start:    $network $syslog
# Required-Stop:     $network $syslog
# Should-Start:      named
# Should-Stop:       $null
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: Lightweight resolver daemon
# Description:       Lwresd is the daemon providing name lookup services to
#	clients that use the BIND lightweight resolver library.
#	It is essentially a stripped-down, caching-only name
#	server that answers queries using the BIND lightweight
#	resolver protocol rather than the DNS protocol.
### END INIT INFO

. /etc/rc.status
rc_reset

# Check for missing binaries
LWRESD_BIN="/usr/sbin/lwresd"
if [ "$1" != "stop" -a ! -x ${LWRESD_BIN} ]; then
	echo -n "Lightweight resolver daemon binary, ${LWRESD_BIN} is not installed! "
	rc_status -s
	exit 5
fi

# Set and check for rndc
RNDC_BIN="/usr/sbin/rndc"
test -x ${RNDC_BIN} || RNDC_BIN=""

# Check for existence of needed config file and read it
SYSCONFIG_FILE="/etc/sysconfig/named"
test -f ${SYSCONFIG_FILE} || \
	cp -a /var/adm/fillup-templates/sysconfig.named-common ${SYSCONFIG_FILE}
. ${SYSCONFIG_FILE}

if [ "${NAMED_RUN_CHROOTED}" = "yes" ]; then
	CHROOT_PREFIX="/var__NSD__/named"
	NAMED_ARGS="${NAMED_ARGS} -t ${CHROOT_PREFIX}"
else
	CHROOT_PREFIX=""
fi

LWRESD_PID="${CHROOT_PREFIX}/run/named/lwresd.pid"

function warnMessage()
{
	tput bold
	echo -en "\nWarning: "
	tput sgr0
	echo -e "$1 "
}

# Create destination directory in the chroot.
function makeDestDir
{
	if [ ! -d "${CHROOT_PREFIX}/${configfile%/*}" ]; then
		umask 0022
		mkdir -p "${CHROOT_PREFIX}/${configfile%/*}"
	fi
}

# Check if all needed configuration files exist and copy these files relativly
# to the chroot directory if 'named' runs chrooted.
function checkAndCopyConfigFiles
{
	test "${checkAndCopyConfigFilesCalled}" = "yes" && return
	# Handle known configuration files.
	if [ "${NAMED_RUN_CHROOTED}" = "yes" ]; then
	# Create link if needed, /run might be on tmpfs
		test -d /run/named && \
			rm -rf /run/named
		test ! -L /run/named && \
			ln -s ${CHROOT_PREFIX}/run/named /run/named

		# mount /proc for multicore CPUs (bnc#470828)
		if [ ! -e "${CHROOT_PREFIX}/proc/meminfo" ]; then
			mkdir -p "${CHROOT_PREFIX}/proc"
			mount -tproc -oro,nosuid,nodev,noexec proc ${CHROOT_PREFIX}/proc 2>/dev/null
		fi;

		for configfile in /etc/{localtime,lwresd.conf,resolv.conf,rndc.key}; do
			if [ ! -e ${configfile} ]; then
				case ${configfile} in
					# Don't complain if we don't have a lwresd.conf
					/etc/lwresd.conf)	
						rm -f "${CHROOT_PREFIX}/${configfile}" # clean chroot env.
						continue ;;
					# Don't complain if we don't have a key.
					/etc/rndc.key) continue ;;
					*)
						warnMessage "File ${configfile} not found. Skipping."
						continue
						;;
				esac
			fi
			makeDestDir
			rm -f ${CHROOT_PREFIX}/${configfile}
			cp -a -L ${configfile} ${CHROOT_PREFIX}/${configfile%/*}
		done
		mkdir -p ${CHROOT_PREFIX}/___lib__
		cp -r /___lib__/engines ${CHROOT_PREFIX}/___lib__/
	else
	# NAMED_RUN_CHROOTED != yes
		test -L /run/named && rm /run/named
		if [ ! -d /run/named ]; then
			mkdir -p /run/named
			chown named: /run/named
		fi
	fi
	export checkAndCopyConfigFilesCalled="yes"
}

case "$1" in
    start)
	echo -n "Starting Lightweight resolver daemon "
	checkAndCopyConfigFiles
	startproc ${LWRESD_BIN} ${NAMED_ARGS} -u named
	rc_status -v
	;;
    stop)
	echo -n "Shutting down Lightweight resolver daemon "
	killproc -p ${LWRESD_PID} -TERM ${LWRESD_BIN}

	# trying to start lwresd before it has terminated can leave
	# us without a running lwresd...
	info="no"; timeout=30; rc=0; startDate=$( date +%s)
	while [ ${rc} -eq 0 ]; do
		checkproc -p ${LWRESD_PID} ${LWRESD_BIN}
		rc=$?
		if [ ${rc} -ne 0 ]; then
			test "${info}" = "yes" && rc_timer_off
			break
		elif [ ${info} = "no" ]; then
			echo -n >&2 " waiting for named to shut down "
			rc_timer_on ${timeout} 63
			info="yes"
		fi
		if [ $(( $( date +%s) - ${startDate} )) -gt $timeout ]; then
			echo -en >&2 "\nLwresd still appears to be running after $timeout seconds, sending SIGTERM"
			rc=1
			killproc -p ${LWRESD_PID} -TERM ${LWRESD_BIN}
		else
			sleep 2
		fi
	done

	rc_status -v
	;;
    try-restart|condrestart)
	if test "$1" = "condrestart"; then
		echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
	fi
	$0 status
	if test $? = 0; then
		$0 restart
	else
		rc_reset
	fi
	rc_status
	;;
    restart)
	$0 stop
	$0 start

	# Remember status and be quiet
	rc_status
	;;
    force-reload|reload)
	echo -n "Reload service Lightweight resolver daemon "
	checkAndCopyConfigFiles
	killproc -p ${LWRESD_PID} -HUP ${LWRESD_BIN}
	rc_status -v
	;;
    status)
	echo -n "Checking for service Lightweight resolver daemon "
	checkproc -p ${LWRESD_PID} ${LWRESD_BIN}
	rc_status -v
	;;
    probe)
	test /etc/resolv.conf -nt ${LWRESD_PID} -o \
	/etc/lwresd.conf -nt ${LWRESD_PID} && \
		echo reload
	;;
    *)
	echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
	exit 1
	;;
esac
rc_exit
