#!/bin/bash
#
# Startup script for the Apache Web Server
#
# chkconfig: 345 92 8
# description: Apache is a World Wide Web server.  It is used to serve \
#	       HTML files and CGI.
# processname: httpd
# pidfile: /var/run/httpd.pid

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

# Source the /etc/sysconfig/httpd file.
if [ -f /etc/sysconfig/httpd ]; then
    . /etc/sysconfig/httpd
fi

# Start httpd in the C locale by default.
LANG=${HTTPD_LANG-"C"}
#${var:-DEFAULT}

# set safe temp
TMP=${HTTPD_TMP:-"/tmp"}
TMPDIR=${HTTPD_TMPDIR:-"/tmp"}

### Hack for Status
lynxbin=${LYNX:-"/usr/bin/lynx -dump"}
statusurl=${STATUSURL:-"http://localhost/server-status"}
statusurlperl=${STATUSURLPERL:-"http://localhost:8200/server-status"}

# Start with defaults
sbindir=${SBINDIR:-"/usr/sbin"}
configdir=${CONFIGDIR:-"/etc/httpd/conf"}
httpd=${HTTPD:-"httpd"}
httpdpid=${HTTPDPID:-"/var/run/httpd.pid"}
httpdperl=${HTTPDPERL:-"httpd-perl"}
httpdperlpid=${HTTPDPERLPID:-"/var/run/httpd-perl.pid"}
options=${OPTIONS-""}

#Directory where 1.3 configuration files reside, in case
#someone installs 2.0, and later decides to install 1.3 on top
#of it
compat=${COMPAT:-"/usr/share/ADVX/compat"}

# unset undesirable variables
unsert_var=${UNSET:-"LS_COLORS KDE_DISPLAY BROWSER HELP_BROWSER GTK_RC_FILES XMODIFIERS COLORTERM DISPLAY LOGNAME SESSION_MANAGER KDE_INITIAL_DESKTOP TERM HOME USERNAME PWD ENV USER SSH_CLIENT MAIL SSH_TTY QT_XFT GDK_USE_XFT SECURE_LEVEL HISTCONTROL LESSOPEN"}
unset $unsert_var

## Number of times to try to start Apache in case of error
#times_start="1 2 3"
times_start="1"
sleep_time="1 2 3 4 5"

# Change the major functions into functions.
moduleargs() {
	moduleargs=
	for module in $1/*.so ; do
		if [ -x ${module} ] ; then
			module=`echo ${module} | awk '{
				gsub(".*/","");
				gsub("^mod_","");
				gsub("^lib","");
				gsub(".so$","");
				print toupper($0)}'`
			moduleargs="${moduleargs} -DHAVE_$module"
		fi
	done
	echo ${moduleargs}
}

# Get the extra modules so only the main server gets them
extramoduleargs() {
	extramoduleargs=
	for extramodule in $1/*.so ; do
		if [ -x ${extramodule} ] ; then
			extramodule=`echo ${extramodule} | awk '{
				gsub(".*/","");
				gsub("^mod_","");
				gsub("^lib","");
				gsub(".so$","");
				print toupper($0)}'`
			extramoduleargs="${extramoduleargs} -DHAVE_$extramodule" 
		fi
	done
	echo ${extramoduleargs}
}

# NOTE: detect/detectlib must be call before any use of $LIB !
detectlib() {
   local httpd=$1

   local is_64bit_httpd=no
   #dd if=$httpd bs=1 count=4 skip=1 2> /dev/null | \
   #   tr '[\001-\011]' '[0-9]' | grep -q 'ELF1' && \
   #   is_64bit_httpd=yes
   case `/usr/bin/file $httpd` in
   *"ELF 64"*)
     is_64bit_httpd=yes
     ;;
   esac

   LIB="lib"
   case `uname -m`:$is_64bit_httpd in
   powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) LIB="lib64";;
   esac
}

