#!/usr/bin/perl -w
#
# qpeek:  Peek into a job's output spool files
# Copyright 2006, 2007 Ohio Supercomputer Center
#
# License:  GNU GPL v2; see ../COPYING for details.
# Revision info:
# $HeadURL$
# $Revision$
# $Date$
#
# Usage:  qpeek [options] JOBID
#
# Options:
#   -c      Show all of the output file ("cat", default)
#   -h      Show only the beginning of the output file ("head")
#   -t      Show only the end of the output file ("tail")
#   -f      Show only the end of the file and keep listening ("tail -f")
#   -#      Show only # lines of output
#   -e      Show the stderr file of the job
#   -o      Show the stdout file of the job
#   -?      Display help

$tool="cat";
$numlines="";
$suffix="OU";
if ( defined($ENV{"PBS_HOME"}) )
  {
    $spool=$ENV{"PBS_HOME"};
  }
else
  {
    @defaults=("/usr/spool/PBS",
	       "/var/spool/pbs",
	       "/var/spool/torque",
	       "/var/spool/batch/pbs",
	       "/var/spool/batch/torque",
	       "/var/spool/batch/pbs-piv",
	       "/var/spool/batch/pbs-ipf",
	       ".",
	      );
    foreach $dir ( @defaults )
      {
	if ( -d $dir )
	  {
	    $spool=$dir;
	    last;
	  }
      }
  }
if ( !defined($spool) )
  {
    die "Unable to find PBS spool directory!\n";
  }
$pbsserver=`cat $spool/server_name` || 
  die "Unable to find PBS server name!\n";
chop($pbsserver);
# in HA configurations, server_name contains a comma-separated list of
# servers with the primary listed first
# strip off all others
$pbsserver =~ s/,.*$//;
# hack for sloppy admins who don't put the full hostname
# in $PBS_HOME/server_name
if ( $pbsserver =~ /:/ )
  {
    ($host,$port) = split(/:/,$pbsserver);
    @server=gethostbyname($host);
    $pbsserver=$server[0].":".$port;
  }
else
  {
    @server=gethostbyname($pbsserver);
    $pbsserver=$server[0];
    $host=$server[0];
  }

while ( $#ARGV>=0 && $ARGV[0] =~ /^[-+].*/ )
  {
    if ( $ARGV[0] eq "-c" )
      {
        $tool="cat";
      }
    elsif ( $ARGV[0] eq "-h" )
      {
        $tool="head";
      }
    elsif ( $ARGV[0] eq "-t" )
      {
        $tool="tail";
      }
    elsif ( $ARGV[0] =~ /^[-+][0-9]*(f)?$/ )
      {
	$tool="tail";
        $numlines=$ARGV[0];
      }
    elsif ( $ARGV[0] eq "-e" )
      {
        $suffix="ER"
      }
    elsif ( $ARGV[0] eq "-o" )
      {
        $suffix="OU"
      }
    elsif ( $ARGV[0] eq "-?" || $ARGV[0] =~ "-(-)?help" )
      {
        print STDERR <<EOF;
qpeek:  Peek into a job's output spool files

 Usage:  qpeek [options] JOBID

 Options:
   -c      Show all of the output file ("cat", default)
   -h      Show only the beginning of the output file ("head")
   -t      Show only the end of the output file ("tail")
   -f      Show only the end of the file and keep listening ("tail -f")
   -<num>f Show only the last <num> lines and keep listening ("tail -<num>f")
   +0f     Show all of the file and keep listening ("tail +0f")
   -#      Show only # lines of output ("tail -<num>")
   -e      Show the stderr file of the job
   -o      Show the stdout file of the job (default)
   -?      Display this help message
EOF
        exit;
      }
    else
      {
        print STDERR "qpeek:  Unrecognized option $ARGV[0] ignored\n";
      }
    shift(@ARGV);
  }

if ( $#ARGV>=0 )
  {
     $jobid=shift(@ARGV);
     $jobid=~s/\.[A-z0-9.:]+$//;
  }
else
  {
    die "No jobid given!\n";
  }

$node=&mothersuperior($jobid);
die "Job $jobid is not running!\n" if ( $node eq "" );

# chop to magic pbs length
$jobname = "$jobid".".lxbsrv01.jinr.ru";
#$jobname =~ s/(.{11}).*/$1/;
###print STDERR "ssh -2axn $node $tool $numlines $spool/spool/$jobname.$suffix\n";
exec "ssh -2axn $node $tool $numlines $spool/spool/$jobname.$suffix\n";

sub mothersuperior
{
  local($jobid,$node);
  $jobid=$_[0];
  $node="";
  open(QSTAT,"qstat -f $jobid |");
  while ( <QSTAT> )
    {
      chop;
      if ( $_ =~ /exec_host/ )
        {
	  ($keyword,$node)=split(/=/);
	  $node=~s:/[0-9]+[A-z0-9/+-]*::;
	  $keyword="";
	}
    }
  close(QSTAT);
  $node;
}
