#!/bin/sh

PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin

setup()
{
	# Set up the inetd pserver stuff
	. /etc/cvs.conf
	
	if test -x /usr/sbin/update-inetd; then
		if test "$CVS_ENAB_PSERV" = "yes"; then
			/usr/sbin/update-inetd --remove "cvspserver.*"
			ALLOWROOT=""
			OLDIFS="$IFS"
			IFS=": 	"
			for i in $CVS_PSERV_REPOS; do
				ALLOWROOT="$ALLOWROOT --allow-root=$i"
			done
			IFS="$OLDIFS"
			[ "$CVS_PSERV_RESPAWN" = "off-def" ] && CVS_PSERV_RESPAWN=off
			if [ "$CVS_PSERV_RESPAWN" = "off" ]; then
				NOWAIT="nowait"
			else
				NOWAIT="nowait.$CVS_PSERV_RESPAWN"
			fi
			/usr/sbin/update-inetd --group OTHER --add \
		"cvspserver	stream	tcp	$NOWAIT	root	/usr/sbin/tcpd	/usr/bin/cvs -b /usr/bin${ALLOWROOT} pserver"
		else
			/usr/sbin/update-inetd --disable cvspserver
		fi
	fi
}

# Usage do_questions last_version
# last_version=0 to ask all questions
do_questions ()
{
	OLDVER="$1"
	# Introduced in version 1
	if [ $OLDVER -lt 1 ]; then
	
	cat <<EOF

Debian CVS configuration

This script will allow you to configure the CVS package under Debian to
work for you.

You may run this configuration program again at any time by running the
program /usr/sbin/cvsconfig. You may also run this script as cvsconfig -u
to update the configuration files (eg /etc/inetd.conf) only, after you have
edited /etc/cvs.conf.

EOF
	# Search for repositories in some standard places
	for i in /SourceControl /var/cvs /usr/local/cvsroot; do
		if echo "$CVS_REPOS" | grep -q $i; then
			continue
		fi
		if test -f $i/CVSROOT/modules,v; then
			if test "$CVS_REPOS" = ""; then
				CVS_REPOS="$i"
			else
				CVS_REPOS="$CVS_REPOS:$i"
			fi
		fi
	done
	
	cat <<EOF
1. Where are your repositories?

The names of these repositories can be used to be exported by the pserver,
to have their history files rotated automatically every week, and for general
repository security checks.

EOF
	
	if test -n "$CVS_REPOS"; then
		echo "Detected in $CVS_REPOS"
		echo
		echo "Enter your repositories, separated by colons. The character '&' will"
		echo "be substituted with the default. To insert a real '&' character, use"
		echo "'\&'. To insert a backslash, use '\\'. Just press enter to use"
		echo "the default."
		echo -n "> "
	else
		echo "Enter your repositories, separated by colons:"
		echo -n "> "
	fi
	
	read CVS_NREPOS
	
	if test "$CVS_NREPOS" != ""; then
		CVS_REPOS="`echo "$CVS_NREPOS" | sed -e 's\(^\|[^\\]\)&'"$CVS_REPOS"'g' \
			-e 's:\\\\&:\\&:g' -e 's:\\\\\\\\:\\\\:g'`"
	fi
	
	echo
	echo -n "Checking the repositories: "
	OLDIFS="$IFS"
	IFS=": 	"
	for i in $CVS_REPOS; do
		if test ! -f $i/CVSROOT/modules,v; then
			echo -n "$i (Warning: may not be a CVS repository) "
		else
			echo -n "$i "
		fi
	done
	IFS="$OLDIFS"
	echo "- OK."
	
	cat <<EOF

2. Do you want the history files in these repositories rotated weekly?

This option is primarily useful for servers with a lot of activity. The script
/etc/cron.weekly/cvs will rotate the "history" files in the repositories you
select. For more customization, edit the file /etc/cvs.conf.

You may specify "yes", "no", or a list of numbers of history files to keep
(default 7) per repository specified above (or 'n' for no rotation), for
example:-

"yes", or
"7:7:3:4:n"

Note: if the first value should be 'n', enter a colon first, as in
":n:7:5:6". The colon will be removed by the script automatically.

EOF
	
	echo -n "> "
	read CVS_YN
	
	case "$CVS_YN" in
		[yY]*)
		CVS_ROTATE="yes"
		;;
		
		[nN]*)
		CVS_ROTATE="no"
		;;
		
		"")
		if test "$CVS_ROTATE" = ""; then
			CVS_ROTATE="no"
		else
			echo "Keeping default of '$CVS_ROTATE'."
		fi
		;;
		
		[0-9:]*)
		echo "Using advanced syntax."
		if test "`echo $CVS_YN | cut -b1`" = ":"; then
			CVS_ROTATE="`echo $CVS_YN | cur -b2-`"
		else
			CVS_ROTATE="$CVS_YN"
		fi
		;;
		
		*)
		echo "Warning: Couldn't understand your reponse '$CVS_YN'."
		echo "Not rotating - rerun this script, or edit /etc/cvs.conf to"
		echo "change this."
		CVS_ROTATE=""
		;;
	esac
	
	echo
	if test "$CVS_ROTATE" = "yes"; then
		echo "Will rotate history files normally."
	elif test "$CVS_ROTATE" = "no"; then
		echo "Not rotating history files."
	else
		echo "Rotating using advanced syntax format '$CVS_ROTATE'."
	fi
	
	if test -x /usr/sbin/update-inetd; then
		cat <<EOF