detect() {
#### Find out if any version of Apache 2.0 is installed ####
if [ -x $sbindir/httpd2-perl ]; then
   detectlib $sbindir/httpd2-perl
   msgperl=${MSGPERL:-"Apache 2.0/mod_perl"}
   httpdperl=${HTTPDPERL:-"httpd2-perl"}
   perlfile=${PERLFILE:-"-f $configdir/httpd2-perl.conf"}
   perlxmods="-DAPACHE2 `extramoduleargs /usr/$LIB/apache2-extramodules`"
   perlregmods=`moduleargs /usr/$LIB/apache2`
   debug=${DEBUG:-"-DNO_DETACH -DONE_PROCESS -DDEBUG"}
elif [ -x $sbindir/httpd-perl ]; then
   detectlib $sbindir/httpd-perl
   msgperl=${MSGPERL:-"Apache 1.3/mod_perl"}
   if [ ! -e /etc/httpd/modules ];then
     echo "Re-creating /etc/httpd/modules"
     pushd /etc/httpd>/dev/null
     ln -sf ../../usr/$LIB/apache modules
     popd >/dev/null
   fi
   if [ ! -e /etc/httpd/extramodules ];then
     echo "Re-creating /etc/httpd/extramodules"
     pushd /etc/httpd >/dev/null
     ln -sf ../../usr/$LIB/apache-extramodules extramodules
     popd >/dev/null
   fi
   if [ ! -e $configdir/httpd-perl.conf -a -e $configdir/httpd-perl.conf.rpmsave ];then
    echo "Recreating httpd-perl.conf from backup file"
    mv $configdir/httpd-perl.conf.rpmsave $configdir/httpd-perl.conf
   fi
   if [ ! -e $configdir/httpd-perl.conf -a -e $compat/httpd-perl.conf ];then
    echo "Recreating httpd-perl.conf from compat file"
    rm -f $configdir/httpd-perl.conf
    cp $compat/httpd-perl.conf $configdir/httpd-perl.conf
   fi
   httpdperl=${HTTPDPERL:-"httpd-perl"}
   perlfile=${PERLFILE:-"-f $configdir/httpd-perl.conf"}
   perlxmods=`extramoduleargs /usr/$LIB/apache-extramodules`
   perlregmods=`moduleargs /usr/$LIB/apache`
   debug=${DEBUG:-"-X -F"}
fi

if [ ! -x $sbindir/httpd -a -e $configdir/RUN1.3 ];then
   echo "Apache 1.3 not present, removing $configdir/RUN1.3"
   rm -f $configdir/RUN1.3
fi

if [ -x $sbindir/httpd2 -a ! -e $configdir/RUN1.3 ]; then
   detectlib $sbindir/httpd2
   msg=${MSG:-"Apache 2.0"}
   httpd=${HTTPD:-"httpd2"}
   httpdconf=${HTTPDCONF:-"-f $configdir/httpd2.conf"}
   apachexmods="-DAPACHE2 `extramoduleargs /etc/httpd/2.0/extramodules`"
   apacheregmods=`moduleargs /etc/httpd/2.0/modules`
   debug=${DEBUG:-"-DNO_DETACH -DONE_PROCESS -DDEBUG"}
elif [ -x $sbindir/httpd ]; then
   detectlib $sbindir/httpd
   msg=${MSG:-"Apache 1.3"}
   if [ ! -e /etc/httpd/modules ];then
     echo "Re-creating /etc/httpd/modules"
     pushd /etc/httpd >/dev/null
     ln -sf ../../usr/$LIB/apache modules
     popd >/dev/null
   fi
   if [ ! -e /etc/httpd/extramodules ];then
     echo "Re-creating /etc/httpd/extramodules"
     pushd /etc/httpd >/dev/null
     ln -sf ../../usr/$LIB/apache-extramodules extramodules
     popd >/dev/null
   fi
   if [ ! -e  $configdir/httpd.conf -a -e $configdir/httpd.conf.rpmsave ];then
    echo "Recreating httpd.conf from backup file"
    rm -f $configdir/httpd.conf
    mv $configdir/httpd.conf.rpmsave $configdir/httpd.conf
   fi
   if [ ! -e  $configdir/httpd.conf -a -e $compat/httpd.conf ];then
    echo "Recreating httpd.conf from compat file"
    rm -f $configdir/httpd.conf
    cp $compat/httpd.conf $configdir/httpd.conf
   fi
   httpd=${HTTPD:-"httpd"}
   httpdconf="-f $configdir/httpd.conf"
   apachexmods=`extramoduleargs /usr/$LIB/apache-extramodules`
   apacheregmods=`moduleargs /usr/$LIB/apache`
   debug=${DEBUG:-"-X -F"}
fi   

#If both servers are installed, perl runs as a proxy
#and has no extra modules
if [ -x $sbindir/$httpd -a -x $sbindir/$httpdperl ]; then 
	define="-DPERLPROXIED"
	perlxmods=""
        msgperl="$msgperl (running in proxied mode)"
fi 
###
} 

## Hack for ApacheJServ that takes forever to shut down and restart
snooze() {
	for count in 1 2 3 4 5 6 7 8 9 ; do echo "."; sleep 1; done
	echo
}

