#!/usr/bin/perl -w
# -*-perl-*-
##################################################################
# "P4CGI" perl module.
#
# This package is documented using perlpod.
#
package P4CGI ;
###
# You might need to uncomment and modify this to set the lib
# to point to the perl libraries.
#
#use lib '/usr/local/lib/perl5/site_perl' ;
###
# Specify configuration file path
#
sub ConfigFileName()
{
return "./P4DB.conf" ; # Change here to move or rename configuration file
}
use CGI ;
use CGI::Carp ;
use strict;
# A feeble attempt to fence off the most blatant DOS attacks.
$CGI::POST_MAX=1024 * 100; # max 100K posts
$CGI::DISABLE_UPLOADS = 1; # no uploads
#### Conficuration file name
my $CONFIG_FILE ;
#### Store error information
my @ERRLOG ; ## Error log
my $ERRORS ; ## Error counter
#### The following variables are set or updated by the init() routine.
my $CGI; # Contains CGI object from CGI.pm
# Constants
my $VERSION ; # P4DB version
my $CHANGELEVEL ; # P4 change level for relesed version
my $REQUIRED_SERVER_VERSION_YEAR ; # Required server version year
my $REQUIRED_SERVER_VERSION_NUMBER ; # Required server version number
my $STYLE_SHEET ; # Style sheet file name
my $HELPFILE_PATH; # Path to help file (html) ### OBSOLETE???
#
my $P4_DEPOT ; # Depot number (as defined by preferences list)
my @P4_DEPOTS ; # Depots from config file
# Information read from p4 depot:
my $LASTCHANGE ; # Current change level
my $SERVER_VERSION_YEAR ; # Server year
my $SERVER_VERSION_NO ; # Server count
my $SERVER_VERSION_QUAL ; # Server version qualifier
my $SERVER_VERSION_CHANGE ; # Server change No.
my $NO_CONTACT_ERROR ; # Defined if no contact with depot or other depot-related problem
# Information from configuration file.a
my %CONF ; # Hash containing configuration
my $P4 ; # Contains p4 command
my $PORT; # Contains p4 port
my $P4_HOSTNAME; # Contains p4 host name
my $UNUSEDCLIWL ; # Unused client warning level (from configuration file)
my $UNUSEDUSRWL ; # Unused user warning level (from configuration file)
my $REDIRECT_ERROR_TO_NULL_DEVICE; # Command that redirects errors to /dev/null
my $REDIRECT_ERROR_TO_STDOUT; # Command that redirects errors to stdout
my @P4DBadmin ; # Admins for P4DB and Perforce server
# Information store in cookies (user preferences etc).
my %SHORTCUTS ; # Shortcuts (from cookie)
my %PREF ; # Current user preferences
my %PREF_LIST ; # List of available preferences
my $IGNORE_CASE; # "YES" if case should be ignored
my $MAX_CHANGES; # Max changes for change list
my $TAB_SIZE; # Tab size for file viewer
my $DEBUG ; # Debug mode, When true, prints log (from preferences)
# Misc info.
my $LEGEND ; # Legend supplied to header (from CGi script)
#### Other package variables
my $pageStartPrinted ; # Mark that html header is printed
# Used to avoid mutliple headers if an error occurres
my %EXTRAHEADER ;
my $ONLOADSCRIPT ;
my $helpTarget ; # target for help text
my $printHeaderButtons ;
#### Convenience variables
my $DEFAULT_SPAN_CLASS ; # Default class for spanClass() method.
###
### Subroutine that prints the error log
###
sub prerrlog() {
my $res = "" ;
if(@ERRLOG> 0) {
map {
if(/^ERROR:/) {
$_ = spanClass(&htmlEncode($_),"LogError") ;
}
else {
if(/^p4call/) {
$_ = spanClass(&htmlEncode($_),"LogP4Call") ;
}
else { $_ = spanClass(&htmlEncode($_),"Log") ; } ;
} ;
} @ERRLOG ;
$res .=
"
" .
"URL: " . $CGI->self_url() . "
\n" .
spanClass("Log printout:","LogHeader") .
"
" . join("\n",@ERRLOG) . "\n" ; } ; return $res ; } ### ### Initialization code, called from BEGIN(). ### sub init( ) { $printHeaderButtons="Y" ; # We require server from 2001 or newer # $REQUIRED_SERVER_VERSION_YEAR = 2002 ; $REQUIRED_SERVER_VERSION_NUMBER = 2 ; # Set config file name # $CONFIG_FILE = &ConfigFileName() ; ## death handler $SIG{'__DIE__'} = sub { # Thank you Ron Shalhoup for the tip my $error = shift; &P4CGI::bail("Signal caught: $error") ; exit 0; }; # clear error counter # $ERRORS = 0 ; # Set P4DB version # $VERSION="3.1b2" ; $CHANGELEVEL=4079 ; # Set some configuration defaults # $HELPFILE_PATH = "./" ; $UNUSEDCLIWL = 10 ; $UNUSEDUSRWL = 10 ; # Initiate CGI module # $CGI = new CGI ; $CGI->autoEscape(undef) ; # Get depot number # $P4_DEPOT = 0 ; $P4_DEPOT = $CGI->param("DP") if defined $CGI->param("DP") ; # Setup list of preferences # %PREF_LIST = ( # "DP" => ["a:LIST","P4 Depot", 0], "IC" => ["d:BOOL","Ignore case", 0], "MX" => ["d:INT" ,"Max changes to show", 100], "TB" => ["d:INT" ,"Default tab stop", 8], "HD" => ["e:BOOL","Hide deleted files ", 0], "VC" => ["f:BOOL","View files with colors", 1], "ST" => ["f:LIST","Style Sheet File", 0], "PH" => ["f:LIST","Header style", 0,"Pulldown Menues","Buttons"], # Comment out line below to disable log printouts completely. "DBG" => ["z:BOOL","Print debug information", 0], ) ; # Read user preferences # %PREF=$CGI->cookie(-name=>"P4DB_31_PREFERENCES") ; # First try cookie... my $p ; foreach $p (keys %PREF_LIST) { # Fill in defaults for those missing in cookie if(! defined $PREF{$p}) { $PREF{$p} = $ {$PREF_LIST{$p}}[2]; ERRLOG("Set default for $p!") ; } } ; foreach $p (keys %PREF) { # Check that all specified prefereces really exists... if(exists $PREF_LIST{$p}) { ERRLOG("PREF: $p => $PREF{$p} (${$PREF_LIST{$p}}[1])") ; } else { delete $PREF{$p} ; } ; } ; # If new preferences are specified, parse and modify if(defined $CGI->param("SET_PREFERENCES")) { my $c ; foreach $c (keys %PREF) { my $val = $CGI->param($c) ; if(defined $val) { $CGI->delete($c) ; my $type = $ {$PREF_LIST{$c}}[0] ; if($type eq "INT") { $val =~ /^\d+$/ or next ; } ; if($type eq "BOOL") { $val =~ /^[01]$/ or next ; } ; # if($c eq "DP" and # $PREF{$c} != $val) { # # if we get here the user as modified depot, we should restart with index.cgi # &ONLOADSCRIPT("location='index.cgi';") ; # $CGI->delete("SET_PREFERENCES") ; # To stop SetPreferences.cgi from replacing the ONLOADSCRIPT # } $PREF{$c} = $val ; } } } # Set up data structure for configuration file # my %configReaderData = ( "P4PATH" => \$P4, "HTML_HELPFILE_PATH" => \$HELPFILE_PATH, "P4DB_ADMIN" => \@P4DBadmin, "SHELL" => \$ENV{"SHELL"}, "REDIRECT_ERROR_TO_NULL_DEVICE" => \$REDIRECT_ERROR_TO_NULL_DEVICE, "REDIRECT_ERROR_TO_STDOUT" => \$REDIRECT_ERROR_TO_STDOUT, "DEPOT" => \@P4_DEPOTS, "STYLES" => $PREF_LIST{"ST"}, "UNUSED_CLIENT_WARNING_LEVEL" => \$UNUSEDCLIWL, "UNUSED_USER_WARNING_LEVEL" => \$UNUSEDUSRWL ) ; # Read configuration file # local *F ; my $line = 0 ; open(F,"<$CONFIG_FILE") or &P4CGI::bail("Could not open config file \"$CONFIG_FILE\" for read") ; while(