#!/opt/SUNWstade/bin/perl -I/opt/SUNWstade/lib
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

#  $Name:  $ 
#  $Id: rashttp,v 1.77 2003/05/19 23:07:04 ccadieux Exp $

use Util;
use Roles;
use Debug;
use System;
use Style;
use Event;
use Http;
use Html;
use PDM::ConfigFile;
use Modules;
use Getopt::Std;
use GUI::Navigation;
#use Agent::T3;

getopts("U:P:XD:", \%opts);

my($local_p);
if ($opts{D}) {
  $HOME = $opts{D};

} else {
  $local_p = $INC[0];
  my($ix) = rindex($local_p, "/");
  $HOME = substr($local_p,0,$ix);
}

System->set_home($HOME);

$logfile   = "$HOME/log/http_access.log";
$CONF      = "$HOME/DATA/rasagent.conf";
%PRIO      = (1 => "High", 2 => "Medium", 3 => "Low", 9 => 'Medium+High');
$PRGMNAME  = $0;
my $ix2    = rindex($PRGMNAME, "/");
$PRGMNAME  = substr($PRGMNAME, $ix2+1);
$PRGMNAME  = $opts{U} if ($opts{U});

$0         = $PRGMNAME;
$PASSW     = "$HOME/System/password";
$UNIXFILE  = Http->unix_file($PRGMNAME, $HOME);

$RASPORT   = System->getConfigPort($HOME);
$BGCOLOR   = "#E0E0E0";
$LIGHT     = "#CCCCFF";

System->set_rasport($RASPORT);
System->set_testMode(0);
System->set_config($CONF);
System->set_secure((-f "$HOME/DATA/SECURE") ? "Y" : "N");
System->set_machine_name(Util->uucpLogin());

$ENV{LANG} = 'C';
# $ENV{LC_ALL} = 'C';  breaks SUNWsecfg


use SE::Startup;
SE::Startup::run();


#if ($opts{X}) {
#  open(O, "ps -ef|");
#  while ($l = <O>) {
#    $l = Util->ltrim($l);
#    @a = split(/\s+/, $l);
#    if ($a[7] =~ /\s+$PRGMNAME\s*$/ && $a[1] != $$) {
#      print "Already there :$l \n";
#      exit(1);
#    }
#  }
#  close(O);
#}


Debug->level(0);

my($renv, $devices, $hosts, $notifs) = PDM::ConfigFile->read();
if (!$renv) {
  die("Error in PDM::ConfigFile->read: $PDM::ConfigFile::$ERR");
}
$renv->{window} = "B" if (!exists($renv->{window})) ;


if (substr($UNIXFILE,-2) eq ".2") {     # configuration-server timeout.
  $TO = $renv->{SERVER_TIMEOUT2} || 31*60;
} else {
  $TO = $renv->{SERVER_TIMEOUT} || 30;  # time-out
}

System->set_renv($renv);
$renv->{"solution_prefix"} = Util->ipPrefix(System->ifconfig("dmfe1"));

Style->init($renv);

  $util = Util->new({
          RASPORT => $RASPORT,
               TO => $TO,
            debug => $debug,
                 });

  open(O,$PASSW); $PASSWORD = <O>; close(O);
  my $role_db = Roles->read();

  $http = Http->new({
                   logfile => "",
                      root => "$HOME/htdocs",
                     roles => $role_db,
                html_login => $renv->{html_login},
                     login => "ras",
                  timeout  => $TO,
                  password => $PASSWORD,
                 });

  $master = Util->findMaster();

  if ($ENV{FCGI}) { # FCGI
     eval {
       $http->fcgi_loop($util, $master);
     };
     if ($@) {
       Http::debug("error:$@");
     }
     Http::debug("Exiting");
     exit;
  }

  if ($opts{X}) {  # uses rashstart
     eval {
       $http->unix_init($UNIXFILE);
       $http->unix_loop($util, $master);
     };
     if ($@) {
       Http::debug("error:$@");
     }
     Http::debug("Exiting");
     exit;
  }

  ($fun,$q, $post_data) = $http->stdin_process();
  if ($fun) {
     if (defined(&$fun)) {
       print $http->text_header;
       &$fun($q, $post_data, $util);
     } else {
       $http->error(501, "Illegal Method", "function '$fun' not found");
     }
  }