conftest() {
	badconf=0
	if [ -x $sbindir/$httpd ]; then
		action "Checking configuration sanity for $msg: " \
			$sbindir/$httpd -t \
			$httpdconf $define $apachexmods $apacheregmods
		badconf=$?
	fi
	if [ -x $sbindir/$httpdperl ]; then
		action "Checking configuration sanity for $msgperl: " \
			$sbindir/$httpdperl -t \
			$perlfile $define $perlxmods $perlregmods
		[ $badconf = 0 ] && badconf=$?
	fi
	return $badconf
}

conftest_vhosts() {
	badconf=0
	if [ -x $sbindir/$httpd ]; then
		action "Checking configuration sanity for $msg: " \
			$sbindir/$httpd -t \
			$httpdconf $define $apachexmods $apacheregmods -D DUMP_VHOSTS
		badconf=$?
	fi
	if [ -x $sbindir/$httpdperl ]; then
		action "Checking configuration sanity for $msgperl: " \
			$sbindir/$httpdperl -t \
			$perlfile $define $perlxmods $perlregmods -D DUMP_VHOSTS
		[ $badconf = 0 ] && badconf=$?
	fi
	return $badconf
}

sanitizer() {
	# OE: 20040515 delete corrupt files
	ssl_scache_file="/var/cache/httpd/mod_ssl/ssl_scache"
	if [ -f "$ssl_scache_file" ]; then
	    echo "Unclean shutdown detected, $ssl_scache_file exists and is probably corrupted, deleting..."
		rm -f "$ssl_scache_file"
	    echo
	fi
}

semdetect() {
	# OE: 20040609 detect dead semaphores
	apache2_semid=`ipcs -s|grep apache|grep '^0x00000000'|awk '{ print $2 }'`
	if ! [ -z "$apache2_semid" ]; then
	    number_of_dead_semid=`echo $apache2_semid|wc -w`
	    echo "Unclean shutdown detected/something made apache segfault leaving $number_of_dead_semid possible dead semaphores (arrays)."
	    echo "A possible solution could be to tune the kernel using sysctl, check these values:"
	    echo "kernel.shmall, kernel.shmmax, kernel.shmmni, kernel.sem and kernel.msgmni"
	    echo "You may have to start apache2 with the \"semcleanrestart\" switch."
	fi
}

semkill() {
	# OE: 20040609 kill dead semaphores
	# OE: 20040610 ipcclean from the postgresql-server package does a much nicer job,
	# should we use that one instead?
	apache2_semid=`ipcs -s|grep apache|grep '^0x00000000'|awk '{ print $2 }'`
	if ! [ -z "$apache2_semid" ]; then
	    echo -n "Killing semid: "
		for dead_semid in $apache2_semid; do
		    ipcrm -s $dead_semid; echo -n "$dead_semid "
		done
	    echo
	fi
}

start() {
	for tries in $times_start; do
	  if [ -x $sbindir/$httpdperl -a ! -e $httpdperlpid ]; then
		if [ $tries -eq 1 ]; then echo -n "Starting $httpdperl: ";fi
		sanitizer; semdetect
    		daemon $httpdperl $perlfile $define $perlxmods $perlregmods $options
		echo
		for wait in $sleep_time;do
			if [ ! -e $httpdperlpid ]; then sleep 1;fi
		done
	  fi
	  if [ -x $sbindir/$httpd -a ! -e $httpdpid ]; then 
		if [ $tries -eq 1 ]; then echo -n "Starting $httpd: ";fi
		sanitizer; semdetect
		daemon $httpd $httpdconf $define $apachexmods $apacheregmods $options
		echo
		for wait in $sleep_time ;do
			if [ ! -e $httpdpid ]; then sleep 1;fi
		done
	  fi
	done
	touch /var/lock/subsys/httpd
}

# OE: 20040610 run the whole shebang in the foreground which will
# make it somewhat easier to see what's going on. Should we run
# gdb or strace in here? 
debugstart() {
	for tries in $times_start; do
	  if [ -x $sbindir/$httpdperl -a ! -e $httpdperlpid ]; then
		if [ $tries -eq 1 ]; then echo -n "Starting $httpdperl: ";fi
		sanitizer; semdetect
		$httpdperl $perlfile $debug \
		-c "Pidfile /tmp/httpd-debug.pid" \
		-c "LogLevel debug" \
		-c "ErrorLog /dev/stdout" \
		-c "CustomLog /dev/stdout common" \
		$define $perlxmods $perlregmods $options
		echo
		for wait in $sleep_time;do
			if [ ! -e $httpdperlpid ]; then sleep 1;fi
		done
	  fi
	  if [ -x $sbindir/$httpd -a ! -e $httpdpid ]; then 
		if [ $tries -eq 1 ]; then echo -n "Starting $httpd: ";fi
		sanitizer; semdetect
		$httpd $httpdconf $debug \
		-c "Pidfile /tmp/httpd-debug.pid" \
		-c "LogLevel debug" \
		-c "ErrorLog /dev/stdout" \
		-c "CustomLog /dev/stdout common" \
		$define $apachexmods $apacheregmods $options
		echo
		for wait in $sleep_time ;do
			if [ ! -e $httpdpid ]; then sleep 1;fi
		done
	  fi
	done
	touch /var/lock/subsys/httpd
}

