Old stuff/Perl/at/Beta/serv.pl
(Deskargatu)
#!/usr/bin/perl -w
# 14 mars 2004
#
# PARTIE DAEMON
# 3 partie:
# + Ecriture du pid fork dans /var/run/atscript.pid
# + Ouverture d un pipe en lecture/ecriture
# + sleep indefini pour ne pas quitter et garder un oeil sur le pipe.
# 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 ($logfile,$oldpid,$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;
$logfile = "/var/log/atscript";
$SIG{'CHLD'} = \&zombies;
#############################################################################
# Reaction commandes de lancement
# die si on est pas root !
# $ARGV[0] eq '--stop' , on coupte
# $ARGV[0] eq '--start' , on commence, si pid non reactif, etc
# $ARGV[0] eq '--restart' , on tue le pid, et on relance?
open(LOG,">>".$logfile);
if ($ENV{'USER'} ne 'root') { print LOG "Pas root, dsl\n"; close LOG; die; }
if ($ARGV[0])
{
if ($ARGV[0] eq '--stop') {
print LOG "OK";
open(PID,"/var/run/atscriptd.pid") or do {
print LOG "NON LANCE!\n";
die();
};
$pid = <PID>;
close PID;
kill 'KILL',$pid;
print LOG "done.\n"; die;
}
elsif ($ARGV[0] eq '--start') {
if (open(PID,"/var/run/atscriptd.pid"))
{
$pid = <PID>;
close PID;
}
if ($pid and kill 0,$pid) { print LOG "Core deja lance!\n"; die; }
print LOG "done.\n";1
}
elsif ($ARGV[0] eq '--restart') {
open(PID,"/var/run/atscriptd.pid") or do {
print LOG "NON LANCE!\n";
die();
};
$pid = <PID>;
print LOG "PID: $pid\n";
close PID;
if (kill 0,$pid) { kill 'KILL',$pid; }
if (open(PID,"/var/run/atscript.pid"))
{
$pid = <PID>;
if (kill 0,$pid) { kill 'KILL',$pid; }
close PID;
}
unlink("/var/run/atscriptd.pid");
print LOG "restarting...\n";
}
}
else { print LOG "Pas d arg"; }
close LOG;
#############################################################################
# Mise a jour du pid atd !
# die si le pid est reactif.
# Nouveau pid si pas de pid, ou non reactif
undef($pid);
if (open(PID,"/var/run/atscriptd.pid"))
{ $pid = <PID>; close PID; }
if ($pid and kill 0,$pid) {
open(LOG,">>".$logfile);
print LOG "\nPid reactif\n";
close LOG;
print STDOUT "Deja lance!\n"; die("not");
}
else
{
open(PID,">/var/run/atscriptd.pid");
print PID $$;
close PID;
}
#############################################################################
open(LOG,">>$logfile") 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,">>$logfile") 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,">>$logfile") or die "log impossible";
select LOG;
if (open(PID,"/var/run/atscript.pid")) { $oldpid = <PID>;} else { $oldpid = 0; }
close PID;
&jobs;
print "\nReception de signal: pid = \" $oldpid\"\n";
if ($oldpid > 0) { print "TUer le pid: $oldpid\n"; kill 'KILL',$oldpid;}
select(undef,undef,undef,0.3);
print "En attente...\n\n";
close LOG;
}
sub jobs
{
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;
print "USERS: "; print @users; print "\n";
undef @times;
foreach $user(@users){
print "Lecture de $user\n";
if ($user ne 'root') { opendir(DIR,"/home/$user/.atscript/") or next; }
else { opendir(DIR,"/$user/.atscript/") or next; }
push (@times,"$_ $user") foreach ( grep(! /^\./, readdir(DIR)));
close DIR;
}
print scalar @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 ($user ne'root') {
if ($file < $current_time) { unlink("/home/$user/.atscript/$file");
print "/home/$user/.atscript/$file fichier obsolete: supprime\n";}
}
else { if ($file < $current_time) { unlink("/root/.atscript/$file");
print "/root/.atscript/$file fichier obsolete: supprime\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: soit une attente de $sleep secondes\n";
if ($sleep > 0 ) {
select(undef,undef,undef,$sleep);
open(JOB,"/home/$user/.atscript/$file") or open(JOB,"/root/.atscript/$file")
or print ("Erreur de lecture du fichier /home/$user|/root|/.atscript/$file\n");
foreach(<JOB>) { s/\"//; chomp; print "su $user -c \"$_\"\n"; system("su $user -c \"$_\"");}
close JOB;
}
print "Suprression du fichier\n";
if ($user ne 'root'){unlink("/home/$user/.atscript/$file") }
else { 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})/;
}
kill 'KILL',$$;
}
}
#########################################################################
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);
}