You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@spamassassin.apache.org by Justin Mason <jm...@jmason.org> on 2004/04/15 23:19:08 UTC
Re: svn commit: rev 10033 - in incubator/spamassassin/trunk: . lib/Mail spamd
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
BTW, I think we should make Storable a Makefile.PL prerequisite (assuming
it works ;). I can't see spamd being much use without it for the typical
use-case...
- --j.
felicity@apache.org writes:
>Author: felicity
>Date: Thu Apr 15 13:53:50 2004
>New Revision: 10033
>
>Modified:
> incubator/spamassassin/trunk/INSTALL
> incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm
> incubator/spamassassin/trunk/spamd/spamd.raw
>Log:
>bug 3272: modify how the configuration is backed up for spamd. added new copy_config() API method to allow third party folks to backup/restore the config.
>
>Modified: incubator/spamassassin/trunk/INSTALL
>==============================================================================
>--- incubator/spamassassin/trunk/INSTALL (original)
>+++ incubator/spamassassin/trunk/INSTALL Thu Apr 15 13:53:50 2004
>@@ -229,6 +229,11 @@
> If it generates an error, you need to install the module. If the
> command just returns, you should be ok.
>
>+ - Storable (from CPAN)
>+
>+ This is a required module if you use spamd, and allow user
>+ configurations to be used (ie: you don't use "-x" or "-u").
>+
>
> Optional Additional Modules
> ---------------------------
>
>Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm
>==============================================================================
>--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm (original)
>+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm Thu Apr 15 13:53:50 2004
>@@ -1533,6 +1533,109 @@
> exit $exitcode;
> }
>
>+# private function to find out if the Storable function is available...
>+sub _is_storable_available {
>+ my($self) = @_;
>+
>+ if (exists $self->{storable_available}) {
>+ }
>+ elsif (!eval { require Storable; }) {
>+ $self->{storable_available} = 0;
>+ dbg("no Storable module found");
>+ }
>+ else {
>+ $self->{storable_available} = 1;
>+ dbg("Storable module found");
>+ }
>+
>+ return $self->{storable_available};
>+}
>+
>+=item $f->copy_config ( [ $source ], [ $dest ] )
>+
>+Used for daemons to keep a persistent Mail::SpamAssassin object's
>+configuration correct if switching between users. Pass an associative
>+array reference as either $source or $dest, and set the other to 'undef'
>+so that the object will use its current configuration. i.e.:
>+
>+ # create object w/ configuration
>+ my $spamtest = Mail::SpamAssassin->new( ... );
>+
>+ # backup configuration to %conf_backup
>+ my %conf_backup = ();
>+ $spamtest->copy_config(undef, \%conf_backup) ||
>+ die "error returned from copy_config!\n";
>+
>+ ... do stuff, perhaps modify the config, etc ...
>+
>+ # reset the configuration back to the original
>+ $spamtest->copy_config(\%conf_backup, undef) ||
>+ die "error returned from copy_config!\n";
>+
>+=cut
>+
>+sub copy_config {
>+ my($self, $source, $dest) = @_;
>+
>+ # At least one of either source or dest needs to be a hash reference ...
>+ unless ((defined $source && ref($source) ne 'HASH') ||
>+ (defined $dest && ref($dest) ne 'HASH')) {
>+ return 0;
>+ }
>+
>+ # We need the Storable module for this, so if it's not available,
>+ # return an error.
>+ return 0 if (!$self->_is_storable_available());
>+
>+ # Set the other one to be the conf object
>+ $source ||= $self->{conf};
>+ $dest ||= $self->{conf};
>+
>+ # Copy the source array to the dest array
>+ while(my($k,$v) = each %{$source}) {
>+ # we know the main value doesn't need to get copied.
>+ # also ignore anything plugin related, since users can't change that,
>+ # and there are usually code references.
>+ next if ($k eq 'main' || $k =~ /plugin/);
>+
>+
>+ my $i = ref($v);
>+
>+ # Not a reference? Just copy the value over.
>+ if (!$i) {
>+ $dest->{$k} = $v;
>+ }
>+ elsif ($i eq 'SCALAR' || $i eq 'ARRAY' || $i eq 'HASH') {
>+ # It's a reference, so make a recursive copy
>+ $dest->{$k} = Storable::dclone($v);
>+ }
>+ elsif ($k =~ /^(internal|trusted)_networks$/) {
>+ # these are objects, but have a single hash array of interest
>+ # it may not exist though, so deal with it appropriately.
>+ if ($v->{nets}) {
>+ # just copy the nets reference over ...
>+ $dest->{$k}->{nets} = Storable::dclone($v->{nets});
>+ }
>+ else {
>+ # this gets tricky... the value is false, or doesn't exist,
>+ # so we need to either delete or undef depending on the destination
>+ if (exists $dest->{$k}) {
>+ delete $dest->{$k}->{nets};
>+ }
>+ else {
>+ $dest->{$k}->{nets} = undef;
>+ }
>+ }
>+ }
>+# else {
>+# warn ">> $k, $i\n";
>+# }
>+ }
>+
>+ return 1;
>+}
>+
>+
> 1;
> __END__
>
>
>Modified: incubator/spamassassin/trunk/spamd/spamd.raw
>==============================================================================
>--- incubator/spamassassin/trunk/spamd/spamd.raw (original)
>+++ incubator/spamassassin/trunk/spamd/spamd.raw Thu Apr 15 13:53:50 2004
>@@ -50,9 +50,6 @@
> use File::Spec 0.8;
> use File::Path;
>
>-# used for dealing with configuration switching ...
>-use Storable qw/freeze thaw/;
>-
> # Check to make sure the script version and the module version matches.
> # If not, die here! Also, deal with unchanged VERSION macro.
> if ($Mail::SpamAssassin::VERSION ne '@@VERSION@@' && '@@VERSION@@' ne "\@\@VERSION\@\@") {
>@@ -642,9 +639,10 @@
>
> # If we're going to be switching users in check(), let's backup the
> # fresh configuration now for later restoring ...
>-my $conf_backup;
>+my %conf_backup = ();
> if ($setuid_to_user) {
>- $conf_backup = freeze $spamtest->{conf};
>+ $spamtest->copy_config(undef, \%conf_backup) ||
>+ die "error returned from copy_config, no Storable module?\n";
> }
>
> # Fork off our children.
>@@ -792,7 +790,8 @@
> # (potentially), so let's restore back the saved version we
> # had before.
> #
>- $spamtest->{conf} = thaw $conf_backup;
>+ $spamtest->copy_config(\%conf_backup, undef) ||
>+ die "error returned from copy_config, no Storable module?\n";
> }
> }
>
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Exmh CVS
iD8DBQFAfvxMQTcbUG5Y7woRAhvXAJ4/uLUi6bheJNP4e2xnTCTCBLEKCwCfXyyr
GoIzzHdlWFvgWT+Nnr5jt+Q=
=gW2U
-----END PGP SIGNATURE-----
Re: svn commit: rev 10033 - in incubator/spamassassin/trunk: . lib/Mail spamd
Posted by Theo Van Dinter <fe...@kluge.net>.
On Thu, Apr 15, 2004 at 03:24:37PM -0700, Justin Mason wrote:
> > > How's about spamd dies at startup -- before even forking -- if the
> > > options *would* require Storable, but it's not installed? (basically
>
> Nifty -- but that's post-daemonize. Hence stderr will be /dev/null...
Oh. Different level of "forking". ;)
I'll see what I can do about that. There's actually no reason off the
top of my head to daemonize before we spawn the children anyway, so ...
--
Randomly Generated Tagline:
"Good news, good news abounds." - Prof. Branche
Re: svn commit: rev 10033 - in incubator/spamassassin/trunk: . lib/Mail spamd
Posted by Theo Van Dinter <fe...@kluge.net>.
On Thu, Apr 15, 2004 at 03:20:08PM -0700, Justin Mason wrote:
> How's about spamd dies at startup -- before even forking -- if the
> options *would* require Storable, but it's not installed? (basically
Already done. ;) The code looks like:
# If we're going to be switching users in check(), let's backup the
# fresh configuration now for later restoring ...
my %conf_backup = ();
if ($setuid_to_user) {
$spamtest->copy_config(undef, \%conf_backup) ||
die "error returned from copy_config, no Storable module?\n";
}
# Fork off our children.
for ( 1 .. $childlimit ) {
spawn();
}
--
Randomly Generated Tagline:
"Deja Fu: The feeling that somehow, somewhere, you've been kicked in the
head like this before." - Unknown
Re: svn commit: rev 10033 - in incubator/spamassassin/trunk: . lib/Mail spamd
Posted by Theo Van Dinter <fe...@kluge.net>.
On Thu, Apr 15, 2004 at 02:19:08PM -0700, Justin Mason wrote:
> BTW, I think we should make Storable a Makefile.PL prerequisite (assuming
> it works ;). I can't see spamd being much use without it for the typical
> use-case...
Well, yes and no. If you're not going to run with user-switching,
it's not required. So if someone installs it for themselves, or it's
a high-throughput site, or ...
--
Randomly Generated Tagline:
"Never doubt that a small group of thoughtful citizens can change the
world. Indeed, it is the only thing that ever has." - Margaret Mead