xref: /netbsd-src/external/gpl2/xcvs/dist/contrib/log.in (revision a7c918477dd5f12c1da816ba05caf44eab2d06d6)
1*a7c91847Schristos#! @PERL@ -T
2*a7c91847Schristos# -*-Perl-*-
3*a7c91847Schristos
4*a7c91847Schristos# Copyright (C) 1994-2005 The Free Software Foundation, Inc.
5*a7c91847Schristos
6*a7c91847Schristos# This program is free software; you can redistribute it and/or modify
7*a7c91847Schristos# it under the terms of the GNU General Public License as published by
8*a7c91847Schristos# the Free Software Foundation; either version 2, or (at your option)
9*a7c91847Schristos# any later version.
10*a7c91847Schristos#
11*a7c91847Schristos# This program is distributed in the hope that it will be useful,
12*a7c91847Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a7c91847Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a7c91847Schristos# GNU General Public License for more details.
15*a7c91847Schristos
16*a7c91847Schristos###############################################################################
17*a7c91847Schristos###############################################################################
18*a7c91847Schristos###############################################################################
19*a7c91847Schristos#
20*a7c91847Schristos# THIS SCRIPT IS PROBABLY BROKEN.  REMOVING THE -T SWITCH ON THE #! LINE ABOVE
21*a7c91847Schristos# WOULD FIX IT, BUT THIS IS INSECURE.  WE RECOMMEND FIXING THE ERRORS WHICH THE
22*a7c91847Schristos# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS
23*a7c91847Schristos# SERVER TRIGGER.  PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND
24*a7c91847Schristos# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE
25*a7c91847Schristos# <@PACKAGE_BUGREPORT@> MAILING LIST.
26*a7c91847Schristos#
27*a7c91847Schristos# For more on general Perl security and taint-checking, please try running the
28*a7c91847Schristos# `perldoc perlsec' command.
29*a7c91847Schristos#
30*a7c91847Schristos###############################################################################
31*a7c91847Schristos###############################################################################
32*a7c91847Schristos###############################################################################
33*a7c91847Schristos
34*a7c91847Schristos# XXX: FIXME: handle multiple '-f logfile' arguments
35*a7c91847Schristos#
36*a7c91847Schristos# XXX -- I HATE Perl!  This *will* be re-written in shell/awk/sed soon!
37*a7c91847Schristos#
38*a7c91847Schristos
39*a7c91847Schristos# Usage:  log.pl [-u user] [[-m mailto] ...] [-s] [-V] -f logfile 'dirname file ...'
40*a7c91847Schristos#
41*a7c91847Schristos#	-u user		- $USER passed from loginfo
42*a7c91847Schristos#	-m mailto	- for each user to receive cvs log reports
43*a7c91847Schristos#			(multiple -m's permitted)
44*a7c91847Schristos#	-s		- to prevent "cvs status -v" messages
45*a7c91847Schristos#	-V		- without '-s', don't pass '-v' to cvs status
46*a7c91847Schristos#	-f logfile	- for the logfile to append to (mandatory,
47*a7c91847Schristos#			but only one logfile can be specified).
48*a7c91847Schristos
49*a7c91847Schristos# here is what the output looks like:
50*a7c91847Schristos#
51*a7c91847Schristos#    From: woods@kuma.domain.top
52*a7c91847Schristos#    Subject: CVS update: testmodule
53*a7c91847Schristos#
54*a7c91847Schristos#    Date: Wednesday November 23, 1994 @ 14:15
55*a7c91847Schristos#    Author: woods
56*a7c91847Schristos#
57*a7c91847Schristos#    Update of /local/src-CVS/testmodule
58*a7c91847Schristos#    In directory kuma:/home/kuma/woods/work.d/testmodule
59*a7c91847Schristos#
60*a7c91847Schristos#    Modified Files:
61*a7c91847Schristos#    	test3
62*a7c91847Schristos#    Added Files:
63*a7c91847Schristos#    	test6
64*a7c91847Schristos#    Removed Files:
65*a7c91847Schristos#    	test4
66*a7c91847Schristos#    Log Message:
67*a7c91847Schristos#    - wow, what a test
68*a7c91847Schristos#
69*a7c91847Schristos# (and for each file the "cvs status -v" output is appended unless -s is used)
70*a7c91847Schristos#
71*a7c91847Schristos#    ==================================================================
72*a7c91847Schristos#    File: test3           	Status: Up-to-date
73*a7c91847Schristos#
74*a7c91847Schristos#       Working revision:	1.41	Wed Nov 23 14:15:59 1994
75*a7c91847Schristos#       Repository revision:	1.41	/local/src-CVS/cvs/testmodule/test3,v
76*a7c91847Schristos#       Sticky Options:	-ko
77*a7c91847Schristos#
78*a7c91847Schristos#       Existing Tags:
79*a7c91847Schristos#    	local-v2                 	(revision: 1.7)
80*a7c91847Schristos#    	local-v1                 	(revision: 1.1.1.2)
81*a7c91847Schristos#    	CVS-1_4A2                	(revision: 1.1.1.2)
82*a7c91847Schristos#    	local-v0                 	(revision: 1.2)
83*a7c91847Schristos#    	CVS-1_4A1                	(revision: 1.1.1.1)
84*a7c91847Schristos#    	CVS                      	(branch: 1.1.1)
85*a7c91847Schristos
86*a7c91847Schristosuse strict;
87*a7c91847Schristosuse IO::File;
88*a7c91847Schristos
89*a7c91847Schristosmy $cvsroot = $ENV{'CVSROOT'};
90*a7c91847Schristos
91*a7c91847Schristos# turn off setgid
92*a7c91847Schristos#
93*a7c91847Schristos$) = $(;
94*a7c91847Schristos
95*a7c91847Schristosmy $dostatus = 1;
96*a7c91847Schristosmy $verbosestatus = 1;
97*a7c91847Schristosmy $users;
98*a7c91847Schristosmy $login;
99*a7c91847Schristosmy $donefiles;
100*a7c91847Schristosmy $logfile;
101*a7c91847Schristosmy @files;
102*a7c91847Schristos
103*a7c91847Schristos# parse command line arguments
104*a7c91847Schristos#
105*a7c91847Schristoswhile (@ARGV) {
106*a7c91847Schristos	my $arg = shift @ARGV;
107*a7c91847Schristos
108*a7c91847Schristos	if ($arg eq '-m') {
109*a7c91847Schristos		$users = "$users " . shift @ARGV;
110*a7c91847Schristos	} elsif ($arg eq '-u') {
111*a7c91847Schristos		$login = shift @ARGV;
112*a7c91847Schristos	} elsif ($arg eq '-f') {
113*a7c91847Schristos		($logfile) && die "Too many '-f' args";
114*a7c91847Schristos		$logfile = shift @ARGV;
115*a7c91847Schristos	} elsif ($arg eq '-s') {
116*a7c91847Schristos		$dostatus = 0;
117*a7c91847Schristos	} elsif ($arg eq '-V') {
118*a7c91847Schristos		$verbosestatus = 0;
119*a7c91847Schristos	} else {
120*a7c91847Schristos		($donefiles) && die "Too many arguments!\n";
121*a7c91847Schristos		$donefiles = 1;
122*a7c91847Schristos		@files = split(/ /, $arg);
123*a7c91847Schristos	}
124*a7c91847Schristos}
125*a7c91847Schristos
126*a7c91847Schristos# the first argument is the module location relative to $CVSROOT
127*a7c91847Schristos#
128*a7c91847Schristosmy $modulepath = shift @files;
129*a7c91847Schristos
130*a7c91847Schristosmy $mailcmd = "| Mail -s 'CVS update: $modulepath'";
131*a7c91847Schristos
132*a7c91847Schristos# Initialise some date and time arrays
133*a7c91847Schristos#
134*a7c91847Schristosmy @mos = ('January','February','March','April','May','June','July',
135*a7c91847Schristos	'August','September','October','November','December');
136*a7c91847Schristosmy @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
137*a7c91847Schristos
138*a7c91847Schristosmy ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
139*a7c91847Schristos$year += 1900;
140*a7c91847Schristos
141*a7c91847Schristos# get a login name for the guy doing the commit....
142*a7c91847Schristos#
143*a7c91847Schristosif ($login eq '') {
144*a7c91847Schristos	$login = getlogin || (getpwuid($<))[0] || "nobody";
145*a7c91847Schristos}
146*a7c91847Schristos
147*a7c91847Schristos# open log file for appending
148*a7c91847Schristos#
149*a7c91847Schristosmy $logfh = new IO::File ">>" . $logfile
150*a7c91847Schristos	or die "Could not open(" . $logfile . "): $!\n";
151*a7c91847Schristos
152*a7c91847Schristos# send mail, if there's anyone to send to!
153*a7c91847Schristos#
154*a7c91847Schristosmy $mailfh;
155*a7c91847Schristosif ($users) {
156*a7c91847Schristos	$mailcmd = "$mailcmd $users";
157*a7c91847Schristos	$mailfh = new IO::File $mailcmd
158*a7c91847Schristos		or die "Could not Exec($mailcmd): $!\n";
159*a7c91847Schristos}
160*a7c91847Schristos
161*a7c91847Schristos# print out the log Header
162*a7c91847Schristos#
163*a7c91847Schristos$logfh->print ("\n");
164*a7c91847Schristos$logfh->print ("****************************************\n");
165*a7c91847Schristos$logfh->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n");
166*a7c91847Schristos$logfh->print ("Author:\t$login\n\n");
167*a7c91847Schristos
168*a7c91847Schristosif ($mailfh) {
169*a7c91847Schristos	$mailfh->print ("\n");
170*a7c91847Schristos	$mailfh->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n");
171*a7c91847Schristos	$mailfh->print ("Author:\t$login\n\n");
172*a7c91847Schristos}
173*a7c91847Schristos
174*a7c91847Schristos# print the stuff from logmsg that comes in on stdin to the logfile
175*a7c91847Schristos#
176*a7c91847Schristosmy $infh = new IO::File "< -";
177*a7c91847Schristosforeach ($infh->getlines) {
178*a7c91847Schristos	$logfh->print;
179*a7c91847Schristos	if ($mailfh) {
180*a7c91847Schristos		$mailfh->print ($_);
181*a7c91847Schristos	}
182*a7c91847Schristos}
183*a7c91847Schristosundef $infh;
184*a7c91847Schristos
185*a7c91847Schristos$logfh->print ("\n");
186*a7c91847Schristos
187*a7c91847Schristos# after log information, do an 'cvs -Qq status -v' on each file in the arguments.
188*a7c91847Schristos#
189*a7c91847Schristosif ($dostatus != 0) {
190*a7c91847Schristos	while (@files) {
191*a7c91847Schristos		my $file = shift @files;
192*a7c91847Schristos		if ($file eq "-") {
193*a7c91847Schristos			$logfh->print ("[input file was '-']\n");
194*a7c91847Schristos			if ($mailfh) {
195*a7c91847Schristos				$mailfh->print ("[input file was '-']\n");
196*a7c91847Schristos			}
197*a7c91847Schristos			last;
198*a7c91847Schristos		}
199*a7c91847Schristos		my $rcsfh = new IO::File;
200*a7c91847Schristos		my $pid = $rcsfh->open ("-|");
201*a7c91847Schristos		if ( !defined $pid )
202*a7c91847Schristos		{
203*a7c91847Schristos			die "fork failed: $!";
204*a7c91847Schristos		}
205*a7c91847Schristos		if ($pid == 0)
206*a7c91847Schristos		{
207*a7c91847Schristos			my @command = ('cvs', '-nQq', 'status');
208*a7c91847Schristos			if ($verbosestatus)
209*a7c91847Schristos			{
210*a7c91847Schristos				push @command, '-v';
211*a7c91847Schristos			}
212*a7c91847Schristos			push @command, $file;
213*a7c91847Schristos			exec @command;
214*a7c91847Schristos			die "cvs exec failed: $!";
215*a7c91847Schristos		}
216*a7c91847Schristos		my $line;
217*a7c91847Schristos		while ($line = $rcsfh->getline) {
218*a7c91847Schristos			$logfh->print ($line);
219*a7c91847Schristos			if ($mailfh) {
220*a7c91847Schristos				$mailfh->print ($line);
221*a7c91847Schristos			}
222*a7c91847Schristos		}
223*a7c91847Schristos		undef $rcsfh;
224*a7c91847Schristos	}
225*a7c91847Schristos}
226*a7c91847Schristos
227*a7c91847Schristos$logfh->close()
228*a7c91847Schristos	or die "Write to $logfile failed: $!";
229*a7c91847Schristos
230*a7c91847Schristosif ($mailfh)
231*a7c91847Schristos{
232*a7c91847Schristos	$mailfh->close;
233*a7c91847Schristos	die "Pipe to $mailcmd failed" if $?;
234*a7c91847Schristos}
235*a7c91847Schristos
236*a7c91847Schristos## must exit cleanly
237*a7c91847Schristos##
238*a7c91847Schristosexit 0;
239