#!/usr/bin/perl -wT my $contentOut = 'false'; my $errLog=""; $ENV{PATH} = '/usr/local/bin:/bin:/usr/bin';#Untaint the path ######################################################## #Get the local host name use Sys::Hostname; my $ipaddr=gethostbyname(hostname()); my ($a, $b, $c, $d)=unpack('C4',$ipaddr); my ($hostname,$aliases, $addrtype, $length, @addrs)=gethostbyaddr($ipaddr,2); my $user=scalar(getpwuid($<)); sub TestFiles{ my $filename = shift; my $writeableCheck = shift; if(!defined($filename) || $filename eq "" ){ return "false"; } if($filename =~/^([-\w.\/]+)$/) {#untaint $filename=$1; } else { $errLog ="Invalid filename = $filename
"; return "false"; } if(!(-e $filename)){ $errLog .= "file: $filename, does not exist.
"; return "false"; } if(-z $filename){ $errLog .= "file: $filename, has a size of 0.
"; #return "false"; } #my $filePermissionCmd = "ls -alh $filename"; if(!(-r $filename)){ $errLog .= "file: $filename, is not readable
";#.`$filePermissionCmd`."
"; return "false"; } if(defined($writeableCheck) && $writeableCheck!=0 && !(-w $filename)){ $errLog .= "file: $filename, is not writeable
";#.`$filePermissionCmd`."
"; return "false"; } my %filemodes; $filemodes{'cgi-lib.pl'} = 493; $filemodes{'data'} = 493; $filemodes{'beacons.txt'} = 420; $filemodes{'pinger.xml'} = 420; $filemodes{'offsite.nodes'} = 420; $filemodes{'pingerCronStat.stderr'} = 420; $filemodes{'pingerCronStat.stdout'} = 420; $filemodes{'lynx'} = 493; my $mode=(stat($filename)) [2] & 07777; #(my $fn = $filename) =~ s'^.*/''; $errLog .= "file: $filename found\n
"; foreach my $key (keys %filemodes) { if($filename =~ /$key/) { my $octmode=sprintf("%lo", $mode & 07777); unless ($mode eq $filemodes{$key}) { my $octfilemode=sprintf("%lo", $filemodes{$key} & 07777); $errLog .= "Mode: $mode/0$octmode, " . "should be $filemodes{$key}/0$octfilemode!\n
"; } else { $errLog .= "Mode: ". ((stat($filename))[2] & 07777) . "/0$octmode are required permissions\n
"; } } } $errLog .= "Bytes: ". (stat($filename))[7] . "\n
"; $errLog .= "Modified Time: ". localtime((stat($filename))[9]) . "\n
"; #Find the free space my $cmd = "df -h $filename"; if($cmd =~ /^(df $filename$)/) {$cmd=$1;} #untaint my @df = `$cmd`; $errLog .= "$cmd\n
";
  foreach my $line (@df) {
    $line=~ s/\s+$//;
    $errLog .= "$line\n";
  }
  $errLog .= "
