#!/bin/sh
#
# This is CFEngine version of apachectl script, being more persistent when
# killing httpd and more resillient when doing so. The only change is special
# processing of "stop" inside "case $ACMD in". When asked to kill httpd
# process, it not just sends a "kill" signal and happily quits, but first waits
# for it to be gone (by checking `ps p` output), and if it's not gone - kills
# the main httpd process and all its children (found via `pgrep --parent` or by
# parsing `ps -eo ppid,pid` output) by sending `kill -9` singal to them. If
# process(es) exist even after that - it gives up with an error message.
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Apache control script designed to allow an easy command line interface
# to controlling Apache.  Written by Marc Slemko, 1997/08/23
#
# Modified by Northern.Tech to try harder in killing httpd process(es)
# and wait for them to be gone before returning to caller.
#
# The exit codes returned are:
#   XXX this doc is no longer correct now that the interesting
#   XXX functions are handled by httpd
#       0 - operation completed successfully
#       1 -
#       2 - usage error
#       3 - httpd could not be started
#       4 - httpd could not be stopped
#       5 - httpd could not be started during a restart
#       6 - httpd could not be restarted during a restart
#       7 - httpd could not be restarted during a graceful restart
#       8 - configuration syntax error
#
# When multiple arguments are given, only the error from the _last_
# one is reported.  Run "apachectl help" for usage info
#
ACMD="$1"
ARGV="$@"
#
# |||||||||||||||||||| START CONFIGURATION SECTION  ||||||||||||||||||||
# --------------------                              --------------------
#
# the path to your httpd binary, including options if necessary
HTTPD='/var/cfengine/httpd/bin/httpd'
#
# pick up any necessary environment variables
if test -f /var/cfengine/httpd/bin/envvars; then
  . /var/cfengine/httpd/bin/envvars
fi
#
# a command that outputs a formatted text version of the HTML at the
# url given on the command line.  Designed for lynx, however other
# programs may work.
LYNX="lynx -dump"
#
# the URL to your server's mod_status status page.  If you do not
# have one, then status and fullstatus will not work.
STATUSURL="http://localhost:80/server-status"
#
# Set this variable to a command that increases the maximum
# number of file descriptors allowed per child process. This is
# critical for configurations that use many file descriptors,
# such as mass vhosting, or a multithreaded server.
ULIMIT_MAX_FILES="ulimit -S -n `ulimit -H -n`"
# --------------------                              --------------------
# ||||||||||||||||||||   END CONFIGURATION SECTION  ||||||||||||||||||||

# Set the maximum number of file descriptors allowed per child process.
if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then
    $ULIMIT_MAX_FILES
fi

ERROR=0
if [ "x$ARGV" = "x" ] ; then
    ARGV="-h"
fi

case $ACMD in
start|restart|graceful|graceful-stop)
    $HTTPD -k $ARGV
    ERROR=$?
    ;;
stop)
    # Added by CFEngine
    PIDFILE='/var/cfengine/httpd/httpd.pid'
    if [ ! -f "$PIDFILE" ] ; then
        PIDFILE='/var/cfengine/httpd/logs/httpd.pid'
    fi
    if [ ! -f "$PIDFILE" ] ; then
        echo PID file not found, nothing to stop
        exit 2
    fi
    PID="$(cat "$PIDFILE")"
    $HTTPD -k $ARGV
    ERROR=$?
    # wait for pid to terminate, up to 5 seconds
    for _iteration in `seq 50`; do
        ps p $PID >/dev/null || exit $ERROR
        sleep 0.1
    done
    echo "process didn't finish gracefully, commencing murder"
    # collect all child processes
    if command -v pgrep >/dev/null; then
        PIDS="$PID $(pgrep --parent $PID)"
    else
        PIDS="$PID $(ps -eo ppid,pid | awk "/ $PID /{print \$2}")"
    fi
    # send KILL signal to all of them
    kill -9 $PIDS
    # wait for them to terminate, up to 5 seconds
    for _iteration in `seq 50`; do
        ps p $PIDS >/dev/null || exit $ERROR
        sleep 0.1
    done
    echo Failed to terminate processes
    ps p $PIDS
    ;;
startssl|sslstart|start-SSL)
    echo The startssl option is no longer supported.
    echo Please edit httpd.conf to include the SSL configuration settings
    echo and then use "apachectl start".
    ERROR=2
    ;;
configtest)
    $HTTPD -t
    ERROR=$?
    ;;
status)
    $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
    ;;
fullstatus)
    $LYNX $STATUSURL
    ;;
*)
    $HTTPD "$@"
    ERROR=$?
esac

exit $ERROR
