#!/usr/bin/perl
#
# Strategy:
# Collect any local mails that are addressed to users who have (probably
# now) a different home node. Put these mails in the forwarding queue
# to their home node or bring them up into the local mailbox.
#
# Last updated: DL6RAI, Thu Apr 27 12:22:59 GMT 2000


$home = (getpwnam('clx_us'))[7];
$db_name = "clx_db";
$psql = "psql -d $db_name -qtc";
$pg_version = (split(' ',`psql -qtc \"select version();\"`))[1];

$qry = "";
$cmd = sprintf("%s \"%s\"",$psql,$qry);
$rc = system($cmd);
die "Cannot contact Postmaster - file cannot be sent.\n" if ($rc != 0);

# determine my own call first
$cfg="$home/config/clx_par";
die "No configuration file ($cfg) found - aborting.\n" if ( ! -e $cfg );
open(CFG,"$cfg");
while(<CFG>) {
	chop;
        if (/^call:/) { 
		$code=(split(/[\t\s]+/,$_,3))[1];
	}
}
$cl_call=`clx_ctl -e \"$code\"`;
chop($cl_call);
$cl_call =~ s/-[0-9]+$//;

# Phase 1:
# Select all messages in the local mailbox whose owner has a
# different home node and which are not already read by the 
# owner.
print "Checking for mail to go to remote nodes.\n";
$qry = "select distinct on us_call
	a.f_name,a.f_ldir,b.us_call,b.hn_call,b.hn_ssid 
	from ml_file a, us_uhn b 
	where a.f_ldir=b.us_call 
	and b.hn_call!='$cl_call'
	and a.f_readc<10000 
	and f_thema='mail'";

if ( $pg_version ge '7' ) {
	$qry =~ s/distinct on us_call/distinct on \(us_call\)/;
}

$cmd = sprintf("%s \"%s\"",$psql,$qry);

open(LIST,"$cmd |");
while(<LIST>) {
	chop;
	s/ //g;
	next if /^$/;
	($f_name,$f_ldir,$us_call,$hn_call,$hn_ssid) = split(/\|/);

	# determine the node callsign
	if ($hn_ssid ne 0) {
		$new_f_ldir=sprintf("%s-%s",$hn_call,$hn_ssid);
	} else {
		$new_f_ldir=$hn_call;
	}

	# remember the to-callsign
	$new_f_indx = $f_ldir;

	# determine the forwarding dir if it does not exist
	$to_dir = "$home/box/iclb/$new_f_ldir";
	mkdir ($to_dir,0755) if ( ! -d  $to_dir);
	$from_dir = "$home/box/mail/$f_ldir";

	# get new message number from ml_dir, d_count and
	# update d_last (current date and time), latest number+1
	$now = gmtime();
	$qry = "select d_count from ml_dir where d_name='iclb'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	$nr = (`$cmd` % 99999) + 1; # 1-99999
	$qry = "update ml_dir set d_count=$nr, 
		d_last='$now' where d_name='iclb'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	system("$cmd");

	# move file from mailbox to forwarding dir
	$cmd = "/bin/mv $from_dir/$f_name $to_dir/$nr";
	system("$cmd");

	# update ml_file 
	$qry = "update ml_file set f_name=$nr,f_thema='iclb',
		f_ldir='$new_f_ldir',f_cntr=$nr,
		f_indx='$new_f_indx',f_readc=0,f_cto='$new_f_ldir'
		where f_name='$f_name' and f_thema='mail'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	system("$cmd");

	# done: show result
	printf("do_fwd: moved mail #%d, to %s@%s (#%d)\n",
		$f_name,$f_ldir,$new_f_ldir,$nr);

}
close(LIST);

# Phase 2:
# Select all messages in the forwarding queue whose owner has (now)
# a different home node (but not our own call). The complicated 
# construction is there to treat the SSID field hn_ssid correctly:
#
# case 1: compare us_uhn.hn_call='db0bcc' us_uhn.hn_ssid=0 to 'db0bcc'
# case 2: compare us_uhn.hn_call='gb7mdx' us_uhn.hn_ssid=7 to 'gb7mdx-7'
#
print "Checking for mail in the FWQ which must go to a different node.\n";
$qry = "select distinct on us_call
	a.f_name,a.f_ldir,a.f_indx,b.us_call,b.hn_call,b.hn_ssid 
	from ml_file a, us_uhn b 
	where a.f_indx=b.us_call
	and ( ( a.f_ldir!=b.hn_call and b.hn_ssid=0 )
		or
	      ( a.f_ldir!=(b.hn_call || '-' || text(b.hn_ssid)) 
		and 
		b.hn_ssid!=0 )
	)
	and b.hn_call!='$cl_call'
	and f_thema='iclb'";

