#!/usr/bin/perl

sub usage;
sub verbose;
sub error;
sub bad;
sub read;
sub write;
sub html;

use Getopt::Std;

use vars qw ($opt_c,$opt_h,$opt_v);

getopts('c:vh');

$maxparams = 52;

if(!$opt_c || !opt_h)
{
	&usage;
}

if($opt_c eq "")
{
	&usage;
}
else
{
	$file = $opt_c;
}

if($opt_v)
{
	$vb = 1;
}

if($UID != 0)
{
	print "You must be root!\n";
	exit(-1);
}
if($UID eq $>)
{
	print "san.check must run under a different UID than root!\n";
	print "The owner must be the UID of your mailserver and it\n";
	print "must be set to suid permissions!\n";
	print "Example: -rwsr-s---   1 daemon daemon     san.check\n";
	exit(-1);
}


&verbose( "Effective UID:  $>");

%option = (	
		"Mail_Sender" 	=> "",
		"Mail_Mail_Admin"      	=> "",
		"Mail_Rcpt"	=> "",
		"Mail_Cc"	=> "",
		"File_Allow_From"	=> "",
		"Value_Auth_Code"	=> "",
		"File_Index_Template"	=> "",
		"File_Index_Output"	=> "",
		"File_Index_Storage"		=> "",
		"Bool_Use_Html"	=> "",
		"Bool_Htmlize_Crlf"		=> "",
		"Html_Item_Head"	=> "",
		"Html_Item_Foot" 	=> "",
		"Value_Field1"	=> "",
		"Value_Field2"	=> "",
		"Value_Field3"	=> "",
		"Value_Field4"	=> "",
		"Bool_Create_Mailto"	=> "",
		"Html_Date_Head"	=> "",
		"Html_Date_Foot"	=> "",
		"Html_Subject_Head"	=> "",
		"Html_Subject_Foot"	=> "",
		"Html_From_Head"	=> "",
		"Html_From_Foot"	=> "",
		"Html_Text_Head"	=> "",
		"Html_Text_Foot"	=> "",
		"Bool_Spam_Protect"	=> "",
		"Bool_Make_Archiv"	=> "",
		"File_Archiv_Output"	=> "",
		"File_Archiv_Template" => "",
		"File_Archiv_Storage"	=> "",
		"Value_Archiv_Maxitems" => "",
		"List_Archiv_Months" => "",
		"Bool_Use_Last_Month" => "",
		"Html_Archiv_Title_Head" => "",
		"Html_Archiv_Title_Foot" => "",
		"Html_Archiv_URL" => "",
		"Value_Archiv_Link_Type" => "",
		"Html_Archiv_Link_Left" => "",
		"Html_Archiv_Link_Right" => "",
		"File_Cron_Template"	=> "",
		"File_Cron_Output_Path"	=> "",
		"File_Cron_History"	=> "",
		"Html_Archiv_Link_Head"	=> "",
		"Html_Archiv_Link_Foot"	=> "",
		"Bool_Look_Detail" => "",
		"File_Detail_Template" => "",
		"File_Detail_Output_Path" 	=> "",
		"Html_Detail_Link"	=> "",
		"Html_Detail_URL"	=> "",
		"Html_Detail_Head"	=> "",
		"Html_Detail_Foot"	=> "");

$countparams = 0;

# read the config-file!
&verbose("open $file");
if(! -r $file )
{
	&error("Could not read $file!");
}
else
{
	open FILE, "< $file" or die &error("Could not read $file!");
	while(<FILE>)
	{
		chomp $_;
		$line++;
		if($_ !~ /^#/ && $_ !~ /^\s/ && $_ !~ /^\t/ && $_ ne "")
		{
			# no comment, a standard config line!
			@param = split(/\s/, $_);
			$option{$param[0]} = $param[1];	
			&verbose("Line $line: $param[0] => \"$param[1]\"");
			$countparams++;	
		}
	}
	close FILE;
}
if($countparams != $maxparams)
{
	&bad("wrong number of options: \n$maxparams expected and $countparams found.\nYou can change it in line 17 if you have an older version of htnews.");
}
else
{
	&verbose("number of options: $countparams - ok.");
}

# start checking...


&verbose("checking read permissions...");

if($option{"File_Allow_From"} ne "")
{
	&read($option{"File_Allow_From"},"File_Allow_From");
} 
&read($option{"File_Index_Template"},"File_Index_Template");
if($option{"Bool_Make_Archiv"} eq "YES")
{
        &read($option{"Archiv_File_Index_Template"},"Archiv_File_Index_Template");
}
if($option{"File_Cron_Template"} ne "")
{
	&read($option{"File_Cron_Template"},"File_Cron_Template");
}
if($option{"Bool_Look_Detail"} eq "YES")
{
	&read($option{"File_Detail_Template"},"File_Detail_Template");
}


&verbose("checking write permissions...");

&write($option{"File_Index_Output"},"File_Index_Output");
&write($option{"File_Index_Storage"},"File_Index_Storage");
if($option{"Bool_Make_Archiv"} eq "YES")
{
	&write($option{"File_Archiv_Output"},"File_Archiv_Output");
	&write($option{"File_Archiv_Storage"},"File_Archiv_Storage");
}
if($option{"File_Cron_Output_Path"} ne "")
{
	&write($option{"File_Cron_Output_Path"} . "san.cron.testfile","File_Cron_Output_Path");
	&write($option{"File_Cron_History"},"File_Cron_History");
}
if($option{"Bool_Look_Detail"} eq "YES")
{
	if($option{"File_Detail_Output_Path"} eq "")
	{
		&bad("option File_Detail_Output_Path has no value, but is required");
	}
	else
	{
		&write($option{"File_Detail_Output_Path"} . "san.detail.testfile","File_Detail_Output_Path");
	}
}

&verbose("checking email-addresses...");
if($option{"Mail_Sender"} !~ /[\@\.]/)
{
	if($option{"Mail_Sender"} eq "")
	{
		&bad("option Mail_Sender has no value, but is required");
	}
	else
	{
		&bad($option{"Mail_Sender"} . " is not a valid email-address(option Mail_Sender)");
	}
}
if($option{"Mail_Admin"} !~ /[\@\.]/)
{
	if($option{"Mail_Admin"} eq "")
	{
		&bad("option Mail_Admin has no value, but is required");
	}
	else
	{
		&bad($option{"Mail_Admin"} . " is not a valid email-address(option Mail_Admin)");
	}
}
if($option{"Mail_Rcpt"} ne "" && $option{"Mail_Rcpt"} !~ /[\@\.]/)
{
	if($option{"Mail_Rcpt"} ne "/dev/null")
	{
		&bad($option{"Mail_Rcpt"} . " is not a valid email-address(option Mail_Rcpt)");
	}
}
if($option{"Mail_Cc"} ne "" && $option{"Mail_Cc"} !~ /[\@\.]/)
{
	&bad($option{"Mail_Cc"} . " is not a valid email-address(option Mail_Cc)");
}

&verbose("checking Value_Field order...");
if($option{"Value_Field1"} ne "Text" && $option{"Value_Field2"} ne "Text" && $option{"Value_Field3"} ne "Text" && $option{"Value_Field4"} ne "Text")
{
	&bad("option Value_FieldX contains no value \"Text\"");
}

&verbose("checking various values...");
if($option{"Bool_Make_Archiv"} eq "YES")
{
	if($option{"Value_Archiv_Maxitems"} eq "")
	{
		&bad("option Value_Archiv_Maxitems has no value, but is required");
	}
	elsif($option{"Value_Archiv_Maxitems"} !~ /\d/)
	{
		&bad("option Value_Archiv_Maxitems is not a digit");
	}
	#new options since 0.6.9:
	$mcount = 1;
	@months = split(/,/,$option{"List_Archiv_Months"});
	for $mon (@months)
	{
		if($mon eq "")
		{
			&bad("Month missing in List_Archiv_Months[$mcount]");
		}
		$mcount++;
	}
	if($mcount != 12)
	{
		&bad("incorrect amount of months in List_Archiv_Months");
	}
	$LT = $option{"Value_Archiv_Link_Type"};
	if($LT ne "TEXT" || $LT ne "C_TEXT" || $LT ne "DIGIT" || $LT ne "C_DIGIT" && $LT ne "")
	{
		&bad("invalid value for Value_Archiv_Link_Type: \"$LT\"");
	}
}


exit(0);


sub usage
{
print qq~
Usage: 	sanity_check [-v] {-c configfile} | {-h}
	Checks a htnews 0.6.9 configfile for errors
	and checks permissions for the specified
	files and directories.
	Options:
	-v	Verbose Output, more informative
	-c	htnews configfile to check
	-h	help message

~;
exit(-1);
}

sub verbose
{
	if($vb)
	{
		print "  san.check VERBOSE: " . $_[0] . "\n";
	}
}

sub error
{
	print "  san.check ERROR  : \"" . $_[0] . "\"\n";
	exit(-1);
}

sub bad
{
	print "  san.check PROBLEM: \"" . $_[0] . "\".\n";
}

sub read
{
	if($_[0] eq "")
	{
		&bad("option $_[1] has no value, but is required");
	}
	elsif($_[0] !~ /^\//)
	{
		&bad("$_[0] is not a valid UNIX-path(option $_[1])");
	}
	elsif($_[0] =~ /$\//)
	{
		&bad("$_[0] seems to be a directory, file expected(option $_[1])");
	}
	else
	{
		if( ! -r $_[0] )
		{
			&bad("Could not read $_[0](option $_[1])");
		}
	}
}

sub write
{
	if($_[0] eq "")
        {
                &bad("option $_[1] has no value, but is required");
        }
        elsif($_[0] !~ /^\//)
        {
                &bad("$_[0] is not a valid UNIX-path(option $_[1])");
        }
        elsif($_[0] =~ /$\//)
        {
                &bad("$_[0] seems to be a directory, file expected(option $_[1])");
        }
        else
        {
                if( ! -w $_[0] )
                {
                        &bad("Could not read $_[0](option $_[1])");
                }
        }
}


sub html
{
}
