Everything has been ported to now run under Perl.
git-svn-id: svn://10.0.0.236/trunk@10080 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#! /usr/bonsaitools/bin/mysqltcl
|
||||
# -*- Mode: tcl; indent-tabs-mode: nil -*-
|
||||
#!/usr/bonsaitools/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.0 (the "License"); you may not use this file except in
|
||||
@@ -22,202 +22,256 @@
|
||||
|
||||
# To recreate the shadow database, run "processmail regenerate" .
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
|
||||
source "globals.tcl"
|
||||
require "globals.pl";
|
||||
|
||||
umask 0
|
||||
$| = 1;
|
||||
|
||||
proc Different {file1 file2} {
|
||||
if {[file size $file1] != [file size $file2]} {
|
||||
return 1
|
||||
umask(0);
|
||||
|
||||
$::lockcount = 0;
|
||||
|
||||
sub Lock {
|
||||
if ($::lockcount <= 0) {
|
||||
$::lockcount = 0;
|
||||
if (!open(LOCKFID, ">>data/maillock")) {
|
||||
mkdir "data", 0777;
|
||||
chmod 0777, "data";
|
||||
open(LOCKFID, ">>data/maillock") || die "Can't open lockfile.";
|
||||
}
|
||||
my $val = flock(LOCKFID,2);
|
||||
if (!$val) { # '2' is magic 'exclusive lock' const.
|
||||
print "Lock failed: $val\n";
|
||||
}
|
||||
chmod 0666, "data/maillock";
|
||||
}
|
||||
set f1 [open $file1 "r"]
|
||||
set f2 [open $file2 "r"]
|
||||
set d1 [read $f1]
|
||||
set d2 [read $f2]
|
||||
close $f1
|
||||
close $f2
|
||||
return [expr ![cequal $d1 $d2]]
|
||||
$::lockcount++;
|
||||
}
|
||||
|
||||
sub Unlock {
|
||||
$::lockcount--;
|
||||
if ($::lockcount <= 0) {
|
||||
flock(LOCKFID,8); # '8' is magic 'unlock' const.
|
||||
close LOCKFID;
|
||||
}
|
||||
}
|
||||
|
||||
sub FileSize {
|
||||
my ($filename) = (@_);
|
||||
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
|
||||
$atime,$mtime,$ctime,$blksize,$blocks)
|
||||
= stat($filename);
|
||||
if (defined $size) {
|
||||
return $size;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
proc DescCC {cclist} {
|
||||
if {[lempty $cclist]} return ""
|
||||
return "Cc: [join $cclist ", "]\n"
|
||||
|
||||
sub Different {
|
||||
my ($file1, $file2) = (@_);
|
||||
my $size1 = FileSize($file1);
|
||||
my $size2 = FileSize($file2);
|
||||
if ($size1 != $size2) {
|
||||
return 1;
|
||||
}
|
||||
open(FID1, "<$file1") || die "Can't open $file1";
|
||||
open(FID2, "<$file2") || die "Can't open $file2";
|
||||
my $d1;
|
||||
my $d2;
|
||||
if (read(FID1, $d1, $size1) ne $size1) {
|
||||
die "Can't read $size1 bytes from $file1";
|
||||
}
|
||||
if (read(FID2, $d2, $size2) ne $size2) {
|
||||
die "Can't read $size2 bytes from $file2";
|
||||
}
|
||||
close FID1;
|
||||
close FID2;
|
||||
return ($d1 ne $d2);
|
||||
}
|
||||
|
||||
|
||||
proc GetBugText {id} {
|
||||
global bug
|
||||
catch {unset bug}
|
||||
set query "
|
||||
select
|
||||
bug_id,
|
||||
product,
|
||||
version,
|
||||
rep_platform,
|
||||
op_sys,
|
||||
bug_status,
|
||||
resolution,
|
||||
priority,
|
||||
bug_severity,
|
||||
area,
|
||||
assigned_to,
|
||||
reporter,
|
||||
bug_file_loc,
|
||||
short_desc,
|
||||
component
|
||||
from bugs
|
||||
where bug_id = $id";
|
||||
sub DescCC {
|
||||
my ($cclist) = (@_);
|
||||
if (scalar(@$cclist) <= 0) {
|
||||
return "";
|
||||
}
|
||||
return "Cc: " . join(", ", $cclist) . "\n";
|
||||
}
|
||||
|
||||
SendSQL $query
|
||||
|
||||
set ret [FetchSQLData]
|
||||
sub GetBugText {
|
||||
my ($id) = (@_);
|
||||
undef %::bug;
|
||||
|
||||
if {$ret == ""} {
|
||||
return ""
|
||||
my @collist = ("bug_id", "product", "version", "rep_platform", "op_sys",
|
||||
"bug_status", "resolution", "priority", "bug_severity",
|
||||
"area", "assigned_to", "reporter", "bug_file_loc",
|
||||
"short_desc", "component");
|
||||
|
||||
my $query = "select " . join(", ", @collist) .
|
||||
" from bugs where bug_id = $id";
|
||||
|
||||
SendSQL($query);
|
||||
|
||||
my @row;
|
||||
if (!(@row = FetchSQLData())) {
|
||||
return "";
|
||||
}
|
||||
set count 0
|
||||
foreach field { bug_id product version rep_platform op_sys bug_status
|
||||
resolution priority bug_severity area assigned_to
|
||||
reporter bug_file_loc short_desc
|
||||
component } {
|
||||
set bug($field) [lindex $ret $count]
|
||||
incr count
|
||||
foreach my $field (@collist) {
|
||||
$::bug{$field} = shift @row;
|
||||
if (!defined $::bug{$field}) {
|
||||
$::bug{$field} = "";
|
||||
}
|
||||
}
|
||||
|
||||
set bug(assigned_to) [DBID_to_name $bug(assigned_to)]
|
||||
set bug(reporter) [DBID_to_name $bug(reporter)]
|
||||
$::bug{'assigned_to'} = DBID_to_name($::bug{'assigned_to'});
|
||||
$::bug{'reporter'} = DBID_to_name($::bug{'reporter'});
|
||||
|
||||
set bug(long_desc) [GetLongDescription $id]
|
||||
$::bug{'long_desc'} = GetLongDescription($id);
|
||||
|
||||
set bug(cclist) [split [ShowCcList $id] ","]
|
||||
my @cclist;
|
||||
@cclist = split(/,/, ShowCcList($id));
|
||||
$::bug{'cclist'} = \@cclist;
|
||||
|
||||
|
||||
return "Bug\#: $id
|
||||
Product: $bug(product)
|
||||
Version: $bug(version)
|
||||
Platform: $bug(rep_platform)
|
||||
OS/Version: $bug(op_sys)
|
||||
Status: $bug(bug_status)
|
||||
Resolution: $bug(resolution)
|
||||
Severity: $bug(bug_severity)
|
||||
Priority: $bug(priority)
|
||||
Component: $bug(component)
|
||||
Area: $bug(area)
|
||||
AssignedTo: $bug(assigned_to)
|
||||
ReportedBy: $bug(reporter)
|
||||
URL: $bug(bug_file_loc)
|
||||
[DescCC $bug(cclist)]Summary: $bug(short_desc)
|
||||
Product: $::bug{'product'}
|
||||
Version: $::bug{'version'}
|
||||
Platform: $::bug{'rep_platform'}
|
||||
OS/Version: $::bug{'op_sys'}
|
||||
Status: $::bug{'bug_status'}
|
||||
Resolution: $::bug{'resolution'}
|
||||
Severity: $::bug{'bug_severity'}
|
||||
Priority: $::bug{'priority'}
|
||||
Component: $::bug{'component'}
|
||||
Area: $::bug{'area'}
|
||||
AssignedTo: $::bug{'assigned_to'}
|
||||
ReportedBy: $::bug{'reporter'}
|
||||
URL: $::bug{'bug_file_loc'}
|
||||
" . DescCC($::bug{'cclist'}) . "Summary: $::bug{'short_desc'}
|
||||
|
||||
$bug(long_desc)"
|
||||
$::bug{'long_desc'}
|
||||
";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
proc fixaddresses {list} {
|
||||
global nomail
|
||||
set result {}
|
||||
foreach i [lrmdups $list] {
|
||||
if {![info exists nomail($i)]} {
|
||||
lappend result $i
|
||||
sub fixaddresses {
|
||||
my ($list) = (@_);
|
||||
my @result;
|
||||
my %seen;
|
||||
foreach my $i (@$list) {
|
||||
if (!defined $::nomail{$i} && !defined $seen{$i}) {
|
||||
push @result, $i;
|
||||
$seen{$i} = 1;
|
||||
}
|
||||
}
|
||||
return [join $result ", "]
|
||||
return join(", ", @result);
|
||||
}
|
||||
|
||||
|
||||
proc Log {str} {
|
||||
set lockfid [open "maillock" "w"]
|
||||
flock -write $lockfid
|
||||
set fid [open "maillog" "a"]
|
||||
puts $fid "[fmtclock [getclock] "%D %H:%M"] $str"
|
||||
close $fid
|
||||
close $lockfid
|
||||
sub Log {
|
||||
my ($str) = (@_);
|
||||
Lock();
|
||||
open(FID, ">>data/maillog") || die "Can't write to data/maillog";
|
||||
print FID time2str("%D %H:%M", time()) . ": $str\n";
|
||||
close FID;
|
||||
Unlock();
|
||||
}
|
||||
|
||||
|
||||
ConnectToDatabase
|
||||
ConnectToDatabase();
|
||||
|
||||
|
||||
|
||||
set template "From: bugzilla-daemon
|
||||
To: %s
|
||||
Cc: %s
|
||||
Subject: \[Bug %s\] %s - %s
|
||||
|
||||
[Param urlbase]show_bug.cgi?id=%s
|
||||
|
||||
%s"
|
||||
|
||||
|
||||
set lockfid [open "maillock" "r"]
|
||||
flock -read $lockfid
|
||||
Lock();
|
||||
|
||||
# foreach i [split [read_file -nonewline "okmail"] "\n"] {
|
||||
# set okmail($i) 1
|
||||
# }
|
||||
|
||||
foreach i [split [read_file -nonewline "nomail"] "\n"] {
|
||||
if {[info exists okmail($i)]} {
|
||||
unset okmail($i)
|
||||
|
||||
|
||||
if (open(FID, "<data/nomail")) {
|
||||
while (<FID>) {
|
||||
$::nomail{trim($_)} = 1;
|
||||
}
|
||||
set nomail($i) 1
|
||||
close FID;
|
||||
}
|
||||
|
||||
|
||||
close $lockfid
|
||||
my $regenerate = 0;
|
||||
|
||||
|
||||
set regenerate 0
|
||||
if {[cequal [lindex $argv 0] "regenerate"]} {
|
||||
set regenerate 1
|
||||
set argv ""
|
||||
SendSQL "select bug_id from bugs order by bug_id"
|
||||
while {[MoreSQLData]} {
|
||||
lappend argv [lindex [FetchSQLData] 0]
|
||||
if ($ARGV[0] eq "regenerate") {
|
||||
$regenerate = 1;
|
||||
$#ARGV = -1;
|
||||
SendSQL("select bug_id from bugs order by bug_id");
|
||||
my @row;
|
||||
while (@row = FetchSQLData()) {
|
||||
push @ARGV, $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
foreach i $argv {
|
||||
if {[lempty $i]} continue
|
||||
set old shadow/$i
|
||||
set new shadow/$i.tmp.[id process]
|
||||
set diffs shadow/$i.diffs.[id process]
|
||||
set verb "Changed"
|
||||
if {![file exists $old]} {
|
||||
close [open $old "w"]
|
||||
set verb "New"
|
||||
foreach my $i (@ARGV) {
|
||||
my $old = "shadow/$i";
|
||||
my $new = "shadow/$i.tmp.$$";
|
||||
my $diffs = "shadow/$i.diffs.$$";
|
||||
my $verb = "Changed";
|
||||
if (!stat($old)) {
|
||||
mkdir "shadow", 0777;
|
||||
chmod 0777, "shadow";
|
||||
open(OLD, ">$old") || die "Couldn't create null $old";
|
||||
close OLD;
|
||||
$verb = "New";
|
||||
}
|
||||
set text [GetBugText $i]
|
||||
if {$text == ""} {
|
||||
error "Couldn't find bug $i."
|
||||
my $text = GetBugText($i);
|
||||
if ($text eq "") {
|
||||
die "Couldn't find bug $i.";
|
||||
}
|
||||
set fid [open $new "w"]
|
||||
puts $fid $text
|
||||
close $fid
|
||||
if {[Different $old $new]} {
|
||||
catch {exec diff -c $old $new > $diffs}
|
||||
set tolist [fixaddresses [list $bug(assigned_to) $bug(reporter)]]
|
||||
set cclist [fixaddresses $bug(cclist)]
|
||||
set logstr "Bug $i changed"
|
||||
if {![lempty $tolist] || ![lempty $cclist]} {
|
||||
set msg [format $template $tolist $cclist $i $verb \
|
||||
$bug(short_desc) $i [read_file $diffs]]
|
||||
if {!$regenerate || ![cequal $verb "New"]} {
|
||||
exec /usr/lib/sendmail -t << $msg
|
||||
set logstr "$logstr; mail sent to $tolist $cclist"
|
||||
open(FID, ">$new") || die "Couldn't create $new";
|
||||
print FID $text;
|
||||
close FID;
|
||||
if (Different($old, $new)) {
|
||||
system("diff -c $old $new > $diffs");
|
||||
my $tolist = fixaddresses([$::bug{'assigned_to'}, $::bug{'reporter'}]);
|
||||
my $cclist = fixaddresses($::bug{'cclist'});
|
||||
my $logstr = "Bug $i changed";
|
||||
if ($tolist ne "" || $cclist ne "") {
|
||||
my %substs;
|
||||
|
||||
$substs{"to"} = $tolist;
|
||||
$substs{"cc"} = $cclist;
|
||||
$substs{"bugid"} = $i;
|
||||
$substs{"diffs"} = "";
|
||||
open(DIFFS, "<$diffs") || die "Can't open $diffs";
|
||||
while (<DIFFS>) {
|
||||
$substs{"diffs"} .= $_;
|
||||
}
|
||||
close DIFFS;
|
||||
$substs{"neworchanged"} = $verb;
|
||||
$substs{"summary"} = $::bug{'short_desc'};
|
||||
my $msg = PerformSubsts(Param("changedmail"), \%substs);
|
||||
|
||||
if (!$regenerate) {
|
||||
open(SENDMAIL, "|/usr/lib/sendmail -t") ||
|
||||
die "Can't open sendmail";
|
||||
print SENDMAIL $msg;
|
||||
close SENDMAIL;
|
||||
$logstr = "$logstr; mail sent to $tolist $cclist";
|
||||
}
|
||||
}
|
||||
unlink $diffs
|
||||
Log $logstr
|
||||
unlink($diffs);
|
||||
Log($logstr);
|
||||
}
|
||||
frename $new $old
|
||||
catch {chmod 0666 $old}
|
||||
if {$regenerate} {
|
||||
puts -nonewline "$i "
|
||||
rename($new, $old) || die "Can't rename $new to $old";
|
||||
chmod 0666, $old;
|
||||
if ($regenerate) {
|
||||
print "$i ";
|
||||
}
|
||||
}
|
||||
|
||||
exit
|
||||
exit;
|
||||
|
||||
Reference in New Issue
Block a user