if ( $pg_version ge '7' ) {
	$qry =~ s/distinct on us_call/distinct on \(us_call\)/;
}

$cmd = sprintf("%s \"%s\"",$psql,$qry);

open(LIST,"$cmd |");
while(<LIST>) {
	chop;
	s/ //g;
	next if /^$/;
	($f_name,$f_ldir,$f_indx,$us_call,$hn_call,$hn_ssid) = split(/\|/);

	# determine the node callsign
	if ($hn_ssid ne 0) {
		$new_f_ldir=sprintf("%s-%s",$hn_call,$hn_ssid);
	} else {
		$new_f_ldir=$hn_call;
	}

	# determine the forwarding dir if it does not exist
	$to_dir = "$home/box/iclb/$new_f_ldir";
	mkdir ($to_dir,0755) if ( ! -d  $to_dir);
	$from_dir = "$home/box/iclb/$f_ldir";

	# move file from old forwarding dir to new forwarding dir
	$cmd = "/bin/mv $from_dir/$f_name $to_dir";
	system("$cmd");

	# update ml_file 
	$qry = "update ml_file set f_ldir='$new_f_ldir',f_cto='$new_f_ldir'
		where f_name='$f_name' and f_thema='iclb'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	system("$cmd");

	# done: show result
	printf("do_fwd: moved mail #%d, from %s@%s to %s@%s\n",
		$f_name,$f_indx,$f_ldir,$f_indx,$new_f_ldir);

}

# Phase 3:
# Select all messages in the forwarding queue whose owner has (now)
# our own node as home node. 
#
print "Checking for mail in the FWQ which should go local.\n";
$qry = "select distinct on us_call
	a.f_name,a.f_ldir,a.f_indx,b.us_call,b.hn_call,b.hn_ssid 
	from ml_file a, us_uhn b 
	where a.f_indx=b.us_call
	and b.hn_call='$cl_call'
	and f_thema='iclb'";

if ( $pg_version ge '7' ) {
	$qry =~ s/distinct on us_call/distinct on \(us_call\)/;
}

$cmd = sprintf("%s \"%s\"",$psql,$qry);
close(LIST);

open(LIST,"$cmd |");
while(<LIST>) {
	chop;
	s/ //g;
	next if /^$/;
	($f_name,$f_ldir,$f_indx,$us_call,$hn_call,$hn_ssid) = split(/\|/);

	# get new message number from ml_dir, d_count and
	# update d_last (current date and time), latest number+1
	$now = gmtime();
	$qry = "select d_count from ml_dir where d_name='mail'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	$nr = (`$cmd` % 99999) + 1; # 1-99999
	$qry = "update ml_dir set d_count=$nr, 
		d_last='$now' where d_name='mail'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	system("$cmd");

	# determine the forwarding dir if it does not exist
	$to_dir = "$home/box/mail/$f_indx";
	mkdir ($to_dir,0755) if ( ! -d  $to_dir);
	$from_dir = "$home/box/iclb/$f_ldir";

	# move file from old forwarding dir to local mailbox
	$cmd = "/bin/mv $from_dir/$f_name $to_dir/$nr";
	system("$cmd");

	# update ml_file 
	$qry = "update ml_file set f_name=$nr,f_cntr=$nr,f_thema='mail',
		f_ldir='$f_indx',f_cto='$f_indx'
		where f_name='$f_name' and f_thema='iclb'";
	$cmd = sprintf("%s \"%s\"",$psql,$qry);
	system("$cmd");

	# done: show result
	printf("do_fwd: moved mail #%d, from %s@%s to %s (local) (#%d)\n",
		$f_name,$f_indx,$f_ldir,$f_indx,$nr);

}
close(LIST);
