cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] ccvs/contrib ChangeLog commit_prep.pl log_accum.pl


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/contrib ChangeLog commit_prep.pl log_accum.pl
Date: Mon, 08 May 2006 21:25:32 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         
Changes by:     Derek Robert Price <address@hidden>     06/05/08 21:25:32

Modified files:
        contrib        : ChangeLog commit_prep.pl log_accum.pl 

Log message:
        * commit_prep.pl: Option -T added to support multiple log_accum hooks.
        Deprecated misleading -u option.  Used 'use strict' and added
        compatibility for 'perl -T' switch.  Documented some more.  Removed
        $cvs_user in the temporary filename.
        * log_accum.pl: -T added again to support multiple log_accum hooks.
        Used 'use strict' and added compatibility for 'perl -T' switch.
        Removed ghost variable.  Documented some more.  Fixed a bug in
        processing -u in log_accum.  Cleaned-up the temporary filenames.  Fixed
        support for UseNewInfoFmtStrings.  Test if files are empty, so they are
        not reported as binary.
        (Patch from Sylvain Beucler <address@hidden>.)
        
        * log_accum.pl (process_argv): Untaint filenames, oldrevs, and newrevs.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/contrib/ChangeLog.diff?tr1=1.180&tr2=1.181&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/contrib/commit_prep.pl.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/contrib/log_accum.pl.diff?tr1=1.12&tr2=1.13&r1=text&r2=text

Patches:
Index: ccvs/contrib/ChangeLog
diff -u ccvs/contrib/ChangeLog:1.180 ccvs/contrib/ChangeLog:1.181
--- ccvs/contrib/ChangeLog:1.180        Tue Apr 18 16:07:40 2006
+++ ccvs/contrib/ChangeLog      Mon May  8 21:25:32 2006
@@ -1,3 +1,19 @@
+2006-05-08  Derek Price  <address@hidden>
+
+       * commit_prep.pl: Option -T added to support multiple log_accum hooks.
+       Deprecated misleading -u option.  Used 'use strict' and added
+       compatibility for 'perl -T' switch.  Documented some more.  Removed
+       $cvs_user in the temporary filename.
+       * log_accum.pl: -T added again to support multiple log_accum hooks.
+       Used 'use strict' and added compatibility for 'perl -T' switch.
+       Removed ghost variable.  Documented some more.  Fixed a bug in
+       processing -u in log_accum.  Cleaned-up the temporary filenames.  Fixed
+       support for UseNewInfoFmtStrings.  Test if files are empty, so they are
+       not reported as binary.
+       (Patch from Sylvain Beucler <address@hidden>.)
+
+       * log_accum.pl (process_argv): Untaint filenames, oldrevs, and newrevs.
+
 2006-04-18  Mark D. Baushke  <address@hidden>
 
        * cvslog.sh: Bourne Shell variation of log.pl functionality.
Index: ccvs/contrib/commit_prep.pl
diff -u ccvs/contrib/commit_prep.pl:1.5 ccvs/contrib/commit_prep.pl:1.6
--- ccvs/contrib/commit_prep.pl:1.5     Thu Oct  6 20:25:12 2005
+++ ccvs/contrib/commit_prep.pl Mon May  8 21:25:32 2006
@@ -13,74 +13,103 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-###############################################################################
-###############################################################################
-###############################################################################
-#
-# THIS SCRIPT IS PROBABLY BROKEN.  REMOVING THE -T SWITCH ON THE #! LINE ABOVE
-# WOULD FIX IT, BUT THIS IS INSECURE.  WE RECOMMEND FIXING THE ERRORS WHICH THE
-# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS
-# SERVER TRIGGER.  PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND
-# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE
-# <@PACKAGE_BUGREPORT@> MAILING LIST.
-#
-# For more on general Perl security and taint-checking, please try running the
-# `perldoc perlsec' command.
-#
-###############################################################################
-###############################################################################
-###############################################################################
-
-# Perl filter to handle pre-commit checking of files.  This program
-# records the last directory where commits will be taking place for
-# use by the log_accum.pl script.
+# Perl filter to handle pre-commit checking of files.
 #
-# IMPORTANT: this script interacts with log_accum, they have to agree
-# on the tmpfile name to use.  See $LAST_FILE below.
+# The CVS workflow is:
+# - process all commitinfo hooks
+# - actually commit
+# - process all loginfo hooks
+#
+# This program records the last directory where commits will be taking
+# place for use by the log_accum.pl script.
+#
+# IMPORTANT: commit_prep and log_accumy have to agree on the tmpfile
+# name to use.  See $LAST_FILE below.
+#
+# Sample CVSROOT/commitinfo:
+# ALL /usr/local/bin/commit_prep -T ccvs_1 %r/%p
+# ^prog1\(/\|$\) /usr/local/bin/commit_prep -T ccvs_2 %r/%p
 #
 # Contributed by David Hampton <address@hidden>
 # Stripped to minimum by Roy Fielding
