#!/usr/bin/perl 

########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####

BEGIN {
    # help script to find its local modules
  use POSIX;
  use lib;
#
# to find lib_module_common.pm, Common/Config.pm
#
  use lib ''.POSIX::getcwd.'/subs/'; ## configure & install
  use lib ''.substr($0,0,rindex($0,'/')).'/subs'; ## admin.pl & configure
  use lib ''.substr($0,0,rindex($0,'/')).'/../subs'; ## updates
  use lib ''.substr($0,0,rindex($0,'/')).'/admin/subs'; ## confixx_updatescript.pl

}

use File::Basename;
use File::Temp qw/ tempfile /;

use strict;

# include common functions
use lib_module_common;

if ( ( $confixxState !~ /conf/ ) && ## don't load configure during configure
		 ( $installDir && -d $installDir ) ## there is $installDir
	 ) {
	
	&initConfig( $installDir );
}


my ($spamAssVersion);

if ( &loadPackage( 'Mail::SpamAssassin' ) ) {
	$spamAssVersion = $Mail::SpamAssassin::VERSION;
}


my ( $wDir, $dir );
$dir = $wDir = dirname($0);


#
# when call with do
#

unless ( -e "$wDir/subs_include_files.pl" ) {
  $wDir = "$dir/subs";
}
unless ( -e "$wDir/subs_include_files.pl" ) {
	$wDir = "$dir/admin/subs";
} 
unless ( -e "$wDir/subs_include_files.pl" ) {
	if ( $installDir && ( -d $installDir ) ) {
		$wDir = "$installDir/admin/subs";
	}
}

safe_do "$wDir/subs_include_files.pl";
safe_do "$wDir/subs_inclue_modules.pl";

sub installSpamassassin {

	&checkSpamd($spamassassinScript);
	&createDefaultInclude();
	&createInitialConfig();

	return 1;

}

sub createDefaultInclude {
	# create default include 

	my ($sa_default_cont	);

	if ( $spamAssVersion < 3 ) {
		$sa_default_cont = << "CONFIG";
# SpamAssassin config file for version 2.5x
# generated by http://www.yrex.com/spam/spamconfig.php (version 1.01)

# How many hits before a message is considered spam.
required_hits           5.0

# Whether to change the subject of suspected spam
rewrite_subject         1

# Text to prepend to subject if rewrite_subject is used
subject_tag             *****SPAM*****

# Encapsulate spam in an attachment
report_safe             1

# Use terse version of the spam report
use_terse_report        0

# Enable the Bayes system
use_bayes               1

# Enable Bayes auto-learning
auto_learn              1

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              1
use_dcc                 1
use_pyzor               1

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_languages            all

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              all
CONFIG
	} else {
		$sa_default_cont = << "CONFIG3";
# SpamAssassin config file for version 3.x

# How many hits before a message is considered spam.
required_score           5.0

# Whether to change the subject of suspected spam
rewrite_header subject  *****SPAM*****

# Encapsulate spam in an attachment
report_safe             1

# Add report into headers
add_header spam Report _REPORT_

# Enable the Bayes system
use_bayes               1

# Enable Bayes auto-learning
bayes_auto_learn              1

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              1
use_dcc                 1
use_pyzor               1

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_languages            all

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              all
CONFIG3
	}

	my $sa_default_file = "$installDir/safe/spamassassin.inc";
	&writeConfig($sa_default_file, $sa_default_cont);
}

