#!/usr/bin/perl -w
# 14 mars 2004
#
# PARTIE DAEMON
# 3 partie:
#     + Ecriture du pid dans /var/run/atscript.pid
#     + Changement des regles pour le signal USR1
#     + sleep indefini.
# les fichiers se nomment en fonction du temps en seconde a la quelle ils vont etre lances.
# 
##############################################################################

# INITIALISATION
use Fcntl;
require POSIX;
use strict;
use Proc::Daemon;
Proc::Daemon::Init;

my ($sleep,$current_time,$sec,$min,$hour,$mday,$mon,$year,$c_sec,$c_min,$c_hour,$c_mday,$c_mon,$c_year,$file
,$pid,$pipe,@users,$user,@times);


$|= 1;
$SIG{'USR1'} = \&mise_a_jour;
$SIG{'CHLD'} = \&zombies;


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

open(LOG,">>/home/tfe/truc/at/test_daemon/log") or die "log impossible";
select LOG;
print "\n\n".gmtime(time)."\n********************************************\nRuning $0\n";
&mise_a_jour;

$pipe = "/var/run/atscript";
if (-e $pipe) {    unlink $pipe;    }
POSIX::mkfifo($pipe,0666) or die "mknod failed $!\n";
chmod 0666, $pipe or die $!;
sysopen(FIFO,$pipe,O_RDWR) or die "LEcture failed\n";

while(1)
{ while (<FIFO>)
    {
	open(LOG,">>/home/tfe/truc/at/test_daemon/log") or die "log impossible";
        if (/Update/) {    print LOG "RECU: update !\n";      &mise_a_jour;}
        if (/Show/) {   print LOG "RECU: show !\n"; print FIFO "Recu !n\n\nRECU !!\n"; select(undef,undef,undef,0.3);}
	else { print LOG "Message inconnu recu !\n"; }
        close LOG;    
        next;
    }
}

        



#Lancement de la mise a jour au debut du script puis a chaque signal recu.









sub mise_a_jour
{
$|= 1;
    open(LOG,">>/home/tfe/truc/at/test_daemon/log") or die "log impossible";
    select LOG;
print "\nReception de signal: \$pid contient: \" $pid \"\n";
if (open(PID,"/var/run/atscript.pid")) { $sleep = <PID>;} else {$pid = 0; }
close PID;
if ($sleep > 0) { print "TUer le pid: $pid\n"; kill 'KILL',$sleep;}
select(undef,undef,undef,0.2);
    if ($pid = fork)
    {
	print "Fork reussi: pid = $pid\n";
    }
    elsif (defined($pid))
    {
	open(PID,">/var/run/atscript.pid");
	print PID $$;
	close PID;
	
        $current_time = &make_time;    
        ($c_year,$c_mon,$c_mday,$c_hour,$c_min,$c_sec) = $current_time =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
        print "Time: $c_year $c_mon $c_mday $c_hour $c_min $c_sec\n";
        @users = &config() or die;
        
        foreach $user(@users){
	    undef @times;
            print "User: $user , et ";
            opendir(DIR,"/home/$user/.atscript/") or next;
	    push (@times,"$_ $user")  foreach ( grep(! /^\./, readdir(DIR))); 
            close DIR;
        }	
	print @times." fichiers dans le .atscript\n";
        @times = sort @times;
	
        foreach (@times) { 
	    print "Etude de $_\n";
	    ($file,$user) = split / /,$_; # user $min , #stop at $sec secondes.
	    if ($file < $current_time) { unlink("/home/$user/.atscript/$file") or print $!; 
					 print "/home/$user/.atscript/$file is an obsolete file: deleted\n";}
            ($year,$mon,$mday,$hour,$min,$sec) = $file =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
            print "Execution: $year $mon $mday $hour $min $sec\n";	
    	    $sleep =(($year-$c_year)*60*60*24*365 + ($mday-$c_mday)*60*60*24 + ($hour-$c_hour)*60*60 + ($min-$c_min)*60  +($sec-$c_sec));

            print "\t+ Sleep de $current_time a $file: $sleep\n"; 
            select(undef,undef,undef,$sleep);
            open(JOB,"/home/$user/.atscript/$file") 
        	or print ("Erreur de lecture du fichier /home/$user/.atscript/$file\n");
            foreach(<JOB>)    	{ s/\"//;  chomp; print "su $user -c \"$_\"\n"; system("su $user -c \"$_\"");}
            close JOB;	    
	    print "Suprression du fichier\n";
	    unlink("/home/$user/.atscript/$file");
	    print "Nouveaux temp: $c_year,$c_mon,$c_mday,$c_hour,$c_min,$c_sec\n";
            $current_time = &make_time;    
	    ($c_year,$c_mon,$c_mday,$c_hour,$c_min,$c_sec) = $current_time =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;

	    }
    }
close LOG;	
}


#########################################################################
sub make_time
{
    ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
    if ($sec==0){ $sec="00";} elsif ($sec<10) { $sec = "0".$sec; }
    if ($min==0){ $min="00";} elsif ($min<10) { $min = "0".$min; }    
    if ($hour==0){ $hour="00";} elsif ($hour<10) { $hour = "0".$hour; }    
    if ($mday==0){ $mday="00";} elsif ($mday<10) { $mday = "0".$mday; }    
    if ($mon==0){ $mon="00";} elsif ($mon<10) { $mon = "0".$mon; }    
    $year = $year+1900;
    return $year.$mon.$mday.$hour.$min.$sec;
}

sub config {
    open(CONF,"/etc/atscript.conf") or die "Fatal: no config found /etc/atscript.conf\n";
    while(<CONF>)   {
        if (/^users:(.*)/) {
	@users = split / /,$1;
        }
    }
    close CONF;
    if (!@users) { die "Fatal: no config users set in /etc/atscript.conf\n"; }
    return @users;
}



sub zombies
{
1 until (waitpid(-1 , 'WNOHANG') == -1);
}



print STDOUT "Fin du lancement.\n";    
close LOG;

while(1)
{
select(undef,undef,undef,1);
}







