=head1 NAME

disclaimer

=head1 DESCRIPTION

Appends a disclaimer/footer to a mail message

=head1 AUTHOR

Michael Weinberger, neddix Stuttgart, 2007

=head1 LICENSE

GNU GPL (GNU General Public License)


=cut


use MIME::Parser;
use MIME::Entity;
use MIME::Head;
use Net::Domain;

my $parser;
my $ent;
my $tmpdir='/var/spool/qpsmtpd';

sub register 
	{
	my ($self, $qp, %arg) = @_;
	$self->register_hook('data_post', 'disclaimer');
	$self->{_disclaimer_html}=($arg{disclaimer_html}||'') eq 'yes' ? 1: 0;
	if( $arg{disclaimer_file} and open( FH, $arg{disclaimer_file} ) )
		{
		local $/;
		$self->{_disclaimer_text}=<FH>;
		close(FH);
		$self->{_disclaimer_part} = MIME::Entity->build( 
			Data=>$self->{_disclaimer_text},
			Filename=>$arg{disclaimer_mime_filename}||'Disclaimer.txt',
			Encoding=>'7bit', 
			Type=> $self->{_disclaimer_html} ? 'text/html' : 'text/plain' );
		}
	}

sub disclaimer ( $$ )
	{
  	my ($self, $transaction) = @_;
	if( not $self->{_disclaimer_text} )
		{
		$self->log(LOGDEBUG, "Return: no disclaimer text" );
		return DECLINED;
		}

	if( $transaction->header->get('X-Qpsmtp-Disclaimer') )
		{
		$self->log(LOGDEBUG, "Return: X-Qpsmtp-Disclaimer header line found" );
		return DECLINED;
		}

	my $domainname=Net::Domain::hostdomain();

	if( $transaction->sender->host ne $domainname )
		{
		$self->log(LOGDEBUG, "Return: Sender domain is not $domainname" );
		return DECLINED;
		}

	my $ext_rcpt=0;
	foreach my $rcpt ( $transaction->recipients )
		{
		$ext_rcpt=1 if( $rcpt->host ne $domainname );
		last if $ext_rcpt;
		}
	
	if( not $ext_rcpt )
		{
		$self->log(LOGDEBUG, "Return: No external recipients" );
		return DECLINED;
		}

	
	# new Parser Object
	$parser = new MIME::Parser;
	# temp output directory
	$parser->output_under( $tmpdir );
	$parser->extract_uuencode(1);

	# read message body
	open BFN, $transaction->body_filename();
  	$ent = $parser->parse(\*BFN);
	close BFN;

	my $data='';
	if( $ent->parts and $ent->parts(0)->mime_type eq 'text/plain' and not $self->{_disclaimer_html} )
		{
		$self->log(LOGDEBUG, "Multipart message. First part is plain text" );
		if (my $fh = $ent->parts(0)->open("r")) 
			{
			local $/;
			$data=$fh->getline;
			$fh->close;
			}
		$data .= $self->{_disclaimer_text}; # TODO charset conversion needed here
		if ( my $fh = $ent->parts(0)->open("w")) 
			{
			$fh->print($data);
			$fh->close;
			}
		}
	elsif( not $ent->parts and $ent->mime_type eq 'text/plain' and not $self->{_disclaimer_html} )
		{
		$self->log(LOGDEBUG, "Plain text non multipart message" );
		if (my $fh = $ent->open("r")) 
			{
			local $/;
			$data=$fh->getline;
			$fh->close;
			}
		$data .= $self->{_disclaimer_text}; # TODO charset conversion needed here
		if ( my $fh = $ent->open("w")) 
			{
			$fh->print($data);
			$fh->close;
			}
		}
	elsif( $ent->parts )
		{
		$self->log(LOGDEBUG, "Multipart message without a plain text part" ) unless $self->{_disclaimer_html};
		$self->log(LOGDEBUG, "Multipart message and DisclaimerHTML=1" ) if $self->{_disclaimer_html};
		my @allatt = $ent->parts;
		push( @allatt, $self->{_disclaimer_part} );
		$ent->parts(\@allatt);
		$data=1; # flag
		}
	else
		{
		$self->log(LOGDEBUG, "Non plain text single part message" ) unless $self->{_disclaimer_html};
		$self->log(LOGDEBUG, "Single part message and DisclaimerHTML=1" ) if $self->{_disclaimer_html};
		$ent->make_multipart();
		my @allatt = $ent->parts;
		push( @allatt, $self->{_disclaimer_part} );
		$transaction->header->empty();
		$transaction->header($ent->head());
		$ent->parts(\@allatt);
		$data=1; # flag
		}

	if( $data )
		{
		$transaction->header->replace( 'X-Qpsmtp-Disclaimer', $domainname );
		# write message body
		open BFN, ">" . $transaction->body_filename();
		$ent->print(\*BFN);
		close BFN;
		$transaction->body_resetpos();
		$self->log(LOGINFO, "Disclaimer appended" );
		}

	# cleaning up
	$ent->purge();
	rmdir( $parser->output_dir );

  	return DECLINED; 
	}

# vi: ft=perl ts=4