exit;


sub luxdisc {
  my($out);
  print "\n<body bgcolor=$main'BGCOLOR><pre>";
  open(O, System->get_home() . "/bin/luxdisc 2>/tmp/luxdisc.err|");
  @a = <O>;
  close(O);
  open(E, "/tmp/luxdisc.err"); @err = <E>; close(E);
  print " <font color=red>@err</font>";
  print "@a";

}

sub menus {
  $D = System->get_home() . "/htdocs";
  my(@a, @b);
  foreach $f ('maint0', 'monitor0','diagnose','system0') {
     if (open(O, "$D/$f.html")) {
       @a = <O>; close(O);
       push(@b, @a);
       push(@b, "<br>");
     }
  }
  $menu = "@b";
  $menu =~ s/\<script /\<xscript /g;
  print $menu;
}

sub idx {
  my($q) = @_;
  GUI::Navigation::index($q);
}





#################################################################
#  RASAGENT MGR Operations
#################################################################

sub rasagent {

  print "\n";
  print "rasagent";
}

sub get_test {
  my($q, $post, $util) = @_;
  open(O, ">$HOME/DATA/get_test.post"); 
  $v = "";
  foreach $x (keys %$q) {
    $v .= "$x=$q->{$x}\n";
  }
  print O "GET :\n$v\n";
  print O "POST:\n$post\n"; 
  close(O);
  print "\nHello";
}

  
sub test {

  print "\n<pre>";
  open(O, "$HOME/bin/rasagent.pl -T web|");
  while ($l = <O>) {
     $l =~ s/</&lt;/g;
     print $l;
  }
  close(O);
}

sub installed_modules {
  my($q) = @_;
  print "\n";
}



sub config_file {
  my($q) = @_;
  print "\n";

  open(O, System->get_home() . "/DATA/rasagent.conf" );
 
  print "<body bgcolor=$main'BGCOLOR><pre>";
  
  while ($l = <O>) {
     print "$l";
  }
  close(O);

}




######################################################
#   LOCAL-NOTIFICATION MAINTENANCE
######################################################

sub find_multiple {
  my($q, $pref) = @_;
  my($ev) = ""; 
  my($l) = length($pref);
  my($all) = 0;
  foreach $x (keys %$q) {
print "$x=$q->{$x},";
    if (substr($x,0,$l ) eq $pref) {
        $ev .= substr($x,$l) . "|";
        $all = 1 if (substr($x,$l) eq "*") ;
    }
  }
  chop($ev);
  if ($all == 1) {
     return "*";
  } else {
     return $ev;
  }
}
  

# val can habe '|' in it.
#
sub select {
  my($values, $val, $m) = @_;
  my($sel, $x, $val0, $key, @a, $i);
  $sel = "";

  @a = split(/ *\| */, $values);
  foreach $x (@a) {
    $key = $val0 = "";
    $i = index($x,"=");
    if ($i >= 0) {
      $key = substr($x,0,$i);
      $val0 = substr($x,$i+1);
      if ($m) {
        $selected = (index($val, $key) >=0) ? "selected":"";
      } else {
        $selected = ($key eq $val) ? "selected":"";
      }
      $sel .= "<option value=\"$key\" $selected>$val0</option>";
    } else {
      if ($m) {
        $selected = (index($val, $x) >= 0) ? "selected":"";
      } else {
        $selected = ($x eq $val) ? "selected":"";
      }
      $sel .= "<option value=\"$x\" $selected>$x</option>";
    }
  }
  $sel .= "</select>";
  
}


######################################################
#   MODULE SPEED
######################################################

sub mod_speed {
  my($q) = @_;
  my ($sum, $x, $mins, $v, $secs, $a, $t);
  $a = Timelapse->readAll();
  my($sum, $sum2);
  foreach $x (keys %$a) {
         $v = $a->{$x}{avg};
         $t = $v->[1] / $v->[0];
         $sum += $t;
        $sum2 += $a->{$x}{last}[1];
  }
  $mins = int($sum / 60);
  $secs = $sum % 60;

  $mins2 = int($sum2 / 60);
  $secs2 = $sum2 % 60;
  return "<pre>Average Agent Runtime: $mins mins. and $secs secs.
   Last Agent Runtime: $mins2 mins. and $secs2 secs.";
}




