#!/usr/bin/perl # License # GPLv2 (http://www.gnu.org/licenses/gpl-2.0.txt) # Authors # DELAPORTE Antoine # Versions # 1.0 Make a first script who just transform the result of mailq # in a one line per mail # 2.0 Add hability to read mail data from postcat (from,to,subject,date) # 2.1 Add filtering options (from && to) # 2.2 Add --delete and --hold option # 2.3 Add first smtp server sender (and filtering) # 2.4 Add Help # 2.5 Add --stat options (who print information by from,to,smtp) # TODO: for stat option try to give msgid # cleaning the code, (variable name, frenglish, key hash name cf 'From: ') # adding an option to give information from logs # maybe add an option to do the postcat -q msgid ? use strict; use warnings; use Data::Dumper; use Getopt::Long; sub trait1msqid { my ($id,$tab,$del,$hol)=@_; print $id.";".$$tab{"Received"}.";".$$tab{"From: "}.";".$$tab{"To: "}.";".$$tab{"Date: "}.";".$$tab{"Subject: "}."\n"; if( (defined($del) and open(FR,"/usr/sbin/postsuper -d $id 2>/dev/null |")) or(defined($hol) and open(FR,"/usr/sbin/postsuper -h $id 2>/dev/null |")) ) { while() {} close(FR); } } sub getheader { my ($ret,$msgid,@toget)=@_; my $cont=1; my $totest; my $ligne; $$ret{Received}=""; if(open(FR,"/usr/sbin/postcat -q $msgid 2>/dev/null |")) { while($cont and $ligne=) { if($ligne =~ /^$/) { $cont=0; } elsif($ligne =~ /^Received: from / and !($ligne =~ /localhost/)) { chomp($ligne); $ligne=~ s/^Received: from //g; $$ret{Received}=$ligne; } else { foreach $totest (@toget) { if($ligne =~ /^$totest/ and !defined($$ret{$totest})) { chomp($ligne); $ligne=~ s/^$totest//g; $$ret{$totest}=$ligne; } } } } close(FR); } foreach(@toget) { if(!defined($$ret{$_})) { $$ret{$_}=""; } } } sub testheader { my ($regex,$chaine)=@_; my $ret; if(defined($regex)) { if($chaine =~ /$regex/i) { $ret=1; } else { $ret=0; } } else { $ret=1; } return($ret); } sub dossomstat { my ($res,$id,$val)=@_; my $filtre; foreach $filtre (("Received","To: ","From: ")) { if(defined($$val{$filtre})) { # FIXME Coder l'integration des msgID if(!defined($$res{$filtre}{$$val{$filtre}}{Nb})) { $$res{$filtre}{$$val{$filtre}}{Nb}=1; } else { $$res{$filtre}{$$val{$filtre}}{Nb}++; } } } } open(MQ,"mailq 2>/dev/null |") or die "Impossible d'ouvrir la mailq...\n"; my $precline=; $precline=""; my %tab; my $id; my @null; my %cou; my %resstat; my ($stat,$help,$SMTP,$FoT,$From,$To); my ($actdel,$acthol); GetOptions('Stat' => \$stat,'help' =>\$help,'SMTP=s'=> \$SMTP, 'FromOrTo=s' => \$FoT, 'From=s' => \$From, 'To=s' => \$To, 'Delete' => \$actdel, 'Hold' => \$acthol ); if(defined($actdel) and defined($acthol)) { print "Options incompatibles\n\n"; $help=1; } elsif((defined($actdel) or defined($acthol)) and !(defined($From) or defined($To) or defined($SMTP))) { print "On ne peux holder ou deleter sans filtre\n\n"; $help=1; } if($help) { print "Fonctions disponibles: ./mailqon1line [--SMTP ] [--FromOrTo |[--From |& --To ] [--Delete || --Hold] --SMTP %s : Recherche les serveur SMTP emetteur --FromOrTo %s : Recheche dans le champs email from ou to --From %s : Recheche dans le champs email from --To %s : Recheche dans le champs email to --Delete : Supprime le mail de la mailq --Hold : Met dans la queue d'attente --Stat : Ne renvoie des statistiques sur les memes filtres (desactive les options hold et delete) "; exit(); } while() { chomp(); if(!/^--/) { tr/\t / /s; s/\*//g; if($precline eq "" and $_ ne "") { #On va commencer une nouvelle ligne ($id,@null)=split(/ /,$_,2); $tab{$id}{mq}=$_; } $tab{$id}{mq}.=$_; $precline=$_; } } close(MQ); foreach $id (keys(%tab)) { getheader($tab{$id},$id,("From: ","To: ","Date: ","Subject: ")); } if(defined($FoT)) { $From=$FoT; $To=$FoT; } # eviter la double boucle qui est inutil et ralenti trop l'affichage # surtout en cas de queue de messageries trop pleines foreach $id (keys(%tab)) { $cou{from}=testheader($From,$tab{$id}{"From: "}); $cou{to}=testheader($To,$tab{$id}{"To: "}); $cou{smtp}=testheader($SMTP,$tab{$id}{"Received"}); if($cou{smtp}) { # la recherche sur un champs non defini renvoie toujours ok if(defined($FoT)) { if($cou{from} or $cou{to}) { if($stat) { dossomstat(\%resstat,$id,$tab{$id}); } else { trait1msqid($id,$tab{$id},$actdel,$acthol); } } } elsif($cou{from} and $cou{to}) { if($stat) { dossomstat(\%resstat,$id,$tab{$id}); } else { trait1msqid($id,$tab{$id},$actdel,$acthol); } } } } if($stat) { foreach my $filtre (keys(%resstat)) { foreach my $val (keys($resstat{$filtre})) { print "$filtre;$val;".$resstat{$filtre}{$val}{Nb}."\n"; } } }