Mike,

> After updating perl on my netbsd system, I encountered the same issue
> with amavis indicating that Compress::Zlib was missing.  The error
> message is somewhat misleading. The module exists, it just fails to load.

Right. I encountered such problems in the past. My simple attempt
to produce a more informative diagnostics resulted in two lines
in sub fetch_modules:

  printf STDERR ("fetch_modules: error loading module %s :\n%s\n", $_,
                 join("\n", map {"> $_"} split(/\n/,$eval_stat)));

(or its variants) which I had to comment out, as it was either
too chatty or failed to report relevant problem, like a module file
being too strongly protected, so it was useless.

The original sin is in a perl's "require", which treats inaccessible
files the same as missing files.

To do it right, a better alternative to 'require' is needed.

So here it is - a patch to amavisd (2.5.2) to produce a more
meaningful diagnostics in case of compile errors in modules,
or module files not being accessible. I'd be interested in a
feedback if this is a viable solution for half-screwed systems -
- for example in case of having two instances of a module in
an @INC path and one of them is broken, my solution produces a
proper diagnostics, while originally the broken module is ignored.

--- amavisd.orig        Wed Jun 27 12:43:00 2007
+++ amavisd     Thu Nov 15 21:29:51 2007
@@ -121,4 +121,47 @@
 use strict;
 use re 'taint';
+use Errno qw(ENOENT EACCES);
+
+# replacement for a 'require' with a more informative error handling
+sub my_require($) {
+  my($filename) = @_;
+  my($result);
+  if (exists $INC{$filename} && !$INC{$filename}) {
+    die "Compilation failed in require\n";
+  } elsif (exists $INC{$filename}) {
+    $result = 1;  # already loaded
+  } else {
+    my($found) = 0;
+    for my $prefix (@INC) {
+      my($full_fname) = "$prefix/$filename";
+      my($errn) = stat($full_fname) ? 0 : 0+$!;  # symlinks-friendly
+      if ($errn != ENOENT) {
+        $INC{$filename} = $full_fname;  $found = 1;  my($msg);
+        if ($errn)         { $msg = "is inaccessible: $!" }
+        elsif (-d _)       { $msg = "is a directory" }
+        elsif (!-f _)      { $msg = "is not a regular file" }
+        elsif ($> && -o _) { $msg = "should not be owned by EUID $>"}
+        elsif ($> && -w _) { $msg = "is writable by EUID $>, EGID $)" }
+        if (defined $msg)  { die "Requiring $full_fname, file $msg,\n" }
+        $! = 0;
+        $result = do $full_fname;
+        if (!defined($result) && $@ ne '') {
+          undef $INC{$filename}; chomp($@);
+          die "Error in file $full_fname: [EMAIL PROTECTED]";
+        } elsif (!defined($result) && $! != 0) {
+          undef $INC{$filename};
+          die "Error reading file $full_fname: $!\n";
+        } elsif (!$result) {
+          undef $INC{$filename};
+          die "Module $full_fname did not return a true value\n";
+        }
+        last;
+      }
+    }
+    die sprintf("my_require: Can't locate %s in [EMAIL PROTECTED] ([EMAIL 
PROTECTED] contains: %s)\n",
+                $filename, join(' ',@INC))  if !$found;
+  }
+  $result;
+}
 
 # Fetch all required modules (or nicely report missing ones), and compile them
@@ -137,10 +180,12 @@
     $_ .= /^auto::/ ? '.al' : '.pm'  if !m{^/} && !m{\.(pm|pl|al|ix)\z};
     s{::}{/}g;
-    eval { require $_ }
+    eval { my_require $_ }
     or do {
       my($eval_stat) = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
       push(@missing,$m);
-    # printf STDERR ("fetch_modules: error loading module %s :\n%s\n", $_,
-    #                join("\n", map {"> $_"} split(/\n/,$eval_stat)));
+      printf STDERR ("fetch_modules: error loading %s module %s:\n%s\n",
+                     $required ? 'required' : 'optional',  $_,
+                     join("\n", map {"  $_"} split(/\n/,$eval_stat)))
+        if $eval_stat !~ /\bCan't locate \S* in [EMAIL PROTECTED]/;
     };
     if ($have_sawampersand && !$amp && Devel::SawAmpersand::sawampersand())


Mark

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
AMaViS-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/amavis-user
AMaViS-FAQ:http://www.amavis.org/amavis-faq.php3
AMaViS-HowTos:http://www.amavis.org/howto/

Reply via email to