#!/usr/bin/perl
=head1 NAME
ferie - Quando una persona appartenente allo staff parte o ritorna dalle vacanze puo' utilizzare questo script
per creare l'autorisponditore
=head1 Synopsis
ferie.pl
=head1 Descrizione
Se una persona parte per le vacanze puo' inviare
un messaggio a ferie@finconsumo.it con oggetto B<inizio> e come corpo I<il testo che vuole rappresenti la risposta automatica">. Al contrario, quando ritorna, per eliminare l'autorisponditore, puo' mandare un messaggio allo stesso indirizzo ma con oggetto la parola B<fine>
=cut
#################################################
### INZIALIZZAZIONE
### MODULI PER UTILIZZO DB E RETE
#################################################
use Time::localtime;
use Mail::POP3Client;
use Mail::Sender;
use strict;
=pod
=head1 Richiede
B<Perl 5.004>, ed i moduli
I<Time::localtime, Mail::Pop3Client, Mail::Sender>
=head1 Esporta
Di default nulla ma genera una mail di risposta a seconda dell'evento desiderato e un file di logg denominato B<logg.csv>
che contiene la lista degli accessi avvenuti.
=cut
#################################################
### INIZIALIZZAZIONE
### DELLE VARIABILI CHE SARANNO UTILIZZATE
#################################################
=pod
=head1 Algoritmo
=head2 Inizializzo variabili ed i moduli
Come prima operazione vi e' l'inizializzazione dei moduli necessari e delle variabili globali
che serviranno per tutta l'esecuzione dello script.
=cut
my $msg;
my $dest;
my $percorso_alias='/etc/exim4';
my $file_alias='aliases';
my $percorso_logg='/var/log';
my $logg='logg.csv';
my $percorso_home='/home';
my $username='ferie';
my $password='ferie';
my $smtp_server='smtp.TUADITTA.it';
my $pop_server='pop.TUADITTA.it';
my $mittente='ferie@TUADITTA.it';
#################################################
### INIZIO
### SCRIPT
#################################################
=pod
=head2 preleva_info
Lo script e' generato interamente dalla funzione B<preleva_info> che viene avviata per prima e,
a seconda degli eventi, passa il controllo a funzioni differenti.
=for html <br>
Essa lancia la funzione di scansione dell'account ferie@finconsumo.it per analizzare la presenza di eventuali
mail che aspettano di essere processate. Dopo essersi collegato al server POP scarica le eventuali mail popolando
il reference denominato C<$msg>. In particolare esso salva I<il mittente, il corpo del messaggio e il subject> nella forma
C<$msg->{$i}->{From}>, C<$msg->{$i}->{Subject}>, C<$msg->{$i}->{msg}>.
=for html <br>
A questo punto parte la funzione di C<logg> che tiene traccia della mail e la funzione C<controlla_utente> che verifica
che l'utente appartenga al dominio aziendale ed esista nel file degli utenti di posta.
Se entrambe le situazioni sono verificate, parte la funzione C<procedura> che si occupa di inserire o eliminare l'autorisponditore altrimenti viene mandata una mail al mittente informandolo che qualcosa e' andato storto.
=cut
preleva_info();
##################################################
#### INIZIO
#### FUNZIONI UTILIZZATE DALLO SCRIPT
##################################################
sub preleva_info{
my $i; #Conta le mail
my $j; #Conta subject e password e poi si azzera
my $pop = new Mail::POP3Client( USER => $username,
PASSWORD => $password,
HOST => $pop_server );
for( $i = 1; $i <= $pop->Count(); $i++ ) {
foreach( $pop->Head( $i ) ) {
if(/^(From|Subject):\s+(.*)/i){
$msg->{$i}->{$1}=$2;
}
$msg->{$i}->{msg}=$pop->HeadAndBody($i);
}
$dest=$msg->{$i}->{From}; #Rappresenta il destinatario della mail
$msg->{$i}->{From}=~s/.+<(.+)\@.+>/$1/; #Rappresenta il nome.cognome che ritrovo in /etc/aliases
logg($msg->{$i}->{From},$msg->{$i}->{Subject});
my ($ok,$user)=controlla_utente($msg->{$i}->{From});
if($ok){
my $report=procedura($user,$msg->{$i}->{Subject},$msg->{$i}->{msg});
mail($dest,$report);
}
else{
mail($dest,"not_found");
}
$pop->Delete($i);
}
$pop->Close();
}
=pod
=head2 logg
Questa funzione si occupa di generare e mantenere un file di log in formato standard CSV che tiene traccia
delle mail ricevute dal sistema. Cio' che esegue e' un semplice aggiornamento di un file
=cut
sub logg{
my $now=ctime();
my $comando=shift;
my $from=shift;
my @now=split(/\s+/,$now);
my %mesi=( Jan=>1,
Feb=>2,
Mar=>3,
Apr=>4,
May=>5,
Jun=>6,
Jul=>7,
Aug=>8,
Sep=>9,
Oct=>10,
Nov=>11,
Dec=>12
);
$now="$now[2]-$mesi{$now[1]}-$now[4];$now[3]";
open(LOG, ">>$percorso_logg/$logg") or die "Non riesco ad aprire sto file!\n";
print LOG "$now;$from;$comando\n";
close(LOG);
}
=pod
=head2 controlla_utente
Questa funzione si occupa di controllare che un utente sia inserito nel file /etc/aliases del sistema
e restituisce una variabile $ok che e' di tipo booleano a seconda che l'utente sia trovato e la variabile
$alias2 nel caso in cui viene trovato l'utente che contiene il nome dell'utente nel sistema ovvero nel
file /etc/passwd.
=for html <br>
La funzione analizza riga per riga il file alla ricerca dell'utente.
Potrebbe essere ottimizzata con il modulo BDB::CSV ma, purtroppo sul sitema in cui ho eseguito le prove
non sono riuscito a caricarlo.
=cut
sub controlla_utente{
my $from=shift;
my $ok=0;
my($alias1,$alias2);
$from=~s/(.+)\@.*/$1/;
open(FILE,"$percorso_alias/$file_alias") or die "Ho un errore sugli aliases: $!";
while(my $riga=<FILE>){
($alias1,$alias2)=$riga=~/(.*)?: (.*)\n/;
if($alias1 eq $from){
$ok=1;
last;
}
elsif($alias2 eq $from){
$ok=2;
last;
}
}
close FILE;
return ($ok,$alias2);
}
=pod
=head2 procedura
Questa funzione e' la esegutiva del gruppo.
In pratica, quando il programma ha ricevuto le mail e controllato l'esistenza dell'utente, passa i parametri a questa funzione che si occupera' di generare o eliminare l'autorisponditore.
Essa ritorna, in uscita la variabile C<$report> che rappresentera' l'oggetto della mail dirisposta e
puo' essere uno dei seguenti valori:
=over1
=item exist
Se l'utente ha mandato una mail con oggetto inizio ma esiste gia' un file .vacation.msg
=item start_vacation
Se l'utente ha mandato una mail con oggetto inizio. In tal caso viene generato un file .vacation.msg nella home directory dell'utente.
=item end_vacation
L'utente ritorna dalle vacanze. Viene eliminato il file .vacation.msg e si manda una mail di bentornato.
=item not_exist
L'utente ha mandato una mail di fine vacanze ma il file .vacation.msg non e' stato generato in passato
=item not_valid
Il prorgamma ha scoperto che l'utente non sembra esistere nel file degli aliases!
=back
=cut
sub procedura{
my $utente=shift;
my $subject=shift;
my $msg=shift;
my $report;
if($subject eq "inizio"){
if(-e "$percorso_home/$utente/.vacation.msg"){
$report='exist';
}
else{
$report='start_vacation';
open(FILE, ">$percorso_home/$utente/.vacation.msg");
print FILE $msg;
close FILE;
}
}
elsif($subject eq "fine"){
if(-e "$percorso_home/$utente/.vacation.msg"){
$report='end_vacation';
unlink "$percorso_home/$utente/.vacation.msg";
unlink "$percorso_home/$utente/.vacation.db";
unlink "$percorso_home/$utente/.vacation.log";
}
else{
$report='not_exist';
}
}
else{
$report='not_valid';
}
return $report;
}
=pod
=head2 mail
Questa funzione viene eseguita a fine script.
Ad essa vengono passati il destinatario ed l'oggetto.
=cut
sub mail{
my $dest=shift;
my $subject=shift;
my $msg;
$msg="Attualmente non c'e' autorisponditore per le mail che arrivano al tuo account. \nSe si desidera impostarlo si mandi una mail a ferie\@DITTA.it con oggetto \"inizio\" e nel corpo del messaggio cio' che si vuole inviare come risposta automatica. \nQuesto messaggio e' stato creato in automatico.\nUlteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "not_exist");
$msg="E' stato impostato un autorisponditore automatico\nSi ricordi, al ritorno dalle ferie di mandare una mail a ferie\@DITTA.it con oggetto \"fine\" per eliminarlo.\nQuesto messaggio e' stato creato in automatico.\n Ulteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "start_vacation");
$msg="L'autorisponditore e' stato eliminato. \nQuesto messaggio e' stato creato in automatico\n Ulteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "end_vacation");
$msg="Attenzione. Attualmente esiste gia' un autorispopnditore. \nSe si desidera impostarlo di nuovo e' necessario, prima, eliminarlo mandando una mail a ferie\@DITTA.it con oggetto \"inizio\" e come testo cio' che si vuole venga recapitato a coloro che vi mandano una mail durante il periodo di ferie.\nQuesto messaggio e' stato creato in automatico\n Ulteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "exist");
$msg="Questo utente non e' stato trovato nel sistema!! \nQuesto messaggio e' stato creato in automatico.\n Ulteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "not_found");
$msg="Attenzione: oggetto puo' essere soltanto inizio o fine!.\nQuesto messaggio e' stato creato in automatico\n Ulteriori info su http://DITTA.it/perl/ferie.html" if ($subject eq "not_valid");
my $sender = new Mail::Sender{smtp => $smtp_server, from => $mittente};
$sender->MailMsg(
{ to => $dest,
subject => $subject,
msg => $msg
}
);
}
__END__