#!/usr/bin/muawk
# (rustic) anacron for muLinux, AWK based
# (C) 2001, m. Andreoli


BEGIN	{
	n=split(arg,opts)	

	#------------
	# syntax
	#-------------

	if ( opts[1] == "-h" ) { Usage(); exit }
	if ( opts[1] == "-report" ) { PrintReport(); exit }

	#------------
	# MAIN 
	#-------------

	main();


	}

function Usage()
{
print "Anacron, (rustic AWK) Anac(h)ronistic daemon";
print "(C) M. Andreoli for muLinux.";
print "Usage: anacron [-h|-report]"
print ""
print "Anacron run every job in the directories /etc/cron.daily,"
print "/etc/cron.weekly, /etc/cron.monthly, if expiration time"
print "is reached. It does not assume that the machine is running 24/24."
print ""
print "Timestamps are stored in the file /etc/anacron.conf"
}

function PrintReport()
{
Conf();
Read()
Report();
}

function main()
{
        Conf();
        Read()
        GetExpired(ex);
        Process(ex);
       	Update(ex);
        Save();
}


function Conf()
{
# configuration file for Anacron: it contains a
# single line "dayjob weekjob monthjob": three time
# corresponding to last run.

CONF="/etc/anacron.conf"

# note: in AWK array's index starts from 1

# job's names

split("daily weekly monthly",job);

# expiration in seconds

sec[1]=3600*24; sec[2]=3600*24*7; sec[3]=3600*24*30;

# natural units (used in report() )

split("hours days days",unit_name);

unit_sec[1]=3600;
unit_sec[2]=3600*24;
unit_sec[3]=3600*24;


}

# read /etc/anacron.tab in the STAMP[] array

function Read()
{
getline s < CONF
split(s,STAMP);
}

function Save()
{
printf "%s %s %s\n",STAMP[1],STAMP[2],STAMP[3] > CONF;
}

# return seconds since Unix epoch

function time()
{
system("time > /tmp/time");
getline t < "/tmp/time" ;
return(t)
}

function GetExpired(expired)
{
ctime=time();

for ( j in job ) {
	dt=ctime - STAMP[j];
	expired[j]=0;
	if ( dt > sec[j] ) expired[j]=1;
}

}

# update timestamps for the expiration array

function Update(expired)
{
for ( j in expired ) {
	if ( expired[j] == 1 ) {
	printf("Updating cron.%s timestamps\n",job[j]);
	STAMP[j]=time();
	}
}
}

# process expired jobs

function Process(expired)
{
wait=60*3;

for ( j in expired ) {
        if ( expired[j] == 1 ) {
	run=sprintf("(sleep %d; run-parts /etc/cron.%s)&",wait,job[j]);
	system(run);
	} 
}
}

function Report()
{
ctime=time();

for ( j in job ) {
	dt=ctime - STAMP[j];
	wait=int( (sec[j]-dt) / unit_sec[j] ); 
	if ( wait < 0 ) wait=0;
	printf("Will run cron.%s in %d %s\n",job[j],wait,unit_name[j]);	
}


}
