From 4727e6c09f88e63f02e6c8f359862d0c0942ed36 Mon Sep 17 00:00:00 2001 From: "terry%netscape.com" <> Date: Wed, 16 Sep 1998 04:49:23 +0000 Subject: Everything has been ported to now run under Perl. --- processmail | 350 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 202 insertions(+), 148 deletions(-) (limited to 'processmail') diff --git a/processmail b/processmail index a40723a0b..7cf4caac1 100755 --- a/processmail +++ b/processmail @@ -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; + } +} -proc DescCC {cclist} { - if {[lempty $cclist]} return "" - return "Cc: [join $cclist ", "]\n" +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 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"; - - SendSQL $query - - set ret [FetchSQLData] + +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); +} + + +sub DescCC { + my ($cclist) = (@_); + if (scalar(@$cclist) <= 0) { + return ""; + } + return "Cc: " . join(", ", $cclist) . "\n"; +} + + +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) - -$bug(long_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'} +"; } -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 - - - -set template "From: bugzilla-daemon -To: %s -Cc: %s -Subject: \[Bug %s\] %s - %s +ConnectToDatabase(); -[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, ") { + $::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" - } - set text [GetBugText $i] - if {$text == ""} { - error "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" +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"; + } + my $text = GetBugText($i); + if ($text eq "") { + die "Couldn't find bug $i."; + } + 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 () { + $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; -- cgit v1.2.3-24-g4f1b