# notify.pl - implements the notify function.
#
# Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 by RIPE NCC
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
# AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# $Id: notify.pl,v 2.11 1999/10/06 16:41:15 marek Exp $
#
#	$RCSfile: notify.pl,v $
#	$Revision: 2.11 $
#	$Author: marek $
#	$Date: 1999/10/06 16:41:15 $


require "encmp.pl";
require "enwrite.pl";
require "entype.pl";
require "dpr.pl";

# It consists of two parts. One is the part that writes out the objects
# to temp files, one temp file per notifier, and this is called from
# updatecheck, the second part should be called at the end of an update
# from dbupdate, and will actually mail out the notify messages.

# %notify is (should be) local to this file and is reset in SendNotifications

#
# notify.pl
#
# exports
#   AddNotify  
#   DoAddNotify
#   SendNotifications
#
# AddNotify & DoAddNotify take two objects, the old and the new.
#  AddNotify finds notifees from the objects
#  DoAddNotify is given an explicit list.
#
# Both store notifications in a tmp file. SendNotifications sends
# these stored notifications.
#

# AddNotify
#
# build list of addresses to notify, give them to DoAddNotify

sub AddNotify {
    local(*old, *new) = @_;

    #
    # add guardians in case they happen to exist for
    # backward compatibility

    if (($old{"ny"}) || ($old{"gd"})) {
       
       local(@notifiers)=split(/\n+/, $old{"ny"}."\n".$old{"gd"});
	
       &DoAddNotify(*notifiers, *old, *new) if (scalar(@notifiers));
    
    }
    elsif ((!%old) && (($new{"ny"}) || ($new{"gd"}))) {
    
       local(@notifiers)=split(/\n+/, $new{"ny"}."\n".$new{"gd"});
	
       &DoAddNotify(*notifiers, *old, *new) if (scalar(@notifiers));
    
    }
    
}

# DoAddNotify
#
# foreach unique notifiee
#   create notification message in temporary file if not already there
#   append notification of this object

sub DoAddNotify {
    local(*notifiers, *old, *new) = @_;

    local(%notifiers)=();

    # persistent (?) hash of temporary filenames for messages
    # %notify

    foreach $notify (@notifiers) {
        
#        &dpr("notifier: $notify\n");
        
        #
        # skip doubles
        
        next unless $notify;
        next if ($notifiers{$notify});

        $notifiers{$notify}++;
        
        #
	# check whether notifiee matches sender of update
	# behaviour is defined by SUPPRESSMESS in config file
        
	{
	  my($regularnotify) = &MakeRegular($notify);

	  my ($match) = ($REPLYTO=~ /$regularnotify/);

#	  &dpr("DoAddNotify: ",
#	       "notifiee [$notify], ",
#	       "sender [$REPLYTO], ",
#	       "regexp [$regularnotify]",
#	       "match [$match]",
#	       "\n");

	  if ($match) {
	    if ($SUPPRESSMESS eq 'NOTIFY') {    # suppress notification
	      next;
	    } elsif ($SUPPRESSMESS eq 'ACK') {  # suppress acknowledgement
	      # set flag for updatedb()
	      $::DontAck = $notify;
	    } 
	    # else send both
	  }
	}

	if (!$notify{$notify}) {
	    $notify{$notify} = &NotifyTmpFile($notify);
	    open(NOTIFY, ">".$notify{$notify}) ||
		&syslog("ERRLOG", "Cannot create notify file $notify{$notify}");
	    &WriteNotifyHeader(NOTIFY, $notify);
	}
	else {
	    open(NOTIFY, ">>".$notify{$notify}) ||
		&syslog("ERRLOG", "Cannot open notify file $notify{$notify}");
	}
	
	print NOTIFY "---\n";
	
	if (!%new) { # Deletion
	   print NOTIFY "OBJECT BELOW DELETED:\n";
	   &enwrite(NOTIFY,*old,1,0,1);
	}
	elsif (!%old) {
	   print NOTIFY "OBJECT BELOW CREATED:\n";
	   &enwrite(NOTIFY,*new,1,0,1);
	}
	else {
	   print NOTIFY "PREVIOUS OBJECT:\n";
	   &enwrite(NOTIFY,*old,1,0,1);
	   print NOTIFY "\nREPLACED BY:\n";
	   &enwrite(NOTIFY,*new,1,0,1);
	}
	
	print NOTIFY "\n";
	
	close(NOTIFY);
    
    }

}


# return name of temporary file for notify message

sub NotifyTmpFile {

    return $TMPDIR."\/".$_[0].".".$$;
    
}

# generate appropriate message header

sub WriteNotifyHeader {
    local($filehandle, $notifier)=@_;

    if ($TESTMODE) {
	$orignotifier = $notifier;
	$notifier=$DEFMAIL;
	print $filehandle $NHEADER, "To: ", $notifier, "\n";
	print $filehandle "X-Notify_Orig_Recipient: ", $orignotifier, "\n\n";
	print $filehandle $NOTITXT;
    }
    else {
        print $filehandle $NHEADER, "To: ", $notifier, "\n\n", $NOTITXT;
    }
    
    if ($NETWORKUPDATE) {
       print $filehandle $NOTINETWORKTXT, "\n";
    }
    else {
       print $filehandle $NOTIMAILTXT, "\n";
    }
    
}    

# feed temporary notify message files to mail system

sub SendNotifications {

    foreach (values %notify) {
       system("$MAILCMD < $_");
#       &dpr("notify: $_\n");
    }
    
    unlink(values %notify);
    
    %notify=();
    
}
