#!/usr/gnu/bin/perl # wwwgnats.pl - a WWW interface to the GNATS bug tracking system # Thanks to Larry Wall, CERN, and NCSA for Perl, WWW, and Mosaic! # Configuration begins here $GNATSADM = "/usr/gnu/lib/gnats/gnats-db/gnats-adm"; $GNATSBIN = "/usr/gnu/bin"; # Configuration ends here # Modification log: # 7/14/94 Dan Kegel (dank@adventure.com) - Originally written # 7/15/94 Huy Le - Added loop over restrictions # 7/16/94 Dan Kegel - added config section & read responsible file # End Modifcation log sub dumpenv { print "
\n";
    foreach (sort(keys(%ENV))) {
    	print "$_ ", $ENV{$_}, "\n";
    }
    print "
\n"; } sub readarrays { # category tag : category name : responsible : other-interested-people # ace-bitmap:Accomplish Bitmap Dwg:sr:dank open(CATEG, "<$GNATSADM/categories") || die "Couln't get categories file\n"; while () { if (!/^\s*#|^\n$/) { ($x, $dummy, $dummy) = split(/:/); push(@nCategory, $x); } } close(CATEG); @nCategory = sort(@nCategory); push(@nCategory, ""); # needed for 'any'? # nametag : fullname : e-mail address # db:Dave Benson:david_benson@ccmail.adventure.com # Note: in our installation, the nametags are also valid local # e-mail aliases. open(RESPON, "<$GNATSADM/responsible") || die "Couln't get responsible file\n"; while () { if (!/^\s*#|^\n$/) { ($x, $dummy, $dummy) = split(/:/); push(@nResponsible, $x); } } close(RESPON); @nResponsible = sort(@nResponsible); push(@nResponsible, ""); # needed for 'any'? } # Query-pr's -i option outputs the following fields numerically. # Define arrays to map numbers to name. @nSeverity = ("", "Critical", "Serious", "Noncritical"); @nPriority = ("", "High", "Medium", "Low"); @nState = ("", "Open", "Analyzed", "Suspended", "Feedback", "Closed"); @nClass = ("", "sw-bug", "doc-bug", "support", "change-request", "mistaken", "duplicate"); # Arrays for output form @outSeverity = ("", "Crit", "Ser", "Noncr"); @outPriority = ("", "Hi", "Med", "Low"); @outform = ("brief","regular","verbose"); # The first field is the outform, the second is the field width %info = ( "CATEGORY", "0:10", "RELEASE", "0:7", "SEVERITY", "1:5", "PRIORITY", "4:3", # Not displayed "RESPONSIBLE", "1:2", "STATE", "0:9", "CLASS", "1:8", "SUBMITTER", "4:7", "ARRIVAL_DATE", "2:14", "ORIGINATOR", "1:9", "SYNOPSIS", "0:0", ); # Easiest way to preserve order of info parameters @info = ( "CATEGORY", "RELEASE", "SEVERITY", "PRIORITY", "RESPONSIBLE", "STATE", "CLASS", "SUBMITTER", "ARRIVAL_DATE", "ORIGINATOR", "SYNOPSIS", ); # Arrays for output restriction # The first field is the restriction, the second field is the default option %outrestr = ( "Category", "any", "State", "Open", "Responsible", "any", ); # For order of output restrictions @outrestr = ( "Category", "State", "Responsible", ); # Trucate a string to the given width, replacing last shown char with $ if truncated. # Usage: $fstr = &truncstr("long string", $width); sub truncstr { local($str) = shift(@_); local($WIDTH) = shift(@_); local($W, $fstring); # Trucate or pad the variable to the desired width. $W=$WIDTH; if (length($str)>$WIDTH && $WIDTH) { --$W }; $fstring = sprintf("%-${W}s",$WIDTH?substr($str,0,$W):$str); # Add a $ if we truncated it. if (length($str)>$WIDTH && $WIDTH) { $fstring .= "\$"; } return $fstring; } sub numerically { $a <=> $b; } sub query_quick { local($outform,@restrict)=@_; # Convert $outform to index into @outform LOOP: for ($i=0; $i<@outform; $i++) { if ($outform eq $outform[$i]) { $outform=$i; last LOOP; } } # Parse restrictions into query-pr options by converting # to lowercase and adding -- local($opts); foreach (@restrict) { tr/A-Z/a-z/; s/^/--/; $opts .= " '$_'" if (!/=any/ && !/=$/); } local(@prs); # Read in quick format list of pr's matching query print "Quick summary of spr's

