#!/usr/bin/perl
#
#  Purpose: Perl script
#
#           - to upload status lines to the Eurolas Status Server either
#             - preformatted and stored in a local file (full status) or
#             - compiled as a reduced status message based on command line input
#
#           - and/or to display once or in an indefinite loop the
#             status messages receiver from the server
#
#  Author:  Werner Gurtner
#           gurtner@aiub.unibe.ch
#
#  Date  :  17 Mar 2008
#
use IO::Socket;
use Getopt::Long;
#
# Eurolas server
$host="aiuli3.unibe.ch";
$port=7810;
$timeout=30;
#
################################################################
#
# Put your station name here (max 13 characters) if you use the
# script to upload reduced status messages:
#
$station="Teststation";
#
# Put the name of the file containing the message line
# to be uploaded (option -f) here:
#
$filupl ="euro.inp";
#
# The format definition of the full status line can be found in
# http://www.aiub.unibe.ch/download//slr/slr_stat.txt
#
################################################################

#  Get command line arguments
#
if (! GetOptions (
      'h|?' => \$help,
      'o=s' => \$station,
      's=s' => \$status,
      't=s' => \$target,
      'f'   => \$file,
      'r'   => \$rep)
   ) {exit;}
if($help)
{
  print "eurostat -o observatory -s DWN|OUT|CUR -r -f\n";
  print "\n";
  print "   Status DWN: Station down (failures, repair, upgrade)\n";
  print "          OUT: Station currently not operating (weather etc)\n";
  print "          CUR: Station currently operating/tracking\n";
  print "       -r    : Script loops indefinitely\n";
  print "       -f    : Status line taken from file defined in the perl script\n";
  print "\n";
  exit;
}
$line_out="";
$status=uc($status);
# Truncate station name to 13 characters
$station=substr($station,0,13);
#
#  If the command line input contains the station status CUR, OUT or DWN
#  the script just sends once a reduced status message to the server, containing
#  - station name
#  - date and time
#  - status
#  and displays the combined status message received from the server 
#
if($status eq "OUT" or $status eq "CUR" or $status eq "DWN")
{
# System time (UT)
  @time=gmtime;
  $year=$time[5]+1900;
  $month=$time[4]+1;
  $day=$time[3];
  $line_out = sprintf "%-13.13s %4i-%02i-%02i %02i:%02i:%02i  %-10.10s %-3.3s",
     $station, $year, $month, $day, $time[2], $time[1], $time[0], $target, $status;
}
elsif ($status ne "")
{
  print "Unknown status: $status\n"; exit;
}
#
# Grand loop
#
# Connect to the status server
#
loop:
#
$remote=IO::Socket::INET->new(Proto => "tcp", PeerAddr => $host, PeerPort => $port, Blocking => 0, Timeout=>5);
if ($@ ne "") {print "$@\n"; if ($rep) {sleep 10; goto loop;}}
#
#  Loop over messages from server
#
$begin=time();
while(1)
{
# If the file $filupl exists it should contain a formatted status line to be uploaded.
# The file is deleted after having been processed.
# This check is periodically done. In the meantime some other program could generate
# a new status line, etc, etc
  if (-e $filupl and $file)
  {
    open IN,$filupl;
    chomp($line_out=<IN>);
    close IN;
    unlink $filupl;
  }
#
# Send line if is is not empty (either status message prepared above or read
# from $filupl
  if ($line_out ne "") {print $remote "$line_out\n"; $line_out="";}
#
# Get status message from server
#
# Loop within status message from server
#
  while(1)
  {
# Anything received?
    if($line_in=<$remote>)
# Yes
    {
      $begin=time();
      print $line_in;
# End of status message received:
# Either exit or check again (option -r) for next messages to be uploaded/downloaded
      if(index($line_in,"------") != -1 and ! $rep) {exit;} else {last;}
    }
    else
#
# Nothing received (non-blocking)
    {
# Hope this return code also flags a non-blocking nothing-received status on your system
      if($! == 11)
      {
        $elapsed = time()-$begin;
        if($elapsed > $timeout)
        {
          print "Time out on Eurostat!\n";
          close $remote;
          if($rep) {goto loop;} else {exit;}
        }
# Wait a second and check again
        sleep 1;
      }
# Connection closed: Try new connection after a short break
      else
      {
        close $remote;
        print "Remote server closed connection!\n";
        if($rep) {sleep 10; goto loop;} else {exit;}
      }
    }
  }
}