sub createInitialConfig {
	# backup primary config
	
	my $sa_backup_dir = "$installDir/backup/spamassassin";
	unless ( -d $sa_backup_dir ) {
		if( mkdir ($sa_backup_dir, 0700) ) {
			chmod 0700,$sa_backup_dir;
		} else {
			die "Unable to create directory '$sa_backup_dir': $!\n";
		}
	}

	if ( -e $spamassassinConfig ) {
		my $sa_basefile = basename($spamassassinConfig);
		&BackUpFile($spamassassinConfig, "$sa_backup_dir/$sa_basefile");
	}


#
# create spamassassin config file
#
	do "$wDir/subs_include_spamassassin.pl";

#	system("$wDir/subs_include_spamassassin.pl") == 0 
#	    or warn("Can not execute $wDir/subs_include_spamassassin.pl: $!\n".
#		    "To complete SpamAssassin support configuration you should".
#		    " launch $wDir/subs_include_spamassassin.pl manually after the installation.\n");
}

sub checkSpamd {
  my $InitSpamd = shift || '/etc/init.d/spamd';
  unless(-T $InitSpamd){
#    print STDERR "Error: file '$InitSpamd' if not found or is not a text file\n";
    return 1;
  }
  my $out = `$bin_grep 'killproc.*/bin/perl' $InitSpamd`;
  unless ( $out=~/killproc.*\s(\S+)bin\/perl\s+(\S+)/ ) {
    return 1;  ## OK
  }

  my $binPerl=$1.'bin/perl';
  my $SPAMD_BIN = $2;
  my $isFound;
  my $pathSpamdBin;

  &report_error("To continue installation of Confixx is necessary to patch script '$InitSpamd'\n".
								"Original script will be saved as '$InitSpamd.confixx-backup'");

  unless($SPAMD_BIN=~s/^\$//){  ## remove first $
    if (-x $SPAMD_BIN){
      $pathSpamdBin=$SPAMD_BIN;
      $isFound = 1;
    }
  }

  if (open(SPAMDSRC,"< $InitSpamd")){
    my ($InitName,$InitDir) = fileparse($InitSpamd);

    my($fh,$tempFile) = tempfile ($InitName.".XXXXX", 'DIR' => $InitDir);

    my ($prefix,$procArgs,$BIN,$spamdArgs,$line,$error,$pathBin);
    if ( $fh ) {
      while (<SPAMDSRC>){
				$line=$_;
				unless($isFound){
					if($line=~/\Q$SPAMD_BIN\E=(\S+)/){
						$pathSpamdBin=$1;
						$isFound=1;
					}
				}
				if ( $line =~ /^(\s*)startproc\s(.*)\s\Q$binPerl\E\s+(\S+)(.*)/ ) {
					$prefix = $1;
					$procArgs = $2;
					$BIN = $3;
					$spamdArgs = $4;
					if ($BIN =~ /^\$\Q$SPAMD_BIN\E$/ ) {
						$pathBin = $pathSpamdBin;
					} else {
						$pathBin = $BIN;
					}
					if ( -x $pathBin ) {
						$line=$prefix.'startproc '.$procArgs.' '.$BIN.$spamdArgs;
					} else {
						$error = 1;
						print STDERR "Error: '$pathBin' is not executable\n";
					}
	  
				} elsif ( $line =~ /^(\s*)killproc\s(.*)\s\Q$binPerl\E\s+(\S+)/ ) {
					$prefix = $1;
					$procArgs = $2;
					$BIN = $3;
					if ( $BIN =~ /^\$\Q$SPAMD_BIN\E$/ ) {
						$pathBin = $pathSpamdBin;
					} else {
						$pathBin = $BIN;
					}
					if ( -x $pathBin ) {
						$line = $prefix.'killproc '.$procArgs.' '.$BIN;
					} else {
						$error = 1;
						print STDERR "Error: '$pathBin' is not executable\n";
					}
				}

				last if ( $error);
				print $fh $line;
  	  }
  	  close ($fh);
  	  if ( $error ) {
				unlink $tempFile;
				print STDERR "Error: parsing of '$InitDir' fail\nScript is not be patched\n";
  	  } else {
				my $confixxSave=$InitSpamd.".confixx-backup";
				unlink $confixxSave if (-f $confixxSave);
				rename $InitSpamd,$confixxSave;
				rename $tempFile,$InitSpamd;
				chmod 0740,$InitSpamd;
  	  }
		}else{
      print SDTERR "Error: Unable to get temporary file in '$InitDir'\n";
		}
  	close (SPAMDSRC);
  }else{
    print STDERR "Error: Unable to open file '$InitSpamd': $!\n";
    return 0;
  }
}