Quick summary of spr's:

"; print "
query-pr -i $opts\n
\n"; open(PIPE,"$GNATSBIN/query-pr -i $opts|") || die "Can't open"; @prs = ; close(PIPE); @prs = sort numerically (@prs); if (@prs == 0) { print "

No bugs match your query.

\n"; return; } print "
\n";
    # Print field headers.
    local($OUTFORM, $WIDTH, $fstring, $str);
    $fstring = "";
    foreach (@info) {
	($OUTFORM, $WIDTH)=split(/:/,$info{$_});
	if ($OUTFORM <= $outform) {
	    $fstring .= &truncstr($_, $WIDTH) . " ";
	}
    }
    print "    ",$fstring,"\n"; 
    # Print each SPR in result as link to full text 
    foreach (@prs) {
	s/\s*\|\s*/|/go;
	( $NUMBER,
	$CATEGORY,
	$SYNOPSIS,
	$CONFIDENTIAL,
	$SEVERITY,
	$PRIORITY,
	$RESPONSIBLE,
	$STATE,
	$CLASS,
	$SUBMITTER,
	$ARRIVAL_DATE,
	$ORIGINATOR,
	$RELEASE ) = split(/\|/, $_);
	$SEVERITY = $outSeverity[$SEVERITY];
	$PRIORITY = $outPriority[$PRIORITY];
	$STATE = $nState[$STATE];
	$CLASS = $nClass[$CLASS];

	$fstring = sprintf("%s", substr("    ", 0, (length($NUMBER<4))?3-length("$NUMBER"):1));
	# @info is an array of the variable names $NUMBER, etc., in presentation order.
	# %info tells which outform level and ?below? to print this variable in,
	#       and how wide to print it.
	foreach (@info) {
	    ($OUTFORM, $WIDTH)=split(/:/,$info{$_});
	    if ($OUTFORM <= $outform) {
		$str = eval "\$$_";
		$fstring .= &truncstr($str, $WIDTH) . " ";
	    }
	}
	print "$NUMBER ",$fstring,"\n"; 
    } 
    print "
\n"; } sub query_full { local($spr) = $_[0]; local(@pr); # Read in full text of given pr print "Full text of spr #$spr

Full text of spr number $spr:

"; open(PIPE,"$GNATSBIN/query-pr -F $spr|") || die "Can't open"; @pr = ; close(PIPE); print "
\n";
    print @pr;
    print "
\n"; } sub main_menu { print "SPR Front End

SPR Front End

"; print "
\n"; # Choose output format. print "Select a\n"; print " output form.

\n"; print "Restrict the output by selecting\n"; print "

    \n"; # Loop over output restrictions (Category, State, Responsible). foreach (@outrestr) { print "
  • \n"; print " $_\n"; } # Loop over freeform search restrictions (Text, Multitext). foreach ("Text", "Multitext") { print "
  • \n"; print " $_\n"; } print "
\n"; print " and .

\n"; print "

\n"; } # Main Program print "Content-type: text/html\n\n"; print "\n"; #&dumpenv(); &readarrays(); # Read environment vars set according to CGI by httpd $SCRIPT_NAME = $ENV{"SCRIPT_NAME"}; $PATH_INFO = $ENV{"PATH_INFO"}; $QUERY_STRING = $ENV{"QUERY_STRING"}; # Get arg of outform= $QUERY_STRING =~ /^outform=(\w+)&/; $OUTFORM = $1; #print"$OUTFORM\n

\n"; # Get all restrictions. First, strip off outform prefix. ($RESTR = $QUERY_STRING) =~ s/^outform=\w+&//; # Then, split into words. @RESTR=split(/&/,$RESTR); #print "@RESTR\n"; # Were we invoked as /full? if ($PATH_INFO =~ /^\/full\//) { local($subdir); $subdir = $PATH_INFO; $subdir =~ s,^\/full\/,,; &query_full($subdir); } elsif ($PATH_INFO =~ /^\/quick/) { &query_quick($OUTFORM,@RESTR); } elsif ($PATH_INFO eq "") { &main_menu(); } else { print "SPR Front End

SPR Front End

"; print "Bad subdirectory specified in URL.\n"; } print "\n"; print "\n"; exit(0);