#!/usr/bin/php
<? // ( -*- php -*- this makes emacs users happy too? )
/*
 Network Interface Statistics Collection Agent v2.5
 by Brett Baugh

 This script purports to import the MRTG logfile for an interface
 into corresponding entries in the "stats" table of the database.
 It will only run if entries for this interface already exist, and
 will not import entries later than the earliest existing entry.
 */

$inhibit_html=1; // tells functions.php to just DIE if this is being run from a browser.
require_once("/etc/nisca/nisca.conf");
require_once($location["functions"]);

// First, check for all the things that can go wrong.
if ($argc < 5) {
?>
Error: incorrect commandline parameters.

Usage:  mrtg_import <log filename> <hostname> <community> <interface NAME>

If you specified correct parameters, your PHP binary may
not be looking for command line arguments. Fix this in
your "php.ini" file; look for a line that starts with
"register_argc_argv" and set it to "On" if it's not
present or set to "Off". You can always set it back to
"Off" once you're done importing, if you wish.

If you need to import MRTG stats collected on your
localhost interfaces (via SNMP and MRTG, of course)
into the non-SNMP localhost counter, you should specify
the community on the commandline as "localhost".

<?
  die;
}

$logfile=$argv[1];
$host=$argv[2];
$commune=$argv[3];
if ($commune=="localhost") { $commune=""; }
$if=$argv[4];
$id=$if_id[$host][$commune][$if];

if (trim($id)=="") {
  echo "\nPlease run the NISCA collector(s) for $host:$commune:$if\n" .
       "first before trying to import data from your MRTG logs. Sorry for the\n" .
       "inconvenience, but I have to know what the current byte counts will be\n" .
       "once you start the collector(s)...\n\n";
  die;
}

if ($commune != "") {
  if (! in_array($host, $hostname)) {
    echo "\nError: the hostname \"$host\" is not defined (see the Administration page).\n";
    echo "You must only use this script for hosts that have already been set up.\n\n";
    die;
  }
} else {
  if ($local_hostname=="") {
    echo "\nError: the hostname \"$host\" is not defined (see the Administration page).\n";
    echo "You must only use this script for hosts that have already been set up.\n\n";
    die;
  }
}

$ifok=0;
if ($commune=="") {
  if (in_array($if, $local_interfaces)) {
    $ifok=1;
  }
} else {
  foreach ($interfaces[$host] as $i) {
    if ($if==$i["if_name"] && $commune==$i["community"]) {
      $ifok=1;
      break;
    }
  }
}

if ($ifok==0) {
  echo "\nError: the interface \"$if\" in the community \"$commune\"\n " .
       "is not defined for the host \"$host\".\n" .
       "You must only use this script for hosts that have already been set up.\n\n";
  die;
}

if (! $log=file($logfile)) {
  echo "\nCouldn't read \"$logfile\".\n\n";
  die;
}

/*
Each line of an MRTG logfile (except the first line) is like this:
   <timestamp> <incoming rate> <outgoing rate> <incoming max> <outgoing max>
We only care about the first three; the maxes are done by all the rest of NISCA.
Note that the rates are bytes per second, NOT total bytes!
 */

// We need the earliest info in the database for this host/community/if.
// We won't be importing any data later than the first stamp value in the database.

$sq="select stamp, r_bytes, t_bytes from stats where if_id='$id' order by stamp limit 1";
$res=dosql($sq);
if (mysql_num_rows($res) > 0) {
  $row=mysql_fetch_array($res);
  $prevstamp=$lowstamp=$row["stamp"];
  $lowrbytes=$row["r_bytes"];
  $lowtbytes=$row["t_bytes"];
} else {
// we just can't do it if there's no data in there already.
// We don't really care if the data from this script go negative;
// the report script will make up for it.
// It's only important that we have an *accurate* starting point for the data counters.
  echo "\nPlease run the NISCA collector(s) for $host:$commune:$if\n" .
       "first before trying to import data from your MRTG logs. Sorry for the\n" .
       "inconvenience, but I have to know what the current byte counts will be\n" .
       "once you start the collector(s)...\n\n";
  die;
}

// The first line is the placeholder for the current sample; we don't need it.
$tmp=array_shift($log);

// We should ignore lines that are like this:
//   <timestamp> 0 0 0 0
// ..as they're just placeholders for data that doesn't exist yet.

$count=0;
foreach ($log as $line) {
  if (!preg_match('/\s+0\s+0\s+0\s+0/', $line)) {
    $tmp=preg_split('/\s+/', $line);
    $stamp=$tmp[0];
// We do NOT want to insert any data later than the earliest entry in the database!
    if ($stamp < $lowstamp) {
// The stamps are returned from the logfile in *reverse order*...
// so our 'floor' will be continually decreasing, not increasing.
// We also have to "un-average" the byte counts using the logfile stamps.
      $lowrbytes -= ($tmp[1] * ($prevstamp-$stamp));
      $lowtbytes -= ($tmp[2] * ($prevstamp-$stamp));
      $sq="insert into stats values($id, $lowrbytes, 0, 0, 0, " .
          "$lowtbytes, 0, 0, 0, $stamp)";
      $res=dosql($sq);
      $count++;
    }
    $prevstamp=$stamp;
  }
}
if ($count > 0) {
  echo "\n$count logfile entries were imported for $host:$commune:$if.\n\n";
} else {
  echo "\nNo entries were imported because none of them were older than\n" .
    "the earliest pre-existing statistics.  Sorry...\n\n";
}
?>