3. CVS pserver configuration

CVS pserver is a client-to-server mechanism which can be used by CVS as
a replacement for the standard "server" method, which uses "rsh", or an
rsh compatible program, such as ssh. It is more efficient than the standard
server protocol, also supporting its own password files, making it more
secure. However, it may be a security risk, and used to contain a security
problem whereby a remote connection may have been able to read the passwd
or other security-related files on the system.

For this reason, it is recommended that you switch this option OFF, unless
you know that you want it specifically. CVS now only allows access to
particular repositories specified on the command line. To change the
repositories it has permissions to from the list of repositories given
above, edit the file /etc/cvs.conf manually.

CVS pserver will be installed in inetd, using tcpd wrappers if you answer
"yes" to this question. The default (just pressing enter) will be your
previous value, or, if you have not configured CVS before, will be set
to "OFF".

EOF
		
		echo -n "Do you want pserver enabled? "
		
		read CVS_YN
		
		echo
		case "$CVS_YN" in
			[yY]*)
			CVS_ENAB_PSERV="yes"
			;;
			
			[nN]*)
			CVS_ENAB_PSERV="no"
			;;
			
			*)
			if test "$CVS_ENAB_PSERV" = ""; then
				echo "Defaulting to OFF."
				CVS_ENAB_PSERV="no"
			else
				echo "Defaulting to old value '$CVS_ENAB_PSERV'."
			fi
			;;
		esac
	else
		cat <<-EOF
		
		Since you don't have appear to networking installed, we won't ask you
		about the pserver configuration.
		EOF
		CVS_ENAB_PSERV="no"
	fi
	
	fi	## End version 1
	
	## Min version 2
	if [ $OLDVER -lt 2 ]; then
	
	if [ "$CVS_ENAB_PSERV" = "yes" ]; then
		[ "$CVS_PSERV_RESPAWN" = "off-def" ] && CVS_PSERV_RESPAWN=400
		cat <<EOF
		
3a. PServer respawn limit

When running a pserver, inetd's default limit of allowing 40 connections in
1 minute can easily be exceeded if a script calls CVS individually on many
files over a pserver connection. This limit is designed to stop system load
from rising too high if the service is continually failing.

Thus a more sensible default limit for most systems is 400. However, if you
are running an inetd clone which does not support the syntax
"nowait.[limit]", you will need to not set a limit using this method.

If you want to not use this syntax, enter "no" or "off" to this question.
Otherwise, enter the limit you want; just pressing enter will accept
the current default of $CVS_PSERV_RESPAWN.