\n"; return "true"; } # End TestFiles ######################################################## # TAILORING SECTION for NEW Hosts, change these to the right locations #See http://www-iepm.slac.stanford.edu/pinger/tools/install2.html. #If you use the standard PingER2 installation then nothing should need changing. my $error = ""; my $cgi_lib = "";#If none of our guesses below work then add the location for #for cgi-lib.pl for your host if(&TestFiles($cgi_lib,0)=~/^true/i){ require $cgi_lib; } elsif(&TestFiles("/afs/slac/g/www/cgi-lib/cgi-lib.pl",0)=~/^true/i){ require "/afs/slac/g/www/cgi-lib/cgi-lib.pl"; } elsif(&TestFiles("/usr/local/cgi-bin/cgi-lib.pl",0)=~/^true/i){ require "/usr/local/cgi-bin/cgi-lib.pl"; } elsif(&TestFiles("/usr/lib/cgi-bin/cgi-lib.pl",0)=~/^true/i) { require "/usr/lib/cgi-bin/cgi-lib.pl"; } elsif(&TestFiles("/usr/bin/cgi-bin/cgi-lib.pl",0)=~/^true/i) { require "/usr/bin/cgi-bin/cgi-lib.pl"; } elsif(&TestFiles("/var/www/cgi-bin/cgi-lib.pl",0)=~/^true/i) { require "/var/www/cgi-bin/cgi-lib.pl"; } else{ print "Status: 200 OK\nContent-type: text/html\n\n" . "
" . " Error: cgi-lib.pl not found. Please provide a valid path for cgi-lib." . "
$errLog
"; exit 1; } #$stats_dir is the directory where the current raw data measured by pinger is saved my $stats_dir = ""; if(&TestFiles($stats_dir)=~/^true/i){ } elsif(&TestFiles("/usr/local/share/pinger/data")=~/^true/i){ $stats_dir = "/usr/local/share/pinger/data"; } elsif(&TestFiles("/nfs/slac/g/net/pinger/pinger2/data")=~/^true/i){ $stats_dir = "/nfs/slac/g/net/pinger/pinger2/data"; } elsif(&TestFiles("/nfs/slac/g/net/pinger/pinger_mon_data")=~/^true/i){ $stats_dir = "/nfs/slac/g/net/pinger/pinger_mon_data"; } elsif(&TestFiles("/home/pingman/share/pinger/data")=~/^true/i) { $stats_dir = "/home/pingman/share/pinger/data"; } #elsif(&TestFiles("/nfs/slac/g/net/pinger/pinger2/data")=~/^true/i){ # $stats_dir = "/nfs/slac/g/net/pinger/pinger2/data"; #} else{ $contentOut = 'true'; print "Status: 200 OK\nContent-type: text/html\n\n"; $error = "
" . "Error: PingER data directory was not found. Please provide a valid path for stats_dir" . "
$errLog
"; #exit 2; } #sites_fn is the file, path for beacons.txt file my $sites_fn = ""; if(&TestFiles($sites_fn)=~/^true/i){ } elsif(&TestFiles("/usr/local/share/pinger/beacons.txt")=~/^true/i){ $sites_fn = "/usr/local/share/pinger/beacons.txt"; } elsif(&TestFiles("/afs/slac/www/comp/net/mon/offsite.nodes")=~/^true/i){ $sites_fn = "/afs/slac/www/comp/net/mon/offsite.nodes"; } else{ $contentOut = 'true'; print "Status: 200 OK\nContent-type: text/html\n\n"; $error = "
" ."Error: PingER data directory was not found. Please provide a valid path for sites_fn" . "
$errLog
"; #exit 3; } # pinger_xml_file is the current path for pinger.xml file for pinger2 # and offsite.nodes file for pinger1 my $pinger_xml_file = ""; if(&TestFiles($pinger_xml_file)=~/^true/i){ } elsif(&TestFiles("/usr/local/share/pinger/pinger.xml")=~/^true/i){ $pinger_xml_file = "/usr/local/share/pinger/pinger.xml"; } elsif(&TestFiles("/afs/slac/package/pinger/pinger2/share/pinger/pinger.xml")=~/^true/i){ $pinger_xml_file = "/afs/slac/package/pinger/pinger2/share/pinger/pinger.xml"; } else{ $contentOut = 'true'; print "Status: 200 OK\nContent-type: text/html\n\n"; $error = "
" . "Error: PingER data directory was not found. Please provide a valid path for sites_fn" . "
$errLog
"; #exit 4; } # $httpd is the httpd.conf configuration file for Apache my $httpd = "/etc/httpd/conf/httpd.conf"; if(&TestFiles($httpd)=~/^true/i){ } elsif(&TestFiles("/afs/slac/package/apache/servers/wanmon/conf/httpd.conf")=~/^true/i){ $httpd = "/afs/slac/package/apache/servers/wanmon/conf/httpd.conf"; } elsif(&TestFiles("/usr/local/apache2/conf/httpd.conf")=~/^true/i){ $httpd ="/usr/local/apache2/conf/httpd.conf"; } elsif(&TestFiles("/etc/apache2/apache2.conf")-~/^true/i) { $httpd ="/etc/apache2/apache2.conf"; } else{ $contentOut = 'true'; print "Status: 200 OK\nContent-type: text/html\n\n"; $error = "
" . "Error: Apache configuration file httpd.conf not found. Please provide a valid path for httpd.conf" . "
$errLog
"; #exit 5; } my $std_beacons_file = ""; if(&TestFiles($std_beacons_file)=~/^true/i){ } elsif(&TestFiles("/usr/local/share/pinger/beacons.txt")=~/^true/i){ $std_beacons_file = "/usr/local/share/pinger/beacons.txt"; } elsif(&TestFiles("/afs/slac/g/www/www-iepm/pinger/beacons.txt")=~/^true/i){ $std_beacons_file = "/afs/slac/g/www/www-iepm/pinger/beacons.txt"; } else{ $contentOut = 'true'; print "Status: 200 OK\nContent-type: text/html\n\n"; $error = "
" . "Error: beacons.txt was not found. Please provide a valid path for std_beacons_file." . "
$errLog
"; #exit 6; } my $stem="/usr/local/share/pinger/"; if($hostname =~ /slac.stanford.edu$/) { $stem="/afs/slac.stanford.edu/package/pinger/pinger2/share/pinger/"; } my @fns=("pingerCronStat.stdout", "pingerCronStat.stderr"); my @std_files=($stem.$fns[0], $stem.$fns[1], "/usr/local/bin/lynx", "/usr/bin/lynx", "/usr/local/share/pinger/pinger2.pl", "/bin/mail", "/bin/ping", "/usr/sbin/ping", "/usr/bin/dig", "/usr/local/bin/dig", "/bin/ping6",); my $std_cron_out_file = $stem.$fns[0]; my $std_cron_err_file = $stem.$fns[1]; foreach my $fn (@std_files) { unless(&TestFiles($fn) =~ /^true/i) { #$contentOut = 'true'; #print "Status: 200 OK\nContent-type: text/html\n\n"; #$error = "
" # . "Error: $fn was not found. Please provide a valid path for file." # . "
$errLog
"; #exit 7; } } my @cmds=('/bin/cat /etc/hosts', '/bin/cat /etc/resolv.conf', '/usr/bin/whoami', '/usr/ucb/whoami', '/bin/pwd', '/usr/sbin/sestatus', '/bin/ps -efl | grep httpd', '/bin/ps -efl | grep pinger2', "/bin/ls -lt $stats_dir", '/usr/bin/crontab -l', '/bin/crontab -l', '/bin/hostname', '/bin/domainname', ); foreach my $cmds (@cmds) { my ($cmd,$opt)=split(/\s/,$cmds, 2); if(!defined($opt)) {$opt="";} else {$opt=" $opt";} if($cmd=~/([\w+|\/|\s]+)/) {#Untaint if(-x $cmd) { $errLog.="
Output from: $1$opt\n".`$1$opt`."
\n"; } else { $errLog.="
$cmd $opt: Command not found
\n"; } } } ################Done with changes####################### use strict; ######################################################## #Set up USAGE (my $progname = $0) =~ s'^.*/'';#strip path components, if any #my $version="3.6; 30-Aug-2010; Fahad Satti and Les Cottrell"; #See beyond __END__ for more #my $version="3.7; 17-Nov-2010; Fahad Satti and Les Cottrell"; #See beyond __END__ for more #my $version="3.8; 11-30-2010; Les Cottrell"; #See beyond __END__ for more #my $version="3.81; 12-20-2010; Les Cottrell"; #See beyond __END__ for more #my $version="3.82; 01-02-2011; Les Cottrell"; #See beyond __END__ for more #my $version="3.83; 01-07-2011; Les Cottrell"; #See beyond __END__ for more #my $version="3.84; 01-07-2011; Les Cottrell"; #See beyond __END__ for more #my $version="3.9; 03-24-2011; Les Cottrell"; #See beyond __END__ for more my $version="3.91; 03-24-2011; Les Cottrell"; #See beyond __END__ for more my $USAGE = " $progname is a CGI script that enables one to gather the pingER data for a user specified time window for user specified remote sites(). It is acccessed via a URL. The default by accessing http:///cgi-bin/ping_data.pl is to display a form allowing the user to select the time and remote site(s). It is also available as a program API (using Lynx or wget) with the user specifying the various parameters as part of the QUERY_STRING. The parameters are: either: begin_year, begin_month, begin_day, begin_hour, begin_min, begin_sec, begin_offset: gives the starting time, begin_ofset is the offset from UDT. end_year, end_month, end_day, end_hour, end_min, end_sec, end_offset: gives the ending time or: begin, end: begin and end times as Unix epoch times. in_form: 1 if no form is to be displayed, undefined otherwise in which case form displayed and exits begin_point: y|n, include or do not include beginning point (default = no). end_point: y|n, see above but replace begnning by ending Output: If successful then data is treturned in records of the form: pinger.slac.stanford.edu 134.79.104.80 www.eldjazair.net.dz 193.194.64.71 100 1301011226 10 10 217.482 217.923 219.169 0 1 2 3 4 5 6 7 8 9 218 217 219 218 218 217 217 217 217 217 If there is no data then 'No data' will appear in the data. This is needed by getdata.pl which gets the data./ Examples of URL calls: http://www.slac.stanford.edu/cgi-wrap/$progname?help=1 http://www.comsats.edu.pk/cgi-bin/$progname http://pinger.comsats.edu.pk/cgi-bin/$progname?in_form=1&begin_hour=00&begin_min=00&begin_sec=00&begin_day=06&begin_month=08&begin_year=2007&begin_offset=&begin_point=y&end_hour=23&end_min=59&end_sec=59&end_day=06&end_month=08&end_year=2007&end_offset=&end_point=y More generically http://www.xxx.yyy.zzz/cgi-bin/$progname?site=a&site=b&site=c&begin=x&end=y&begin_point=n&end_point=n http://www.xxx.yy.zzz/cgi-bin/$progname?site=a&site=b&site=c&begin_hour=HH&begin_min=MM&begin_sec=SS&begin_offset=[-]HH&begin_day=DD&begin_month=MM&begin_year=YYYY&end_hour=HH&end_min=MM&end_sec=SS&end_offset=[-]HH&end_day=DD&end_month=MM&end_year=YYYY&begin_point=n&end_point=n The raw PingER data is obtained from the directory $stats_dir The list of remote nodes is obtained from $sites_fn Acknowledgments: $progname originally written by David E. Martin of HEP Network Resource Center, Fermilab, Batavia, IL based on work done by Connie Logg and Les Cottrell at the Stanford Linear Accelerator Center Heavily modified over the years by Les Cottrell, SLAC Version=$version "; ########################################################## require "timelocal.pl"; require "ctime.pl"; ########################################################### #Get default time stamps for form my $time=time(); #Unix epoch time for today my ($temp, $mday, $mon, $year); ($temp, $temp, $temp, $mday, $mon, $year, $temp, $temp, $temp) = localtime($time); $year=1900+$year; $mon++; if($mon < 10) {$mon ="0".$mon;} #Add leading zero if($mday < 10) {$mday="0".$mday;} #Add leading zero my $yday=$mday-1; if($yday<=0) {$yday="01"}; my $stats_base_fn = "ping-"; # put all values from command line into $in associative array our %in=(); &ReadParse(*in); # If the host is at slac.stanford.edu then use cgi-wrap else use cgi-bin my $cgi_bin="cgi-bin"; if($hostname =~ /.+\.slac\.stanford\.edu/){ $cgi_bin="cgi-wrap"; } ############################################################################# #If help requested then provide it if (defined($in{'help'})) { if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } print "ping_data.pl Help\n" . "$error

