[8760] | 1 | #!/usr/athena/bin/perl |
---|
| 2 | |
---|
[20100] | 3 | # In commitinfo, put: |
---|
| 4 | # ALL $CVSROOT/CVSROOT/record.pl $CVSROOT |
---|
| 5 | # In loginfo, put: |
---|
| 6 | # ALL $CVSROOT/CVSROOT/logfilter.pl %{sVv} commit-address diff-adddress |
---|
[8760] | 7 | |
---|
[20100] | 8 | # Mails the CVS commit logs to commit-address. Also mails the commit |
---|
| 9 | # logs to diff-address, followed by context diffs of the modified |
---|
[13241] | 10 | # files. |
---|
[8818] | 11 | |
---|
[20100] | 12 | use strict; |
---|
| 13 | use File::Compare; |
---|
| 14 | use File::Path; |
---|
| 15 | use File::Spec::Functions ':ALL'; |
---|
| 16 | use File::stat; |
---|
| 17 | use Fcntl ':mode'; |
---|
[8760] | 18 | |
---|
[20100] | 19 | my ($sendmail, $dir, @files, $commit_addr, $diff_addr, $tmpdir, $sb); |
---|
| 20 | my ($filename, $firstdir, $lastdir, $repdir, $old, $new, $file); |
---|
| 21 | my (@d1, @d2, $i, $subject, $cmd); |
---|
| 22 | |
---|
[10619] | 23 | $sendmail = ( -x "/usr/sbin/sendmail") ? "/usr/sbin/sendmail" |
---|
| 24 | : "/usr/lib/sendmail"; |
---|
[8760] | 25 | |
---|
[20100] | 26 | # $ARGV[0] is of the form "dir filename,oldrev,newrev ...". |
---|
| 27 | ($dir, @files) = split(/ /, $ARGV[0]); |
---|
| 28 | $commit_addr = $ARGV[1]; |
---|
| 29 | $diff_addr = $ARGV[2]; |
---|
[13241] | 30 | |
---|
[20100] | 31 | if ($files[0] eq "-") { |
---|
| 32 | # This is a new directory or import notification. There's no |
---|
| 33 | # commitinfo step for these operations, so just pass on the |
---|
| 34 | # supplied log message. |
---|
[10619] | 35 | |
---|
[20100] | 36 | open(COMMITMAIL, "| $sendmail $commit_addr"); |
---|
| 37 | print COMMITMAIL "To: $commit_addr\n"; |
---|
[20116] | 38 | print COMMITMAIL "Subject: $ARGV[0]\n\n"; |
---|
[10619] | 39 | |
---|
[20100] | 40 | open(DIFFMAIL, "| $sendmail $diff_addr"); |
---|
| 41 | print DIFFMAIL "To: $diff_addr\n"; |
---|
[20116] | 42 | print DIFFMAIL "Subject: $ARGV[0]\n\n"; |
---|
[20100] | 43 | |
---|
| 44 | while (<STDIN>) { |
---|
[13241] | 45 | print COMMITMAIL; |
---|
| 46 | print DIFFMAIL; |
---|
[20100] | 47 | } |
---|
| 48 | close(COMMITMAIL); |
---|
| 49 | close(DIFFMAIL); |
---|
| 50 | |
---|
| 51 | exit 0; |
---|
[8760] | 52 | } |
---|
| 53 | |
---|
[20100] | 54 | # Make sure our temporary directory exists and is kosher. |
---|
| 55 | $tmpdir = "/tmp/athena-cvs-" . getpgrp(); |
---|
| 56 | $sb = lstat($tmpdir) || die "Can't stat $tmpdir: $!\n"; |
---|
| 57 | if (!S_ISDIR($sb->mode) || ($sb->mode & (S_IWGRP|S_IWOTH)) || $sb->uid != $>) { |
---|
| 58 | die "Problem with temporary directory\n"; |
---|
| 59 | } |
---|
[8818] | 60 | |
---|
[20100] | 61 | # Read the first committed directory (recorded from commitinfo by record.pl). |
---|
| 62 | $filename = catfile($tmpdir, "firstdir"); |
---|
| 63 | open(FILE, "< $filename") || die "Can't open $filename for reading: $!\n"; |
---|
| 64 | $firstdir = <FILE> || die "Can't read $filename: $!\n"; |
---|
| 65 | chomp $firstdir; |
---|
| 66 | close(FILE); |
---|
| 67 | |
---|
| 68 | # Read the last committed directory (recorded from commitinfo by record.pl). |
---|
| 69 | $filename = catfile($tmpdir, "lastdir"); |
---|
| 70 | open(FILE, "< $filename") || die "Can't open $filename for reading: $!\n"; |
---|
| 71 | $lastdir = <FILE> || die "Can't read $filename: $!\n"; |
---|
| 72 | chomp $lastdir; |
---|
| 73 | close(FILE); |
---|
| 74 | |
---|
| 75 | # Write out the log message to a file. |
---|
| 76 | $filename = catfile($tmpdir, "logs"); |
---|
| 77 | open(FILE, ">> $filename") || die "Can't open $filename for writing: $!\n"; |
---|
| 78 | while (<STDIN>) { |
---|
| 79 | if (/^Update of (.*)$/) { |
---|
| 80 | # Remember the repository directory for the diffs. |
---|
| 81 | $repdir = $1; |
---|
| 82 | } |
---|
| 83 | print FILE; |
---|
| 84 | } |
---|
| 85 | close(FILE); |
---|
| 86 | |
---|
| 87 | $filename = catfile($tmpdir, "diffs"); |
---|
| 88 | open(FILE, ">> $filename") || die "Can't open $filename for append: $!\n"; |
---|
| 89 | # Write out the diffs. |
---|
[13241] | 90 | foreach (@files) { |
---|
[20100] | 91 | ($file, $old, $new) = split(/,/); |
---|
| 92 | next if ($new eq "NONE"); |
---|
| 93 | print FILE "\n"; |
---|
| 94 | print FILE "==================================================\n"; |
---|
| 95 | if ($old eq "NONE") { |
---|
| 96 | print FILE "Initial contents of new file $file\n"; |
---|
| 97 | $cmd = "diff -c /dev/null $file"; |
---|
| 98 | } else { |
---|
| 99 | print FILE "Differences for $file (revision $old -> $new)\n"; |
---|
| 100 | $cmd ="rcsdiff -c -kk -r$old -r$new $repdir/$file 2>/dev/null"; |
---|
| 101 | } |
---|
| 102 | print FILE "==================================================\n"; |
---|
| 103 | open(DIFF, "$cmd|"); |
---|
| 104 | print FILE while (<DIFF>); |
---|
| 105 | close(DIFF); |
---|
[8760] | 106 | } |
---|
[20100] | 107 | close(FILE); |
---|
[8760] | 108 | |
---|
[20100] | 109 | if ($dir eq $lastdir) { |
---|
| 110 | # All the logs are in. Fire off the mail messages. But first, |
---|
| 111 | # find the common initial sequence of the first and last |
---|
| 112 | # directories for the subject line. |
---|
| 113 | @d1 = splitdir($firstdir); |
---|
| 114 | @d2 = splitdir($lastdir); |
---|
| 115 | for ($i = 0; $i < scalar @d1; $i++) { |
---|
| 116 | last if ($d1[$i] ne $d2[$i]); |
---|
| 117 | } |
---|
| 118 | $subject = catdir(@d1[0..($i - 1)]); |
---|
| 119 | |
---|
| 120 | open(COMMITMAIL, "| $sendmail $commit_addr"); |
---|
| 121 | print COMMITMAIL "To: $commit_addr\n"; |
---|
| 122 | print COMMITMAIL "Subject: $subject\n\n"; |
---|
| 123 | |
---|
| 124 | open(DIFFMAIL, "| $sendmail $diff_addr"); |
---|
| 125 | print DIFFMAIL "To: $diff_addr\n"; |
---|
| 126 | print DIFFMAIL "Subject: $subject\n\n"; |
---|
| 127 | |
---|
| 128 | $filename = catfile($tmpdir, "logs"); |
---|
| 129 | open(FILE, "< $filename") || die "Can't open $filename for reading: $!\n"; |
---|
| 130 | while (<FILE>) { |
---|
| 131 | print COMMITMAIL; |
---|
| 132 | print DIFFMAIL; |
---|
| 133 | } |
---|
| 134 | close(FILE); |
---|
| 135 | close(COMMITMAIL); |
---|
| 136 | |
---|
| 137 | $filename = catfile($tmpdir, "diffs"); |
---|
| 138 | open(FILE, "< $filename") || die "Can't open $filename for reading: $!\n"; |
---|
| 139 | print DIFFMAIL while (<FILE>); |
---|
| 140 | close(FILE); |
---|
| 141 | close(DIFFMAIL); |
---|
| 142 | |
---|
| 143 | rmtree($tmpdir); |
---|
| 144 | } |
---|