#!/bin/sh
#
# Startup script for the DNS caching server under ALTLinux
#
# chkconfig: - 20 55
# description: This script starts your DNS caching server
# processname: dnsmasq
# config: /etc/dnsmasq.conf
# pidfile: /var/run/dnsmasq.pid

# Do not load RH compatibility interface.
WITHOUT_RC_COMPAT=1

# Source function library.
. /etc/init.d/functions

if [ "$1" = "--trace-script" ]; then
    shift
    set -x
fi

# Source networking configuration and check that networking is up.
SourceIfNotEmpty /etc/sysconfig/network
is_yes "${NETWORKING}" || exit 0

dnsmasq=/usr/sbin/dnsmasq
[ -x $dnsmasq ] || exit 0

# Assign default values, then load configuration file.
OPTIONS=""
ALL=255.255.255.255
DOMAIN_SUFFIX=$(dnsdomainname 2>/dev/null || hostname --domain 2>/dev/null)
SourceIfExists /etc/sysconfig/dnsmasq

# Build program command line
[ -n "${MAILHOSTNAME}"    ] && OPTIONS="$OPTIONS -m $MAILHOSTNAME"
[ -n "${RESOLV_CONF}"     ] && OPTIONS="$OPTIONS -r $RESOLV_CONF"
[ -n "${DOMAIN_SUFFIX}"   ] && OPTIONS="$OPTIONS -s $DOMAIN_SUFFIX"
[ -n "${DHCP_LEASE}"      ] && OPTIONS="$OPTIONS -l $DHCP_LEASE"

# Internal variables
PIDFILE=/var/run/dnsmasq.pid
LOCKFILE=/var/lock/subsys/dnsmasq
RETVAL=0

# External commands
CP=/bin/cp
MV=/bin/mv
RM=/bin/rm
TOUCH=/bin/touch
EGREP=/bin/egrep
RESOLVCONF=/sbin/resolvconf

#---------------------------------------------------------------
#
#	/etc/resolv.conf
#

start_resolvconf()
{
    if [ -n "$RESOLV_CONF" -a -n "$CONF_RESOLVCONF" ]; then
        "$TOUCH" "$RESOLV_CONF" "$CONF_RESOLVCONF"
        local msg="Start resolvconf:"
        echo -n "$msg"
        echo 'nameserver 127.0.0.1' | /sbin/resolvconf -a lo.dnsmasq &&
            success "$msg" || failure "$msg"
        echo
    fi
}

stop_resolvconf()
{
    if [ -n "$RESOLV_CONF" -a -n "$CONF_RESOLVCONF" ]; then
        # Don't remove files if another dnsmasq running under NetworkManager
        if ! ls -1 /var/run/ /var/lib/run/ 2>/dev/null | grep -qs '^nm-dnsmasq'; then
            "$RM" -f "$RESOLV_CONF" "$CONF_RESOLVCONF"
        fi
        action "Stop resolvconf:" "$RESOLVCONF" -fd lo.dnsmasq
    fi
}

#---------------------------------------------------------------
#
#	Broadcast routing
#

function print_all_ifaces()
{
    local linenum=0
    netstat -vai | while read iface moredata; do
	[ $[++linenum] -le 2 ] && continue
	case "$iface" in
	    lo )  ;;  # skip loopback
    #       *:* ) ;;  # skip aliases?
	    * ) echo $iface ;;
	esac
    done
}

function print_listening_ifaces()
{
    local line words dev
    netstat -ltnp | egrep '[0-9]*/dnsmasq' | egrep ':53 ' | while read line; do
	words=($line)
	dev="${words[3]%:*}"
	if [ "$dev" = "0.0.0.0" ]; then
	    print_all_ifaces
	    break
	fi
	echo "$dev"
    done | uniq
}

function do_route() {
    [ -n "$ALL_DEV" ] || return
    local msg='Broadcast device ALL_DEV is defined, but destaddr ALL is empty!'
    if [ -z "$ALL" ]; then
	echo -n $msg
	failure "$msg"; echo
	return 1
    fi
    local cmd=$1
    shift
    echo -n $*
    start_daemon --no-announce -- \
	/sbin/ip route $cmd $ALL dev $ALL_DEV
}

function cleanup_routing()
{
    [ -z "$ALL" ] && return
    /sbin/ip route list | $EGREP "^$ALL dev " | while read dst dev_kword iface tail; do
	/sbin/ip route del $dst dev $iface $tail
    done
}

#---------------------------------------------------------------
#
#	Main routines
#

function start()
{
    [ -z "$1" ] && start_resolvconf
    start_daemon --pidfile "$PIDFILE" --lockfile "$LOCKFILE" --expect-user nobody -- $dnsmasq $OPTIONS
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
        do_route add "Adding local broadcast host route:"
    else
        stop_resolvconf
    fi
    return $RETVAL
}

function start_debug()
{
    "$RESOLVCONF" -u
    # don't adds/removes routing!
    $dnsmasq -d -q $OPTIONS
}

function stop()
{
    do_route del "Removing host route defined at startup:"
    stop_daemon --pidfile "$PIDFILE" --lockfile "$LOCKFILE" --expect-user nobody -- $dnsmasq
    RETVAL=$?
    [ -z "$1" ] && stop_resolvconf
    return $RETVAL
}

function my_status() {
    status --pidfile "$PIDFILE" --expect-user nobody -- $dnsmasq
    RETVAL=$?
    if [ $RETVAL = 0 ]; then
	echo "Listening interfaces:"
	print_listening_ifaces
    fi
    return $RETVAL
}

function restart() {
    # Do not call resolvconf during restart to avoid loop
    # if restarting from resolvconf itself
    stop restart
    start restart
    RETVAL=$?
    return $RETVAL
}

function reload() {
    msg_reloading dnsmasq
    stop_daemon --pidfile "$PIDFILE" --expect-user nobody -HUP -- $dnsmasq
    RETVAL=$?
    return $RETVAL
}

function clean() {
    stop
    $RM -f $LOCKFILE $PID_FILE
    cleanup_routing
    RETVAL=0
}

case "$1" in
    start)   start ;;
    stop)    stop ;;
    status)  my_status ;;
    restart) restart ;;
    reload)  reload ;;
    clean)   clean ;;
    startdebug)  start_debug ;;
    condrestart) [ -e "$LOCKFILE" ] && restart ;;
    condreload)  [ -e "$LOCKFILE" ] && reload ;;
    condstop)    [ -e "$LOCKFILE" ] && stop ;;
    *)
        echo "Usage: ${0##*/} {start|stop|restart|reload|condrestart|condreload|condstop|clean|status}"
        exit 1
esac

exit $RETVAL

## EOF ##