Enter the respawn limit parameter to use, or "OFF" to disable this feature:-
EOF
		echo -n "> "
		
		read CVS_YN
		
		case "$CVS_YN" in
			[Nn][Oo]|[Oo][Ff][Ff]*)
			CVS_PSERV_RESPAWN="off"
			;;
			
			[0-9]*)
			CVS_PSERV_RESPAWN="$CVS_YN"
			;;
			
			*)
			echo "Defaulting to $CVS_PSERV_RESPAWN."
			;;
		esac
	fi
	
	fi		## End version 2
}

# upgrade_conffile oldversion
upgrade_conffile ()
{
	OLDVER="$1"
	if [ $OLDVER -lt 2 ]; then
		## Upgrade conffile to version 2
		TEMP_UFILE=`tempfile -m 600`
		TMPFILES="$TEMP_UFILE $TMPFILES"
		#UP_SEDCMD="$UP_SEDCMD -e '/^CVS_PSERV_REPOS=/r$TEMP_UFILE'"
		#echo 'CVS_PSERV_RESPAWN="400"' > $TEMP_UFILE
		if ! grep -q CVS_PSERV_REPOS /etc/cvs.conf; then
			sed -e '/^CVS_PSERV_REPOS=/a\
CVS_PSERV_RESPAWN="400"' /etc/cvs.conf > $TEMP_UFILE
			cp $TEMP_UFILE /etc/cvs.conf
			CVS_PSERV_REPOS=400
		fi
	fi
}

create_config ()
{
	cat <<EOF >/etc/cvs.conf
#
# Configuration file for the Debian CVS-related scripts
#

# Please do not touch this - it enables the postinst scripts detection
# of whether the "cvsconfig" script needs to be run or not.
CVSCONF_VERSION="none"

# 1. Where are your repositories?
CVS_REPOS=""

# 2. Do you want history files rotated?
# 2a. If, so, only those in different dirs, or in all the dirs above?

# Set CVS_ROTATE to a colon-separated list of the rotations to keep
# (the default is seven).
CVS_ROTATE=""
CVS_ROTDIRS="\$CVS_REPOS"

# The CVSROOT directories pserver is allowed to read from as standard
CVS_ENAB_PSERV=""
CVS_PSERV_REPOS="\$CVS_REPOS"
CVS_PSERV_RESPAWN="400"

# End of file.
EOF
}

# Defaults if NOT SPECIFIED in config file
set_defaults ()
{
	CVSCONF_VERSION="none"
	CVS_REPOS=""
	CVS_ROTATE=""
	CVS_ROTDIRS=""
	CVS_ENAB_PSERV="no"
	CVS_PSERV_REPOS=""
	CVS_PSERV_RESPAWN="off-def"
}

OURCVSCONF_VERSION="2"

#TMPFILE=/tmp/$$.cvsconfig-tmp
#rm -f $TMPFILE
#:>$TMPFILE
#chmod 600 $TMPFILE

TMPFILE=`tempfile -m 600`
TMPFILES="$TMPFILE"

trap "rm -f $TMPFILES; exit 1" SIGINT SIGHUP SIGQUIT SIGTERM

OPTION="$1"

if [ "$OPTION" = "-s" ]; then
	set_defaults
	. /etc/cvs.conf
	if [ -f /etc/cvs.conf.dpkg-old ]; then
		. /etc/cvs.conf.dpkg-old
	fi
	setup
	exit 0
fi

# Check the situation with /etc/cvs.conf.dpkg-dist
if test -f /etc/cvs.conf.dpkg-dist; then
	if test -f /etc/cvs.conf.dpkg-old; then
		savelog -l /etc/cvs.conf.dpkg-old
	fi
	mv -f /etc/cvs.conf /etc/cvs.conf.dpkg-old
	mv -f /etc/cvs.conf.dpkg-dist /etc/cvs.conf
	echo "You have a newer version of /etc/cvs.conf in /etc/cvs.conf.dpkg-dist."
	echo "Your old configuration file has been backed up, and the new one"
	echo "will be used in place."
