/**
  * @param string $targetString The string from the config file
  * @param the $map A reference to the map object (redundant)
  * @param the $mapItem A reference to the object this target is attached to
  * @return array invalue, outvalue, unix timestamp that the data was valid
  */
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $matches = 0;
     if (preg_match("/^time:(.*)\$/", $targetString, $matches)) {
         $timezone = $matches[1];
         $offset = "now";
         if (preg_match("/^([^:]+):(.*)\$/", $timezone, $matches2)) {
             $timezone = $matches2[1];
             $offset = $matches2[2];
             // test that the offset is valid
             $timestamp = strtotime($offset);
             if ($timestamp === false || $timestamp === -1) {
                 warn("Time ReadData: Offset String ({$offset}) is bogus - ignoring [WMTIME03]\n");
                 $offset = "now";
             }
         }
         $timezone_l = strtolower($timezone);
         if (array_key_exists($timezone_l, $this->timezones)) {
             $tz = $this->timezones[$timezone_l];
             wm_debug("Time ReadData: Timezone exists: {$tz}\n");
             $dateTime = new DateTime($offset, new DateTimeZone($tz));
             $mapItem->add_note("time_time12", $dateTime->format("h:i"));
             $mapItem->add_note("time_time12ap", $dateTime->format("h:i A"));
             $mapItem->add_note("time_time24", $dateTime->format("H:i"));
             $mapItem->add_note("time_timet", $dateTime->format("U"));
             $mapItem->add_note("time_timezone", $tz);
             $data[IN] = $dateTime->format("H");
             $data[OUT] = $dateTime->format("i");
             $data_time = time();
             $matches++;
         }
         if ($matches == 0) {
             wm_warn("Time ReadData: Couldn't recognize {$timezone} as a valid timezone name [WMTIME02]\n");
         }
     } else {
         // some error code to go in here
         wm_warn("Time ReadData: Couldn't recognize {$targetString} \n");
     }
     wm_debug("Time ReadData: Returning (" . WMUtility::valueOrNull($data[IN]) . "," . WMUtility::valueOrNull($data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 /**
  * @param string $targetString The string from the config file
  * @param the $map A reference to the map object (redundant)
  * @param the $mapItem A reference to the object this target is attached to
  * @return array invalue, outvalue, unix timestamp that the data was valid
  */
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     if (preg_match("/^time:(.*)\$/", $targetString, $matches)) {
         $timezone = $matches[1];
         $offset = "now";
         if (preg_match("/^([^:]+):(.*)\$/", $timezone, $matches2)) {
             $timezone = $matches2[1];
             $offset = $matches2[2];
             // test that the offset is valid
             $timestamp = strtotime($offset);
             if ($timestamp === false || $timestamp === -1) {
                 warn("Time ReadData: Offset String ({$offset}) is bogus - ignoring [WMTIME03]\n");
                 $offset = "now";
             }
         }
         list($required_time, $timezone_name) = $this->getTimeForTimeZone($timezone, $offset);
         $data = $this->populateTimeData($mapItem, $required_time, $timezone_name);
         $data_time = time();
     } else {
         // some error code to go in here
         wm_warn("Time ReadData: Couldn't recognize {$targetString} \n");
     }
     wm_debug("Time ReadData: Returning (" . WMUtility::valueOrNull($data[IN]) . "," . WMUtility::valueOrNull($data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 /**
  * @param $fileHandle
  * @param $itemName
  * @return array
  */
 protected function readDataFromTSV($fileHandle, $itemName)
 {
     $data = array();
     $data[IN] = null;
     $data[OUT] = null;
     while (!feof($fileHandle)) {
         $buffer = fgets($fileHandle, 4096);
         // strip out any line-endings that have gotten in here
         $buffer = str_replace("\r", "", $buffer);
         $buffer = str_replace("\n", "", $buffer);
         $parts = explode("\t", $buffer);
         if ($parts[0] == $itemName) {
             $data[IN] = WMUtility::interpretNumberWithMetricPrefixOrNull($parts[1]);
             $data[OUT] = WMUtility::interpretNumberWithMetricPrefixOrNull($parts[2]);
         }
     }
     return $data;
 }
 function ReadData($targetString, &$map, &$mapItem)
 {
     $inbw = null;
     $outbw = null;
     $data_time = 0;
     if (preg_match($this->regexpsHandled[0], $targetString, $matches)) {
         $inbw = WMUtility::interpretNumberWithMetricPrefix($matches[1], $map->kilo);
         $outbw = WMUtility::interpretNumberWithMetricPrefix($matches[2], $map->kilo);
         $data_time = time();
     }
     if (preg_match($this->regexpsHandled[1], $targetString, $matches)) {
         $inbw = WMUtility::interpretNumberWithMetricPrefix($matches[1], $map->kilo);
         $outbw = $inbw;
         $data_time = time();
     }
     wm_debug("Static ReadData: Returning ({$inbw}, {$outbw}, {$data_time})\n");
     return array($inbw, $outbw, $data_time);
 }
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $ping_count = intval($map->get_hint("fping_ping_count"));
     if ($ping_count == 0) {
         $ping_count = 5;
     }
     $target = $this->extractTargetHost($targetString);
     if ($target == "") {
         wm_warn("FPing ReadData: No target? [WMFPING05]\n");
         return array(null, null, 0);
     }
     $pattern = $this->buildMatchPattern($target, $ping_count);
     $pipe = $this->openPipeToFping($target, $ping_count);
     if (!isset($pipe)) {
         wm_warn("FPing ReadData: Couldn't open pipe to fping [WMFPING04]\n");
         return array(null, null, 0);
     }
     list($count, $hitcount, $loss, $ave, $min, $max) = $this->readDataFromFping($pipe, $pattern, $ping_count);
     pclose($pipe);
     if ($count == 0) {
         wm_warn("FPing ReadData: No lines read. Bad hostname? ({$target}) [WMFPING03]\n");
     }
     if ($count > 0 && $hitcount == 0) {
         wm_warn("FPing ReadData: {$count} lines read. But nothing returned for target??? ({$target}) Try running with DEBUG to see output.  [WMFPING02]\n");
     }
     if ($hitcount > 0) {
         $data[IN] = $ave;
         $data[OUT] = $loss;
         $mapItem->add_note("fping_min", $min);
         $mapItem->add_note("fping_max", $max);
     }
     wm_debug("FPing ReadData: Returning (" . WMUtility::valueOrNull($data[IN]) . "," . WMUtility::valueOrNull($data[OUT]) . ", {$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 public function getConfig()
 {
     assert(isset($this->owner));
     // TODO - These should all check against the defaults
     $output = "# All settings for scale " . $this->name . "\n";
     if (1 == 0) {
         if (null === $this->keypos) {
             $output .= sprintf("\tKEYPOS %s %s %s\n", $this->name, "-1 -1", $this->keytitle);
         } else {
             $output .= sprintf("\tKEYPOS %s %s %s\n", $this->name, $this->keypos->asConfig(), $this->keytitle);
         }
         // TODO - need to add size if non-standard
         $output .= sprintf("\tKEYSTYLE %s %s\n", $this->name, $this->keystyle);
         $output .= sprintf("\tKEYBGCOLOR %s %s\n", $this->name, $this->keybgcolour->asConfig());
         $output .= sprintf("\tKEYTEXTCOLOR %s %s\n", $this->name, $this->keytextcolour->asConfig());
         $output .= sprintf("\tKEYOUTLINECOLOR %s %s\n", $this->name, $this->keyoutlinecolour->asConfig());
         $output .= sprintf("\tSCALEMISSCOLOR %s %s\n", $this->name, $this->scalemisscolour->asConfig());
     }
     $locale = localeconv();
     $decimal_point = $locale['decimal_point'];
     $output .= "\n";
     foreach ($this->colours as $scaleEntry) {
         $top = rtrim(rtrim(sprintf("%f", $scaleEntry['top']), "0"), $decimal_point);
         $bottom = rtrim(rtrim(sprintf("%f", $scaleEntry['bottom']), "0"), $decimal_point);
         if ($bottom > $this->owner->kilo) {
             $bottom = WMUtility::formatNumberWithMetricPrefix($scaleEntry['bottom'], $this->owner->kilo);
         }
         if ($top > $this->owner->kilo) {
             $top = WMUtility::formatNumberWithMetricPrefix($scaleEntry['top'], $this->owner->kilo);
         }
         $tag = isset($scaleEntry['tag']) ? $scaleEntry['tag'] : '';
         // Non-real colour, c1==c2 and c2==null all mean a single SCALE colour
         if (!$scaleEntry['c1']->isRealColour() || null === $scaleEntry['c2'] || $scaleEntry['c1']->equals($scaleEntry['c2'])) {
             $output .= sprintf("\tSCALE %s %-4s %-4s  %s  %s\n", $this->name, $bottom, $top, $scaleEntry['c1']->asConfig(), $tag);
         } else {
             $output .= sprintf("\tSCALE %s %-4s %-4s  %s  %s  %s\n", $this->name, $bottom, $top, $scaleEntry['c1']->asConfig(), $scaleEntry['c2']->asConfig(), $tag);
         }
     }
     $output .= "\n";
     return $output;
 }
 function asJSCore()
 {
     $output = "";
     $output .= "\"id\":" . $this->id . ", ";
     if (isset($this->a)) {
         $output .= "a:'" . $this->a->name . "', ";
         $output .= "b:'" . $this->b->name . "', ";
     }
     $output .= "width:'" . $this->width . "', ";
     $output .= "target:";
     $tgt = '';
     $i = 0;
     foreach ($this->targets as $target) {
         if ($i > 0) {
             print " ";
         }
         $tgt .= $target->asConfig();
         $i++;
     }
     $output .= WMUtility::jsEscape(trim($tgt));
     $output .= ",";
     $output .= "bw_in:" . WMUtility::jsEscape($this->max_bandwidth_in_cfg) . ", ";
     $output .= "bw_out:" . WMUtility::jsEscape($this->max_bandwidth_out_cfg) . ", ";
     $output .= "name:" . WMUtility::jsEscape($this->name) . ", ";
     $output .= "overlibwidth:'" . $this->overlibheight . "', ";
     $output .= "overlibheight:'" . $this->overlibwidth . "', ";
     $output .= "overlibcaption:" . WMUtility::jsEscape($this->overlibcaption[IN]) . ", ";
     $output .= "commentin:" . WMUtility::jsEscape($this->comments[IN]) . ", ";
     $output .= "commentposin:" . intval($this->commentoffset_in) . ", ";
     $output .= "commentout:" . WMUtility::jsEscape($this->comments[OUT]) . ", ";
     $output .= "commentposout:" . intval($this->commentoffset_out) . ", ";
     $output .= "infourl:" . WMUtility::jsEscape($this->infourl[IN]) . ", ";
     $output .= "overliburl:" . WMUtility::jsEscape(join(" ", $this->overliburl[IN])) . ", ";
     $output .= "via: [";
     $nItem = 0;
     foreach ($this->vialist as $via) {
         if ($nItem > 0) {
             $output .= ", ";
         }
         $output .= sprintf("[%d,%d", $via[0], $via[1]);
         if (isset($via[2])) {
             $output .= "," . WMUtility::jsEscape($via[2]);
         }
         $output .= "]";
         $nItem++;
     }
     $output .= "]";
     return $output;
 }
 function asJSCore()
 {
     $output = "";
     $output .= "x:" . (is_null($this->x) ? "'null'" : $this->x) . ", ";
     $output .= "y:" . (is_null($this->y) ? "'null'" : $this->y) . ", ";
     $output .= "\"id\":" . $this->id . ", ";
     $output .= "ox:" . $this->original_x . ", ";
     $output .= "oy:" . $this->original_y . ", ";
     $output .= "relative_to:" . WMUtility::jsEscape($this->relative_to) . ", ";
     $output .= "label:" . WMUtility::jsEscape($this->label) . ", ";
     $output .= "name:" . WMUtility::jsEscape($this->name) . ", ";
     $output .= "infourl:" . WMUtility::jsEscape($this->infourl[IN]) . ", ";
     $output .= "overlibcaption:" . WMUtility::jsEscape($this->overlibcaption[IN]) . ", ";
     $output .= "overliburl:" . WMUtility::jsEscape(join(" ", $this->overliburl[IN])) . ", ";
     $output .= "overlibwidth:" . $this->overlibheight . ", ";
     $output .= "overlibheight:" . $this->overlibwidth . ", ";
     if (sizeof($this->boundingboxes) > 0) {
         $output .= sprintf("bbox:[%d,%d, %d,%d], ", $this->boundingboxes[0][0], $this->boundingboxes[0][1], $this->boundingboxes[0][2], $this->boundingboxes[0][3]);
     } else {
         $output .= "bbox: [], ";
     }
     if (preg_match("/^(none|nink|inpie|outpie|box|rbox|gauge|round)\$/", $this->iconfile)) {
         $output .= "iconfile:" . WMUtility::jsEscape("::" . $this->iconfile);
     } else {
         $output .= "iconfile:" . WMUtility::jsEscape($this->iconfile);
     }
     return $output;
 }
 private function handleSCALE($fullcommand, $args, $matches)
 {
     // The default scale name is DEFAULT
     if ($matches[1] == '') {
         $matches[1] = 'DEFAULT';
     } else {
         $matches[1] = trim($matches[1]);
     }
     if (isset($this->mapObject->scales[$matches[1]])) {
         $newscale = $this->mapObject->scales[$matches[1]];
     } else {
         $this->mapObject->scales[$matches[1]] = new WeatherMapScale($matches[1], $this->mapObject);
         $newscale = $this->mapObject->scales[$matches[1]];
     }
     $key = $matches[2] . '_' . $matches[3];
     $tag = $matches[11];
     $colour1 = null;
     $colour2 = null;
     $bottom = WMUtility::interpretNumberWithMetricPrefix($matches[2], $this->mapObject->kilo);
     $top = WMUtility::interpretNumberWithMetricPrefix($matches[3], $this->mapObject->kilo);
     $this->mapObject->colours[$matches[1]][$key]['key'] = $key;
     $this->mapObject->colours[$matches[1]][$key]['tag'] = $tag;
     $this->mapObject->colours[$matches[1]][$key]['bottom'] = WMUtility::interpretNumberWithMetricPrefix($matches[2], $this->mapObject->kilo);
     $this->mapObject->colours[$matches[1]][$key]['top'] = WMUtility::interpretNumberWithMetricPrefix($matches[3], $this->mapObject->kilo);
     $this->mapObject->colours[$matches[1]][$key]['special'] = 0;
     if (isset($matches[10]) && $matches[10] == 'none') {
         $this->mapObject->colours[$matches[1]][$key]['c1'] = new WMColour('none');
         $colour1 = new WMColour("none");
     } else {
         $colour1 = new WMColour((int) $matches[4], (int) $matches[5], (int) $matches[6]);
         $colour2 = $colour1;
         $this->mapObject->colours[$matches[1]][$key]['c1'] = $colour1;
     }
     // this is the second colour, if there is one
     if (isset($matches[7]) && $matches[7] != '') {
         $colour2 = new WMColour((int) $matches[7], (int) $matches[8], (int) $matches[9]);
         $this->mapObject->colours[$matches[1]][$key]['c2'] = $colour2;
     }
     $newscale->AddSpan($bottom, $top, $colour1, $colour2, $tag);
     if (!isset($this->mapObject->numscales[$matches[1]])) {
         $this->mapObject->numscales[$matches[1]] = 1;
     } else {
         $this->mapObject->numscales[$matches[1]]++;
     }
     // we count if we've seen any default scale, otherwise, we have to add
     // one at the end.
     //        if ($matches[1] == 'DEFAULT') {
     //            $this->mapObject->scalesseen++;
     //        }
     return true;
 }
function weathermap_run_maps($mydir, $map_id = -1)
{
    global $weathermap_debugging;
    global $WEATHERMAP_VERSION;
    global $weathermap_warncount;
    global $weathermap_poller_start_time;
    global $weathermap_error_suppress;
    global $weathermap_mem_highwater;
    $weathermap_mem_highwater = 0;
    // This one makes Cacti's database.php puke...
    // WMMemoryNote('weathermap_initial_memory');
    require_once "all.php";
    // and this..
    // WMMemoryNote('weathermap_loaded_memory');
    $total_warnings = 0;
    $warning_notes = "";
    $start_time = microtime(true);
    if ($weathermap_poller_start_time == 0) {
        $weathermap_poller_start_time = $start_time;
    }
    $outputDirectory = realpath($mydir . DIRECTORY_SEPARATOR . 'output');
    $configDirectory = realpath($mydir . DIRECTORY_SEPARATOR . 'configs');
    $mapCount = 0;
    // take our debugging cue from the poller - turn on Poller debugging to get weathermap debugging
    if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG) {
        $weathermap_debugging = true;
        $mode_message = "DEBUG mode is on";
        $global_debug = true;
    } else {
        $mode_message = "Normal logging mode. Turn on DEBUG in Cacti for more information";
        $global_debug = false;
    }
    $quietLogging = intval(WMCactiAPI::getConfigOption("weathermap_quiet_logging"), 0);
    // moved this outside the module_checks, so there should always be something in the logs!
    if ($quietLogging == 0) {
        cacti_log("Weathermap {$WEATHERMAP_VERSION} starting - {$mode_message}\n", true, "WEATHERMAP");
    }
    if (!wm_module_checks()) {
        wm_warn("Required modules for PHP Weathermap {$WEATHERMAP_VERSION} were not present. Not running. [WMPOLL08]\n");
        return;
    }
    weathermap_memory_check("MEM Initial");
    // move to the weathermap folder so all those relatives paths don't *have* to be absolute
    $orig_cwd = getcwd();
    chdir($mydir);
    WMCactiAPI::setConfigOption("weathermap_last_start_time", $start_time);
    // first, see if the output directory exists and is writable
    if (weathermap_directory_writeable($outputDirectory)) {
        $mapList = weathermap_get_runlist($map_id, $quietLogging);
        wm_debug("Iterating all maps.");
        $imageFormat = strtolower(WMCactiAPI::getConfigOption("weathermap_output_format", "png"));
        $rrdtool_path = read_config_option("path_rrdtool");
        foreach ($mapList as $mapParameters) {
            $weathermap_warncount = 0;
            weathermap_run_map($mapParameters, $configDirectory, $outputDirectory, $imageFormat, $quietLogging, $global_debug, $mapCount, $rrdtool_path, $weathermap_error_suppress, $weathermap_poller_start_time, $total_warnings);
            $total_warnings += $weathermap_warncount;
            $mapCount++;
        }
        wm_debug("Iterated all {$mapCount} maps.\n");
    } else {
        wm_warn("Output directory ({$outputDirectory}) doesn't exist!. No maps created. You probably need to create that directory, and make it writable by the poller process (like you did with the RRA directory) [WMPOLL07]\n");
        $total_warnings++;
        $warning_notes .= " (Output directory problem prevents any maps running WMPOLL07)";
    }
    weathermap_memory_check("MEM Final");
    chdir($orig_cwd);
    $end_time = microtime(true);
    $duration = $end_time - $start_time;
    $stats_string = sprintf('%s: %d maps were run in %.2f seconds with %d warnings', date(DATE_RFC822), $mapCount, $duration, $total_warnings);
    if (true === function_exists("memory_get_peak_usage")) {
        $peak_memory = memory_get_peak_usage();
        WMCactiAPI::setConfigOption("weathermap_peak_memory", WMUtility::formatNumberWithMetricPrefix($peak_memory));
        $stats_string .= sprintf(" using %sbytes peak memory", $peak_memory);
    }
    if ($quietLogging == 0) {
        wm_warn("STATS: Weathermap {$WEATHERMAP_VERSION} run complete - {$stats_string}\n", true);
    }
    WMCactiAPI::setConfigOption("weathermap_last_stats", $stats_string);
    WMCactiAPI::setConfigOption("weathermap_last_finish_time", $end_time);
    WMCactiAPI::setConfigOption("weathermap_last_map_count", $mapCount);
    if (true === function_exists('memory_get_usage')) {
        WMCactiAPI::setConfigOption("weathermap_final_memory", memory_get_usage());
        WMCactiAPI::setConfigOption("weathermap_highwater_memory", $weathermap_mem_highwater);
    }
    if (true === function_exists("memory_get_peak_usage")) {
        WMCactiAPI::setConfigOption("weathermap_peak_memory", memory_get_peak_usage());
    }
}
 public function testWeathermapInternals()
 {
     $this->assertEquals(array(0, 0), WMUtility::calculateOffset("donkey", 10, 20));
     $this->assertEquals(array(0, 0), WMUtility::calculateOffset("", 10, 20));
     $this->assertEquals(array(0, 0), WMUtility::calculateOffset("C", 10, 20));
     // +Y is down (i.e. South)
     $this->assertEquals(array(0, -10), WMUtility::calculateOffset("N", 10, 20));
     $this->assertEquals(array(0, 10), WMUtility::calculateOffset("S", 10, 20));
 }
                         $map->links[$name]->overliburl[OUT][] = $overlib;
                         $map->links[$name]->infourl[IN] = $infourl;
                         $map->links[$name]->infourl[OUT] = $infourl;
                     } else {
                         print " Couldn't find a graph that uses this rrd??\n";
                     }
                 } else {
                     print "  Failed to find RRD file for {$tgt_host}/{$interface}\n";
                 }
             }
             print "    SPEED {$total_speed}\n";
             if ($total_speed > 0) {
                 $map->links[$name]->max_bandwidth_in = $total_speed;
                 $map->links[$name]->max_bandwidth_out = $total_speed;
                 $map->links[$name]->max_bandwidth_in_cfg = WMUtility::formatNumberWithMetricPrefix($total_speed);
                 $map->links[$name]->max_bandwidth_out_cfg = WMUtility::formatNumberWithMetricPrefix($total_speed);
                 if ($map_widths) {
                     foreach ($width_map as $map_speed => $map_width) {
                         if ($total_speed <= $map_speed) {
                             $map->links[$name]->width = $width_map[$map_speed];
                             print "    WIDTH " . $width_map[$map_speed] . "\n";
                             continue 2;
                         }
                     }
                 }
             }
         }
     } else {
         print "Skipping link with targets\n";
     }
 }
 protected function asJS($type = "Thing", $prefix = "T")
 {
     $output = '';
     $output .= $type . "s[" . WMUtility::jsEscape($this->name) . "] = {";
     $output .= $this->asJSCore();
     $output .= "};\n";
     $output .= $type . "IDs[\"" . $prefix . $this->id . "\"] = " . WMUtility::jsEscape($this->name) . ";\n";
     return $output;
 }
 function asJS()
 {
     $javascript = '';
     $javascript .= "var Links = new Array();\n";
     $javascript .= "var LinkIDs = new Array();\n";
     foreach ($this->links as $link) {
         $javascript .= $link->asJS();
     }
     $javascript .= "var Nodes = new Array();\n";
     $javascript .= "var NodeIDs = new Array();\n";
     foreach ($this->nodes as $node) {
         $javascript .= $node->asJS();
     }
     $mapName = array_pop(explode("/", $this->configfile));
     $javascript .= "var Map = {\n";
     $javascript .= sprintf('  "file": %s,', WMUtility::jsEscape($mapName));
     $javascript .= sprintf('  "width": %s,', WMUtility::jsEscape($this->width));
     $javascript .= sprintf('  "height": %s,', WMUtility::jsEscape($this->height));
     $javascript .= sprintf('  "title": %s,', WMUtility::jsEscape($this->title));
     $javascript .= "\n};\n";
     return $javascript;
 }