stop() {
	if [ -e $httpdperlpid ]; then 
		echo -n "Shutting down $httpdperl: "
		killproc httpd-perl
		echo
		rm -f $httpdperlpid
	fi
	if [ -e $httpdpid ]; then 
		echo -n "Shutting down $httpd: "
		killproc httpd
		echo
		if [ -e /usr/$LIB/apache-extramodules/mod_jserv.so ]; then
			snooze
			while [ -e $httpdpid ]; do
				echo Trying harder
				snooze
				killproc httpd
			done
		fi
		rm -f $httpdpid
	fi
	rm -f /var/lock/subsys/httpd
}

# See how we were called.
case "$1" in
  start)
        detect
	start
	;;
  stop)
        detect
	stop
	;;
  extendedstatus|es)
        detect
	$lynxbin $statusurl | awk ' /process$/ { print; exit } { print } '	
	echo
	echo "#######################################"
	echo "#######################################"
	if [ -x $sbindir/$httpd -a -x $sbindir/$httpdperl ]; then
	  $lynxbin $statusurlperl | awk ' /process$/ { print; exit } { print } '	
	  echo
 	  echo "#######################################"
	  echo "#######################################"
	fi
	;;
  status|stats)
        detect
	echo
	if [ -e $httpdperlpid ]; then 
		echo "Apache-mod_perl is running."
 		echo "$httpdperl: `pidof $httpdperl`"
		echo
	fi
	if [ -e $httpdpid ]; then 
		echo "Apache is running."
		echo "$httpd: `pidof $httpd`"
		echo
	fi
	if [ ! -e $httpdpid -a ! -e $httpdperlpid ]; then	
		echo "Apache is *not* running."
		echo
	fi
	echo "Use $0 extendedstatus for more information."
	echo
	;;
  restart)
        detect
	stop
        detect
	start
	;;
  update|condrestart|u|cr)
        detect
	if [ -e $httpdpid -o -e $httpdperlpid ]; then
		stop
		conftest || exit $?
		start
	fi
	;;
  reload|graceful|r|g)
	# in doubt, check both possible library dirs
	if [ -e /usr/lib/apache-extramodules/mod_jserv.so -o \
	     -e /usr/lib64/apache-extramodules/mod_jserv.so ]; then
		detect
		stop
		detect
		start
	else
                detect
		if [ -e $httpdperlpid ]; then 
			echo -n "Reloading $httpdperl: "
			killproc httpd-perl -USR1
			echo
		fi
		if [ -e $httpdpid ]; then 
			echo -n "Reloading $httpd: "
			killproc httpd -USR1
			echo
		fi
	fi
	;;
  closelogs|cl)
        detect
	if [ -e $httpdperlpid ]; then 
		echo -n "Sending HUP to $httpdperl: "
		killproc httpd-perl -HUP
		echo
	fi
	if [ -e $httpdpid ]; then 
		echo -n "Sending HUP to $httpd: "
		killproc httpd -HUP
		echo
	fi
	;;
  configtest|ct)
        detect
	conftest
	exit $?
	;;
  configtest_vhosts|ctv)
        detect
	conftest_vhosts
	exit $?
	;;
  show_defines|sd)
	# OE 20041013 make it spit out all those -D variables to make it
	# easier to use something like:
	# httpd2 -f /etc/httpd/conf/httpd2.conf `/etc/rc.d/init.d/httpd define` -t
        detect
	echo "$define $apachexmods $apacheregmods $perlxmods $perlregmods $options"
	exit $?
	;;
  semcleanrestart|scr)
	if ! [ -e $httpdpid -o -e $httpdperlpid ]; then
	    semkill; detect; stop; detect; start
	fi
	;;
  debug|d)
	if ! [ -e $httpdpid -o -e $httpdperlpid ]; then
	    semkill; detect; stop; detect; debugstart
	
	fi
	;;
  *)
	echo "Usage: $0 {start|stop|restart|reload/graceful|closelogs|update|status|configtest|configtest_vhosts|semcleanrestart|debug|show_defines}"
	exit 1
esac

exit 0
