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/