+# Changes by Sylvain Beucler <address@hidden> (2006-05-08):
+# - option -T added again to support multiple log_accum hooks
+# - deprecated misleading option -u
+# - used 'use strict' and added compatibility for 'perl -T' switch
+# - documented some more
+# - removed $cvs_user in the temporary filename - its value is not
+#   compatible with log_accum's and it's safer to use -T
 #
 ############################################################
-$TMPDIR        = $ENV{'TMPDIR'} || '/tmp';
-$FILE_PREFIX   = '#cvs.';
 
-# If see a "-u $USER" argument, then destructively remove it from the
-# argument list, so $ARGV[0] will be the repository dir again, as it
-# used to be before we added the -u flag.
-if ($ARGV[0] eq '-u') {
-  shift @ARGV;
-  $CVS_USERNAME = shift (@ARGV);
+use strict;
+
+# CONSTANTS
+my $TMPDIR          = '/tmp';
+my $FILE_PREFIX     = '#cvs.';
+
+
+# Options
+my $hook_identifier = '';
+my $full_directory_path = '';
+
+while (@ARGV) {
+    my $arg = shift @ARGV;
+
+    # If see a "-u $USER" argument, then destructively remove it from
+    # the argument list, so $ARGV[0] will be the repository dir again,
+    # as it used to be before we added the -u flag.
+    # This option was used to build $LIST_FILE, but this is not safe
+    # wrt multiple hooks. Check -T.
+    if ($arg eq '-u') {
+       my $param = shift (@ARGV);
+       if ($param =~ /^([a-zA-Z0-9_.-]+)$/) { # POSIX
+           $hook_identifier = $1;
+           warn "Using deprecated -u option. Use -T instead."
+       } else {
+           die "Invalid username passed to option -u: $param";
+       }
+    # -T is a string to be included in the $last_file filename. It is
+    # necessary to pass different -T options to commit_prep if you
+    # need to call it for different scripts in the same commit (eg:
+    # call log_accum with different parameters in module/ and in ALL)
+    } elsif ($arg eq '-T') {
+       my $param = shift (@ARGV);
+       if ($param =~ /^([a-zA-Z0-9_.-]+)$/) {
+           $hook_identifier = $1;
+       } else {
+           die "Invalid identifier passed to option -T: $param";
+       }
+    # The non-option argument is the complete path to the current
+    # commit directory
+    } else {
+       # It is written in a file and read by log_accum after being
+       # character-escaped. No security issues here. We still check
+       # for '..' and ensure this is a full path.
+       if (($arg !~ /\/..(\/|\$)/) and ($arg =~ /^(\/.*)$/)) {
+           $full_directory_path = $1;
+       } else {
+           die "Commit path must be a full path, not a relative one: $arg";
+       }
+    }
 }
 
-# This needs to match the corresponding var in log_accum.pl, including
-# the appending of the pgrp and username suffixes (see uses of this
-# var farther down).
-$LAST_FILE = "$TMPDIR/${FILE_PREFIX}lastdir";
-
-sub write_line {
-    my ($filename, $line) = @_;
-
-# A check of some kind is needed here, but the rules aren't apparent
-# at the moment:
-
-#    foreach($filename, $line){        
-#        $_ =~ m#^(address@hidden)$#;
-#        $_ = $1;
-#    }
-
-    open(FILE, ">$filename") || die("Cannot open $filename: $!\n");
-    print(FILE $line, "\n");
-    close(FILE);
+if ($full_directory_path eq '') {
+    die "Usage: $0 [-T hook_identifier] current_commit_path"
 }
 
-#
+
+# This needs to match the corresponding var in log_accum.pl, including
+# the appending of the pgrp and hook identifier suffixes (see uses of
+# this var farther down).
+my $id = getpgrp();
+my $last_file = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.lastdir";
+
 # Record this directory as the last one checked.  This will be used
 # by the log_accumulate script to determine when it is processing
 # the final directory of a multi-directory commit.
-#
-$id = getpgrp();
-
-&write_line("$LAST_FILE.$id.$CVS_USERNAME", $ARGV[0]);
+open(FILE, "> $last_file") || die("Cannot open $last_file: $!\n");
+print(FILE $full_directory_path, "\n");
+close(FILE);
 
 exit(0);
Index: ccvs/contrib/log_accum.pl
diff -u ccvs/contrib/log_accum.pl:1.12 ccvs/contrib/log_accum.pl:1.13
--- ccvs/contrib/log_accum.pl:1.12      Wed Oct 12 14:14:17 2005
+++ ccvs/contrib/log_accum.pl   Mon May  8 21:25:32 2006
@@ -13,31 +13,13 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-###############################################################################
-###############################################################################
-###############################################################################
-#
-# THIS SCRIPT IS PROBABLY BROKEN.  REMOVING THE -T SWITCH ON THE #! LINE ABOVE
-# WOULD FIX IT, BUT THIS IS INSECURE.  WE RECOMMEND FIXING THE ERRORS WHICH THE
-# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS
-# SERVER TRIGGER.  PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND
-# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE
-# <@PACKAGE_BUGREPORT@> MAILING LIST.
-#
-# For more on general Perl security and taint-checking, please try running the
-# `perldoc perlsec' command.
-#
-###############################################################################
-###############################################################################
-###############################################################################
-
 # Perl filter to handle the log messages from the checkin of files in
 # a directory.  This script will group the lists of files by log
 # message, and mail a single consolidated log message at the end of
 # the commit.
 #
 # This file assumes a pre-commit checking program that leaves the
-# names of the first and last commit directories in a temporary file.
+# names of the last commit directory in a temporary file.
 #
 # IMPORTANT: what the above means is, this script interacts with
 # commit_prep, in that they have to agree on the tmpfile name to use.
@@ -49,7 +31,7 @@
 # examining the contents of $LAST_FILE.  Between invocations, it
 # caches information for its future incarnations in various temporary
 # files in /tmp, which are named according to the process group and
-# the committer (by themselves, neither of these are unique, but
+# TODO the committer (by themselves, neither of these are unique, but
 # together they almost always are, unless the same user is doing two
 # commits simultaneously).  The final invocation is the one that
 # actually sends the mail -- it gathers up the cached information,
@@ -61,7 +43,17 @@
 # Contributed by David Hampton <address@hidden>
 # Roy Fielding removed useless code and added log/mail of new files
 # Ken Coar added special processing (i.e., no diffs) for binary files
-#
+# Changes by Sylvain Beucler <address@hidden> (2006-05-08):
+# - option -T added again to support multiple log_accum hooks
+# - used 'use strict' and added compatibility for 'perl -T' switch
+#   (and found a ghost variable!)
+# - documented some more
+# - fixed a bug in processing -u in log_accum
+# - cleaned-up the temporary filenames
+# - fixed support for UseNewInfoFmtStrings
+# - test if files are empty, so they are not reported as binary
+
+use strict;
 
 ############################################################
 #
@@ -78,28 +70,30 @@
 my $UseNewInfoFmtStrings = 1;
 
 #
-# Where do you want the RCS ID and delta info?
+# <s>Where do you want the RCS ID and delta info?</s> What additional info do 
you want in your mail?
 # 0 = none,
-# 1 = in mail only,
-# 2 = in both mail and logs.
+# 1 = <s>in mail only,</s> summaries
+# 2 = <s>in both mail and logs.</s> summaries twice??
 #
-$rcsidinfo = 2;
+my $rcsidinfo = 2;
 
 #if you are using CVS web then set this to some value... if not set it to ""
 #
 # When set properly, this will cause links to aspects of the project to
 # print in the commit emails.
-#$CVSWEB_SCHEME = "http";
-#$CVSWEB_DOMAIN = "nongnu.org";
-#$CVSWEB_PORT = "80";
-#$CVSWEB_URI = "source/browse/";
-#$SEND_URL = "true";
-$SEND_DIFF = "false";
+my $CVSWEB_SCHEME = "http";
+my $CVSWEB_DOMAIN = "cvs.sv.gnu.org";
+my $CVSWEB_PORT = "80";
+my $CVSWEB_URI = "viewcvs/";
+my $SEND_URL = "false";
+
+my $SEND_DIFF = "false";
 
 
 # Set this to a domain to have CVS pretend that all users who make
 # commits have mail accounts within that domain.
-#$EMULATE_LOCAL_MAIL_USER="nongnu.org"; 
+# my $EMULATE_LOCAL_MAIL_USER="nongnu.org"; 
+my $EMULATE_LOCAL_MAIL_USER=''; 
 
 
 ############################################################
@@ -107,25 +101,50 @@
 # Constants
 #
 ############################################################
-$STATE_NONE    = 0;
-$STATE_CHANGED = 1;
-$STATE_ADDED   = 2;
-$STATE_REMOVED = 3;
-$STATE_LOG     = 4;
-
-$TMPDIR        = $ENV{'TMPDIR'} || '/tmp';
-$FILE_PREFIX   = '#cvs.';
-
-$LAST_FILE     = "$TMPDIR/${FILE_PREFIX}lastdir";  # Created by commit_prep!
-$ADDED_FILE    = "$TMPDIR/${FILE_PREFIX}files.added";
-$REMOVED_FILE  = "$TMPDIR/${FILE_PREFIX}files.removed";
-$LOG_FILE      = "$TMPDIR/${FILE_PREFIX}files.log";
-$BRANCH_FILE   = "$TMPDIR/${FILE_PREFIX}files.branch";
-$SUMMARY_FILE  = "$TMPDIR/${FILE_PREFIX}files.summary";
+my $STATE_NONE    = 0;
+my $STATE_CHANGED = 1;
+my $STATE_ADDED   = 2;
+my $STATE_REMOVED = 3;
+my $STATE_LOG     = 4;
 
-$MAIL_CMD      = "| /usr/lib/sendmail -i -t";
+my $TMPDIR        = '/tmp';
+my $FILE_PREFIX   = '#cvs.';
+
+my $CVSBIN = "/usr/bin";
+my $MAIL_CMD      = "| /usr/lib/sendmail -i -t";
 #$MAIL_CMD      = "| /var/qmail/bin/qmail-inject";
-$SUBJECT_PRE   = 'CVS update:';
+my $SUBJECT_PRE   = 'CVS update:';
+
+
+############################################################
+#
+# Global variables
+#
+############################################################
+
+my $update_dir = "";           # The relative directory in the repo the
+                               # sandbox is rooted in.
+my @diffargs = ();             # Diff options.
+my $branch = "";               # The branch being processed.
+my $have_r_opt = 0;            # Whether -r was seen on the command line.
+my $onlytag = "";              # With $have_r_opt, only send mail for changes
+                               # on this branch.
+my @mailto = ();               # Email addresses to send mail to.
+my $new_directory = 0;          # Is this a 'cvs add directory' command?
+my $imported_sources = 0;       # Is this a 'cvs import' command?
+my $hook_identifier = '';      # Unique identifier to support multiple hooks
+
+my $id = getpgrp();
+my $cvs_user = $ENV{'USER'} || getlogin || (getpwuid($<))[0] || 
sprintf("uid#%d",$<);
+my @path;
+my %oldrev;
+my %newrev;
+
+# Temporary filenames
+my $ADDED_FILE;
+my $CHANGED_FILE;
+my $REMOVED_FILE;
+my $BRANCH_FILE;
 
 
 ############################################################
@@ -135,11 +154,11 @@
 ############################################################
 
 sub format_names {
-    local($dir, @files) = @_;
-    local(@lines);
+    my ($dir, @files) = @_;
+    my (@lines);
 
     $lines[0] = sprintf(" %-08s", $dir);
-    foreach $file (@files) {
+    foreach my $file (@files) {
         if (length($lines[$#lines]) + length($file) > 60) {
             $lines[++$#lines] = sprintf(" %8s", " ");
         }
@@ -149,10 +168,10 @@
 }
 
 sub cleanup_tmpfiles {
-    local(@files);
+    my (@files);
 
     opendir(DIR, $TMPDIR);
-    push(@files, grep(/^${FILE_PREFIX}.*\.${id}\.${cvs_user}$/, readdir(DIR)));
+    push(@files, grep(/^${FILE_PREFIX}${hook_identifier}.${id}.*\.$/, 
readdir(DIR)));
     closedir(DIR);
     foreach (@files) {
         unlink "$TMPDIR/$_";
@@ -160,7 +179,7 @@
 }
 
 sub write_logfile {
-    local($filename, @lines) = @_;
+    my ($filename, @lines) = @_;
 
     open(FILE, ">$filename") || die ("Cannot open log file $filename: $!\n");
     print(FILE join("\n", @lines), "\n");
@@ -168,10 +187,10 @@
 }
 
 sub append_to_file {
-    local($filename, $dir, @files) = @_;
+    my ($filename, $dir, @files) = @_;
 
     if (@files) {
-        local(@lines) = &format_names($dir, @files);
+        my (@lines) = &format_names($dir, @files);
         open(FILE, ">>$filename") || die ("Cannot open file $filename: $!\n");
         print(FILE join("\n", @lines), "\n");
         close(FILE);
@@ -179,7 +198,7 @@
 }
 
 sub write_line {
-    local($filename, $line) = @_;
+    my ($filename, $line) = @_;
 
     open(FILE, ">$filename") || die("Cannot open file $filename: $!\n");
     print(FILE $line, "\n");
@@ -187,7 +206,7 @@
 }
 
 sub append_line {
-    local($filename, $line) = @_;
+    my ($filename, $line) = @_;
 
     open(FILE, ">>$filename") || die("Cannot open file $filename: $!\n");
     print(FILE $line, "\n");
@@ -195,8 +214,8 @@
 }
 
 sub read_line {
-    local($filename) = @_;
-    local($line);
+    my ($filename) = @_;
+    my ($line);
 
     open(FILE, "<$filename") || die("Cannot open file $filename: $!\n");
     $line = <FILE>;
@@ -206,8 +225,8 @@
 }
 
 sub read_line_nodie {
-    local($filename) = @_;
-    local($line);
+    my ($filename) = @_;
+    my ($line);
     open(FILE, "<$filename") || return ("");
 
     $line = <FILE>;
@@ -217,8 +236,8 @@
 }
 
 sub read_file_lines {
-    local($filename) = @_;
-    local(@text) = ();
+    my ($filename) = @_;
+    my (@text) = ();
 
     open(FILE, "<$filename") || return ();
     while (<FILE>) {
@@ -230,8 +249,8 @@
 }
 
 sub read_file {
-    local($filename, $leader) = @_;
-    local(@text) = ();
+    my ($filename, $leader) = @_;
+    my (@text) = ();
 
     open(FILE, "<$filename") || return ();
     while (<FILE>) {
@@ -244,8 +263,8 @@
 }
 
 sub read_logfile {
-    local($filename, $leader) = @_;
-    local(@text) = ();
+    my ($filename, $leader) = @_;
+    my (@text) = ();
 
     open(FILE, "<$filename") || die ("Cannot open log file $filename: $!\n");
     while (<FILE>) {
@@ -260,8 +279,8 @@
 # do an 'cvs -Qn status' on each file in the arguments, and extract info.
 #
 sub change_summary {
-    local($out, @filenames) = @_;
-    local($file, $rcsfile, $line, $vhost, $cvsweb_base);
+    my ($out, @filenames) = @_;
+    my ($file, $rcsfile, $line, $vhost, $cvsweb_base);
 
     while (@filenames) {
         $file = shift @filenames;
@@ -270,11 +289,11 @@
             next;
         }
 
-        $delta = "";
+        my $delta = "";
         $rcsfile = "$update_dir/$file";
 
         if ($oldrev{$file}) {
-            open(RCS, "-|") || exec "$cvsbin/cvs", '-Qn', 'log',
+            open(RCS, "-|") || exec "$CVSBIN/cvs", '-Qn', 'log',
                                    "-r$newrev{$file}",
                                    '--', $file;
             while (<RCS>) {
@@ -286,7 +305,7 @@
             close(RCS);
         }
 
-        $diff = "\n\n";
+        my $diff = "\n\n";
         $vhost = $path[0];
         if ($CVSWEB_PORT eq "80") {
           $cvsweb_base = "$CVSWEB_SCHEME://$vhost.$CVSWEB_DOMAIN/$CVSWEB_URI";
@@ -304,13 +323,17 @@
         # Perl's 'is this binary' algorithm; it's pretty good.  But not
         # perfect.
         #
-        if (($file =~ /\.(?:pdf|gif|jpg|mpg)$/i) || (-B $file)) {
+        if (($file =~ /\.(?:pdf|gif|jpg|mpg)$/i) || (-B $file) || (-z $file)) {
           if ($SEND_URL eq "true") {
             $diff .= "?rev=" . $newrev{$file};
            $diff .= "&content-type=text/x-cvsweb-markup\n\n";
           }
           if ($SEND_DIFF eq "true") {
-            $diff .= "\t<<Binary file>>\n\n";
+             if (-z $file) {
+                 $diff .= "\t<<Empty file>>\n\n";
+             } else {
+                 $diff .= "\t<<Binary file>>\n\n";
+             }
           }
         }
         else {
@@ -332,7 +355,7 @@
               $diff .= "(In the diff below, changes in quantity "
                     . "of whitespace are not shown.)\n\n";
               open(DIFF, "-|")
-                || exec "$cvsbin/cvs", '-Qn', 'diff', '-N', @diffargs,
+                || exec "$CVSBIN/cvs", '-Qn', 'diff', '-N', @diffargs,
                 "-r$oldrev{$file}", "-r$newrev{$file}", '--', $file;
 
               while (<DIFF>) {
@@ -352,9 +375,9 @@
 
 
 sub build_header {
-    local($header);
+    my ($header);
     delete $ENV{'TZ'};
-    local($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
+    my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
 
     $header = sprintf("  User: %-8s\n  Date: %02d/%02d/%02d %02d:%02d:%02d",
                        $cvs_user, $year%100, $mon+1, $mday,
@@ -369,9 +392,10 @@
 {
   my $subj = "";
 
+  my $i;
   for ($i = 0; ; $i++)
   {
-    open (CH, "<$CHANGED_FILE.$i.$id.$cvs_user") or last;
+    open (CH, "<$CHANGED_FILE.$i") or last;
 
     while (my $change = <CH>)
     {
@@ -404,7 +428,7 @@
   }
   else {
       # NPM: See if there's any file-addition notifications.
-      my $added = &read_line_nodie("$ADDED_FILE.$i.$id.$cvs_user");
+      my $added = &read_line_nodie("$ADDED_FILE.$i");
       if ($added ne "") {
           $subj .= "ADDED: $added "; 
       }
@@ -412,7 +436,7 @@
 #    print "derive_subject_from_changes_file().. added== $added \n";
     
        ## NPM: See if there's any file-removal notications.
-      my $removed = &read_line_nodie("$REMOVED_FILE.$i.$id.$cvs_user");
+      my $removed = &read_line_nodie("$REMOVED_FILE.$i");
       if ($removed ne "") {
           $subj .= "REMOVED: $removed "; 
       }
@@ -420,7 +444,7 @@
 #    print "derive_subject_from_changes_file().. removed== $removed \n";
     
       ## NPM: See if there's any branch notifications.
-      my $branched = &read_line_nodie("$BRANCH_FILE.$i.$id.$cvs_user");
+      my $branched = &read_line_nodie("$BRANCH_FILE.$i");
       if ($branched ne "") {
           $subj .= "BRANCHED: $branched"; 
       }
@@ -445,32 +469,37 @@
 
 sub mail_notification
 {
-    local($addr_list, @text) = @_;
-    local ($mail_to, $mail_from);
+    my ($addr_list, @text) = @_;
+    my ($mail_to, $mail_from);
 
     my $subj = &derive_subject_from_changes_file ();
 
     if ($EMULATE_LOCAL_MAIL_USER) {
-      $mail_from = "address@hidden";
-    } else {
-      $mail_from = "$cvs_user\@" . `hostname`;
-      chomp $mail_from;
+       $mail_from = "address@hidden";
     }
 
     $mail_to = join(", ", @{$addr_list});
 
-    print "Mailing the commit message to $mail_to (from $mail_from)\n";
+    print "Mailing the commit message to $mail_to (from "
+       . ($mail_from ? $mail_from : $cvs_user) . ")\n";
 
     $ENV{'MAILUSER'} = $mail_from;
     # Commented out on hocus, so comment it out here.  -kff
     # $ENV{'QMAILINJECT'} = 'f';
 
-    open(MAIL, "$MAIL_CMD -f$mail_from");
-    print MAIL "From: $mail_from\n";
+    if ($mail_from) {
+       open(MAIL, "$MAIL_CMD -f$mail_from");
+       print MAIL "From: $mail_from\n";
+    } else {
+       # Let the system determine (correctly) how to send mail
+       open(MAIL, "$MAIL_CMD");
+    }
+
     print MAIL "To: $mail_to\n";
     print MAIL "Subject: $SUBJECT_PRE $subj\n\n";
     print(MAIL join("\n", @text));
     close(MAIL);
+
 #    print "Mailing the commit message to $MAIL_TO...\n";
 #
 #    #added by address@hidden 1999/12/15
@@ -502,10 +531,8 @@
 #   -u USER    - Set CVS username to USER.
 sub process_argv
 {
-    local(@argv) = @_;
-    local(@files);
-    local($arg);
-    print "Processing log script arguments...\n";
+    my (@argv) = @_;
+    my (@files, $arg, $donefiles);
 
     while (@argv) {
        $arg = shift @argv;
@@ -521,8 +548,18 @@
        } elsif ($arg eq '-r') {
            $have_r_opt = 1;
            $onlytag = shift @argv;
-       } elsif ($arg eq '-u' && !defined($cvs_user)) {
-           $cvs_user = shift @argv;
+       } elsif ($arg eq '-u') {
+           my $param = shift @argv;
+           if (!defined($cvs_user)) {
+               $cvs_user = $param;
+           }
+       } elsif ($arg eq '-T') {
+           my $param = shift @argv;
+           if ($param =~ /^([a-zA-Z0-9_.-]+)$/) {
+               $hook_identifier = $1;
+           } else {
+               die "Invalid identifier passed to option -T: $param";
+           }
        } else {
            ($donefiles) && die "Too many arguments!\n";
            $donefiles = !$UseNewInfoFmtStrings;
@@ -532,13 +569,27 @@
            } elsif ($arg eq '- Imported sources') {
                $imported_sources = 1;
            } elsif ($UseNewInfoFmtStrings) {
-               push @file, $arg;
-               $oldrev{$arg} = shift @argv
-                   or die "Not enough modifiers for $arg";
-               $newrev{$arg} = shift @argv
-                   or die "Not enough modifiers for $arg";
-               $oldrev{$arg} = 0 if $oldrev{$arg} eq "NONE";
-               $newrev{$arg} = 0 if $newrev{$arg} eq "NONE";
+               push @files, $arg; # current directory
+               while (@argv) {
+                   my $filename = shift @argv;
+                   push @files, $filename;
+                   $oldrev{$filename} = shift @argv
+                       or die "No previous revision given for $filename";
+                   $newrev{$filename} = shift @argv
+                       or die "No new revision given for $filename";
+
+                   # Simplify diffs.
+                   $oldrev{$filename} = 0 if $oldrev{$arg} eq "NONE";
+                   $newrev{$filename} = 0 if $newrev{$arg} eq "NONE";
+
+                   # Untaint.
+                   die "invalid characters in $filename"
+                       if $filename =~ s#/+##g;
+                   die "invalid old revision $oldrev{$filename}"
+                       if $oldrev{$filename} =~ s/[^0-9.]+//g;
+                   die "invalid new revision $newrev{$filename}"
+                       if $newrev{$filename} =~ s/[^0-9.]+//g;
+               }
            } else {
                push @files, split (' ', $arg);
                for (@files)
@@ -567,34 +618,39 @@
 #
 ############################################################
 #
-# Setup environment
+# Setup and clean up environment
 #
 umask (002);
-
-# Connect to the database
-$cvsbin = "/usr/bin";
+$ENV{"PATH"} = "/bin";
+delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
+ 
 
 #
 # Initialize basic variables
 #
-$id = getpgrp();
-$state = $STATE_NONE;
-$cvs_user = $ENV{'USER'} || getlogin || (getpwuid($<))[0] || 
sprintf("uid#%d",$<);
-$new_directory = 0;             # Is this a 'cvs add directory' command?
-$imported_sources = 0;          # Is this a 'cvs import' command?
-$have_r_opt = 0;               # Whether -r was seen on the command line.
-$onlytag = "";                 # With $have_r_opt, only send mail for changes
-                               # on this branch.
-$branch = "";                  # The branch being processed.
address@hidden = ();                    # Email addresses to send mail to.
-$update_dir = "";              # The relative directory in the repo the
-                               # sandbox is rooted in.
address@hidden = ();                    # Diff options.
+print join(' ', @ARGV);
+print "\n";
+my @files = process_argv @ARGV;
+
+my $state = $STATE_NONE;
+my @branch_lines;
+my @changed_files;
+my @added_files;
+my @removed_files;
+my @log_lines;
+my $header;
+
+my $LAST_FILE     = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.lastdir";  # 
Created by commit_prep!
+my $LOG_FILE      = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.log";
+my $SUMMARY_FILE  = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.summary";
+$ADDED_FILE    = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.added";
+$CHANGED_FILE  = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.changed";
+$REMOVED_FILE  = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.removed";
+$BRANCH_FILE   = "$TMPDIR/${FILE_PREFIX}${hook_identifier}.$id.branch";
 
address@hidden = process_argv @ARGV;
 
 # Set defaults that could have been overridden on the command line.
-$update_dir = `cat CVS/Repository` unless $update_dir;
+$update_dir = `/bin/cat CVS/Repository` unless $update_dir;
 chomp $update_dir;
 die "Could not determine update dir" unless $update_dir;
 
@@ -602,6 +658,7 @@
 
 
 @path = split '/', $files[0];
+my $dir;
 if ($#path == 0) {
     $dir = ".";
 } else {
@@ -623,7 +680,7 @@
 #
 if ($new_directory) {
     $header = &build_header;
-    @text = ();
+    my @text = ();
     push(@text, $header);
     push(@text, "");
     push(@text, "  ".$files[0]." - New directory");
@@ -667,7 +724,7 @@
                 /^Obtained from:$/i) {
                 next;
             }
-            push (@log_lines,     $_);
+            push (@log_lines, $_);
         }
     }
 }
@@ -686,7 +743,7 @@
     last if ($log_lines[$#log_lines] ne "");
     pop(@log_lines);
 }
-for ($i = $#log_lines; $i > 0; $i--) {
+for (my $i = $#log_lines; $i > 0; $i--) {
     if (($log_lines[$i - 1] eq "") && ($log_lines[$i] eq "")) {
         splice(@log_lines, $i, 1);
     }
@@ -695,9 +752,10 @@
 #
 # Find the log file that matches this log message
 #
+my $i;
 for ($i = 0; ; $i++) {
-    last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
-    @text = &read_logfile("$LOG_FILE.$i.$id.$cvs_user", "");
+    last if (! -e "$LOG_FILE.$i");
+    my @text = &read_logfile("$LOG_FILE.$i", "");
     last if ($#text == -1);
     last if (join(" ", @log_lines) eq join(" ", @text));
 }
@@ -705,25 +763,26 @@
 #
 # Spit out the information gathered in this pass.
 #
-&write_logfile("$LOG_FILE.$i.$id.$cvs_user", @log_lines);
-&append_to_file("$BRANCH_FILE.$i.$id.$cvs_user",  $dir, @branch_lines);
-&append_to_file("$ADDED_FILE.$i.$id.$cvs_user",   $dir, @added_files);
-&append_to_file("$CHANGED_FILE.$i.$id.$cvs_user", $dir, @changed_files);
-&append_to_file("$REMOVED_FILE.$i.$id.$cvs_user", $dir, @removed_files);
+&write_logfile("$LOG_FILE.$i", @log_lines);
+&append_to_file("$BRANCH_FILE.$i",  $dir, @branch_lines);
+&append_to_file("$ADDED_FILE.$i",   $dir, @added_files);
+&append_to_file("$CHANGED_FILE.$i", $dir, @changed_files);
+&append_to_file("$REMOVED_FILE.$i", $dir, @removed_files);
 if ($rcsidinfo) {
-  &change_summary ("$SUMMARY_FILE.$i.$id.$cvs_user",
+  &change_summary ("$SUMMARY_FILE.$i",
                   (@changed_files, @added_files, @removed_files));
 }
 
 #
 # Check whether this is the last directory.  If not, quit.
 #
-if (-e "$LAST_FILE.$id.$cvs_user") {
-   $_ = &read_line("$LAST_FILE.$id.$cvs_user");
-   $tmpfiles = $files[0];
+if (-e "$LAST_FILE") {
+   $_ = &read_line("$LAST_FILE");
+   my $tmpfiles = $files[0];
+   # Characters escape for use in regexp:
    $tmpfiles =~ s,([^a-zA-Z0-9_/]),\\$1,g;
    if (! grep(/$tmpfiles$/, $_)) {
-        print "More commits to come...\n";
+        print "More commits to come... - files[0]=$tmpfiles - lastdir=$_)\n";
         exit 0
    }
 }
@@ -738,22 +797,22 @@
 #
 # Produce the final compilation of the log messages
 #
address@hidden = ();
+my @text = ();
 push(@text, $header);
 push(@text, "");
-for ($i = 0; ; $i++) {
-    last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
-    push(@text, &read_file("$BRANCH_FILE.$i.$id.$cvs_user", "Branch:"));
-    push(@text, &read_file("$CHANGED_FILE.$i.$id.$cvs_user", "Modified:"));
-    push(@text, &read_file("$ADDED_FILE.$i.$id.$cvs_user", "Added:"));
-    push(@text, &read_file("$REMOVED_FILE.$i.$id.$cvs_user", "Removed:"));
+for (my $i = 0; ; $i++) {
+    last if (! -e "$LOG_FILE.$i");
+    push(@text, &read_file("$BRANCH_FILE.$i", "Branch:"));
+    push(@text, &read_file("$CHANGED_FILE.$i", "Modified:"));
+    push(@text, &read_file("$ADDED_FILE.$i", "Added:"));
+    push(@text, &read_file("$REMOVED_FILE.$i", "Removed:"));
     push(@text, "  Log:");
-    push(@text, &read_logfile("$LOG_FILE.$i.$id.$cvs_user", "  "));
+    push(@text, &read_logfile("$LOG_FILE.$i", "  "));
     if ($rcsidinfo == 2) {
-        if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") {
+        if (-e "$SUMMARY_FILE.$i") {
             push(@text, "  ");
             push(@text, "  Revision  Changes    Path");
-            push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", "  "));
+            push(@text, &read_logfile("$SUMMARY_FILE.$i", "  "));
         }
     }
     push(@text, "");
@@ -763,14 +822,14 @@
 # Now generate the extra info for the mail message..
 #
 if ($rcsidinfo == 1) {
-    $revhdr = 0;
-    for ($i = 0; ; $i++) {
-        last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
-        if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") {
+    my $revhdr = 0;
+    for (my $i = 0; ; $i++) {
+        last if (! -e "$LOG_FILE.$i");
+        if (-e "$SUMMARY_FILE.$i") {
             if (!$revhdr++) {
                 push(@text, "Revision  Changes    Path");
             }
-            push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", ""));
+            push(@text, &read_logfile("$SUMMARY_FILE.$i", ""));
         }
     }
     if ($revhdr) {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]