#!/usr/bin/perl
# /etc/httpd/bin/copy-weblogs.pl
#
# copies the daily httpd (or httpsd) logs to the central repository
#  and removes them. runs as root so it can remove the old logs.
# runs logres on a separate host, to resolve the IP addresses.
# runs daily or every six hours on the regular servers and the secure
#  servers, after the logs have been rotated

$rhost='zivijo';		# run logres on this host
$ruser='radish';		#  as this user
$DELAYSEC=3*60;			# wait this long before removing old version
$verbose='';			#  so hitcounter has time to read it

chop($DA=`which date`);
die("can't find date program\n") if $DA =~ /^no /;

$httpd='httpd';	
if ($#ARGV > 0) {
    die "usage: copy-weblogs.pl [httpd|httpsd|wdamb]\n";
} elsif ($#ARGV == 0) {
    $httpd=$ARGV[0];
}

chop($date=`$DA +%Y%m%d%H`);		# yyyymmddhh
die("old date program does not support %Y option\n") unless $date;

print "debuging mode, date=$date\n" if $verbose;

$ECHO ='/bin/echo';
$CP   ='/bin/cp';
$RM   ='/bin/rm';
chop($TOUCH=`which touch`);
die("can't find touch\n") if $TOUCH =~ /^no /;
chop($HN=`which hostname`);
die("can't find hostname program\n") if $HN =~ /^no /;
chop($host=`$HN`);

$weekfile="/www/data/httpd/log/nextweek"; # the week that ends next Saturday

$LOGDIR='/www/data/httpd/log';
$ALTERNATE='/c/sy/subsys/httpd-logs';
if (!&execute("$ECHO $TOUCH $LOGDIR/temp.$$ | su $ruser")) {
    &execute("$ECHO $RM $LOGDIR/temp.$$ | su $ruser");
} else {
    print "$LOGDIR not writable\n";
    $LOGDIR=$ALTERNATE;
    die "$LOGDIR not writable either, giving up\n"
		if &execute("$ECHO $TOUCH $LOGDIR/temp.$$ | su $ruser");
    &execute("$ECHO $RM $LOGDIR/temp.$$ | su $ruser");
    print "writing logs to alternate directory: $LOGDIR\n";
}

if ($httpd eq 'httpd') {
    $LOG="$LOGDIR/fu";
} elsif ($httpd eq 'httpsd') {
    $LOG="$LOGDIR/sec";
} elsif ($httpd eq 'wdamb') {
    $LOG="$LOGDIR/wdamb";
    &wdamb_logs;
    exit;
} else {
    die "undefined log type: $httpd\n";
}

# get the curr subdirectory name
die "Unable to open $weekfile because $!\n"
			unless open(DATEFILE, "<$weekfile");
chop($currwk=<DATEFILE>);	# report date in the form "Sep 13, 1997"
chop($curr=<DATEFILE>);		# report date in the form "19970913"
close(DATEFILE);

# copy the most recent log file to the repository
#  and remove it from the web server host
# logs from primary web servers need to be resolved using logres

for $ftype ('access', 'error') {
    for ($ver=1; $ver<=4; $ver++) {		# look for old files, too

      local($zlog)="/var/log/cnet/${httpd}_${ftype}_log.$ver.gz";
      local($rlog)="$LOG/$host/$curr/$httpd.$ftype.$date.gz";
      $rlog =~ s|\.gz$|.$ver.gz| unless $ver==1;
      local($olog)=$rlog;
      $olog =~ s|\.gz$|.wrk.gz| if ($ftype eq 'access') &&
		(($host eq 'osiyou')  || ($host eq 'yasu'));

      if (-r $zlog) {
	print "found a log file that's $ver rots old\n" unless $ver==1;
      } else {
	print "$zlog is missing\n" if $ver==1;
	next;					# input file missing
      }
      print "create output file, date is $date\n" if $verbose;

      die "$olog exists\n" if -e $olog;
      $cmd="$CP -p $zlog $olog";
      print "--> $cmd\n" if $verbose;
      next if &execute("$ECHO \"$cmd\" | su $ruser"); # copy the log file
      &logres($olog, $rlog) if $olog ne $rlog;	# run logres on separate host
      unless ($pid = fork) {		# "sleep; rm" in the background
        sleep($DELAYSEC);		# pause for hitcounter
        unlink($zlog);			# remove the log file
        exit;				# background process is done
      }
    }
}



sub wdamb_logs {
  # copy the most recent log file to the repository
  #  and remove it from the web server host
  $ruser='autopsy';				# wdamb logs owned by autopsy
  $date=substr($date, 0, 8);			# yyyymmdd
  for $ftype ('requests', 'error') {
    for ($ver=1; $ver<=4; $ver++) {		# look for old files, too

      local($zlog)="/var/log/cnet/wdamb_${ftype}_log.$ver.gz";
      local($olog)="$LOG/$host/wdamb.$ftype.$date.gz";
      $olog =~ s|\.gz$|.$ver.gz| unless $ver==1;
      if (-r $zlog) {
	print "found a log file that's $ver rots old\n" unless $ver==1;
      } else {
	print "$zlog is missing\n" if $ver==1;
	next;					# input file missing
      }
      $cmd="$CP -p $zlog $olog";
      print "--> $cmd\n" if $verbose;
      if (!&execute("$ECHO \"$cmd\" | su $ruser")) { # copy the log file
	print "--> $RM $zlog\n" if $verbose;
	&execute("$RM $zlog");			# remove the log file
      }
    }
  }
} # wdamb_logs



sub logres {
    local($infile, $outfile) = @_;
    $RSH='/usr/ucb/rsh';
    $ISOLATE='/opt/local/bin/isolate';
    $MAILIF='/opt/local/sbin/mailifoutput';	# on Solaris 2.7
    $LOGRES='/opt/ACISweb/bin/getstats/logres.pl';

    $cmd="$RSH $rhost $ISOLATE $MAILIF audit-cnet $LOGRES $infile";
    print "--> $cmd\n" if $verbose;
    &execute("$ECHO \"$cmd\" | su $ruser");
} # logres



sub execute {			# run a program and check the return code
    local(@args) = @_;		# returns 0 on success
    local($rc) = 0xffff & system @args;
    if ($rc > 0x80) {
	$rc >>= 8;
	return $rc;
    } elsif ($rc) {
	if ($rc & 0x80) {
	    $rc &= ~0x80;
	    print "coredump written\n";
	}
	printf "%s\n  aborted with signal $rc\n", "@args";
	exit(3);
    }
    return 0;
}



# find out our OS type
# returns "solaris" or "sunos"
sub setos {
  system("/bin/sun");
  if (!$?) {
    if (substr (`/bin/uname -r`,0,1) >= 5) {
      return 'solaris';
    }
    return 'sunos';
  }
  return '???';
}
