#!/optware/unsupported/bin/perl     # change this to point to YOUR perl

require 'getopts.pl';
require 'importenv.pl'; # Need this for environment var parsing.

# Written by Mike Campbell (mcampbel@schubert.sbi.com).  I'm releasing into the
# public domain.  Modify, spindle, fold, mutilate at will.  If you DO use this,
# all I ask is that you send me an email telling me.  (No, I don't keep track
# of who is using it; I just would like to say "hi" and thanks.)  If you add
# something to it, let me know!  I probably will find it useful too.  Thanks.

# This script reads a file of "rule sets", applies the logic of the rule-set
# and returns a true (0) or false (non-0) value to the shell based on the
# result. 

# Anything after a '#' is ignored.  Blank lines are ignored.

# A "rule-set" is defined as a set of conditions (1 per line) between the lines
# "BEGIN-RULE" and "END-RULE".  A valid rule-set could be:

# BEGIN-RULE
# EXIST $HOME/.login
# END-RULE

# Running this script on this rule-set would return true if you had a .login
# file in your home directory (and it is non-0 size - see the gotcha's section
# below.

# Each "rule set' is 'and'ed.  That is to say, for the rule set to be true,
# everything *in* the rule set must be true.

# Multiple rule sets in a file are 'or'd, meaning if *ANY* of the rule sets were
# true, the whole thing is true.

# Rule-set Format:

# BEGIN-RULE              Begins a rule set.
# EXIST <filename>        True if file exists and has > 0 size.
# NOTEXIST <filename>     True if the file does NOT exist or is 0 size.
# DAY   <0-6>	     	  True if "today" is value specified.  No ranges.  
#                         Use multiple rules for that.           
# HOUR  <0-23>	     	  True if "now" is hour specified.  No ranges.  
#                         Use multiple rules for that. 
# END-RULE                Ends a rule set  

# A couple of things to watch out for:

# * Because the way perl reads in multiple files, multiple rule sets across
# multiple files are considered no different from a SINGLE file with the same
# multiple rule sets.

# * An *EMPTY* rule-set, that is, one with no rules is always TRUE.  It could
# be written so that this is always false, but it would require a bit more
# code.

# * However, a complete absence of rule sets, (i.e. running this script and
# using /dev/null as the rule-set file) will return false.  Wacky.

# * This script does not grok ~'s.  Checking for existence (or absence) of
# ~/foo will not work.  Use $HOME for that.  It DOES parse environment
# variables (assuming the "require 'importenv.pl'" worked.)



($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = 
    localtime(time);

&Getopts("d"); $debug = $opt_d;


while (<>) {
    s/\#.*//;
    next if /^\s*$/;
    
    if (/^\s*BEGIN-RULE/){
	print "\nChecking new rule\n";
	exit 0 if &do_rule_set;
	next;
    }
}
exit 1;



sub do_rule_set
{
    local($truth);

    $truth = 1;
    while (<>) {
	last unless $truth;
	s/\#.*//;
	next if /^\s*$/;

	last if /^\s*END-RULE/;

	if (/^\s*EXIST\s*(.*)/) {
	    eval "\$name = \"$1\"";	# for env var parsing.
	    print "Checking for existence of $name..." if $debug;
	    $truth *= -s $name;
	    if ($debug) {
		if ($truth) {
		    print "exists!\n";
		} else {
		    print "not there.\n";
		}
	    }
	    next;
	}

	if (/^\s*NOTEXIST\s*(.*)/) {
	    eval "\$name = \"$1\"";	# for env var parsing.
	    print "Checking for absence of $name..." if $debug;
	    $truth *= (! -s $name);
	    if ($debug) {
		if ($truth) {
		    print "absent.\n";
		} else {
		    print "exists!\n";
		}
	    }
	    next;
	}
	
	if (/^\s*DAY\s*([0-6])/) {
	    print "Checking day $1..." if $debug;
	    $truth *= ($wday == $1); 
	    if ($debug) {
		if ($truth) {
		    print "passed.\n";
		} else {
		    print "failed.\n";
		}
	    }
	    next;
	}

	if (/^\s*HOUR\s*(\d+)/) {
	    print "Checking hour $1..." if $debug;
	    $truth *= ($hour == $1); 
	    if ($debug) {
		if ($truth) {
		    print "passed.\n";
		} else {
		    print "failed.\n";
		}
	    }
	    next;
	}

	# Other checks go here

	# Do this last.  Unparseable line.  Always false.  (Or true; you
 	# decide). 
	$truth = 0;
	print "Unparseable line \"$_\"\n" if $debug;
    }

    $truth;
}
