1 | <?php |
||||
2 | |||||
3 | /* |
||||
4 | * Copyright (C) 2009 Bruno Prémont <bonbons AT linux-vserver.org> |
||||
5 | * |
||||
6 | * This program is free software; you can redistribute it and/or modify it under |
||||
7 | * the terms of the GNU General Public License as published by the Free Software |
||||
8 | * Foundation; only version 2 of the License is applicable. |
||||
9 | * |
||||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||||
11 | * ANY WARRANTY; without even the implied wadsnty of MERCHANTABILITY or FITNESS |
||||
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
||||
13 | * details. |
||||
14 | * |
||||
15 | * You should have received a copy of the GNU General Public License along with |
||||
16 | * this program; if not, write to the Free Software Foundation, Inc., |
||||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
18 | */ |
||||
19 | |||||
20 | use LibreNMS\Config; |
||||
21 | |||||
22 | require 'includes/html/collectd/config.php'; |
||||
23 | require 'includes/html/collectd/functions.php'; |
||||
24 | require 'includes/html/collectd/definitions.php'; |
||||
25 | |||||
26 | function makeTextBlock($text, $fontfile, $fontsize, $width) |
||||
27 | { |
||||
28 | // TODO: handle explicit line-break! |
||||
29 | $words = explode(' ', $text); |
||||
30 | $lines = [$words[0]]; |
||||
31 | $currentLine = 0; |
||||
32 | foreach ($words as $word) { |
||||
33 | $lineSize = imagettfbbox($fontsize, 0, $fontfile, $lines[$currentLine] . ' ' . $word); |
||||
34 | if (($lineSize[2] - $lineSize[0]) < $width) { |
||||
35 | $lines[$currentLine] .= ' ' . $word; |
||||
36 | } else { |
||||
37 | $currentLine++; |
||||
38 | $lines[$currentLine] = $word; |
||||
39 | } |
||||
40 | } |
||||
41 | |||||
42 | error_log(sprintf('Handles message "%s", %d words => %d/%d lines', $text, count($words), $currentLine, count($lines))); |
||||
43 | |||||
44 | return implode("\n", $lines); |
||||
45 | }//end makeTextBlock() |
||||
46 | |||||
47 | /** |
||||
48 | * No RRD files found that could match request |
||||
49 | * |
||||
50 | * @code HTTP error code |
||||
51 | * @code_msg Short text description of HTTP error code |
||||
52 | * @title Title for fake RRD graph |
||||
53 | * @msg Complete error message to display in place of graph content |
||||
54 | */ |
||||
55 | function error($code, $code_msg, $title, $msg) |
||||
56 | { |
||||
57 | header(sprintf('HTTP/1.0 %d %s', $code, $code_msg)); |
||||
58 | header('Pragma: no-cache'); |
||||
59 | header('Expires: Mon, 01 Jan 2008 00:00:00 CET'); |
||||
60 | header('Content-Type: image/png'); |
||||
61 | $w = (Config::get('rrd_width') + 81); |
||||
62 | $h = (Config::get('rrd_height') + 79); |
||||
63 | |||||
64 | $png = imagecreate($w, $h); |
||||
65 | $c_bkgnd = imagecolorallocate($png, 240, 240, 240); |
||||
66 | $c_fgnd = imagecolorallocate($png, 255, 255, 255); |
||||
67 | $c_blt = imagecolorallocate($png, 208, 208, 208); |
||||
68 | $c_brb = imagecolorallocate($png, 160, 160, 160); |
||||
69 | $c_grln = imagecolorallocate($png, 114, 114, 114); |
||||
70 | $c_grarr = imagecolorallocate($png, 128, 32, 32); |
||||
71 | $c_txt = imagecolorallocate($png, 0, 0, 0); |
||||
72 | $c_etxt = imagecolorallocate($png, 64, 0, 0); |
||||
73 | |||||
74 | if (function_exists('imageantialias')) { |
||||
75 | imageantialias($png, true); |
||||
76 | } |
||||
77 | |||||
78 | imagefilledrectangle($png, 0, 0, $w, $h, $c_bkgnd); |
||||
79 | imagefilledrectangle($png, 51, 33, ($w - 31), ($h - 47), $c_fgnd); |
||||
80 | imageline($png, 51, 30, 51, ($h - 43), $c_grln); |
||||
81 | imageline($png, 48, ($h - 46), ($w - 28), ($h - 46), $c_grln); |
||||
82 | imagefilledpolygon($png, [49, 30, 51, 26, 53, 30], 3, $c_grarr); |
||||
83 | imagefilledpolygon($png, [$w - 28, $h - 48, $w - 24, $h - 46, $w - 28, $h - 44], 3, $c_grarr); |
||||
84 | imageline($png, 0, 0, $w, 0, $c_blt); |
||||
85 | imageline($png, 0, 1, $w, 1, $c_blt); |
||||
86 | imageline($png, 0, 0, 0, $h, $c_blt); |
||||
87 | imageline($png, 1, 0, 1, $h, $c_blt); |
||||
88 | imageline($png, ($w - 1), 0, ($w - 1), $h, $c_brb); |
||||
89 | imageline($png, ($w - 2), 1, ($w - 2), $h, $c_brb); |
||||
90 | imageline($png, 1, ($h - 2), $w, ($h - 2), $c_brb); |
||||
91 | imageline($png, 0, ($h - 1), $w, ($h - 1), $c_brb); |
||||
92 | |||||
93 | imagestring($png, 4, ceil(($w - strlen($title) * imagefontwidth(4)) / 2), 10, $title, $c_txt); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
94 | imagestring($png, 5, 60, 35, sprintf('%s [%d]', $code_msg, $code), $c_etxt); |
||||
95 | if (function_exists('imagettfbbox') && is_file(Config::get('error_font'))) { |
||||
96 | // Detailled error message |
||||
97 | $errorfont = Config::get('error_font'); |
||||
98 | $fmt_msg = makeTextBlock($msg, $errorfont, 10, ($w - 86)); |
||||
99 | $fmtbox = imagettfbbox(12, 0, $errorfont, $fmt_msg); |
||||
100 | imagettftext($png, 10, 0, 55, (35 + 3 + imagefontwidth(5) - $fmtbox[7] + $fmtbox[1]), $c_txt, $errorfont, $fmt_msg); |
||||
101 | } else { |
||||
102 | imagestring($png, 4, 53, (35 + 6 + imagefontwidth(5)), $msg, $c_txt); |
||||
103 | } |
||||
104 | |||||
105 | imagepng($png); |
||||
106 | imagedestroy($png); |
||||
107 | }//end error() |
||||
108 | |||||
109 | /** |
||||
110 | * No RRD files found that could match request |
||||
111 | */ |
||||
112 | function error404($title, $msg) |
||||
113 | { |
||||
114 | return error(404, 'Not found', $title, $msg); |
||||
0 ignored issues
–
show
Are you sure the usage of
error(404, 'Not found', $title, $msg) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
115 | }//end error404() |
||||
116 | |||||
117 | function error500($title, $msg) |
||||
118 | { |
||||
119 | return error(500, 'Not found', $title, $msg); |
||||
0 ignored issues
–
show
Are you sure the usage of
error(500, 'Not found', $title, $msg) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
120 | }//end error500() |
||||
121 | |||||
122 | /** |
||||
123 | * Incomplete / invalid request |
||||
124 | */ |
||||
125 | function error400($title, $msg) |
||||
126 | { |
||||
127 | return error(400, 'Bad request', $title, $msg); |
||||
0 ignored issues
–
show
Are you sure the usage of
error(400, 'Bad request', $title, $msg) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
128 | }//end error400() |
||||
129 | |||||
130 | // Process input arguments |
||||
131 | // $host = read_var('host', $_GET, null); |
||||
132 | $host = $device['hostname']; |
||||
133 | if (is_null($host)) { |
||||
134 | return error400('?/?-?/?', 'Missing host name'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400('?/?-?/?', 'Missing host name') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
135 | } elseif (! is_string($host)) { |
||||
136 | return error400('?/?-?/?', 'Expecting exactly 1 host name'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400('?/?-?/?', 'Exp...g exactly 1 host name') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
137 | } elseif (strlen($host) == 0) { |
||||
138 | return error400('?/?-?/?', 'Host name may not be blank'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400('?/?-?/?', 'Host name may not be blank') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
139 | } |
||||
140 | |||||
141 | $plugin = read_var('c_plugin', $_GET, null); |
||||
142 | if (is_null($plugin)) { |
||||
143 | return error400($host . '/?-?/?', 'Missing plugin name'); |
||||
144 | } elseif (! is_string($plugin)) { |
||||
145 | return error400($host . '/?-?/?', 'Plugin name must be a string'); |
||||
146 | } elseif (strlen($plugin) == 0) { |
||||
147 | return error400($host . '/?-?/?', 'Plugin name may not be blank'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400($host . '/?-?/?...name may not be blank') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
148 | } |
||||
149 | |||||
150 | $pinst = read_var('c_plugin_instance', $_GET, ''); |
||||
151 | if (! is_string($pinst)) { |
||||
152 | return error400($host . '/' . $plugin . '-?/?', 'Plugin instance name must be a string'); |
||||
153 | } |
||||
154 | |||||
155 | $type = read_var('c_type', $_GET, ''); |
||||
156 | if (is_null($type)) { |
||||
157 | return error400($host . '/' . $plugin . (strlen($pinst) ? '-' . $pinst : '') . '/?', 'Missing type name'); |
||||
158 | } elseif (! is_string($type)) { |
||||
159 | return error400($host . '/' . $plugin . (strlen($pinst) ? '-' . $pinst : '') . '/?', 'Type name must be a string'); |
||||
160 | } elseif (strlen($type) == 0) { |
||||
161 | return error400($host . '/' . $plugin . (strlen($pinst) ? '-' . $pinst : '') . '/?', 'Type name may not be blank'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400($host . '/' . $...name may not be blank') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
162 | } |
||||
163 | |||||
164 | $tinst = read_var('c_type_instance', $_GET, ''); |
||||
165 | |||||
166 | $graph_identifier = $host . '/' . $plugin . (strlen($pinst) ? '-' . $pinst : '') . '/' . $type . (strlen($tinst) ? '-' . $tinst : '-*'); |
||||
167 | |||||
168 | $timespan = read_var('timespan', $_GET, Config::get('timespan.0.name')); |
||||
169 | $timespan_ok = false; |
||||
170 | foreach (Config::get('timespan') as &$ts) { |
||||
171 | if ($ts['name'] == $timespan) { |
||||
172 | $timespan_ok = true; |
||||
173 | } |
||||
174 | } |
||||
175 | |||||
176 | if (! $timespan_ok) { |
||||
177 | return error400($graph_identifier, 'Unknown timespan requested'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error400($graph_identifi...wn timespan requested') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
178 | } |
||||
179 | |||||
180 | $logscale = (bool) read_var('logarithmic', $_GET, false); |
||||
0 ignored issues
–
show
false of type false is incompatible with the type string expected by parameter $default of read_var() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
181 | $tinylegend = (bool) read_var('tinylegend', $_GET, false); |
||||
182 | |||||
183 | // Check that at least 1 RRD exists for the specified request |
||||
184 | $all_tinst = collectd_list_tinsts($host, $plugin, $pinst, $type); |
||||
185 | if (count($all_tinst) == 0) { |
||||
186 | return error404($graph_identifier, 'No rrd file found for graphing'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error404($graph_identifi...le found for graphing') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
187 | } |
||||
188 | |||||
189 | // Now that we are read, do the bulk work |
||||
190 | load_graph_definitions($logscale, $tinylegend); |
||||
191 | |||||
192 | $pinst = strlen($pinst) == 0 ? null : $pinst; |
||||
193 | $tinst = strlen($tinst) == 0 ? null : $tinst; |
||||
194 | |||||
195 | $opts = []; |
||||
196 | $opts['timespan'] = $timespan; |
||||
197 | if ($logscale) { |
||||
198 | $opts['logarithmic'] = 1; |
||||
199 | } |
||||
200 | |||||
201 | if ($tinylegend) { |
||||
202 | $opts['tinylegend'] = 1; |
||||
203 | } |
||||
204 | |||||
205 | $rrd_cmd = false; |
||||
206 | if (isset($MetaGraphDefs[$type])) { |
||||
207 | $identifiers = []; |
||||
208 | foreach ($all_tinst as &$atinst) { |
||||
209 | $identifiers[] = collectd_identifier($host, $plugin, $type, is_null($pinst) ? '' : $pinst, $atinst); |
||||
210 | } |
||||
211 | |||||
212 | collectd_flush($identifiers); |
||||
0 ignored issues
–
show
$identifiers of type array|string[] is incompatible with the type string expected by parameter $identifier of collectd_flush() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
213 | $rrd_cmd = $MetaGraphDefs[$type]($host, $plugin, $pinst, $type, $all_tinst, $opts); |
||||
214 | } else { |
||||
215 | if (! in_array(is_null($tinst) ? '' : $tinst, $all_tinst)) { |
||||
216 | return error404($host . '/' . $plugin . (! is_null($pinst) ? '-' . $pinst : '') . '/' . $type . (! is_null($tinst) ? '-' . $tinst : ''), 'No rrd file found for graphing'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error404($host . '/' . $...le found for graphing') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
217 | } |
||||
218 | |||||
219 | collectd_flush(collectd_identifier($host, $plugin, $type, is_null($pinst) ? '' : $pinst, is_null($tinst) ? '' : $tinst)); |
||||
220 | if (isset($GraphDefs[$type])) { |
||||
221 | $rrd_cmd = collectd_draw_generic($timespan, $host, $plugin, $type, $pinst, $tinst); |
||||
222 | } else { |
||||
223 | $rrd_cmd = collectd_draw_rrd($host, $plugin, $type, $pinst, $tinst); |
||||
224 | } |
||||
225 | } |
||||
226 | |||||
227 | if (isset($rrd_cmd)) { |
||||
228 | $from = (int) ($_GET['from'] ?? time() - 86400); |
||||
229 | $to = (int) ($_GET['to'] ?? time()); |
||||
230 | |||||
231 | $rrd_cmd .= ' -s ' . $from . ' -e ' . $to; |
||||
232 | } |
||||
233 | |||||
234 | if ($_GET['legend'] == 'no') { |
||||
235 | $rrd_cmd .= ' -g '; |
||||
236 | } |
||||
237 | |||||
238 | if ($height < '99') { |
||||
239 | $rrd_cmd .= ' --only-graph '; |
||||
240 | } |
||||
241 | |||||
242 | if ($width <= '300') { |
||||
243 | $rrd_cmd .= ' --font LEGEND:7:' . Config::get('mono_font') . ' --font AXIS:6:' . Config::get('mono_font') . ' '; |
||||
244 | } else { |
||||
245 | $rrd_cmd .= ' --font LEGEND:8:' . Config::get('mono_font') . ' --font AXIS:7:' . Config::get('mono_font') . ' '; |
||||
246 | } |
||||
247 | |||||
248 | if (isset($_GET['debug'])) { |
||||
249 | header('Content-Type: text/plain; charset=utf-8'); |
||||
250 | printf("Would have executed:\n%s\n", $rrd_cmd); |
||||
251 | |||||
252 | return 0; |
||||
253 | } elseif ($rrd_cmd) { |
||||
254 | header('Content-Type: image/png'); |
||||
255 | header('Cache-Control: max-age=60'); |
||||
256 | $rt = 0; |
||||
257 | passthru($rrd_cmd, $rt); |
||||
258 | if ($rt !== 0) { |
||||
259 | return error500($graph_identifier, 'RRD failed to generate the graph: ' . $rt); |
||||
0 ignored issues
–
show
Are you sure the usage of
error500($graph_identifi...ate the graph: ' . $rt) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
260 | } |
||||
261 | |||||
262 | return $rt; |
||||
263 | } else { |
||||
264 | return error500($graph_identifier, 'Failed to tell RRD how to generate the graph'); |
||||
0 ignored issues
–
show
Are you sure the usage of
error500($graph_identifi...to generate the graph') is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
265 | } |
||||
266 |