HEX
Server: Apache/2.4.41 (FreeBSD) OpenSSL/1.0.2s mod_fcgid/2.3.9
System: FreeBSD salazo 12.0-RELEASE-p1303-ZFS hostBSD 12.0-RELEASE-p1303-ZFS DMR amd64
User: admin (1000)
PHP: 7.4.3
Disabled: NONE
Upload Files
File: /usr/local/www/apache24/cgi-bin/easytecc4/mailstats.pl
#!/usr/iports/bin/perl

BEGIN {
	if(-e '/etc/sudoers'){
		
		my $osversion = `/usr/bin/uname -K`;
		chomp $osversion;
		
		my $perl;
		
		if($osversion >= 1300000){
			
			$perl = '5.34';
		
		} elsif($osversion >= 1200000){
			
			$perl = '5.26';
		
		} elsif($osversion >= 1003000){
			
			$perl = '5.24';

		} else {
			
			$perl = '5.20';
			
		}
		
		@INC = (
				"/usr/iports/lib/perl5/site_perl",
				"/usr/iports/lib/perl5/amd64-freebsd-thread-multi",
				"/usr/iports/lib/perl5/$perl",
				"/usr/iports/lib/perl5/$perl/mach",
				"/usr/iports/lib/perl5/site_perl/mach/$perl",
				"/usr/local/lib/perl5/site_perl",
				"/usr/local/lib/perl5/amd64-freebsd-thread-multi",
				"/usr/local/lib/perl5/$perl",
				"/usr/local/lib/perl5/$perl/mach",
				"/usr/local/lib/perl5/site_perl/mach/$perl",
				"/usr/local/www/apache24/cgi-bin/easytecc4"
		);
				
			
	} else {
		push @INC, '/home/httpd/cgi-bin/easytecc4';
	}
}

use strict;
use warnings;
use diagnostics;

sub usage {
	print STDERR "usage:\n$0 [[mail@]domain.tld]\n";
	exit(1);
}

if(scalar @ARGV > 1){
	usage();
}
my $param=$ARGV[0];

my $doveadm='/usr/sbin/doveadm';

if(!defined($doveadm) || ! -f $doveadm){
	print STDERR "$0: doveadm executable not found\n";
	exit(1);
}
$doveadm = "/usr/iports/bin/sudo $doveadm";

use constant {
	ALL => 0,
	DOMAIN => 1,
	USER => 2
};

my $query_type = ALL;
my $doveadm_user_param = '-A';

my $user;
my $localpart;
my $domain;

if(defined($param)){
	if($param =~ m/^([^\@]+)\@([^\@]+)$/){
		$query_type = USER;
		$user = $param;
		$doveadm_user_param = "-u '$user'";
		$localpart = $1;
		$domain = $2;
	} else {
		$query_type = DOMAIN;
		$domain = $param;
		$doveadm_user_param = "-u '*\@$domain'";
	}
}

my $stats = `$doveadm -f tab mailbox status $doveadm_user_param 'messages unseen vsize guid' '*' 2>/dev/null`;
chomp $stats;
my @stats = split(/\n/,$stats);
shift @stats;

my %stats;
my $boxstats;
my @boxstats;
my $box;
my $guid;
my $spam;

use constant {
	MESSAGES => 0,
	UNSEEN => 1,
	VSIZE => 2,
	SPAM => 3
};

foreach $boxstats (@stats){

	@boxstats = split(/\t/,$boxstats);

	if($query_type != USER){
		$user = shift @boxstats;
	
		if($query_type == ALL){
			($localpart,$domain) = $user =~ m/^([^\@]+)\@([^\@]+)$/;
		} else {
			$localpart = $user;
			$localpart =~ s/\@[^\@]+$//;
		}
	}

	$guid = pop @boxstats;	
	$box = shift @boxstats;
	$box .= '(' . $guid . ')';

	$spam = `$doveadm -f flow search -u '$user' mailbox-guid '$guid' HEADER X-Spam-Flag YES 2>/dev/null`;
	chomp $spam;
	$spam = scalar split(/\n/,$spam);
	push @boxstats, $spam;

	$stats{$domain}{$localpart}{$box} = [ @boxstats ];

	for (MESSAGES,UNSEEN,VSIZE,SPAM){
		$stats{$domain}{$localpart}{'*'}[$_] += $boxstats[$_];

		if($query_type != USER){
			$stats{$domain}{'*'}{'*'}[$_] += $boxstats[$_];

			if($query_type != DOMAIN){
				$stats{'*'}{'*'}{'*'}[$_] += $boxstats[$_];
			}
		}
	}
						
}

sub sort_by_wildcard {
	$a eq '*' ? $b eq '*' ? 0 : 1 : $b eq '*' ? -1 : $a cmp $b;
}	

foreach $domain (sort sort_by_wildcard keys %stats){

	foreach $localpart (sort sort_by_wildcard keys %{$stats{$domain}}){

		foreach $box (sort sort_by_wildcard keys %{$stats{$domain}{$localpart}}){

			@boxstats = @{$stats{$domain}{$localpart}{$box}};
			print "$localpart\@$domain/$box messages=$boxstats[MESSAGES] unseen=$boxstats[UNSEEN] spam=$boxstats[SPAM] vsize=$boxstats[VSIZE]\n";

		}
	
	}

}

exit(0);