#!/usr/bin/perl
#
# This is anacron (like `anac(h)ronistic') -- a cron-like program
# that doesn't go by time.
#
# Copyright (C) 1996 Christian Schwarz <C.Schwarz@monet.m.isar.de>
# See file /usr/doc/copyright/anacron for details.
#
# Version 1.0.2

$TAB = '/etc/anacrontab';
$LIBDIR = '/var/spool/anacron';
$LOGFILE = '/var/log/anacron';
$LOCKDIR = '/var/lock';

open(LOG,">>$LOGFILE") || die "Cannot open log file for writing\n";

chop($date = `date`);
&log("anacron started at $date\n");

if ( !open(TAB,$TAB) ) {
    &log("warning: cannot open $TAB.\n");
    close(LOG);
    exit 0;
}

chop($datecode = `date +%Y%m%d`);

while (<TAB>) {
    s/\#.*$//og;
    next if /^\s*$/;
    chop;
    if ( !/^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S.*)$/ ) {
	if ( !/^\s*(\S+)=(.+)$/ ) {
	    &log("error: syntax error in $TAB: $_\n");
	    &log("skipping this line.\n");
	    next;
	}
	($var,$param) = ($1,$2);

	$ENV{$var} = $param;
	next;
    }
    ($period,$delay,$jobname,$action) = ($1,$2,$3,$4);

    $datefile = "$LIBDIR/$jobname";
    $lockfile = "$LOCKDIR/anacron.$jobname.lock";

    # Lets see if we have to do something...
    if ( -f $datefile ) {
	if ( !open(DATEFILE,$datefile) ) {
	    &log("error: cannot open $datefile.\n");
	    &log("skipping this line.\n");
	    next;
	}
	chop($lastdate = <DATEFILE>);
	close(DATEFILE);

	if ( $datecode-$lastdate < $period ) {
	    next;
	}
    }

    # Is there a lock file?
    if ( -f $lockfile ) {
	# Job already scheduled, so skip it.
	next;
    }

    # Create lock file.
    if (!open(LOCK,">$lockfile")) {
	&log("error: cannot create lock file $lockfile.\n");
	&log("skipping this line.\n");
	next;
    }
    print LOCK "Job scheduled.\n";
    close(LOCK);

    # Run job.
    &log("Job $jobname scheduled for execution in $delay minutes.\n");
    $action = "(sleep ${delay}m; $action; echo $datecode > $datefile; ".
	"rm -f $lockfile) >>$LOGFILE 2>&1 &";
    
    system($action);
}

&log("\n");

close(TAB);
close(LOG);

exit 0;

####################

sub log {
    print LOG @_;
}
