package ot_receive;
use strict;
use FindBin;
use lib $FindBin::Bin;
#use lib '/data/httpd/lib/perl';
use ot_const qw( %ot %r &is_err );
use ot_maillib qw( &mail &debug &mailerror &usermail &split_email_addr
&extract_body );
use ot_dblib qw( &db_connect &db_disconnect &db_count &db_insert_receive
&db_get_memb_id &db_set_status &db_insert_cmd );
use vars qw(@ISA @EXPORT_OK $VERSION);
use Exporter;
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&receive);

=head1 NAME

ot_receive - receives mails and stores them in a database 

=head1 SYNOPSIS

receives and analyzes mails and store them in table receive

=head1 DESCRIPTION

All functions and procedures are described below.

=cut

# receive - receives mail from <stdin> and stores it to db
# in-param:	--
# returns:	$status - status of processing
# returns:	$msg_id - message id from mail header
#			- OR: error message for user
# returns:	$fromlong - sender address from header
 
sub receive {

my $dbh;		# database handle
my @mailtext;		# mail text array

my $s;			# dummy
my $status;		# status of processing	
my $txt = '';		# mail text string
my $fromlong = '';	# sender's complete email address e.g. Alias <email@domain>
my $fromaddr = '';	# sender's short email address e.g. email@domain
my $fromalias = '';	# sender's alias e.g. Name
my $frompos = '';	# header position of "From:"-line
my $mailto = '';	# target address e.g. command*project@domain
my $mailcc = '';	# target address e.g. command*project@domain
my $subject = '';	# subject of the header
my $msg_id = '';	# message-id from header
my $dat = '';		# date of the mail
my $proj_addr = '';	# project and/or address
my $mid = 0;		# member id
my %rec;		# table record
my $rec_id = 0;		# receive_id of receive record
my $cmd_id = 0;		# command_id of command record (used in case of error)
my @p_addr;		# address array

debug( "##### Start receive: ".localtime, 0 );

$status = $r{ok_nothing_done};

my $i = 0;
my $j = 0;
while( <STDIN> ) {
	if ( /\AFrom:\s+(.*)\Z/i ) {
		push( @mailtext, $_ );
		$fromlong = $1;
		$i++;
		$frompos = $i;
	} elsif( /\ATo:\s+(.*)\Z/i ) {
		push( @mailtext, $_ );
		$mailto = $1;
		$j = 0;
		while(( $j < 200 ) && substr( $1, -1 ) eq ',' ){
			$_ = <STDIN>;
			debug( "TO: $_", 2 );
			if( /\s*(.+)/ ){
				debug( "to: $1", 2 );
				$mailto .= " $1";
			}
			else { last; }
			$j++;
		}
		$i++;
	} elsif( /\ACc:\s+(.*)\Z/i ) {
		push( @mailtext, $_ );
		$mailcc = $1;
		$j = 0;
		while(( $j < 200 ) && substr( $1, -1 ) eq ',' ){
			$_ = <STDIN>;
			debug( "CC: $_", 2 );
			if( /\s*(.+)/ ){
				debug( "cc: $1", 2 );
				$mailcc .= " $1";
			}
			else { last; }
			$j++;
		}
		$i++;
	} elsif( /\ASubject:\s+(.*)\Z/i ) {
		$subject = $1;
		$i++;
	} elsif( /\AMessage-Id:\s+(.*)\Z/i ) {
		$msg_id = $1;
		$i++;
	} elsif( /\ADate:\s+(.*)\Z/i ) {
		$dat = $1;
		$i++;
	} elsif ( /\AReply-To:\s+.*\Z/i ) {
		# omit Reply-To line
	} else {
		push( @mailtext, $_ );
		$i++;
	}
}

$txt = extract_body( @mailtext );
$txt =~ s/(['"])/\\$1/g;	# backslash quotes

if( $msg_id eq '' ){ $msg_id = $dat; }
if( $msg_id eq '' ){
	$msg_id = 'undefined';
	$status = $r{error};
}

debug( "To: $mailto, Cc: $mailcc, Subj: $subject", 2 );
debug( "fromlong: $fromlong, frompos: $frompos, msg-id: $msg_id", 2 );

# check to: and cc:
if( !is_err( $status ) && ( $mailto eq '' ) && ( $mailcc eq '' )){
	$status = $r{bcc_not_allowed};
}

$dbh = db_connect;

if( is_err( $status )) {
	%rec = (
		msg_id		=> $msg_id,
		proj_addr	=> $proj_addr,
		addr_to		=> $mailto,
		addr_cc		=> $mailcc,
		subject		=> $subject,
		sender		=> $fromlong,
		memb_id		=> $mid,
		send		=> $dat,
		body		=> $txt
	);
	$rec_id = db_insert_receive( $dbh, %rec );
}
elsif( !( $s = db_count( $dbh, 'receive', "msg_id = '$msg_id'" ))) {
	debug( "NumEntry in receive: $s", 2 );
	( $fromaddr, undef ) = split_email_addr( $fromlong );	# ignore alias
	$mid = db_get_memb_id( $dbh, $fromaddr );
	$fromlong =~ s/(['"])/\\$1/g;	# backslash quotes
	$subject =~ s/(['"])/\\$1/g;	# backslash quotes
	$mailto =~ s/(['"])/\\$1/g;	# backslash quotes
	$mailcc =~ s/(['"])/\\$1/g;	# backslash quotes
	$_ = "$mailto $mailcc";		# concat to: and cc: addresses
	s/,|<|>|(|)//g;
	debug( $_, 2 );
	while(( !is_err( $status )) && ( /(\S+)\@$ot{maildom}/g )){
		$proj_addr = $1;
		$proj_addr =~ s/^\s+//;
		$proj_addr =~ s/\s+$//;
		if( $proj_addr eq "$ot{bb_addr}" ) {	# avoid mixed-mode
			if( $status == $r{ok_ab_mode} ) {
				$status = $r{mixed_mode}; 
			} else {
				$status = $r{ok_bb_mode};
			}
		} else {
			if( $status == $r{ok_bb_mode} ) {
				$status = $r{mixed_mode};
			} else {
				$status = $r{ok_ab_mode};
			}
		}
#		if( !is_err( $status )) { push( @p_addr, $proj_addr ); }
		if(( $proj_addr ne 'stefan' )
			&& ( $proj_addr ne 'stefan.meretz' )
			&& ( $proj_addr ne 'meretz' )
			&& ( $proj_addr ne 'anonym' )
			&& ( $proj_addr ne 'listmaster' )
			&& ( $proj_addr ne 'webmaster' )) {
			push( @p_addr, $proj_addr );
		}
	}
	foreach $proj_addr ( @p_addr ) {
		%rec = (
		msg_id		=> $msg_id,
		proj_addr	=> $proj_addr,
		addr_to		=> $mailto,
		addr_cc		=> $mailcc,
		subject		=> $subject,
		sender		=> $fromlong,
		memb_id		=> $mid,
		send		=> $dat,
		body		=> $txt
		);
		if( !( $rec_id = db_insert_receive( $dbh, %rec ))) {
			$status = $r{error};
		}
		if( is_err( $status )) { last; }
	}
}
if( is_err( $status )) {
	$cmd_id = int( rand( 1000000000 ));
	db_insert_cmd( $dbh, $rec_id, $cmd_id, 1, 'receive', '' );
	db_set_status( $dbh, $cmd_id, $status );
}
db_disconnect( $dbh );
return( $status, $msg_id, $fromlong );
}
1;
