#!/usr/bin/perl

# $Id: cvsmail.pl 1.6 Wed, 09 Jun 1999 19:54:11 -0500 vulcan $
#
# Copyright 1999 Sidney Cammeresi.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

##############################################################################
## INSTALLATION INSTRUCTIONS:
##
## 1. Copy this file to $CVSROOT/CVSROOT.
## 2. Edit paths for perl and sendmail.
## 3. Create a .list file for each module to use this script containing the
##    e-mail addresses which should receive logs for that module.
## 4. Create a file $CVSROOT/CVSROOT/users with entries like the following
##
##         sac     Sidney Cammeresi <sac@omni.cx>
##
##    to match user ids to e-mail addresses.
## 5. Add a line like
##
##         DEFAULT (echo %s; cat) | `cat CVS/Root`/CVSROOT/cvsmail.pl
##
##    to $CVSROOT/CVSROOT/loginfo.  DON'T use the environment variable
##    CVSROOT here!  Some people might not have it set.  The content of
##    CVS/Root is safer since it must exist in a valid repository.
##
## You can disable this script for a module by setting its .list file to
## mode 0 or by moving away the .list file.
##############################################################################

###########################
##       constants       ##
###########################
$debug = 0;
$sendmail = "/usr/sbin/sendmail";
###########################
## don't edit below here ##
###########################

$cvsroot = `cat CVS/Root`;
$user = `whoami`;
$host = `hostname`;
chomp ($cvsroot);
chomp ($user);
chomp ($host);

$_ = <STDIN>;
$debug && print "a " . $_;
$split1 = index ($_, ' ', 0);
$split2 = index ($_, '/', 0);
$splitat = ($split2 == -1) ? $split1 : $split2;
if ($split2 != -1)
{
	$subdir = substr ($_, $split2 + 1, $split1 - $split2 - 1) . '/';
}

$module = substr ($_, 0, $splitat);

## get recipient list, if none, we're not supposed to do anything
open (DEST, "$cvsroot/CVSROOT/$module.list") || exit 0;
while (<DEST>)
{
	chomp ($_);
	if ($_ ne "")
	{
		$list .= $_ . ', ';
	}
}
close (DEST);
$list =~ s/ *$//;
$list =~ s/,$//;

## get sender's e-mail address
$email = "";
open (USERS, "$cvsroot/CVSROOT/users") || die ("no users");
while (<USERS>)
{
	if (substr ($_, 0, length ($user)) eq $user)
	{
		$email = substr ($_, length ($user) + 1, length ($_) -
			length ($user) - 1);
		chomp ($email);
	}
}
close (USERS);
($email ne "") || die ("no address in CVSROOT/users");

## open pipe to sendmail
close (STDOUT);
open (STDOUT, "|$sendmail -t");
print "From: $email\n";
print "To: $email\n";
print "Bcc: $list\n";
print "Subject: CVS: $module\n";
print "X-CVS-Log: module $module\n";
print "\n";

## output
print "CVSROOT:        $cvsroot\n";
print "Module name:    $module\n";
print "Changes by:     $user" . "@" . "$host\n";

$state = 0;
while (<STDIN>)
{
	if ($_ !~ /^\s/)
	{
		$state = 0;
	}

	if (($_ =~ /Update of/) || ($_ =~ /In directory/))
	{
		$debug && print "b " . $_;
	}
	elsif (($_ =~ /Modified Files:/) || ($state == 1))
	{
		if ($state != 1)
		{
			$debug && print "c " . $_;
			print "\n" . $_;
			$state = 1;
		}
		else
		{
			$debug && print "e " . $_;
			foreach $file (split (' ', $_))
			{
				print "        $subdir$file\n";
			}
		}
	}
	elsif (($_ =~ /Added Files:/) || ($state == 2))
	{
		if ($state != 2)
		{
			$debug && print "f " . $_;
			print "\n" . $_;
			$state = 2;
		}
		else
		{
			$debug && print "g " . $_;
			foreach $file (split (' ', $_))
			{
				print "        $subdir$file\n";
			}
		}
	}
	elsif (($_ =~ /Removed Files:/) || ($state == 3))
	{
		if ($state != 3)
		{
			$debug && print "h " . $_;
			print "\n" . $_;
			$state = 3;
		}
		else
		{
			$debug && print "i " . $_;
			foreach $file (split (' ', $_))
			{
				print "        $subdir$file\n";
			}
		}
	}
	elsif ($_ =~ /Log Message:/)
	{
		$debug && print "d " . $_;
		print "\n" . $_;
		$_ = <STDIN>;
		if ($_ =~ /Directory/)
		{
			$_ =~ s,$cvsroot/$module/,,;
			print $_;
		}
		else
		{
			print $_;
		}
		while (<STDIN>)
		{
			$debug && print "d " . $_;
			print $_;
		}
	}
	else
	{
		$debug && print "z " . $_;
	}
}

0;

