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