#!/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.1.1" ;
$CHANGELEVEL=4228 ;
# 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") ;
$P4_DEPOT = 0 unless $P4_DEPOT =~ /^\d+$/ ;
# Setup list of preferences
#
%PREF_LIST =
(
# "DP" => ["a:LIST","P4 Depot", 0], !Handled separately!
"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 ; } ;
$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(