-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I have patched the greylist plugin to use File::NFSLock when given an
option 'nfslock => 1'.  It seems to work fine on our systems.  The patch
is attached.

It was made against the svn version linked from the wiki.  that version
says it is 0.7.  Probably should change version if applying the patch?

- --
JT Moree
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFtQWoFI6sVJUR1B8RAlCpAJ9n5dqR3Lc4ESQx5nxWymToMThI2gCdHuww
UFM6eOvbYZIbTmAT4xla+SE=
=HNc8
-----END PGP SIGNATURE-----
--- greylisting.svn     2007-01-22 11:03:56.000000000 -0700
+++ greylisting.svn-nfslock     2007-01-22 11:38:27.000000000 -0700
@@ -87,6 +87,11 @@
 Flag to indicate whether to use per-recipient greylisting 
 databases (default is to use a shared database).
 
+=item nfslock <bool>
+
+Flag to indicate that the database is stored on NFS.  Will use
+File::NFSLock instead of flock.
+
 =back
 
 =head1 BUGS
@@ -95,15 +100,18 @@
 network filesystems e.g. NFS. If this is a problem, you may want to
 use something like File::NFSLock instead.
 
+JT: I implemented a switch that will use NFSLock.  Seems to work fine.
+
 =head1 AUTHOR
 
 Written by Gavin Carr <[EMAIL PROTECTED]>.
+nfslock feature added by JT Moree <[EMAIL PROTECTED]>
 
 =cut
 
 BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) }
 use AnyDBM_File;
-use Fcntl qw(:DEFAULT :flock);
+use Fcntl qw(:DEFAULT :flock LOCK_EX LOCK_NB);
 use strict;
 
 my $VERSION = '0.07';
@@ -121,6 +129,7 @@
   grey_timeout =>  3 * 3600 + 20 * 60,
   white_timeout => 36 * 24 * 3600,
   mode => 'denysoft',
+  nfslock => 0,
 );
 
 sub register {
@@ -180,6 +189,7 @@
 
 sub denysoft_greylist {
   my ($self, $transaction, $sender, $rcpt, $config) = @_;
+  my $nfslock;  #this will go out of scope and remove the lock
   $config ||= $self->{_greylist_config};
   $self->log(LOGDEBUG, "config: " . join(',',map { $_ . '=' . $config->{$_} } 
sort keys %$config));
 
@@ -198,15 +208,34 @@
   my $remote_ip = $self->qp->connection->remote_ip;
   my $fmt = "%s:%d:%d:%d";
 
-  # Check denysoft db
-  unless (open LOCK, ">$db.lock") {
-    $self->log(LOGCRIT, "opening lockfile failed: $!");
-    return DECLINED;
+  if ($config->{nfslock}) {
+    require File::NFSLock;
+    ### set up a lock - lasts until object looses scope
+    unless ($nfslock = new File::NFSLock {
+      file      => "$db.lock",
+      lock_type => LOCK_EX|LOCK_NB,
+      blocking_timeout   => 10,      # 10 sec
+      stale_lock_timeout => 30 * 60, # 30 min
+    }) {
+      $self->log(LOGCRIT, "nfs lockfile failed: $!");
+      return DECLINED;
+    }
+    unless (open(LOCK, "+<$db.lock")) {
+      $self->log(LOGCRIT, "opening nfs lockfile failed: $!");
+      return DECLINED;
+    }
   }
-  unless (flock LOCK, LOCK_EX) {
-    $self->log(LOGCRIT, "flock of lockfile failed: $!");
-    close LOCK;
-    return DECLINED;
+  else {
+    # Check denysoft db
+    unless (open LOCK, ">$db.lock") {
+      $self->log(LOGCRIT, "opening lockfile failed: $!");
+      return DECLINED;
+    }
+    unless (flock LOCK, LOCK_EX) {
+      $self->log(LOGCRIT, "flock of lockfile failed: $!");
+      close LOCK;
+      return DECLINED;
+    }
   }
   my %db = ();
   unless (tie %db, 'AnyDBM_File', $db, O_CREAT|O_RDWR, 0600) {

Reply via email to