#! /bin/sh
#
# $Id: run-once,v 1.1 2005/05/17 21:37:23 ferlatte Exp $
# modified by ben 2006/06/09
#
# run scripts or programs in a directory no more than one time.
#
# Prerequisite - $rundir and $statedir *must* exist
#
# I call it from cron every minute like so:
## [ben@web010 ~]$ cat /etc/cron.d/run-once
## # run any files found in /var/lib/run-once/rundir once
## * * * * * root /usr/local/sbin/run-once --statedir=/var/lib/run-once/statedir /var/lib/run-once/rundir


LANG=C

me=$(basename $0)

statedir=/tmp

die()
{
	echo "${me}: $@" 1>&2
	exit 1
}

usage()
{
	cat <<EOH
Usage: ${me} [OPTION]... DIRECTORY
      --statedir=DIR  
              Directory which contains the run-once state.  There should be
              one seperate statedir per DIRECTORY.  Default is /tmp
      --help  Display this help and exit.
EOH
}

# capture arguments to $me
while test $# -gt 0; do
	case "$1" in
		-*=*)
			optarg=$(echo "$1" | sed 's/[-_a-zA-Z0-9]*=//')
			;;
		*)
			optarg=
			;;
	esac
	case "$1" in
		--statedir=*)
			statedir=$optarg
			;;
		--help)
			usage
			exit 0
			;;
		--)
			shift
			break
			;;
		-*)
			die "invalid option $1"
			;;
		*)
			break
			;;
	esac
	shift
done

# rundir is the last argument (required)
rundir=$1

# die unless both rundir and statedir exist
if [ ! -d "$rundir" ]
then
	die "Rundir ($rundir) doesn't exist or is not a directory"
fi
if [ ! -d "$statedir" ]
then
	die "Statedir ($statedir) doesn't exist or is not a directory"
fi

# move into rundir and execute files that aren't yet in statedir and
# copy them into statedir
pushd "$rundir" > /dev/null
for f in *; do
	if cmp -s "$f" "$statedir/$f"; then
		# Do nothing
		:
	else
		cp "$f" "$statedir"
		echo "running script $f" #generate output for cron anytime something actually happens
		pushd / > /dev/null
		"$rundir/$f"
		popd > /dev/null
		echo ""
	fi
done
popd > /dev/null

# Cleanup the state directory
pushd "$statedir" > /dev/null
for f in *; do
	if [ ! -f "$rundir/$f" ]; then
		rm "$f"
	fi
done

