This script was written in a week of work experience, and this is as far as it got. It works, but is horrifically slow.
Code:
#!/usr/bin/perl
use strict;
use warnings;
use Text::Wrap;
my $target = $ARGV[0];
die "Usage: $0 <target to search for>\n" unless $target;
die "Must run as user zimbra\n" if $> != 1001;
mkdir $target;
chmod 0755, $target;
my @emails;
open ACCTS, "zmaccts|";
for (<ACCTS>) {
last if /domain summary/;
next if /^-|account|^$/;
my @words = split /\s+/;
push @emails, $words[0];
}
my @msgs;
for my $addr (@emails) {
open SEARCH, "zmmailbox -z -m $addr s \"from:$target OR to:$target\"|";
while (my $line = <SEARCH>) {
next unless $line =~ /^\d+\./;
# get rid of meaningless rubbish at start of line
$line =~ s/\d+\.\s+(-?\d+)\s+conv\s+//;
open CONV, "zmmailbox -z -m $addr gc $1|";
while (my $msgline = <CONV>) {
next unless $msgline =~ /^\d+\.\s+(\d+)/;
my $mailmsg = `zmmailbox -z -m $addr gm $1`;
push @msgs, $mailmsg;
}
}
}
# remove dupes from @msgs
my %temp = map { $_, 1 } @msgs;
@msgs = sort keys %temp;
open OUTCACHE, "> $target.cache";
print OUTCACHE <<EOF;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Emails involving $target</target>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Emails sent/received by $target</h1>
<table border="1">
<tr>
<th>From</th>
<th>To</th>
<th>Subject</th>
<th>Time</th>
</tr>
EOF
my %dates_seen;
for (@msgs) {
next if exists $dates_seen{$_};
$dates_seen{$_}++;
my ($date, $from, $to, $subject, $id);
for (lines($_)) {
$subject = $1 and last if /^Subject: (.*)/;
}
for (lines($_)) {
$date = $1 and last if /^Sent: (.*)/;
}
for (lines($_)) {
$from = $1 and last if /^From: (.*)/;
}
for (lines($_)) {
$to = $1 and last if /^To: (.*)/;
}
for (lines($_)) {
$id = $1 and last if /^Id: (.*)/;
}
print OUTCACHE <<EOF;
<tr>
<td>$from</td>
<td>$to</td>
<td><a href="$target/$id">$subject</a></td>
<td>$date</td>
</tr>
EOF
s/^Id: |^Conversation-Id: |^Flags: |^Folder: |^Size//;
open MSG, "> $target/$id";
print MSG wrap("", "", $_);
}
print OUTCACHE <<EOF;
</table>
</body>
</html>
EOF
sub lines {
local $_ = shift;
return split /\n/;
} I also wrote a bit of PHP to display the results:
Code:
<?php
$addr = $_REQUEST['email'];
if (!$addr) {
exit(1);
}
$filename = $addr . ".cache";
if (file_exists($filename)) {
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;
}
?>