sub report_error($) {
  my ($str) = @_;

  warn "PROBLEM FOUND: $str\n";
  my $logfile = "$installDir/INSTALLATION_PROBLEMS.LOG";
  unless (open(FILE, ">>$logfile")) {
    warn "Warning: can not save problem description to $logfile: can not open file $logfile: $!\n";
    return;
  }
  print FILE "$str\n";
  unless (close(FILE)) {
    warn "Warning: can not save problem description to $logfile: can not close file $logfile: $!\n";
    return;
  }
}

sub configureSpamassassin {

# predict where the spamassassin config is located

	&header2(&ltext('install_header_spamassassin'));

# predict where the spamassassin config is located
	my $default_config = $spamassassinConfig || '/etc/mail/spamassassin/local.cf';
	my $default_script = $spamassassinScript || '/etc/init.d/spamassassin';
	unless (-x $default_script) {
		$default_script = "/etc/init.d/spamd";
	}

	$spamassassinConfig = &FileQuestion(&ltext('install_question_spamassassin_conf'), $default_config);
	$spamassassinScript = &FileQuestion(&ltext('install_question_spamassassin_script'), $default_script);

	my $restart = &getReloadKey($spamassassinScript,'restart','reload') || 'restart';

	$pm_spamassassin_reload = "$spamassassinScript $restart";
	$pm_spamassassin_start = "$spamassassinScript start";

	$spamassassinUid = &getSpamdUid( $spamassassinScript );

}

sub getSpamdUid {
	my $initdScript = shift;

	if ( !$initdScript && 
			 ( $pm_spamassassin_start =~ /(.*)\s+\S+$/ ) ) { ## remove the last word
		$initdScript = $1;
	}


	my $sysconfigSpamassassin = '/etc/sysconfig/spamassasin';
	my ( $spamdOptions,$spamdUser,$spamdUid, $spamdGid );
	if ( -T $sysconfigSpamassassin ) {
		if ( open( CONFIG, "<$spamassassinScript") ) {
			while ( <CONFIG> ) {
			  chomp;
			  next unless $_;  ## skip blank lines
			  next if /^#/;	## skip comment
				if ( /SPAMDOPTIONS=("|')(.*)\1/ ) {
					$spamdOptions .= $2;
				}
			}
			close CONFIG;
		} else {
			warn "error: unable to open '$sysconfigSpamassassin': $!\n";
		}
	}
	if ( -T $initdScript ) {
		if ( open( CONFIG, "<$initdScript") ) {
			while ( <CONFIG> ) {
			  chomp;
			  next unless $_;  ## skip blank lines
			  next if /^#/;	## skip comment
				if ( /SPAMDOPTIONS=("|')(.*)\1/ ) {
					$spamdOptions .= $2.' ';
				}
			}
			close CONFIG;
		} else {
			warn "error: unable to open '$initdScript': $!\n";
		}
	}

	unless ( $spamdOptions ) {  ## get from ps
		if ( open (PS,'ps -Af|') ){
			while ( <PS> ) {
				chomp;
				if ( /\/spamd\s+(.*)/ ){
					$spamdOptions = $1;
					last;
				}
			}
			close PS;
		}
	}

	if ( $spamdOptions=~/-u\s*(\S+)/ ) {
		$spamdUser = $1;
		($spamdUid,$spamdGid) = (getpwnam($spamdUser))[2,3];
	} else {
		$spamdUser = 'root';
		$spamdUid = 0;
	}
	if ( wantarray() ) {
		return ( $spamdUid,$spamdUser );
	} else {
		return $spamdUid;
	}
}
