--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exim-exigrey.pl Tue Jan 02 15:23:46 2007 +0000
@@ -0,0 +1,91 @@
+# © 2006,2007 Heiko Schlittermann <hs@schlittermann.de>
+# $Id$
+# $URL$
+
+use strict;
+use warnings;
+use BerkeleyDB;
+
+my %DEFAULT = (
+ delay => 600,
+ db => "seen.db",
+);
+
+sub unseen($;$$);
+
+sub getDBDir();
+sub findExim(;$);
+sub getDefault() { %DEFAULT };
+
+# Usage:
+# ${perl{unseen}{$sender_host_address}}
+# ${perl{unseen}{$sender_host_address}{600}}
+# ${perl{unseen}{$sender_host_address}{600}{seen.db}}
+# ${perl{unseen}{$sender_host_address}{600}{/some/dir/seen.db}}
+#
+# record structure: key: item\0
+# value: timestamp(creation) timestamp(usage)\0
+# (This way we're compatible with ${lookup{...}dbm{...}})
+sub unseen($;$$) {
+ my ($item, $delay, $db) = @_;
+ $item .= "\0";
+ $delay = $DEFAULT{delay} unless defined $delay;
+ $db = $DEFAULT{db} unless defined $db;
+
+ my $now = time();
+ my $umask;
+ my $rc;
+
+ $db = getDBDir() . "/$db" unless $db =~ /^\//;
+
+ $umask = umask 0077 if !-f $db;
+
+ my %h; tie %h, "BerkeleyDB::Hash",
+ -Filename => $db,
+ -Flags => DB_CREATE
+ or die;
+
+ umask $umask if defined $umask;
+
+ if (not exists $h{$item}) {
+ $h{$item} = "$now $now\0";
+ $rc = "yes";
+ } else {
+ my $created = (split " ", $h{$item})[0];
+ if ($now - $created < $delay) { $rc = "yes" }
+ else {
+ $rc = "no";
+ $h{$item} = "$created $now\0";
+ }
+ }
+ untie %h;
+ return $rc;
+}
+
+# Get the directory where we could store the database file(s)
+# If we're running under exim it's easy, otherwise we've to find exim
+# and then ask...
+sub getDBDir() {
+ my $spooldir;
+ eval { $spooldir = Exim::expand_string('$spool_directory') };
+ if (not defined $spooldir) {
+ my $exim = findExim();
+ chomp($spooldir = `$exim -be '\$spool_directory'`);
+ die "Can't find spooldir" if not defined $spooldir;
+ }
+ return "$spooldir/db";
+}
+
+sub findExim(;$) {
+ my $path = shift || $ENV{PATH};
+ my $exim;
+ foreach (split /:/, $ENV{PATH}) {
+ -x ($exim = "$_/exim") and return $exim;
+ -x ($exim = "$_/exim4") and return $exim;
+ }
+ return undef;
+}
+
+1;
+
+# vim:aw: