# -*- perl -*-
-# $Id: errorlib.in,v 1.17 2002/11/17 22:45:16 cjwatson Exp $
+# $Id: errorlib.in,v 1.29 2003/06/06 17:56:05 cjwatson Exp $
sub F_SETLK { 6; } sub F_WRLCK{ 1; }
$flockstruct= 'sslll'; # And there ought to be something for this too.
}
sub lockreadbugmerge {
- local ($lref) = @_;
- if (!&lockreadbug($lref)) { return 0; }
- if (!length($s_mergedwith)) { return 1; }
+ local ($lref, $location) = @_;
+ local $data;
+ if (!($data = &lockreadbug($lref, $location))) { return ( 0, undef ); }
+ if (!length($data{mergedwith})) { return ( 1, $data ); }
&unfilelock;
&filelock('lock/merge');
- if (!&lockreadbug($lref)) { &unfilelock; return 0; }
- return 2;
+ if (!&lockreadbug($lref, $location)) { &unfilelock; return ( 0, undef ); }
+ return ( 2, $data );
+}
+
+sub getbuglocation {
+ my ( $bugnum, $ext ) = @_;
+ my $archdir = sprintf "%02d", $bugnum % 100;
+ return 'archive' if ( -r "$gSpoolDir/archive/$archdir/$bugnum.$ext" );
+ return 'db-h' if ( -r "$gSpoolDir/db-h/$archdir/$bugnum.$ext" );
+ return 'db' if ( -r "$gSpoolDir/db/$bugnum.$ext" );
+ return undef;
+}
+
+sub getlocationpath {
+ my ($location) = @_;
+ if ($location eq 'archive') {
+ return "$gSpoolDir/archive";
+ } elsif ($location eq 'db') {
+ return "$gSpoolDir/db";
+ } else {
+ return "$gSpoolDir/db-h";
+ }
+}
+
+sub getbugcomponent {
+ my ($bugnum, $ext, $location) = @_;
+
+ $location = getbuglocation($bugnum, $ext) unless defined $location;
+ my $dir = getlocationpath($location);
+ return undef unless $dir;
+ if ($location eq 'db') {
+ return "$dir/$bugnum.$ext";
+ } else {
+ my $hash = get_hashname($bugnum);
+ return "$dir/$hash/$bugnum.$ext";
+ }
+}
+
+sub readbug {
+ local ($lref, $location) = @_;
+ my $status = getbugcomponent($lref, 'status', $location);
+ return undef unless defined $status;
+ if (!open(S,$status)) { return undef; }
+ my %data;
+ chop($data{originator}= <S>);
+ chop($data{date}= <S>);
+ chop($data{subject}= <S>);
+ chop($data{msgid}= <S>);
+ chop($data{package}= <S>);
+ chop($data{keywords}= <S>);
+ chop($data{done}= <S>);
+ chop($data{forwarded}= <S>);
+ chop($data{mergedwith}= <S>);
+ chop($data{severity}= <S>);
+ chop($data{versions}= <S>);
+ chop($data{fixed_versions}= <S>);
+ close(S);
+ $data{severity} = 'normal' if $data{severity} eq '';
+ return \%data;
}
sub lockreadbug {
- local ($lref) = @_;
+ local ($lref, $location) = @_;
&filelock("lock/$lref");
- my $hash = get_hashname($lref);
- if (!open(S,"db-h/$hash/$lref.status")) { &unfilelock; return 0; }
- chop($s_originator= <S>);
- chop($s_date= <S>);
- chop($s_subject= <S>);
- chop($s_msgid= <S>);
- chop($s_package= <S>);
- chop($s_keywords= <S>);
- chop($s_done= <S>);
- chop($s_forwarded= <S>);
- chop($s_mergedwith= <S>);
- chop($s_severity= <S>);
- chop($s_versions= <S>);
- chop($s_fixed_versions= <S>);
- close(S);
- $s_severity = 'normal' if $s_severity eq '';
- return 1;
+ my $data = readbug($lref, $location);
+ &unfilelock unless defined $data;
+ return $data;
+}
+
+sub writebug {
+ local ($ref, $data, $location) = @_;
+ my $change;
+ my $status = getbugcomponent($ref, 'status', $location);
+ &quit("can't find location for $ref") unless defined $status;
+ open(S,"> $status.new") || &quit("opening $status.new: $!");
+ print(S
+ "$data->{originator}\n".
+ "$data->{date}\n".
+ "$data->{subject}\n".
+ "$data->{msgid}\n".
+ "$data->{package}\n".
+ "$data->{keywords}\n".
+ "$data->{done}\n".
+ "$data->{forwarded}\n".
+ "$data->{mergedwith}\n".
+ "$data->{severity}\n".
+ "$data->{versions}\n".
+ "$data->{fixed_versions}\n") || &quit("writing $status.new: $!");
+ close(S) || &quit("closing $status.new: $!");
+ if (-e $status) {
+ $change = 'change';
+ } else {
+ $change = 'new';
+ }
+ rename("$status.new",$status) ||
+ &quit("installing new $status: $!");
+ &bughook($change,$ref,
+ "$data->{originator}\n".
+ "$data->{date}\n".
+ "$data->{subject}\n".
+ "$data->{msgid}\n".
+ "$data->{package}\n".
+ "$data->{keywords}\n".
+ "$data->{done}\n".
+ "$data->{forwarded}\n".
+ "$data->{mergedwith}\n".
+ "$data->{severity}\n".
+ "$data->{versions}\n".
+ "$data->{fixed_versions}\n");
+}
+
+sub unlockwritebug {
+ writebug(@_);
+ &unfilelock;
}
sub filelock {
}
sub unfilelock {
+ if (@filelocks == 0) {
+ warn "unfilelock called with no active filelocks!\n";
+ return;
+ }
local ($lockfile) = pop(@filelocks);
pop(@cleanups);
- eval 'close(FLOCK'.($#filelocks+1).');' || warn "failed to close lock file: $!";
- unlink($lockfile) || warn "failed to remove lock file: $!";
+ eval 'close(FLOCK'.($#filelocks+1).');' || warn "failed to close lock file $lockfile: $!";
+ unlink($lockfile) || warn "failed to remove lock file $lockfile: $!";
}
sub quit {
open(IDXNEW, ">$file.new");
my $line;
+ my @line;
while($line = <IDXDB>) {
- my @line = split /\s/, $line;
- last if ($line[1] == $ref);
+ @line = split /\s/, $line;
+ last if ($line[1] >= $bug);
print IDXNEW $line;
+ $line = "";
}
if ($new eq "NOCHANGE") {
- print IDXNEW $line;
+ print IDXNEW $line if ($line ne "" && $line[1] == $ref);
} elsif ($new eq "REMOVE") {
0;
} else {
print IDXNEW $new;
}
+ if ($line ne "" && $line[1] > $bug) {
+ print IDXNEW $line;
+ $line = "";
+ }
print IDXNEW while(<IDXDB>);
my @stuff=split /\n/, "$_[0]\n\n\n\n\n\n\n";
- my $firstpkg;
my $whendone = "open";
my $severity = $gDefaultSeverity;
- ($firstpkg = $stuff[4]) =~ s/[,\s].*$//;
+ (my $pkglist = $stuff[4]) =~ s/[,\s]+/,/g;
+ $pkglist =~ s/^,+//;
+ $pkglist =~ s/,+$//;
$whendone = "forwarded" if length $stuff[7];
$whendone = "done" if length $stuff[6];
$severity = $stuff[9] if length $stuff[9];
my $k = sprintf "%s %d %d %s [%s] %s %s\n",
- $firstpkg, $ref, $stuff[1], $whendone, $stuff[0],
+ $pkglist, $ref, $stuff[1], $whendone, $stuff[0],
$severity, $stuff[5];
update_realtime("$gSpoolDir/index.db.realtime", $ref, $k);
}
-@severities= @gSeverityList;
+@severities= grep { not exists $gObsoleteSeverities{$_} } @gSeverityList;
@showseverities= @severities;
grep ($_= $_ eq '' ? $gDefaultSeverity : $_, @showseverities);
@strongseverities= @gStrongSeverities;