#!/usr/bin/perl -w

#David Luyer <david_luyer@pacific.net.au> provides us with a similar
#script in perl. Its attached. Run from /var/spool with $files = `echo mail/*`
#or $files = result of building list from grep.  No forks, execs, etc, etc,
#so it can be run over a few hundred thousand mailboxes without too much pain,
#although the locking is very ugly and doesn't actually test the lock.

# Additional code, dies etc. Dobrica Pavlinusic <dpavlin@rot13.org>

# pipe list of mailboxes to this script!!!
# eg. find /var/spool/mail | fix.pl | tee stat

$virusremoved = 0;
$mboxes = 0;

$|=1;	# don't buffer

while(<>) {
	chomp;
	$file=$_;
	next if (-d "$file");	# skip dirs
	print STDERR "$file";
	$mboxes++;
	$msg = "";
	$isvirus = 0;
	$isnotvirus = 0;
	open (TMP, ">$file.lock") || die "lock: $!";
	close (TMP);
	(undef,undef,$mode,undef,$uid,$gid,undef,undef,$atime,$mtime) = stat($file);
	rename ("$file", "$file.TMP-RM-VIRUS") || die "rename: $!";
	open (FILEOLD, "<$file.TMP-RM-VIRUS") || die "old: $!";
	open (FILENEW, ">$file") || die "new: $!";
	while (<FILEOLD>) {
		if (/^From /) {
			if (!$isvirus) {
				print FILENEW $msg;
			} else {
				$virusremoved++;
				print STDERR " $virusremoved";
				$infected{$file}++;
			}
			$msg = "";
			$isvirus = 0;
			$isnotvirus = 0;
		}
		$msg .= $_;
		if (/^$/ && !$isvirus) {
			$isnotvirus++;
		}
		if (/^Subject: fwd: Joke$/) {
			$isvirus++ if (!$isnotvirus);
		}
	}

	print FILENEW $msg if (!$isvirus);
	$virusremoved++ if ($isvirus);
	$msg = "";
	$isvirus = 0;
	$isnotvirus = 0;
	close (FILEOLD);
	close (FILENEW);
	unlink("$file.TMP-RM-VIRUS") || die "unlink: $!";
	unlink("$file.lock") || die "unlock: $!";
	chown $uid, $gid, $file || die "chown: $!";
	chmod $mode, $file || die "chmod: $!";
	utime $atime, $mtime, $file || die "utime: $!";
	print STDERR "\n";
}

print "stat: $mboxes mailboxes, $virusremoved viruses found\n";
foreach $k (keys %infected) {
	print "$k $infected{$k}|";
}
