#!/usr/bin/perl # CGI script that displays a complete report, or a report segment # if reptype is '' or 'dtr' - dir tree report # complete report if webdir is null, otherwise extract the relevant dir # also accepts repdate (or weeknum), server, detail, honly, sortkey # # if reptype is 'dom' - domain report # complete report if webdir is null, otherwise extract the relevant dir # also accepts repdate, server, detail # # if reptype is 'red' - redirect report # complete report if webdir is null, otherwise extract the relevant dir # also accepts repdate, server $DEFSERV='columbia'; # default server $WEEKLIST='/www/data/httpd/reports/weeklist'; # use the statmap array to identify: # the server name # users authorized to see those reports (NULL means all users) # directory that contains the reports # URL of those reports @statmap = ( ['columbia', '', '/www/data/httpd/reports/columbia', 'http://www.columbia.edu/httpd/reports/columbia'], ['ciao', '', '/www/data/httpd/reports/ciao', 'http://www.columbia.edu/httpd/reports/ciao'] ); # use the secmap array to restrict users to a given directory # these restrictions only apply to the www1 server and the wwwc server @secmap = (); $ICON_REG='http://www.columbia.edu/httpd/getstats/getstats.gif'; $ICON_SEC='https://www1.columbia.edu/icons/getstats.gif'; $SRVPORT=$ENV{'SERVER_PORT'}; # get server's port number if ($SRVPORT eq '443') { # secure server $ICON_OUT=$ICON_SEC; } else { # regular server $ICON_OUT=$ICON_REG; } # set defaults $reptype='dtr'; $server=$DEFSERV; # default server $repdate=''; $weeknum=''; $webdir=''; $detail=1; $honly=''; $sortkey='req'; # alp or req (byt no longer supported) $debug=''; if ($ENV{'REQUEST_METHOD'} eq 'GET') { # get the input using method=get $buffer = $ENV{'QUERY_STRING'}; } else { # get the input using method=post read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } @pairs = split(/&/, $buffer); # split the name-value pairs foreach $pair (@pairs) { # put values into scalar variables ($name, $value) = split(/=/, $pair); # Un-Webify plus signs, undo the %-encoding $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($name eq 'reptype') { # report type: dtr, dom, red $reptype = $value; } elsif ($name eq 'server') { $server = $value; } elsif ($name eq 'repdate') { # 8 digit report date $repdate = $value; } elsif ($name eq 'weeknum') { # 0=current week, 1=one week ago $weeknum = $value; # (for back compatibility) } elsif ($name eq 'webdir') { # desired directory $webdir = $value; } elsif ($name eq 'detail') { # levels of detail $detail = $value; } elsif ($name eq 'honly') { # count HTML files only $honly = $value; } elsif ($name eq 'sortkey') { # alp or req $sortkey = $value; } elsif ($name eq 'showsum') { # include summary (no longer used) $showsum = $value; } elsif ($name eq 'debug') { $debug = $value; } else { print "Content-type: text/html\n unexpected variable: $name=$value
\n"; } } $uni=$ENV{'REMOTE_USER'}; # Kerberos handle $emain=$ENV{'USER_EMAIL'}; # email address $person="$uni <$emain>"; $secure_server = ($server eq 'www1') || ($server eq 'wwwc'); for $statrow (@statmap) { # look up server name to get report dir ($srv, $uzerz, $repdir, $baseurl) = (@$statrow); # and authorized user list last if $srv eq $server; } &errmsg2("undefined server: $server") unless $srv eq $server; for $secrow (@secmap) { # check further restrictions, per user ($clients, $clidir) = (@$secrow); last if $clients =~ /-$uni-/; } if ($repdate) { $weeknum=''; &errmsg2("repdate must be numeric: $repdate") if $repdate =~ /\D/; &errmsg2("repdate must be eight digits: $repdate") unless length($repdate)==8; } else { &errmsg('weeknum must not be negative') if $weeknum < 0; $weeknum='0' unless $weeknum; $repdate = &get_repdate($weeknum); # translate week number to date string &errmsg("no web usage report on the $srv server from $weeknum weeks ago") unless $repdate; } chop($webdir) if $webdir =~ m|/$|; # remove trailing slash $webdir = '/' . $webdir unless $webdir =~ m|^/|; # add leading slash @wdirs = split('/', $webdir); # count the slashes in webdir $detail = $#wdirs if $detail < $#wdirs; # increase detail if necessary undef(@wdirs); $webdir='' if $webdir eq '/'; if ($reptype eq 'dom') { $sortkey='req'; $detail=2 if $detail > 2; $baseurl .= '/dom'; $repdir .= '/dom'; } if (($server ne 'columbia') && ($server ne 'www1') && ($server ne 'wwwc')) { $honly='on'; # other servers only have these $sortkey='req'; $detail=4 if $detail > 4; } $reptype = 'htr' if ($reptype eq 'dtr') && $honly; if (!$webdir) { # user wants FULL REPORT: DTR DOM RED &errmsg2("user $person is not authorized to see full reports on server $server") if ($secure_server) && ($clients =~ /-$uni-/); if ($reptype eq 'red') { print "Location: $baseurl/$repdate.redir.html\n\n"; } else { # URL of the form /httpd/reports/19970816.dtrreq3.html print "Location: $baseurl/$repdate.$reptype$sortkey$detail.html\n\n"; } exit; } if ($reptype eq 'dom') { # user wants partial domain report $detail=2; # construct URL of the form /httpd/reports/cu/help/19970816.domreq2.html print "Location: $baseurl$webdir/$repdate.$reptype$sortkey$detail.html\n\n"; exit; } print "Content-type: text/html\n\n"; # user wants partial dir tree report &errmsg('detail must be at least 1') if $detail < 1; &errmsg('detail must not be greater than 6') if $detail > 6; &errmsg("user $person is not authorized to see reports for server $srv") unless (!$uzerz) || $uzerz =~ m/-$uni-/; # this user restricted to specific directories on secure servers if (($secure_server) && ($clients =~ /-$uni-/)) { &errmsg("user $person is only authorized to see reports for directory $clidir on server $server") unless $webdir =~ m|^$clidir|; } # construct file name of the form "19950114.dtrreq3.html" if ($reptype eq 'red') { $repfilnam = "$repdir/$repdate.redir.html"; } else { $repfilnam = "$repdir/$repdate.$reptype$sortkey$detail.html"; } if (!open(REP, "<$repfilnam")) { &errmsg("Can't open report file $repfilnam: $!"); } $visible=1; $dtr_header=''; while () { # skip the summary and the top 10 list # save the Directory Tree Report header in memory # must display icon from server this CGI script is running on # to prevent Netscape warnings about mixing secure and unsecure data s|$ICON_REG|$ICON_OUT|o; s|$ICON_SEC|$ICON_OUT|o; $visible='' if /Summary Report/; $visible=1 if s/Directory Tree Report/$& for $webdir/; $visible=1 if s/Redirect Report/$& for $webdir/; $dtr_header .= $_ if $visible; if ($visible && /------------------/) { # line after "Dir/file Req" $doffset = length($`); last; } } &errmsg("$webdir not found in $detail level report for $srv server") unless &extract_section($webdir, $dtr_header); $visible=''; while () { $visible=1 if /Created by /; print if $visible; } close REP; exit; ######################################## # read the weeklist file to map weeknum into repdate # returns the 8 digit report date, or NULL if not found sub get_repdate { local($weeknumber) = @_; local($thisweek) = 0; if (!open(DATES, "<$WEEKLIST")) { &errmsg("Can't open $WEEKLIST: $!"); } while () { if ($weeknumber == $thisweek) { chop; return $_; # success } $thisweek++; } close DATES; return ''; # not found } sub extract_section { # print the relevant portion of the web usage report # returns 1 on success, '' otherwise local($webdir, $dheader) = @_; local($visible, $dirlevel, $offset, $tlev, $m, $j); local(@wdirs) = split('/', $webdir); # directory components are stored in the @wdirs array # e.g. /cu/help is stored this way: # $wdir[1] = 'cu' # $wdir[2] = 'help' $dirlevel = $#wdirs; # levels specified by the user foreach $wdir (@wdirs) { $wdir .= '/'; } repline: while () { last repline if m|^\|; chop($rline=$_); # set tlev to the level of the current line (0 to 6) for ($tlev = 0; $tlev <= 6; $tlev++) { local($rlev) = $tlev; local($roffset) = 0; # level 0, indent 0 if ($rlev) { # level 1, indent 1 $roffset++; $rlev--; } $roffset += $rlev*3; # indent 3 for each level past 1 $offset = $doffset+$roffset; if (substr($rline, $offset, 1) ne ' ') { $dirname[$tlev] = substr($rline, $offset); last; } } if ($visible) { if (($tlev < $dirlevel) || (($tlev == $dirlevel) && ($wdirs[$tlev] ne $dirname[$tlev]))) { last repline; # we are done } print "$rline\n"; } else { next repline if $tlev != $dirlevel; # keep looking $m = 1; for ($j = 1; $j <= $dirlevel; $j++) { if ($wdirs[$j] ne $dirname[$j]) { $m = 0; last; } } if ($m == 1) { # found beginning of section $visible = 1; print $dheader; print "$rline\n"; } } } return $visible; } # extract_section sub errmsg { # print an error message local($mess) = @_; print "Showstats Error

Showstats Error

$mess"; exit; } sub errmsg2 { # header + error message local($mess) = @_; print "Content-type: text/html\n Showstats Error

Showstats Error

$mess"; exit; }