sub get_device {
  my($q, $post, $util) = @_;

  my($pk)   = "GUIAdmin/" .  uc($q->{type});
  my($func) = "GUIAdmin::" . uc($q->{type}) . "::getDevices";
  require "$pk.pm";
  if (defined(&$func)) {
     print &$func($q,$post,$util);
  } else {
     print "\nFunction $func not defined!";
  }
}


sub make_select {
  my($name, $l, $val) = @_;
  my($o, $ck);
  @a = split(/\|/, $l);
  $o = "<select name=$name><option value=\"\">[Select]</option>";
  foreach $x (@a) {
    @b = split(/=/, $x);
    $b[1] = $b[0] if (!$b[1]);
    $ck = ($b[0] eq $val)? "selected":"";
    $o .= "<option $ck value=$b[0]>$b[1]</option>";
  }
  $o .= "</select>";
  return $o;
}

sub make_radio {
  my($name, $l, $val) = @_;
  my($o, $ck);
  @a = split(/\|/, $l);
  foreach $x (@a) {
    @b = split(/=/, $x);
    $ck = ($b[0] eq $val)? "checked":"";
    $o .= "<input type=radio name=$name $ck value=$b[0]>&nbsp;<b>:$b[1]</b>&nbsp;&nbsp;";
  }
  return $o;
}
  
#
# REALLY A PUT STARTD
# Updates the config file of a slave.
#
sub get_startd {
  my($q) = @_;
  my($done, $current);
  Debug->log("get_startd");
  ($renv, $devs, $host,$notifs) = PDM::ConfigFile->read();

  if (!$q->{active}) {
    print "ER No active value!";
    return;
  }
  for ($x=0; $x <= $#$devs; $x++) {
    if ($devs->[$x]{name} eq $q->{name}) {
       $devs->[$x]{active} = $q->{active};
       $done = 1;
       last;
    }
  }

  if ($done) {
    PDM::ConfigFile->write( $renv, $devs, $host,$notifs);
    print "OK";
  } else {
    print "ER $q->{name} not found!";
  }
}

sub get_all_startd {

  ($renv, $devs, $host,$notifs) = PDM::ConfigFile->read();

  for ($x=0; $x <= $#$devs; $x++) {
     print "$devs->[$x]{name}=$devs->[$x]{active}\n";
  }
}


sub info {
  my($m, $col) = @_;
  $col= "red" if (!$col);
  return "<center><table border=0 cellspacing=4 cellpadding=2><tr><td bgcolor=$col> <table border=0 cellspacing=2 cellpadding=3 bgcolor=white> <tr><td><b><center>&nbsp;$m &nbsp;</table></table></center>";
}

# header("", "<options>", "help section");

sub header {
  my($m,$w, $opt, $move) = @_;

  Html->header($m, $w, $opt, $move);
}


sub select_frequency {
  my($renv) = @_;
  return Html->select_frequency($renv);
}

sub find_devices {
  my(@MODS, @dirs, $x);

  my($list) = Util->findMethods("GUIAdmin", undef, "isDevice");

  foreach my $f (sort @$list) {
    my(@b) = split(/=/, $f);
    if ($b[1]) {
       push(@MODS, $b[0]);
    }
  }
  @MODS = sort(@MODS);
  return \@MODS;
}




sub get_color {
  my($category, $att, $value) = @_;
  return "" if (!$value);
  if (index("degraded",lc($value)) >= 0) {
     return "bgcolor=#F0F0C0";
  } elsif (index("failed", lc($value)) >= 0) {
     return "bgcolor=#F0C0C0";
  }
  return "";
}


# SLAVE GENERATE ANSWER to httpi-master

