Skip to content

Instantly share code, notes, and snippets.

@moisseev
Last active August 29, 2015 14:22
Show Gist options
  • Save moisseev/7bb447af528725040763 to your computer and use it in GitHub Desktop.
Save moisseev/7bb447af528725040763 to your computer and use it in GitHub Desktop.
Retrieve the last login and login count of each email account from maillog (courier-imap + postfix)
#!/usr/local/bin/perl -w
#============================================================= -*-perl-*-
# courier-imap_postfix_last-login.pl
#========================================================================
# Version 0.0.1, 2015-06-04
#========================================================================
# Parsing is possible only for one year at time due to syslog date/time format limitation.
# The current year is hardcoded in the script.
use strict;
use Time::Local;
use POSIX qw(strftime);
my $logDir = '/var/log';
# Jun 4 15:15:40 hostname imapd: LOGIN, [email protected], ip=[::1], port=[43029], protocol=IMAP
# Jun 4 15:15:46 hostname pop3d: LOGIN, [email protected], ip=[::ffff:127.0.0.238], port=[15226]
my $REcourierLOGIN =
qr/^((\w{3})\s+(\d+) (\d{2}):(\d{2}):(\d{2})) \S+ (\S+): LOGIN, user=([^,]+),/;
# Jun 3 17:46:46 hostname postfix/smtpd[739497]: 9E9721E40254: client=127-0-0-2.example.com[127.0.0.2], sasl_method=LOGIN, [email protected]
# Jun 4 00:00:02 hostname postfix/smtpd[999616]: 7F3D91E40254: client=unknown[127.0.0.6], sasl_method=LOGIN, [email protected]
my $REpostfixSASL =
qr/^((\w{3})\s+(\d+) (\d{2}):(\d{2}):(\d{2})) \S+ postfix\/(\S+)\[\d+\]: [[:xdigit:]]+: client=[^,]+, sasl_method=[^,]+, sasl_username=(.+)$/;
my $currentYear = strftime "%Y", localtime(time);
my $filename = "-name maillog-$currentYear* ! -name maillog-${currentYear}01* -o -name maillog";
my %lastAccess;
my %month = (
Jan => 1,
Feb => 2,
Mar => 3,
Apr => 4,
May => 5,
Jun => 6,
Jul => 7,
Aug => 8,
Sep => 9,
Oct => 10,
Nov => 11,
Dec => 12,
);
open( LIST, "find $logDir $filename | sort |" )
or die("Cannot fetch filelist: $!\n");
foreach my $file (<LIST>) {
my $counter = 0;
chomp $file;
print "Processing $file ... ";
open( MAILLOG, "zcat -f $file|" )
or die("Cannot open $0: $!\n");
while (<MAILLOG>) {
( index( $_, ': LOGIN, ' ) == -1 )
&& ( index( $_, ', sasl_username=' ) == -1 )
&& next;
if ( /$REcourierLOGIN/ || /$REpostfixSASL/ ) {
my $epoch =
timelocal( $6, $5, $4, $3, $month{$2} - 1, $currentYear );
if ( !defined( $lastAccess{$8}{'epoch'} )
|| $epoch > $lastAccess{$8}{'epoch'} )
{
$lastAccess{$8}{'time'} = $1;
$lastAccess{$8}{'epoch'} = $epoch;
}
$lastAccess{$8}{'count'}++;
$lastAccess{$8}{'service'}{$7}++;
$counter++;
#print 'U';
}
}
close(MAILLOG);
print "matches: $counter\n";
}
close(LIST);
printf "\n%30s | %16s | %6s\n", "E-mail account", "Last access time",
"Access count";
my $i = 77;
while ( $i-- ) { print "-" }
print "\n";
map {
printf "%30s | %16s | %6d (",
$_, $lastAccess{$_}{'time'}, $lastAccess{$_}{'count'};
my $time = $_;
map { print " $_=$lastAccess{$time}{'service'}{$_}"; }
sort keys %{ $lastAccess{$_}{'service'} };
print " )\n";
#my $epochTime = strftime "%b %e %H:%M:%S", localtime($lastAccess{$_}{'epoch'});
#print $epochTime, "\n";
} sort keys %lastAccess;
beep();
exit;
sub beep {
my $i = 0;
$| = 1;
while ( $i++ <= 2 ) { print "\a"; system("sleep .12"); }
print "\a";
$| = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment