#!/usr/bin/perl -w
#
my $Cmd		= "ku-mail";
my $CmdVer	= "1.1";
my $CmdSig	= "$Cmd v$CmdVer (2018/02)";

use strict;
use Net::SMTP;


my $CfgFile	= "/etc/$Cmd.conf";
my %Parms;
my $Subj	= "(no subject)";
my $From;
my $To;
my @Body;
my $User;
my $Pass;

read_config();
check_config();

usage( "missing to_addr argument" )	if (!scalar(@ARGV));

ARGS: while (scalar(@ARGV)) {
  $_ = shift(@ARGV);
  CASE: {
    if ($_ eq "-s") {
    	usage( "-s requires an argument" )	if (!scalar(@ARGV));
    	$Subj	= shift(@ARGV);
	last CASE;
    }
    if ($_ eq "-r") {
    	usage( "-r requires an argument" )	if (!scalar(@ARGV));
	$From	= shift(@ARGV);
	last CASE;
    }
    if ($_ eq "-V") {
    	printf( "%s\n", $CmdSig );
	exit( 0 );
    }
    usage( "unknown option '$_'" )		if ($_ =~ /^-/);
    usage( "empty options not allowed" )	if ($_ =~ /^\s*$/);
    $To	= $_;
    last ARGS;
  }
}
usage( "too many parms" )	if (scalar(@ARGV));

if (!defined $From) {
	my $id		= `id -n -u`; chomp($id);
	my $host	= `uname -n`; chomp($host);
	$From		= "$id\@$host";
	printf( STDERR "warning: from_address not defined, using '%s'\n", $From );
}

# gets email body from stdin
#
@Body = <STDIN>;

for (my $kk=0;$kk<scalar(@Body);$kk++) {
	chomp( $Body[$kk] );
}

send_mail( $From, $To, $Subj, @Body );

exit( 0 );



sub usage {
	printf( STDERR "\n%s\n", @_ )	if (scalar(@_));
	printf( STDERR "\nusage: %s [-s subject] [-r from] to_addr\n", $Cmd );
	printf( STDERR "\nusage: %s -V     (show version)\n", $Cmd );
	die "\n";
}

sub read_config {
	my $CFG	= open( CFG, "<$CfgFile" ) ||
		die "can't read config file '$CfgFile': $!\n";
	while (<CFG>) {
		chomp();
		next	if ($_ =~ /^\s*$/);	# skip empty lines
		next	if ($_ =~ /^[#;]/);	# skip comments lines

		my @tmp = split( /\s+/ );
		die "malformed line in '$CfgFile':\n$_\n"	if (scalar(@tmp) < 2);
		my $var	= lc( $tmp[0] );
		my $val	= $_; $val =~ s/^$var\s+//;
		CASE: {
			if ($var eq "relay")	{ $Parms{'Host'} = $val; last CASE; }
			if ($var eq "host")	{ $Parms{'Host'} = $val; last CASE; }
			if ($var eq "mailhost")	{ $Parms{'Host'} = $val; last CASE; }
			if ($var eq "port")	{ $Parms{'Port'} = $val; last CASE; }
			if ($var eq "timeout")	{ $Parms{'Timeout'} = $val; last CASE; }
			if ($var eq "hello")	{ $Parms{'Hello'} = $val; last CASE; }
			if ($var eq "debug")	{ $Parms{'Debug'} = $val; last CASE; }
			if ($var eq "from")	{ $From = $val; last CASE; }
			if ($var eq "user")	{ $User = $val; last CASE; }
			if ($var eq "pass")	{ $Pass = $val; last CASE; }
			die "unknown parm in '$CfgFile': $var\n";
		}
	}
	close( CFG ) ||
		die "error reading config file '$CfgFile': $!\n";
	return 1;
}


sub check_config {
	if (!defined $Parms{'Host'}) {
		die( "error ($CfgFile): you need to define at least 'relay' hostname\n" );
	}
	if (!defined $Parms{'Hello'}) {
		printf( STDERR "warning ($CfgFile): you should define your hostname using 'hello ....'\n" );
		}
	if (defined $Parms{'Debug'} && $Parms{'Debug'} ne '1' && $Parms{'Debug'} ne '0') {
		printf( STDERR "warning ($CfgFile): debug is not '1' or '0', forced to '1'\n" );
		$Parms{'Debug'} = '1';
	}
	if (defined $User && !defined $Pass) {
		die( "error ($CfgFile): SASL user defined without password ('pass ...')\n" );
	}
	return 1;
}



sub send_mail {
	my ($from, $to, $subject, @body) = @_;
	my ($body);

	my $smtp = Net::SMTP->new(%Parms) ||
		die "can't open SMTP connection: $!\n";

	if (defined $User) {
		$smtp->auth( $User, $Pass )	or die( "error: on smpt->auth()\n" );
	}

	$smtp->mail($from)	or die( "error: on FROM command\n" );
	$smtp->to($to)		or die( "error: on TO command\n" );

	$smtp->data()		or die( "error: on DATA command\n" );

	$smtp->datasend("To: $to\n");
	$smtp->datasend("From: $from\n");
	$smtp->datasend("Subject: $subject\n");
	$smtp->datasend("X-Mailer: " . $CmdSig . "\n");
	$smtp->datasend("\n");

	foreach $body (@body) {
		chomp($body);
		$smtp->datasend("$body\n");
	}

	$smtp->dataend();
	$smtp->quit();

	return 1;
}