sub two_cols {
  my($p, $skip) = @_;
  my(@save) = ();
  my($att2, $val, $xx, $half, $col1, $col2);

  foreach $att2 (sort keys %$p) {
      next if ($att2 eq "elem_type" || $att2 eq $skip);
      $val = $p->{$att2};
      $val = substr($val,0,30) if ($att2 eq "volWWN");
      push(@save, "$att2=$val");
  }
  $half = int($#save/2);
  for ($xx=0; $xx <= $half; $xx++) {
     $col1 .= "$save[$xx]<br>";
  }
  for ($xx=$half+1; $xx <= $#save; $xx++) {
     $col2 .= "$save[$xx]<br>";
  }
  return ($col1, $col2);
}




# slave returns a list of instrumentation reports.

sub get_run_file_list {
  my($q, $port, $util) = @_;
  my($created, $VAR1);

#  my($xref) = Util->getXref();

  print "OK";
  
  opendir(O, "$HOME/DATA/OLD_REPORTS");
  @a = readdir(O); closedir(O);
  foreach $file (@a) {
     next if ($file !~ /.+:.+/);
     $created = Util->get_file_created("$HOME/DATA/OLD_REPORTS/$file");
     @b = split(/:/, $file);
     next if ($q->{exclude} && index($q->{exclude}, $b[1]) >= 0);
     open(O1, "$HOME/DATA/OLD_REPORTS/$file");
     my(@a) = <O1>; close(O1);
     eval "@a";

     if (!$q->{include} || ($q->{include} && index($q->{include}, $b[1]) >= 0)) {
       my($name) = $VAR1->{_id}{name};
       print "$file||$created||$name\n";

     }
  }
}

sub get_run_file {
  my($q, $port, $util) = @_;
  
  if (open(O, "$HOME/DATA/OLD_REPORTS/$q->{file}")) {

     while ($l = <O>) {
        print  $l;
     }
     close(O);
  } else {
     print "ERR File $q->{file} does not exist!";
  }
}

sub get_file_exist {
  my($q, $port, $util) = @_;
  print "\n";
 
  if (-f $q->{file} || -d $q->{file}) {
     print "OK";
  } else {
     print "ERR";
  }
}


sub get_logfile {
  my($q, $post) = @_;
  my($out); 
  print "\n";
  if (!open(O, "$HOME/log/errors.log")) {
    print "ERR Cannot read errors.log: $!\n";
    return;
  } else {
    print "OK\n";
  }
  $cnt = 0; $MAX = $q->{max} || 25;
  while ($l = <O>) {
     $cnt = 0 if ($cnt > $MAX);
     $S[$cnt] = $l;
     $cnt++;
  }
  close(O);
  
  $cnt2 = $cnt - 1;
  $cnt2 = $MAX if ($cnt < 0);
  $cnt3 = 0;
  while ($cnt3 < $MAX) {
    $out .=  $S[$cnt2];
    $cnt2--; $cnt3++;
  }
  print $out;
}


##################################################
#  PUT HTTP : RECEIVE INFORMATION (POST), ANSWER STATUS
##################################################

sub put_config {
  my($q, $post) = @_;

  if (open(O, ">" . System->get_home() . "/DATA/rasagent.conf" )) {
     print O $post;
     close(O);
     print "OK\n";
  } else {
     print "Err: Cannot open rasagent.conf: $!\n";
  }
}

# NOT USED, replaced by a pull from the master
sub put_slave_data {    # store slave data on master file.
  my($q, $post) = @_;

  my($f) =  "$HOME/data/SLAVE/LOG";
  if (! open(O, ">>$f")) {
    print "ER-" . &log2("Error with $f: $!");
  } else {
    my($l) = length($post);
    print O sprintf("%10.10d", $l);
    print O $post;
    close(O);
    print "OK-" . length($post);
  }
  chmod 0666, $f;

}

# 
# this is executed on the slave at the request of the master and empties the 
# SLAVE_DATA file where the rasagent_slave wrote all new events.
#
sub get_slave_data {
  my($q) = @_;

  my($f) =  "$HOME/DATA/SLAVE_DATA";
  print "\n";
  unlink "$f.P";
  rename $f, "$f.P";
  open(O, "$f.P");
  while ($l = <O>) {
    print $l;
  }
  close(O);

}

# Executed by http at the request of the Shuttle Provider
# will return all Messages that are old enough.

#sub get_eventDocs {
#  my($q) = @_;
#  my($eds) = PDM::SAFread({ dir => "Shuttle"});
#  print "\n<pre>\n";
#
#  foreach $ed (@$eds) {
#     print "+D\t" . $ed->fileNo . "\n";
#     print $ed->toC;
#     print "-D\n";
#  }
#}


##################################################
#  GET HTTP : REQUEST INFORMATION
##################################################


sub get_hostinfo {
  my($q) = @_;

  my $hostid = System->hostid();
  my $master = Util->findMaster();
  print "$hostid\t$master";
}

sub get_hostid {
  my($q) = @_;

  my $hostid = System->hostid();
  print $hostid;
  
}
sub get_info {
  my($q) = @_;
  my $hostid = System->hostid();
  my $renv = System->get_renv();
  
  print "$hostid|$renv->{version}";
}

sub get_isMaster {
  my($q) = @_;
  if (-f "$HOME/DATA/MASTER") {
     print "N";
  } else {
     print "Y";
  }
}



sub get_start {
  my($q) = @_;

#  print "\n";
  if (-f "$HOME/DATA/start"){
    print "Yes";
  } else {
    print "No";
  }
}

sub put_start {
  my($q) = @_;
  if ($q->{start} =~ "Y") {
    open(O, ">$HOME/DATA/start");
    print O "Y";
    close(O);
  } else {
    unlink "$HOME/DATA/start";
  }
  print "OK";
}


sub get_test2 {
  my($q) = @_;

  print "\n";

}


sub log2 {
  my($v) = @_;
  open(OO , ">>$HOME/log/httpi.log");
  print  OO  Util->today . "\t$v";
  close(OO);
  print "\n $v";
}

# GET_CONFIG: THIS WILL SERVE A CUSTOM CONFIG TO ANY SLAVE who asks

sub get_config {
  my($q, $post, $util) = @_;
  my($name, $config);
  print "\n";

  return "" if (!$q->{hostid});

  print PDM::ConfigFile->getSlaveConfig($q->{hostid}, 1);
}



sub log_change {
  my($info, $type) = @_;
  $type = "Warning" if (!$type);

  open(LOG, ">>$HOME/data/ras_server.log");
  $info =~ s/\n/ /g;
  my($today) = Util->today("YMDH");
  $out = "<log_line line_type=\"$type\" date=\"$today\" text=\"$info\" />\n";
  print LOG $out;
  close(LOG);
}

################################################
#    LOCAL LOG DISPLAY
################################################


sub NUevent_log {
  my($q, $post, $util) = @_;
  print "\n<body bgcolor=$main'BGCOLOR><center>";
  $h = &header("Local Event Log");
 
  $o =<<EOF;
$h

<table border=2 cellspacing=2 width=80% bgcolor=white><tr><td>
<table border=0 cellspacing=2 width=100% bgcolor=#F0F0F0>
<tr><td colspan=2 bgcolor=#666699><b><font color=white>&nbsp;Available Local Logs</td>
<tr bgcolor=#D0D0D0><td>Name</td>
   <td>Last Update</td>
<tr>
EOF

  $cnt = -1;
  opendir(O, "$HOME/data/EVENTS");
  @a = readdir(O); closedir(O);
  foreach $x (@a) {
     next if ($x =~ /^\./);
     @xx = split(/\./, $x);
     $desc = Event->get_description($xx[0]);
     push(@M, "$desc|$x");
  }
  foreach $x0 (sort @M) {
     ($desc, $x) = split(/\|/, $x0);
     $mod = Util->get_file_created("$HOME/DATA/EVENTS/$x");
     $o .= "<tr><td><a href=/?GO=event_log1&file=$x>$desc</a></td><td>$mod</td>" ;
  }
  $o .= "</table></table>";

  print $o;

}


sub read_badge {}

sub get_message_log {
  my($q) = @_;
  my(@a);
  print "\n";
  if (open(O, $q->{file})) {
     seek(O,-20000, 2);
     $l = <O>;
     while ($l = <O>) {
        push(@a, $l);
     }
     close(O);
     for ($x=$#a; $x >= 0; $x--) {
       print "$a[$x]<br>";
     }
     close(O);
  } else {
     print "Cannot read $q->{file}: $!<br>";
  }
}





#####################################
#    Agents
#####################################

@MODULES = ();
%MODULES = ();

sub register {
   my($module) = @_;
   push(@MODULES, $module);
   $MODULES{ref($module)} = $module;
   open(REG, ">$HOME/log/modules.log");
   print REG $module->{name} . "\n";
   close(REG);
}