fi

if test ! -f /etc/cvs.conf; then
	echo "You have no current CVS configuration file (/etc/cvs.conf)"
	echo "I will create a new one with appropriate defaults for you."
	create_config
fi

set_defaults
. /etc/cvs.conf

if test -f /etc/cvs.conf.dpkg-old; then
	echo "Loading your old configuration defaults..."
	. /etc/cvs.conf.dpkg-old
	#sed -ne 's\([^=]\+\)="\([^"]*\)"\(.*\)\1 \2 \3gp' \
	#	/etc/cvs.conf.dpkg-old > $TMPFILE
	#SEDCMD=""
	#while read LINE; do
	#	set -- $LINE
	#	SEDCMD="$SEDCMD -e 's\($1=\\\"\)[^\\\"]*\(\\\".*\)\1$2\2$3g'"
	#done < $TMPFILE
	#eval sed $SEDCMD /etc/cvs.conf >$TMPFILE
	#cp $TMPFILE /etc/cvs.conf
fi

no_apply=0

#UP_SEDCMD=""
if test "$OPTION" = "-u"; then
	if test "$CVSCONF_VERSION" != "$OURCVSCONF_VERSION"; then
		if [ "$CVSCONF_VERSION" != "none" ]; then
			do_questions "$CVSCONF_VERSION"
		else
			do_questions 0
		fi
	fi
elif test "$OPTION" = "-a"; then
	echo Doing automatic update of CVS configuration file...
	echo "(without applying any new settings)"
	no_apply=1
elif test "$OPTION" = "-r"; then
	echo Any local changes other than actual settings
	echo 'will be eliminated!'
	echo -n "Are you sure? "
	read CVS_YN
	case "$CVS_YN" in
		[Yy]|[Yy][Ee][Ss])
		echo Regenerating config file from default file...
		create_config
		UP_SEDCMD=""
		;;
		
		[Nn]|[Nn][Oo])
		echo No action taken
		exit 0
		;;
		
		*)
		echo Defaulting to no action
		exit 0
		;;
	esac
else
	do_questions 0
fi

if test -f /etc/cvs.conf -a "$CVSCONF_VERSION" != "$OURCVSCONF_VERSION"; then
	if [ "$CVSCONF_VERSION" != "none" ]; then
		upgrade_conffile "$CVSCONF_VERSION"
	else
		upgrade_conffile 1
	fi
fi

sed \
	-e 's:\(CVSCONF_VERSION=\"\)[^\"]*\(\".*\):\1'"${OURCVSCONF_VERSION}"'\2:g' \
	-e 's\(CVS_REPOS=\"\)[^\"]*\(\".*\)\1'"${CVS_REPOS}"'\2g' \
	-e 's\(CVS_ROTATE=\"\)[^\"]*\(\".*\)\1'"${CVS_ROTATE}"'\2g' \
	-e 's\(CVS_ENAB_PSERV=\"\)[^\"]*\(\".*\)\1'"${CVS_ENAB_PSERV}"'\2g' \
	-e 's\(CVS_PSERV_RESPAWN=\"\)[^\"]*\(\".*\)\1'"${CVS_PSERV_RESPAWN}"'\2g' \
	/etc/cvs.conf > $TMPFILE

if ! cmp -s $TMPFILE /etc/cvs.conf; then
	cp $TMPFILE /etc/cvs.conf
fi

rm -f $TMPFILES

if test -f /etc/cvs.conf.dpkg-old; then
	echo "Your configuration file has been updated successfully."
	echo "Do you wish to remove the backup dpkg created of your old"
	echo "file, /etc/cvs.conf.dpkg-old?"
	echo -n "> "
	read CVS_YN
	case "$CVS_YN" in
		[Yy]*)
		echo "OK, removing it..."
		rm -f /etc/cvs.conf.dpkg-old
		;;
		
		*)
		echo "Keeping it."
		;;
	esac
fi

if [ $no_apply -eq 0 ]; then
	setup
fi

# End of file.