Help for http://$hostname/$cgi_bin/ping_data.pl

\n" . "
$USAGE
\n"; exit 100; } if (defined($in{'admin_func'}) && ($in{'admin_func'} eq 'fileLog')) { if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } print "
$errLog
\n"; exit 101; } if (defined($in{'admin_func'}) && ($in{'admin_func'} eq 'httpd')) { if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } if(-e $httpd){ if(open(HTTPD,$httpd)){ print "Starting Output of Apache configuration file\n\n
\n";
      while(){
        print "$_\n";
      }
      print "--------------Output complete---------------------\n";
    }
    else{
      print "Can't open Apache configuration file [$httpd]\n";
      last;
    }
  }
  else{
    print "Aapche configration file [$httpd]: No such File Found\n";
    last;
  }
  exit 102;
}
if(defined($in{'admin_func'}) && ($in{'admin_func'} eq 'pinger_xml')){
  if($contentOut eq 'false'){
    print "Status: 200 OK\nContent-type: text/plain\n\n";
  }
  if(-e $pinger_xml_file){
    if(open(PINGERXML,$pinger_xml_file)){
      print "Starting Output of PingER Landmarks file[$pinger_xml_file]\n\n";
      while(){
        print "$_\n";
      }
      print "--------------Output complete---------------------\n";
    }
    else{
      print "Can't open $pinger_xml_file error \n";
      last;
    }
  }
  else{
    print "pinger.xml[$pinger_xml_file]: No such File Found\n";
    last;
  }
  exit 5;
}
if(defined($in{'admin_func'}) && ($in{'admin_func'} eq 'std_cron_out')){
  if($contentOut eq 'false'){
    print "Status: 200 OK\nContent-type: text/html\n\n";
  }
  if(-e $std_cron_out_file){
    if(open(CRONOUT,$std_cron_out_file)){
      print "
"; print "Starting Output of Standard Cron Out[$std_cron_out_file]
\n\n"; while(){ print "$_
"; } print "--------------Output complete---------------------
\n
"; } else{ print "Can't open $std_cron_out_file fatal error
\n"; last; } } else{ print "Cron Output File[$std_cron_out_file]: No such File Found
\n"; last; } exit 6; } if(defined($in{'admin_func'}) && ($in{'admin_func'} eq 'std_cron_err')){ if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } if(-e $std_cron_err_file){ if(open(CRONERR,$std_cron_err_file)){ print "
"; print "Starting Output of Cron Errors for PingER2[$std_cron_err_file]
\n\n"; while(){ print "$_
"; } print "--------------Output complete---------------------
\n
"; } else{ print "Can't open $std_cron_err_file FATAL ERROR
\n"; last; } } else{ print "Cron Error File [$std_cron_err_file]: No such File Found
\n"; last; } exit 7; } if(defined($in{'admin_func'}) && ($in{'admin_func'} eq 'beacons')){ if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } if(-e $std_beacons_file){ if(open(BEACONS,$std_beacons_file)){ print "
"; print "Starting Output of beacons.txt file for PingER2[$std_beacons_file]
\n\n"; while(){ print "$_
"; } print "--------------Output complete---------------------
\n
"; } else{ print "Can't open $std_beacons_file FATAL ERROR
\n"; last; } } else{ print "Beacons.txt File [$std_beacons_file]: No such File Found
\n"; last; } exit 8; } ############################################################################# # if in_form not defined then return the form. if (!defined $in{'in_form'}) { if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/html\n\n"; } print " "; print " \n"; print ""; print "Get Ping Data from $hostname\n" . "\n"; print "$error

Get Ping Data from $hostname

" . ""; print "
This is a test form to retrieve ping data from $hostname " . "using $progname version=$version.\n"; print <<'EOM1';
There are similar retrieval scripts running elsewhere. Most of the time the data will be retrieved by automated scripts. This form is a good way of testing installations (see Verify XML Syntax for how to verify the PingER.xml file) and looking at up-to-the-minute data.
Please note SLAC only provides the most recent data available via this web page. For older data please refer to the following archive(anonymous FTP).
EOM1 print "
" . "
" . ""; my ($node,$site)=split(/\./,$hostname,2); print "
\n" . "
" . "" . "" . "
" . "Search: " . "
" . "" . "
" . "" . "
\n" . "" ."
" . "Search: " . "
\n" . "Note: Selecting no site will cause data for all $nodes sites to be returned.\n
"; print <<'EOM';
EOM print "
Start
HH:MM:SS
DD:MM:YYYY
Offset from GMT
Endpoint
: : \n" . " :\n" . " :\n" . " \n"; print <<'EOM';
Include
EOM print "
End
HH:MM:SS
DD:MM:YYYY
Offset from GMT

Endpoint

: : \n" . " :\n" . " :\n" . " \n"; print <<'EXECUTE';
Include

EXECUTE my $time=scalar(localtime()); print "Form created by $0 for $user on $hostname($a.$b.$c.$d). \n" . "Local time=$time.\n " . "Raw PingER data obtained from $stats_dir. " . "Remote sites obtained from $sites_fn. \n" . "The most current version of this script and instructions to install can be found at: " . "" . "Installing ping_data.pl and traceroute.pl for PingER2. " . "The " . "master template pinger.xml is available from SLAC. " . "There is USAGE " . "information on the script.\n"; exit; } ############################################################################# #Not requesting help or a form so provide results else { if($contentOut eq 'false'){ print "Status: 200 OK\nContent-type: text/plain\n\n"; } } my ($begin, $end); if (defined $in{'begin_hour'}) { $begin = &timegm($in{'begin_sec'},$in{'begin_min'},$in{'begin_hour'},$in{'begin_day'}, ($in{'begin_month'} -1), ($in{'begin_year'} -1900)); $begin = $begin - ($in{'begin_offset'} *3600); $end = &timegm($in{'end_sec'},$in{'end_min'},$in{'end_hour'},$in{'end_day'}, ($in{'end_month'} -1), $in{'end_year'} -1900); $end = $end - ($in{'end_offset'} *3600); } elsif (defined $in{'begin'}) { $begin = $in{'begin'}; $end = $in{'end'}; } else { print "No begin and end times\n"; exit; } # if no sites specified, return all sites my $all_sites; my %site_list; if (!defined $in{'sites'}) { $all_sites = 1; } else { $all_sites = 0; # put (lower-cased) site names in associate array for easy checking for (split(/\0/, $in{'sites'})) { tr/A-Z/a-z/; $site_list{$_} = 1; } } # Exclude the end points unless begin_point (or end_point) is specfied. if ($in{'begin_point'} ne 'y') { ++$begin } if ($in{'end_point'} ne 'y') { --$end } if ($end < $begin) { print "End < Begin\n"; exit; } my ($begin_sec, $begin_min, $begin_hour, $begin_mday, $begin_mon, $begin_year, $begin_wday, $begin_yday, $begin_isdst) = gmtime($begin); my ($end_sec, $end_min, $end_hour, $end_mday, $end_mon, $end_year, $end_wday, $end_yday, $end_isdst) = gmtime($end); # Add 2 minutes of "fuzz" to the timestamp search limits to allow for # the timestamps' being a little out of strict sort order. my $begin_search = $begin - 120; my $end_search = $end + 120; my $fn; # for $month ((($begin_year +1900) * 12 + $begin_mon +1).. # (($end_year+1900) * 12 + $end_mon +1)) { # $fn = sprintf("%s/%s%4.4d-%2.2d.txt", $stats_dir, # $stats_base_fn, int($month / 12), $month % 12) # # for $month ((($begin_year +1900) * 12 + $begin_mon ).. # (($end_year+1900) * 12 + $end_mon )) { # $fn = sprintf("%s/%s%4.4d-%2.2d.txt", $stats_dir, # $stats_base_fn, int($month / 12), ($month % 12) +1); my $nline=0; for my $month ((($begin_year +1900) * 12 + $begin_mon )..(($end_year+1900) * 12 + $end_mon)) { $fn = sprintf("%s/%s%4.4d-%2.2d.txt", $stats_dir, $stats_base_fn, int($month / 12), ($month % 12) +1); if (!open(PINGDATA, $fn)) { if(!(-d $stats_dir)){ print "Unable to locate Data Dir = ".$stats_dir."\n"; } if(!(-e $fn)){ print "Unable to locate Data File = ".$fn."\n"; } print "#Warning $progname can't open $fn: $!\n"; next; } # print "Opened $fn\n"; # Use a binary search to quickly position the PINGDATA file to a little # before the $begin timestamp data. &SeekBinSrch(*PINGDATA, $begin_search, 1500); while () { my ($src_name, $src_ip, $dest_name, $dest_ip, $pingsize, $ctime) = split(/\s+/, $_); # The following 5 lines are optimized for speed at the expense of beauty. next if ($ctime < $begin); if ($ctime > $end) { if ($ctime < $end_search) {next;} last; } $nline++; $dest_name =~ tr/A-Z/a-z/; print if (defined $site_list{$dest_name} || $all_sites); } # while () close (PINGDATA); } # for $month if($nline<=0) { print "#No data found in $nline lines of data between dates specified in $fn.\n" . "#Dates: " . ($begin_year+1900)."/".($begin_mon+1).".." . ($end_year +1900)."/".($end_mon +1).". " . "Epoch time searched from $begin-120 secs to $end+120 secs\n"; my $n=20; my @tails=("/usr/bin/tail", "/bin/tail"); foreach my $tail (@tails) { if(-e $tail){ if($tail=~/([\w\/]+)/){$tail=$1;} else {print "#Command $tail is tainted\n"; next;} if($n=~/(\d+)/) {$n=$1;} else {print "#Line count $n is tainted\n"; next;} if($fn=~/([\w\/\-\.]+)/) {$fn=$1;} else {print "#File name $fn is tainted\n"; next;} my $cmd="$tail -$n $fn"; my @ans=`$cmd`; print "#Results (".scalar(@ans)." lines) from $cmd are:\n"; if(scalar(@ans)<=0) {print "$cmd returned ?=$? !=$!\n";} else { foreach my $line (@ans) {print "#$line\n";} } } } } ############################################################################# sub SeekBinSrch # ( *FH, $key, $close_enough ) # Subroutine to seek to the vicinity of the $begin data records in the # ping_data file using a binary search. The binary search only attempts # to get within $close_enough bytes of the "exact" position in the sorted # file which contains the search key (or, if no such record exists in the # file, then to where such a record would be placed if it existed). # More precisely, the binary search finds a region of the file such that # (1) the size of the region is less than or equal to $close_enough bytes; # (2) the beginning of the region is the beginning of a record whose key is # less than or equal to the search key if such a record exists, otherwise # the start of the region is the start of the file; and # (3) the first record that begins after the end of the region has a key # which is greater than or equal to the search key if such a record # exists, otherwise the end of the region is the end of the file. # The file is left positioned to the beginning of the region. # # Author: John Halperin 6 June 1997. { local(*FH) = $_[0]; my($key, $close_enough) = @_[1..2]; my($lo_posn, $hi_posn); # return unless (defined());#remove warning "Value of construct can be "0"; test with defined()" return unless (-f FH); # can't handle pipes or other oddities $lo_posn = 0; $hi_posn = (-s FH) or die "BinSrchFile: error stat'ing FH: $!\n"; my $loop_ct = 0; my($mid_posn, $rec_start, $rec, $rec_key, $lt_eq_gt, $errct); BinSrch: while (($hi_posn - $lo_posn) > $close_enough && ++$loop_ct < 40) { $mid_posn = ($lo_posn + $hi_posn) >> 1; seek(FH, $mid_posn, 0) or die "BinSrchFile: seek($mid_posn) failed: $!\n"; ; # skip to start of next record for ($errct = 0; ; ) { $rec_start = (tell); last BinSrch if ($rec_start >= $hi_posn); if(!defined($rec = )){ die "SeekBinSrch: error reading file: $!\n"; } $rec_key = (split(/ /, $rec, 7))[5]; last if (defined($rec_key) && $rec_key =~ m/^\d+$/); warn "BinSrchFile: record at posn $rec_start has a bad timestamp\n", "*** $rec"; die "BinSrchFile terminating\n" if (++$errct > 10); } $lt_eq_gt = $key - $rec_key; if ($lt_eq_gt < 0) { $hi_posn = $mid_posn; # srch key < rec, so drop ceiling } elsif ($lt_eq_gt > 0) { $lo_posn = $rec_start; # srch key > rec, so raise floor } else { $hi_posn = $lo_posn = $rec_start; # key == rec; found. } } # BinSrch: while () die "BinSrchFile failed; looping?\n" if (($hi_posn - $lo_posn) > $close_enough); seek(FH, $lo_posn, 0) or die "BinSrchFile: seek($lo_posn) failed: $!\n"; } # &SeekBinSrch() __END__ ########################### Copyright Notice ################################### # Copyright (c)1996 Universities Research Association, Inc. # # All Rights Reserved # # /*---------------------------------------------------------------*/ # /* STANFORD UNIVERSITY NOTICES FOR SLAC SOFTWARE */ # /* ON WHICH COPYRIGHT IS DISCLAIMED */ # /* */ # /* AUTHORSHIP */ # /* This software was created by , Stanford Linear */ # /* Accelerator Center, Stanford University. */ # /* */ # /* ACKNOWLEDGEMENT OF SPONSORSHIP */ # /* This software was produced by the Stanford Linear Accelerator */ # /* Center, Stanford University, under Contract DE-AC03-76SFO0515 */ # /* with the Department of Energy. */ # /* */ # /* GOVERNMENT DISCLAIMER OF LIABILITY */ # /* Neither the United States nor the United States Department of */ # /* Energy, nor any of their employees, makes any warranty, */ # /* express or implied, or assumes any legal liability or */ # /* responsibility for the accuracy, completeness, or usefulness */ # /* of any data, apparatus, product, or process disclosed, or */ # /* represents that its use would not infringe privately owned */ # /* rights. */ # /* */ # /* STANFORD DISCLAIMER OF LIABILITY */ # /* Stanford University makes no representations or warranties, */ # /* express or implied, nor assumes any liability for the use of */ # /* this software. */ # /* */ # /* STANFORD DISCLAIMER OF COPYRIGHT */ # /* Stanford University, owner of the copyright, hereby disclaims */ # /* its copyright and all other rights in this software. Hence, */ # /* anyone may freely use it for any purpose without restriction. */ # /* */ # /* MAINTENANCE OF NOTICES */ # /* In the interest of clarity regarding the origin and status of */ # /* this SLAC software, this and all the preceding Stanford */ # /* University notices are to remain affixed to any copy or */ # /* derivative of this software made or distributed by the */ # /* recipient and are to be affixed to any copy of software made */ # /* or distributed by the recipient that contains a copy or */ # /* derivative of this software. */ # /* */ # /* SLAC Software Notices, Set 4 (OTT.002a, 2004 FEB 03) */ # /*---------------------------------------------------------------*/ # Copyright (c) 2006, 2007, 2008, 2009, 2010 # The Board of Trustees of # the Leland Stanford Junior University. All Rights Reserved. # # *** changes in version 1.1.1 # - selecting no sites returns all sites # - refer to /usr/local/netmon # *** changes in version 1.1.2 # - fast skip to starting time, and exit after ending time # *** changes in version 1.1.4, June 24, 2006 # - Provide default dates and times in form boxes # - Sort the sites, increase the size of box, compress output # *** changes in version 1.1.5, July 20, 2006 # - Automate getting the hostname and add version number output. # - Correct URL for getting FTP data. # *** changes in version 1.1.6 August 18, 2006, Les Cottrell # Check if running on host at slac.stanford.edu, if so use cgi-wrap, else use cgi-bin # Add warning if can't open file # *** changes in version 1.1.7 March 29, 2007, Les Cottrell # use #!/usr/bin/perl -- rather than #!/usr/local/bin/perl5 # *** changes in version 1.1.8 May 30, 2007 # Report no data found in file. # Prevent $yday going < 01 #my $version="1.1.8, 5/30/07, Cottrell."; # *** changes in version 2.0 8/6/07, add help, use strict -T # *** changes in version 3.1 2/17/10, provide access to help, pinger.xml, # error and log. Get file locations automatically. # Allow target node selection. # *** changes in version 3.2 2/23/10, added require "/usr/lib/cgi-bin/cgi-lib.pl"; #Below is an example of the data format minos.slac.stanford.edu 134.79.196.100 dukhet.phy.duke.edu 152.3.57.20 100 862526343 10 10 90 106 133 # *** changes in version 3.3 2/23/10, # * Added a subroutine(TestFiles) at the top, to check required files for # ** existance # ** size > 0 # ** is readable # ** is writeable(except in case of cgi-lib) # * Added, checks to look for the most important files, like # pinger.xml, cgi-lib.pl and pinger data dir in most obvious locations. # This should help remove the need to make any changes to this script. # *** changes in version 3.4 2/24/10, # * Added the ability to output PingER2 FAQ # * Added the ability to output beacons.txt file # *** changes in version 3.5 2/24/10, # * Added, search capability. # *** changes in version 3.5.1 2/27/10, # * Added, mode and Last modified output for files. # *** Changes in version 3.6 8/30/2010, # * Added octal display of permissions, space check, # * info on checking the pinger.xml file # *** Changes in version 3.7 11/17/2010 # * Provided date stamp of cronStat files. # * Added test to see if lynx, mail, dig, ping, ping6 present # *** Changes in version 3.8 11/30/10, # * Added ability to list httpd.conf file. # *** Changes in version 3.81 12/20/2010, # * Added selinux check. # *** Changes in version 3.82 01/02/2011, # * Added "/usr/local/apache2/conf/httpd.conf" to possible httpd.conf locations # * Added pwd, whoami and list of httpd processes # *** Changes in version 3.83 01/07/2011, # * Added /etc/hosts and /etc/resolv.conf, ip addr, local time, # * location of master template for pinger.xml # *** Changes in version 3.84 02/18/2011, # * Added /bin/hostname, /bin/domainname. # *** Changes in version 3.9 3/24/2011, # * Added ps -efl | grep pinger2, ls -lt $stats_dir, added more # * diagnostics for No data found. # *** Changes in version 3.91 12/21/2011 # * Added look for $httpd in /etc/apache2/apache2.conf for acmesecurity