in lib/Mail/SpamAssassin.pm [1741:1922]
sub init {
my ($self, $use_user_pref) = @_;
# Allow init() to be called multiple times, but only run once.
if (defined $self->{_initted}) {
# If the PID changes, reseed the PRNG (if permitted) and the DNS ID counter
if ($self->{_initted} != $$) {
$self->{_initted} = $$;
srand if !$self->{skip_prng_reseeding};
$self->{resolver}->reinit_post_fork();
}
return;
}
my $timer = $self->time_method("init");
# Note that this PID has run init()
$self->{_initted} = $$;
# if spamd or other forking, wait for spamd_child_init
if (!$self->{skip_prng_reseeding}) {
$self->set_global_state_dir();
}
#fix spamd reading root prefs file
if (!defined $use_user_pref) {
$use_user_pref = 1;
}
if (!defined $self->{config_text}) {
$self->{config_text} = '';
# read a file called "init.pre" in site rules dir *before* all others;
# even the system config.
my $siterules = $self->{site_rules_filename};
$siterules ||= $self->first_existing_path (@site_rules_path);
my $sysrules = $self->{rules_filename};
$sysrules ||= $self->first_existing_path (@default_rules_path);
if ($siterules) {
$self->{config_text} .= $self->read_pre($siterules, 'site rules pre files');
}
else {
warn "config: could not find site rules directory\n";
}
if ($sysrules) {
$self->{config_text} .= $self->read_pre($sysrules, 'sys rules pre files');
}
else {
warn "config: could not find sys rules directory\n";
}
if ($sysrules) {
my $cftext = $self->read_cf($sysrules, 'default rules dir');
if ($self->{require_rules} && $cftext !~ /\S/) {
die "config: no rules were found! Do you need to run 'sa-update'?\n";
}
$self->{config_text} .= $cftext;
}
if (!$self->{languages_filename}) {
$self->{languages_filename} = $self->find_rule_support_file("languages");
}
if ($siterules && !$self->{ignore_site_cf_files}) {
$self->{config_text} .= $self->read_cf($siterules, 'site rules dir');
}
if ( $use_user_pref != 0 ) {
$self->get_and_create_userstate_dir();
# user prefs file
my $fname = $self->{userprefs_filename};
$fname ||= $self->first_existing_path (@default_userprefs_path);
if (!$self->{dont_copy_prefs}) {
# bug 4932: if the userprefs path doesn't exist, we need to make it, so
# just use the last entry in the array as the default path.
$fname ||= $self->sed_path($default_userprefs_path[-1]);
my $stat_errn = stat($fname) ? 0 : 0+$!;
if ($stat_errn == 0 && -f _) {
# exists and is a regular file, nothing to do
} elsif ($stat_errn == 0) {
warn "config: default user preference file $fname is not a regular file\n";
} elsif ($stat_errn != ENOENT) {
warn "config: default user preference file $fname not accessible: $!\n";
} elsif (!$self->create_default_prefs($fname)) {
warn "config: failed to create default user preference file $fname\n";
}
}
$self->{config_text} .= $self->read_cf($fname, 'user prefs file');
}
}
if ($self->{pre_config_text}) {
$self->{pre_config_text} .= "\n" unless $self->{pre_config_text} =~ /\n\z/;
$self->{config_text} = "file start (pre_config_text)\n".
$self->{pre_config_text}.
"file end (pre_config_text)\n".
$self->{config_text};
}
if ($self->{post_config_text}) {
$self->{post_config_text} .= "\n" unless $self->{post_config_text} =~ /\n\z/;
$self->{config_text} .= "\n" unless $self->{config_text} =~ /\n\z/;
$self->{config_text} .= "file start (post_config_text)\n".
$self->{post_config_text}.
"file end (post_config_text)\n";
}
if ($self->{config_text} !~ /\S/) {
my $m = "config: no configuration text or files found! do you need to run 'sa-update'?\n";
if ($self->{require_rules}) {
die $m;
} else {
warn $m;
}
}
# Go and parse the config!
$self->{conf}->{main} = $self;
if (would_log('dbg', 'config_text') > 1) {
dbg('config_text: '.$self->{config_text});
}
$self->{conf}->parse_rules ($self->{config_text});
$self->{conf}->finish_parsing(0);
delete $self->{conf}->{main}; # to allow future GC'ing
undef $self->{config_text}; # ensure it's actually freed
delete $self->{config_text};
if ($self->{require_rules} && !$self->{conf}->found_any_rules()) {
die "config: no rules were found! Do you need to run 'sa-update'?\n";
}
# Initialize the Bayes subsystem
if ($self->{conf}->{use_bayes}) {
require Mail::SpamAssassin::Bayes;
$self->{bayes_scanner} = Mail::SpamAssassin::Bayes->new($self);
}
$self->{'learn_to_journal'} = $self->{conf}->{bayes_learn_to_journal};
# Figure out/set our initial scoreset
my $set = 0;
$set |= 1 unless $self->{local_tests_only};
$set |= 2 if $self->{bayes_scanner} && $self->{bayes_scanner}->is_scan_available() && $self->{conf}->{use_bayes_rules};
$self->{conf}->set_score_set ($set);
if ($self->{only_these_rules}) {
$self->{conf}->trim_rules($self->{only_these_rules});
}
if (!$self->{timer_enabled}) {
# enable timing implicitly if _TIMING_ is used in add_header templates
foreach my $hf_ref (@{$self->{conf}->{'headers_ham'}},
@{$self->{conf}->{'headers_spam'}}) {
if ($hf_ref->[1] =~ /_TIMING_/) { $self->timer_enable(); last }
}
}
# should be called only after configuration has been parsed
$self->{resolver} = Mail::SpamAssassin::DnsResolver->new($self);
# load GeoDB if some plugin wants it
if ($self->{geodb_wanted}) {
eval '
use Mail::SpamAssassin::GeoDB;
$self->{geodb} = Mail::SpamAssassin::GeoDB->new({
conf => $self->{conf}->{geodb},
wanted => $self->{geodb_wanted},
});
1;
';
if ($@ || !$self->{geodb}) {
dbg("config: GeoDB disabled: $@");
}
}
# TODO -- open DNS cache etc. if necessary
}