#!/bin/sh

#
# inetcis.limit
#
# SSR Versions
#   1.0 12Mar96 (bchatfield) First version.
#

# Set variables.
upper_bound=100
lower_bound=75
program_name=inetcis.limit
ps_file=/tmp/$program_name.$$
state_file=/var/db/inetcis.state
#state_file=$HOME/inetcis.state
refuse_file=/etc/inetd.conf.refuse
accept_file=/etc/inetd.conf.accept
command_column=7
syslog_priority=user.crit

# Define exit function.
clean_exit ( ) {
	rm $ps_file
	exit $1
}
 
# Check for necessary files that aren't automatically generated.
for file in $refuse_file $accept_file; do
	if [ ! -f "$file" ]; then
		logger -p $syslog_priority -t $program_name \
			"$file is missing, exiting"
		echo "$file is missing, exiting."
		clean_exit 1
	fi
done

# Calculate how many tpads are being used.
ps -ax -o pid,command > $ps_file
num_logins=`cut -c "${command_column}"- ${ps_file} | grep -c "^inetcis.login"`
num_inetcisds=`cut -c "${command_column}"- ${ps_file} | grep -c "^inetcisd"`
num_tpads=`expr $num_logins + $num_inetcisds`

# Get the PID for inetd out of the ps listing.
inetd_pid=`grep -E ' *[0123456789]+ (inetd|/usr/sbin/inetd)$' "$ps_file" | cut -c 1-6`

# Make sure we got the pid for inetd.
if [ -z $inetd_pid ]; then
	logger -p $syslog_priority -t $program_name \
		"Could not find PID for inetd, exiting"
        echo "Could not find PID for inetd, exiting."
	clean_exit 1
fi

# Make sure the state file exists.  If it does not, initialize it.
if [ ! -f $state_file ]; then
	echo $num_tpads > $state_file
	if [ $num_tpads -gt $upper_bound ]; then
		echo Initializing to refuse state.
		cp $refuse_file /etc/inetd.conf
		kill -HUP $inetd_pid
		echo 0 >> $state_file
	else
		echo Initializing to accept state.
		cp $accept_file /etc/inetd.conf
		kill -HUP $inetd_pid
		echo 1 >> $state_file
	fi
fi

# Get the current state.
old_num_tpads=`head -1 $state_file`
accepting_connections=`tail -1 $state_file`

# Detect a state change and take the appropriate action.
if [ $accepting_connections -eq 1 -a $num_tpads -gt $upper_bound ]; then
	# Start refusing connections.
	echo "Number of connections reached upper bound.  Refusing new connections."
	logger -p $syslog_priority -t $program_name "Refusing connections"
	cp $refuse_file /etc/inetd.conf
	kill -HUP $inetd_pid
	echo $num_tpads > $state_file
	echo 0 >> $state_file
elif [ $accepting_connections -eq 0 -a $num_tpads -lt $lower_bound ]; then
	# Start accepting connections again.
	echo "Number of connections reached lower bound.  Accepting connections again."
	logger -p $syslog_priority -t $program_name "Accepting connections"
	cp $accept_file /etc/inetd.conf
	kill -HUP $inetd_pid
	echo $num_tpads > $state_file
	echo 1 >> $state_file
else
	# There is no state change.
	if [ $accepting_connections -eq 1 ]; then
		cmp -s $accept_file /etc/inetd.conf
		if [ $? -eq 1 ]; then
			# Files $accept_file and /etc/inetd.conf are different.
			logger -p $syslog_priority -t $program_name \
				"Recopying $accept_file to /etc/inetd.conf"
			echo "Accept state files out of sync, recopying."
			cp $accept_file /etc/inetd.conf
			kill -HUP $inetd_pid
		fi
	else
		cmp -s $refuse_file /etc/inetd.conf
		if [ $? -eq 1 ]; then
			# Files $refuse_file and /etc/ined.conf are different.
			logger -p $syslog_priority -t $program_name \
				"Recopying $refuse_file to /etc/inetd.conf"
			echo "Refuse state files out of sync, recopying."
			cp $refuse_file /etc/inetd.conf
			kill -HUP $inetd_pid
		fi
	fi
	echo $num_tpads > $state_file
	echo $accepting_connections >> $state_file
fi

clean_exit 0
