#!/usr/local/bin/perl
# analizza solo le entries relative al protocollo SMTP
$qid=0;
$local=0;
open(FILEOUTPUT,">>output_smtp_sendmail");

#---------------------------------------------------------------------------
# $local=1->significa locale;$local=2->significa remoto
#
#inizializza le hash
#---------------------------------------------------------------------------
if(open(FILECODICI,"codici_hosts")){
    while(<FILECODICI>){
	chomp;
	($key,$value)=split/ /;
	$codici_hosts{$key}=$value;
    }
}
else{
%codici_hosts=();
}
close(FILECODICI);
#--------------------------------------------------------------------
if(open(CODICICLIENTI,"codici_clients")){
    while(<CODICICLIENTI>){
	chomp;
	($key,$value)=split/ /;
	$codici_client{$key}=$value;
    }
}
else{
%codici_client=();
}
close(CODICICLIENTI);
#--------------------------------------------------------------------
if(open(FILECODICIMACCH,"codici_macchina")){
    while(<FILECODICIMACCH>){
	chomp;
	($key,$value)=split/ /;
	$codici_macchina_host{$key}=$value;
    }
}
else{
%codici_macchina_host=();
}
close(FILECODICIMACCH);
#--------------------------------------------------------------------
##############################################
while ($line=<>){
    chomp($line);
    if($line!~/sendmail/){next;}
    if($line=~/starting daemon|forward|runqueue|NOQUEUE/){next;}
    if($line=~/User unknown/){$qid=0;next;}
    @tmp_array=split(/ /,$line);
    $nuovo_qid=substr($tmp_array[5],0,-1);
# controlla gli spazi
    if($tmp_array[3]=~/:{1,2}/){
	$nuovo_qid=substr($tmp_array[6],0,-1);
    }
#--------------------------------------------------------------------
    if($nuovo_qid ne $qid){
	$ctrl_ciclo=1;
	@tmp=();
# sono nel caso di una nuova entry: cliente->sendmail
	$ref_tempo=data($tmp_array[0],$tmp_array[1],$tmp_array[2]);
	@time_login=@$ref_tempo;
	$host=$tmp_array[3];
#controllo sul numero di spazi nella data
	if($host=~/:{1,2}/){
	    $ref_tempo=data($tmp_array[0],$tmp_array[2],$tmp_array[3]);
	    @time_login=@$ref_tempo;
	    $host=$tmp_array[4];
	}
#assegno un codice all'host e inserisco nella tavola
	if(exists($codici_hosts{$host})){
		if(defined($codici_hosts{$host})){
			$host_code=$codici_hosts{$host};}
		else{
			$tipo=0;
			while(($key,$value)=each(%codici_hosts)){
				$tipo=($value>$tipo)?$value:$tipo;
			}
			$host_code=$tipo+1;
			$codici_hosts{$host}=$host_code;
		}
	}
	else{
		$tipo=0;
		while(($key,$value)=each(%codici_hosts)){
				$tipo=($value>$tipo)?$value:$tipo;
			}
		$host_code=$tipo+1;
		$codici_hosts{$host}=$host_code;
	}
#$host_code contiene il codice del l'host
#identifico il client
	for ($i=0;$i<=$#tmp_array;$i++){
	    if($tmp_array[$i]=~/from/){
# sistema il cliente:
# ci sono due possibili forme per questo campo:
# from=<user@indirizzo>,
# from=user,
		($ctrl,$user)=split(/=/,$tmp_array[$i],2);
		if($user=~/<|>/){
		    if($user=~/\@/){
			($cliente,$indirizzo)=split(/\@/,$user,2);
			$cliente=substr($cliente,1);
		    }
		    else{
			$cliente=substr($user,1);
			$cliente=substr($cliente,0,-1);
		    }
		}
		else{
		    if($user=~/\@/){
			($cliente,$indirizzo)=split(/\@/,$user,2);
		    }
		    else{
			$cliente=substr($user,0,-1);
		    }
		}
# ho $cliente, devo trovargli un codice
	        if(exists($codici_client{$cliente})){
	        	if(defined($codici_client{$cliente})){
			    $cliente_code=$codici_client{$cliente};}
			else{
			    $tipo=0;
			    while(($key,$value)=each(%codici_client)){
				$tipo=($value>$tipo)?$value:$tipo;
			    }
			    $cliente_code=$tipo+1;
			    $codici_client{$cliente}=$cliente_code;
			}
		    }
        	else{
		    $tipo=0;
		    while(($key,$value)=each(%codici_client)){
				$tipo=($value>$tipo)?$value:$tipo;
			    }
		    $cliente_code=$tipo+1;
		    $codici_client{$cliente}=$cliente_code;
		}		
	    }
	    if($tmp_array[$i]=~/size/){
		($ctrl,$size)=split(/=/,$tmp_array[$i],2);
		$size=substr($size,0,-1);	
		next;
	    }
	    if($tmp_array[$i]=~/class|pri|msgid/){next;}
	    if($tmp_array[$i]=~/nrcpts/){
		($ctrl,$num_rcpt)=split(/=/,$tmp_array[$i],2);
		$num_rcpt=substr($num_rcpt,0,-1);	
		next;
		}
	    if($tmp_array[$i]=~/proto/){
		($ctrl,$prot)=split(/=/,$tmp_array[$i],2);
		$prot=substr($prot,0,-1);
		next;
	       	}
	    if($tmp_array[$i]=~/relay/){
		($ctrl,$macchina)=split(/=/,$tmp_array[$i],2);
		if($macchina=~/localhost/){
		   #l'utente e' locale
		   # ($utente,$address)=split(/@/,$macchina,2);
		   # if($address=~/localhost/){
		    $macchina="localhost";
			$local=1;
		}
		$address=$macchina;
# ho l'indirizzo del cliente->devo trovargli un codice
	        if(exists($codici_macchina_host{$address})){
	        	if(defined($codici_macchina_host{$address})){
			    $address_code=$codici_macchina_host{$address};}
			else{
			    $tipo=0;
			    while(($key,$value)=each(%codici_macchina_host)){
				$tipo=($value>$tipo)?$value:$tipo;
			    }
			    $address_code=$tipo+1;
			    $codici_macchina_host{$address}=$address_code;
			}
		    }
        	else{
		    $tipo=0;
		    while(($key,$value)=each(%codici_macchina_host)){
				$tipo=($value>$tipo)?$value:$tipo;
			    }
		    $address_code=$tipo+1;
		    $codici_macchina_host{$address}=$address_code;
		}	
		
       	}
	}
   
    }
    else{
	if($line=~/stat=Sent/){
# preserva il qid precedente e raccogli tutte le informazioni relative a 
# questa entry dalle righe successive
	$ctrl_ciclo=2;
	if($tmp_array[3]=~/:{1,2}/){
	    $ref_tempo_out=data($tmp_array[0],$tmp_array[2],$tmp_array[3]);
	}
	else{
	    $ref_tempo_out=data($tmp_array[0],$tmp_array[1],$tmp_array[2]);
	}
	@time_logout=@$ref_tempo_out;
	for($y=0;$y<=$#tmp_array;$y++){
	    if($tmp_array[$y]=~/to/){next;}
	    if($tmp_array[$y]=~/^delay/){
#delay indica il tempo totale che il messaggio ha preso per essere mandato
#inserire controllo per verificare se esiste il +
		($ctrl,$tempo)=split(/=/,$tmp_array[$y],2);
		if($tempo=~/'+'/){
#ci ha impiegato piu' di 24 ore
		    ($day,$time)=split(/'+'/,$tempo);
		    $time=substr($time,0,-1);
		}
		else{
		    $time=substr($tempo,0,-1);
		    $day=0;
		}
		($hour,$min,$sec)=split(/:/,$time);
#calcolo il tempo impiegato in secondi
		$durata_trasmissione=(($day*86400)+($hour*3600)+($min*60)+$sec);
		next;
	    }
	    if($tmp_array[$y]=~/^xdelay/){
		($ctrl,$tempo_finale)=split(/=/,$tmp_array[$y]);
		$tempo_finale=substr($tempo_finale,0,-1);
		($hour,$min,$sec)=split(/:/,$tempo_finale);
#converto in secondi
		$durata_finale=(($hour*3600)+($min*60)+$sec);
		next;
	    }
	    if($tmp_array[$y]=~/^ctladdr/){next;}
	    if($tmp_array[$y]=~/mailer/){
		($ctrl,$mailer)=split(/=/,$tmp_array[$y]);
		$mailer=substr($mailer,0,-1);
		next;
	    }
	    if($tmp_array[$y]=~/relay/){next;}
	    if($tmp_array[$y]=~/stat/){
		($ctrl,$status)=split(/=/,$tmp_array[$y]);
		if($status=~/User|unknown/){next;}
		if(($status=~/Sent/)&&($y!=$#tmp_array)){
#l'utente e' remoto
		    $local=2;
		}
		if(($status=~/Sent/)&&($y==$#tmp_array)){
		    $local=1;
		}
	    }
	}
    }
	if($line=~/stat=queued/){
	    $linea_successiva=<>;
	    chomp($linea_successiva);
	    @prova=split(/ /,$linea_successiva);
	    if($prova[3]=~/:{1,2}/){
		$codice_qid=substr($prova[6],0,-1);
	    }
	    else{
		$codice_qid=substr($prova[5],0,-1);
	    }
	    $qid_interno1=0;
	    while($codice_qid ne $qid){
####################################################
# inserire copia esatta dei passaggi precedenti    #
####################################################
# $codice qid diventa il nuovo codice di test---------
		if(($linea_successiva=~/starting daemon|forward|runqueue|NOQUEUE|User unknown/)||($linea_successiva!~/sendmail/)){
		    $linea_successiva=<>;
		    chomp($linea_successiva);
		    @prova=split(/ /,$linea_successiva);
		    if($prova[3]=~/:{1,2}/){
			$codice_qid=substr($prova[6],0,-1);
		    }
		    else{
			$codice_qid=substr($prova[5],0,-1);
		    }
		}
		else{
		    if($codice_qid ne $qid_interno1){			    
                    #sono appena entrata
			$ctrl_ciclo=1;
			$ref_tempo=data($prova[0],$prova[1],$prova[2]);
			@login=@$ref_tempo;
			$host=$prova[3];
#controllo sul numero di spazi nella data
			if($host=~/:{1,2}/){
			    $ref_tempo=data($prova[0],$prova[2],$prova[3]);
			    @login=@$ref_tempo;
			    $host=$prova[4];
			}
#assegno un codice all'host e inserisco nella tavola
			if(exists($codici_hosts{$host})){
			    if(defined($codici_hosts{$host})){
				$hostcodice=$codici_hosts{$host};}
			    else{
				$tipo=0;
				while(($key,$value)=each(%codici_hosts)){
				    $tipo=($value>$tipo)?$value:$tipo;
				}
				$hostcodice=$tipo+1;
				$codici_hosts{$host}=$hostcodice;
			    }
			}
			else{
			    $tipo=0;
			    while(($key,$value)=each(%codici_hosts)){
				$tipo=($value>$tipo)?$value:$tipo;
			    }
			    $hostcodice=$tipo+1;
			    $codici_hosts{$host}=$hostcodice;
			}
#$host_code contiene il codice del l'host
#identifico il client
			for ($i=0;$i<=$#prova;$i++){
			    if($prova[$i]=~/from/){
# sistema il cliente:
# ci sono due possibili forme per questo campo:
# from=<user@indirizzo>,
# from=user,
				($ctrl,$user)=split(/=/,$prova[$i],2);
				if($user=~/<|>/){
				    if($user=~/\@/){
					($cliente,$indirizzo)=split(/\@/,$user,2);
					$cliente=substr($cliente,1);
				    }
				    else{
					$cliente=substr($user,1);
					$cliente=substr($cliente,0,-1);
				    }
				}
				else{
				    if($user=~/\@/){
					($cliente,$indirizzo)=split(/\@/,$user,2);
				    }
				    else{
					$cliente=substr($user,0,-1);
				    }
				}
# ho $cliente, devo trovargli un codice
				if(exists($codici_client{$cliente})){
				    if(defined($codici_client{$cliente})){
					$clientecodice=$codici_client{$cliente};}
				    else{
					$tipo=0;
					while(($key,$value)=each(%codici_client)){
					    $tipo=($value>$tipo)?$value:$tipo;
					}
					$clientecodice=$tipo+1;
					$codici_client{$cliente}=$clientecodice;
				    }
				}
				else{
				    $tipo=0;
				    while(($key,$value)=each(%codici_client)){
					$tipo=($value>$tipo)?$value:$tipo;
				    }
				    $clientecodice=$tipo+1;
				    $codici_client{$cliente}=$clientecodice;
				}		
			    }
			    if($prova[$i]=~/size/){
				($ctrl,$dim)=split(/=/,$prova[$i],2);
				$dim=substr($dim,0,-1);	
				next;
			    }
			    if($prova[$i]=~/class|pri|msgid/){next;}
			    if($prova[$i]=~/nrcpts/){
				($ctrl,$rcpt)=split(/=/,$prova[$i],2);
				$rcpt=substr($rcpt,0,-1);	
				next;
			    }
			    if($prova[$i]=~/proto/){
				($ctrl,$prot)=split(/=/,$prova[$i],2);
				$prot=substr($prot,0,-1);
				next;
			    }
			    if($prova[$i]=~/relay/){
				($ctrl,$macchina)=split(/=/,$prova[$i],2);
				if($macchina=~/localhost/){
				    $macchina="localhost";
				    $local=1;
				}
				$address=$macchina;
# ho l'indirizzo del cliente->devo trovargli un codice
				if(exists($codici_macchina_host{$address})){
				    if(defined($codici_macchina_host{$address})){
					$addresscode=$codici_macchina_host{$address};}
				    else{
					$tipo=0;
					while(($key,$value)=each(%codici_macchina_host)){
					    $tipo=($value>$tipo)?$value:$tipo;
					}
					$addresscode=$tipo+1;
					$codici_macchina_host{$address}=$addresscode;
				    }
				}
				else{
				    $tipo=0;
				    while(($key,$value)=each(%codici_macchina_host)){
					$tipo=($value>$tipo)?$value:$tipo;
				    }
				    $addresscode=$tipo+1;
				    $codici_macchina_host{$address}=$addresscode;
				}	
				
			    }
			}
			
		    }
		    else{
			if($linea_successiva=~/stat=Sent/){
# preserva il qid precedente e raccogli tutte le informazioni relative a 
# questa entry dalle righe successive
			    $ctrl_ciclo=2;
			    if($prova[3]=~/:{1,2}/){
				$ref_tempo_out=data($prova[0],$prova[2],$prova[3]);
			    }
			    else{
				$ref_tempo_out=data($prova[0],$prova[1],$prova[2]);
			    }
			    @time_logout=@$ref_tempo_out;
			    for($y=0;$y<=$#prova;$y++){
				if($prova[$y]=~/to/){next;}
				if($prova[$y]=~/^delay/){
#delay indica il tempo totale che il messaggio ha preso per essere mandato
#inserire controllo per verificare se esiste il +
				    ($ctrl,$tempo)=split(/=/,$prova[$y],2);
				    if($tempo=~/'+'/){
#ci ha impiegato piu' di 24 ore
					($day,$time)=split(/'+'/,$tempo);
					$time=substr($time,0,-1);
				    }
				    else{
					$time=substr($tempo,0,-1);
					$day=0;
				    }
				    ($hour,$min,$sec)=split(/:/,$time);
#calcolo il tempo impiegato in secondi
				    $durata_trasmissione=(($day*86400)+($hour*3600)+($min*60)+$sec);
				    next;
				}
				if($prova[$y]=~/^xdelay/){
				    ($ctrl,$tempo_finale)=split(/=/,$prova[$y]);
				    $tempo_finale=substr($tempo_finale,0,-1);
				    ($hour,$min,$sec)=split(/:/,$tempo_finale);
#converto in secondi
				    $durata_finale=(($hour*3600)+($min*60)+$sec);
				    next;
				}
				if($prova[$y]=~/^ctladdr/){next;}
				if($prova[$y]=~/mailer/){
				    ($ctrl,$mailer)=split(/=/,$prova[$y]);
				    $mailer=substr($mailer,0,-1);
				    next;
				}
				if($prova[$y]=~/relay/){next;}
				if($prova[$y]=~/stat/){
				    ($ctrl,$status)=split(/=/,$prova[$y]);
				    if($status=~/User|unknown/){next;}
				    if(($status=~/Sent/)&&($prova[$y+2]=~/^Message/)){
#l'utente e' remoto
					$local=2;
				    }
				    if(($status=~/Sent/)&&($y==$#prova)){
					$local=1;
				    }
				}
			    }
			}
		    }
		    #inserire aggiornamento sia del qid_interno, sia lettura della nuova riga per il test principale
		    @tmp=($clientecodice,$addresscode,@login,$prot,$hostcodice,$rcpt,$dim,@time_logout,$durata_trasmissione,$durata_finale,$mailer,$local);
		    if($ctrl_ciclo==2){
			for($ctf=0;$ctf<=$#tmp;$ctf++){
			    if($tmp[$ctf] eq ""){
				$tmp[$ctf]="*";
			    }
			}
			push @matrice,[@tmp];
			for($re=0;$re<=$#tmp;$re++){
			    print FILEOUTPUT "$tmp[$re] ";
			} 
			print FILEOUTPUT "\n";
			$prot="*";
			$ctrl_ciclo=0;
		    }		    
		    $qid_interno1=$codice_qid;
		    $linea_successiva=<>;
		    chomp($linea_successiva);
		    @prova=split(/ /,$linea_successiva);
		    if($prova[3]=~/:{1,2}/){
			$codice_qid=substr($prova[6],0,-1);
		    }
		    else{
			$codice_qid=substr($prova[5],0,-1);
		    }
		}		
	    }
	    if($linea_successiva=~/stat=Sent/){
# preserva il qid precedente e raccogli tutte le informazioni relative a 
# questa entry dalle righe successive
		$ctrl_ciclo=2;
		if($prova[3]=~/:{1,2}/){
		    $ref_tempo_out=data($prova[0],$prova[2],$prova[3]);
		}
		else{
		    $ref_tempo_out=data($prova[0],$prova[1],$prova[2]);
		}
		@time_logout=@$ref_tempo_out;
		for($y=0;$y<=$#prova;$y++){
		    if($prova[$y]=~/to/){next;}
		    if($prova[$y]=~/^delay/){
#delay indica il tempo totale che il messaggio ha preso per essere mandato
#inserire controllo per verificare se esiste il +
		($ctrl,$tempo)=split(/=/,$prova[$y],2);
		if($tempo=~/'+'/){
#ci ha impiegato piu' di 24 ore
		    ($day,$time)=split(/'+'/,$tempo);
		    $time=substr($time,0,-1);
		}
		else{
		    $time=substr($tempo,0,-1);
		    $day=0;
		}
		($hour,$min,$sec)=split(/:/,$time);
#calcolo il tempo impiegato in secondi
		$durata_trasmissione=(($day*86400)+($hour*3600)+($min*60)+$sec);
		next;
	    }
	    if($prova[$y]=~/^xdelay/){
		($ctrl,$tempo_finale)=split(/=/,$prova[$y]);
		$tempo_finale=substr($tempo_finale,0,-1);
		($hour,$min,$sec)=split(/:/,$tempo_finale);
#converto in secondi
		$durata_finale=(($hour*3600)+($min*60)+$sec);
		next;
	    }
	    if($prova[$y]=~/^ctladdr/){next;}
	    if($prova[$y]=~/mailer/){
		($ctrl,$mailer)=split(/=/,$prova[$y]);
		$mailer=substr($mailer,0,-1);
		next;
	    }
	    if($prova[$y]=~/relay/){next;}
	    if($prova[$y]=~/stat/){
		($ctrl,$status)=split(/=/,$prova[$y]);
		if($status=~/User|unknown/){next;}
		if(($status=~/Sent/)&&($prova[$y+2]=~/^Message/)){
#l'utente e' remoto
		    $local=2;
		}
		if(($status=~/Sent/)&&($y==$#prova)){
		    $local=1;
		}
	    }
	}
       }
	}
    }
 @tmp=($cliente_code,$address_code,@time_login,$prot,$host_code,$num_rcpt,$size,@time_logout,$durata_trasmissione,$durata_finale,$mailer,$local);
    if($ctrl_ciclo==2){
	for($ctf=0;$ctf<=$#tmp;$ctf++){
	    if($tmp[$ctf] eq ""){
		$tmp[$ctf]="*";
	    }
	}
	push @matrice,[@tmp];
	for($re=0;$re<=$#tmp;$re++){
	    print FILEOUTPUT "$tmp[$re] ";
	} 
	print FILEOUTPUT "\n";
###########################################
	$prot="*";
	$ctrl_ciclo=0;
	$linea_successiva=$line;
###########################################
    }
    $qid=$nuovo_qid;

}

close(FILEOUTPUT);
# riscrivo sui files le hash->per consistenza
open(FILECODICI,">codici_hosts");
while(($key,$value)=each(%codici_hosts)){
    print FILECODICI "$key $value\n";
}
close(FILECODICI);
open(CODICICLIENTI,">codici_clients");
while(($key,$value)=each(%codici_client)){
    print CODICICLIENTI "$key $value\n";
}
close(CODICICLIENTI);
open(FILECODICIMACCH,">codici_macchina");
while(($key,$value)=each(%codici_macchina_host)){
    print FILECODICIMACCH "$key $value\n";
}
close(FILECODICIMACCH);
#-------------------------------------------------------------------------
#subroutine per calcolare la data e sistemarla: argomenti sono
#    - primo campo del vettore $tmp_array->mese
#    - secondo campo dello stesso->giorno
#    - terzo campo->tempo
#-------------------------------------------------------------------------

sub data(\$\$\$){
    my ($mese,$giorno,$tempo)=($_[0],$_[1],$_[2]);
#sistemo i mesi

  SWITCH:{
    if($mese eq "Jan"){$mese="00";last SWITCH;}
    if($mese eq "Feb"){$mese="01";last SWITCH;}
    if($mese eq "Mar"){$mese="02";last SWITCH;}
    if($mese eq "Apr"){$mese="03";last SWITCH;}
    if($mese eq "May"){$mese="04";last SWITCH;}
    if($mese eq "Jun"){$mese="05";last SWITCH;}
    if($mese eq "Jul"){$mese="06";last SWITCH;}
    if($mese eq "Aug"){$mese="07";last SWITCH;}
    if($mese eq "Sep"){$mese="08";last SWITCH;}
    if($mese eq "Oct"){$mese="09";last SWITCH;}
    if($mese eq "Nov"){$mese="10";last SWITCH;}
    if($mese eq "Dec"){$mese="11";last SWITCH;}
  }
#sistemo i giorni
  SWITCH1:{
    if ($giorno eq "1"){$giorno="01";last SWITCH1;}
    if ($giorno eq "2"){$giorno="02";last SWITCH1;}
    if ($giorno eq "3"){$giorno="03";last SWITCH1;}
    if ($giorno eq "4"){$giorno="04";last SWITCH1;}
    if ($giorno eq "5"){$giorno="05";last SWITCH1;}
    if ($giorno eq "6"){$giorno="06";last SWITCH1;}
    if ($giorno eq "7"){$giorno="07";last SWITCH1;}
    if ($giorno eq "8"){$giorno="08";last SWITCH1;}
    if ($giorno eq "9"){$giorno="09";last SWITCH1;}
   }
#definisco la variabile per i tempi
   my @time=($giorno,$mese,$tempo);
   my $ref=\@time; 
   return $ref;
}	    
