2 * upsstats - cgi program to generate the main UPS info page
4 * Author: Russell Kroll <rkroll@exploits.org>
6 * To use: install the binary in a directory where CGI programs may be
7 * executed by your web server. On many systems something like
8 * /usr/local/etc/httpd/cgi-bin will work nicely. I recommend
9 * calling the binary "upsstats.cgi" in that directory.
11 * Assuming a path like the above, the following link will suffice:
12 * <A HREF="/cgi-bin/upsstats.cgi">UPS Status</A>
14 * This program assumes that upsimage.cgi will be in the same
15 * directory. The install-cgi target will take care of putting
16 * things in the right place if you set the paths properly in the
19 * Modified: Jonathan Benson <jbenson@technologist.com>
20 * 19/6/98 to suit apcupsd
21 * 23/6/98 added more graphs and menu options
23 * Modified: Kern Sibbald <kern@sibbald.com>
24 * Nov 1999 to work with apcupsd networking and
25 * to include as much of the NUT code
33 #include <sys/types.h>
35 #include "cgiconfig.h"
39 #ifndef DEFAULT_REFRESH
40 #define DEFAULT_REFRESH 30
43 #ifndef MAXHOSTNAMELEN
44 #define MAXHOSTNAMELEN 64
47 static char monhost
[MAXHOSTNAMELEN
] = "127.0.0.1";
51 static char temps
[16] = "C";
52 static int refresh
= DEFAULT_REFRESH
;
54 void parsearg(const char *var
, const char *value
)
56 if (strcmp(var
, "host") == 0) {
57 strncpy (monhost
, value
, sizeof(monhost
));
58 monhost
[sizeof(monhost
) - 1] = '\0';
60 } else if (strcmp(var
, "img1") == 0) {
62 if ((img1
<= 0) || (img1
> 6)) {
66 } else if (strcmp(var
, "img2") == 0) {
68 if ((img2
<= 0) || (img2
> 6)) {
72 } else if (strcmp(var
, "img3") == 0) {
74 if ((img3
<= 0) || (img3
> 6)) {
78 } else if (strcmp(var
, "temp") == 0) {
79 strncpy (temps
, value
, sizeof(temps
));
80 temps
[sizeof(temps
) - 1] = '\0';
82 } else if (strcmp(var
, "refresh") == 0) {
83 refresh
= atoi(value
);
85 refresh
= DEFAULT_REFRESH
;
90 void send_image(int report
, int defrpt
)
92 char answer
[256], answer2
[256], answer3
[256];
94 if (report
< 1 || report
> 6)
97 fputs ("<img src=\"upsimage.cgi?display=", stdout
);
100 getupsvar (monhost
, "battcap", answer
, sizeof(answer
));
101 getupsvar (monhost
, "mbattchg", answer2
, sizeof(answer2
));
102 printf ("battcap&value=%s&value2=%s\" alt=\"Battery Capacity %s%%\"",
103 answer
, answer2
, answer
);
106 getupsvar (monhost
, "battvolt", answer
, sizeof(answer
));
107 getupsvar (monhost
, "nombattv", answer2
, sizeof(answer2
));
108 printf ("battvolt&value=%s&value2=%s\" alt=\"Battery Voltage %s VDC\"",
109 answer
, answer2
, answer
);
112 getupsvar (monhost
, "utility", answer
, sizeof(answer
));
113 getupsvar (monhost
, "lowxfer", answer2
, sizeof(answer2
));
114 getupsvar (monhost
, "highxfer", answer3
, sizeof(answer3
));
115 printf ("utility&value=%s&value2=%s&value3=%s\" alt=\"Utility Voltage %s VAC\"",
116 answer
, answer2
, answer3
, answer
);
119 getupsvar (monhost
, "outputv", answer
, sizeof(answer
));
120 printf ("outputv&value=%s\" alt=\"Output Voltage %s VAC\"",
124 getupsvar (monhost
, "upsload", answer
, sizeof(answer
));
125 printf ("upsload&value=%s\" alt=\"UPS Load %s%%\"",
129 getupsvar (monhost
, "runtime", answer
, sizeof(answer
));
130 getupsvar (monhost
, "mintimel", answer2
, sizeof(answer2
));
131 printf ("runtime&value=%s&value2=%s\" alt=\"Run time remaining %s minutes\"",
132 answer
, answer2
, answer
);
135 puts (" width=\"150\" height=\"350\" />");
138 static void image_menu(int select
)
140 fputs (" <option value=\"1\"", stdout
);
142 fputs(" selected=\"selected\"", stdout
);
143 puts (">Battery Capacity</option>");
145 fputs (" <option value=\"2\"", stdout
);
147 fputs(" selected=\"selected\"", stdout
);
148 puts (">Battery Voltage</option>");
150 fputs (" <option value=\"3\"", stdout
);
152 fputs(" selected=\"selected\"", stdout
);
153 puts (">Utility Voltage</option>");
155 fputs (" <option value=\"4\"", stdout
);
157 fputs(" selected=\"selected\"", stdout
);
158 puts (">Output Voltage</option>");
160 fputs (" <option value=\"5\"", stdout
);
162 fputs(" selected=\"selected\"", stdout
);
163 puts (">UPS Load</option>");
165 fputs (" <option value=\"6\"", stdout
);
167 fputs(" selected=\"selected\"", stdout
);
168 puts (">Run Time Remaining</option>");
171 int main(int argc
, char **argv
)
178 (void) extractcgiargs();
180 p
= strstr(monhost
, "%3");
182 *p
++ = ':'; /* set colon */
183 memmove(p
, p
+2, sizeof(monhost
)-(p
-monhost
)); /* get rid of hex 3A */
186 snprintf(answer
, sizeof(answer
), "%s UPS Status", monhost
);
187 html_begin(answer
, refresh
);
189 if (!checkhost(monhost
)) {
190 fputs ("<p><strong>Access to host ", stdout
);
192 puts (" is not authorized.</strong></p>");
197 /* check if host is available */
198 if (getupsvar(monhost
, "date", answer
, sizeof(answer
)) <= 0) {
199 fputs ("<p><strong>Unable to communicate with the UPS on ", stdout
);
201 puts (".</strong></p>");
206 puts ("<div class=\"Center\">");
207 puts ("<table border=\"2\" cellspacing=\"10\" cellpadding=\"5\">");
209 getupsvar(monhost
, "date", answer
, sizeof(answer
));
210 fputs ("<tr><th>", stdout
);
215 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
216 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n", monhost
);
217 printf (" <select onchange=\"this.form.submit()\" name=\"img1\">\n");
219 printf (" </select>\n");
220 printf (" <input type=\"hidden\" name=\"img2\" value=\"%d\" />\n",img2
);
221 printf (" <input type=\"hidden\" name=\"img3\" value=\"%d\" />\n",img3
);
222 printf (" <input type=\"hidden\" name=\"temp\" value=\"%s\" />\n",temps
);
223 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
224 puts (" </div></form>");
228 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
229 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n", monhost
);
230 printf (" <input type=\"hidden\" name=\"img1\" value=\"%d\" />\n",img1
);
231 printf (" <select onchange=\"this.form.submit()\" name=\"img2\">\n");
233 printf (" </select>\n");
234 printf (" <input type=\"hidden\" name=\"img3\" value=\"%d\" />\n",img3
);
235 printf (" <input type=\"hidden\" name=\"temp\" value=\"%s\" />\n",temps
);
236 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
237 puts (" </div></form>");
241 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
242 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n", monhost
);
243 printf (" <input type=\"hidden\" name=\"img1\" value=\"%d\" />\n",img1
);
244 printf (" <input type=\"hidden\" name=\"img2\" value=\"%d\" />\n",img2
);
245 printf (" <select onchange=\"this.form.submit()\" name=\"img3\">\n");
247 printf (" </select>\n");
248 printf (" <input type=\"hidden\" name=\"temp\" value=\"%s\" />\n",temps
);
249 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
250 puts (" </div></form>");
253 puts ("<tr><td><pre>");
255 getupsvar (monhost
, "hostname", answer
, sizeof(answer
));
256 fputs ("Monitoring: ", stdout
);
258 fputs ("\n", stdout
);
260 getupsvar (monhost
, "model", answer
, sizeof(answer
));
261 fputs (" UPS Model: ", stdout
);
263 fputs ("\n", stdout
);
265 getupsvar (monhost
, "upsname", answer
, sizeof(answer
));
266 fputs (" UPS Name: ", stdout
);
268 fputs ("\n", stdout
);
270 getupsvar (monhost
, "version", answer
, sizeof(answer
));
271 fputs (" APCUPSD: Version ", stdout
);
273 fputs ("\n", stdout
);
275 fputs (" Status: ", stdout
);
277 if (getupsvar (monhost
, "status", answer
, sizeof(answer
)) <= 0) {
278 puts ("Not available");
280 status
= strtol(answer
, 0, 16);
281 if (status
& UPS_calibration
)
282 fputs ("CALIBRATION ", stdout
);
283 if (status
& UPS_trim
)
284 fputs ("TRIM ", stdout
);
285 if (status
& UPS_boost
)
286 fputs ("BOOST ", stdout
);
287 if (status
& UPS_online
)
288 fputs ("ONLINE ", stdout
);
289 if (status
& UPS_onbatt
)
290 fputs ("ON BATTERY ", stdout
);
291 if (status
& UPS_overload
)
292 fputs ("OVERLOADED ", stdout
);
293 if (status
& UPS_battlow
)
294 fputs ("BATTERY LOW ", stdout
);
295 if (status
& UPS_replacebatt
)
296 fputs ("REPLACE BATTERY ", stdout
);
297 if (status
& UPS_commlost
)
298 fputs("COMM LOST ", stdout
);
299 if (status
& UPS_shutdown
)
300 fputs("SHUTDOWN ", stdout
);
301 if (status
& UPS_slave
)
302 fputs("SLAVE ", stdout
);
303 if (!(status
& UPS_battpresent
))
304 fputs("NOBATT ", stdout
);
305 fputs ("\n", stdout
);
308 puts ("</pre></td>");
310 puts ("<td rowspan=\"3\">");
314 puts ("<td rowspan=\"3\">");
318 puts ("<td rowspan=\"3\">");
323 puts ("<tr><td><pre>");
325 getupsvar (monhost
, "selftest", answer
, sizeof(answer
));
326 fputs ("Last UPS Self Test: ", stdout
);
328 fputs ("\n", stdout
);
330 getupsvar(monhost
, "laststest", answer
, sizeof(answer
));
331 /* To reduce the length of the output, we drop the
332 * seconds and the trailing year.
334 for (p
=answer
; *p
&& *p
!= ':'; p
++) ;
337 for ( ; *p
&& *p
!= ':'; p
++) ;
339 fputs ("Last Test Date: ", stdout
);
341 fputs ("\n", stdout
);
343 puts ("</pre></td></tr>");
345 puts ("<tr><td><pre>");
347 getupsvar (monhost
, "utility", answer
, sizeof(answer
));
348 fputs ("Utility Voltage: ", stdout
);
352 getupsvar (monhost
, "linemin", answer
, sizeof(answer
));
353 fputs (" Line Minimum: ", stdout
);
357 getupsvar (monhost
, "linemax", answer
, sizeof(answer
));
358 fputs (" Line Maximum: ", stdout
);
362 getupsvar (monhost
, "outputfreq", answer
, sizeof(answer
));
363 fputs (" Output Freq: ", stdout
);
367 if (getupsvar(monhost
, "ambtemp", answer
, sizeof(answer
)) > 0) {
368 if (strcmp(answer
, "Not found" ) != 0) {
369 if (strcmp(temps
,"F") == 0) {
370 tempf
= (strtod (answer
, 0) * 1.8) + 32;
371 printf (" Amb. Temp.: %.1f° F\n", tempf
);
372 } else if (strcmp(temps
,"K") == 0) {
373 tempf
= (strtod (answer
, 0)) + 273;
374 printf (" Amb. Temp.: %.1f° K\n", tempf
);
376 printf (" Amb. Temp.: %s° C\n", answer
);
381 if ( getupsvar (monhost
, "humidity", answer
, sizeof(answer
)) > 0) {
382 if (strcmp(answer
, "Not found") != 0) {
383 fputs (" Amb. Humidity: ", stdout
);
389 printf ("</pre>\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tr>\n<td colspan=\"2\">\n<pre>\n");
391 if (getupsvar (monhost
, "upstemp", answer
, sizeof(answer
)) > 0) {
392 if (strcmp(temps
,"F") == 0) {
393 tempf
= (strtod (answer
, 0) * 1.8) + 32;
394 printf (" UPS Temp: %.1f \n</pre>\n</td>\n<td>\n", tempf
);
395 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
396 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n",monhost
);
397 printf (" <input type=\"hidden\" name=\"img1\" value=\"%d\" />\n",img1
);
398 printf (" <input type=\"hidden\" name=\"img2\" value=\"%d\" />\n",img2
);
399 printf (" <input type=\"hidden\" name=\"img3\" value=\"%d\" />\n",img3
);
400 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
401 printf (" <select onchange=\"this.form.submit();\" name=\"temp\">\n");
402 printf (" <option value=\"C\">° C</option>\n");
403 printf (" <option selected=\"selected\" value=\"F\">° F</option>\n");
404 printf (" <option value=\"K\">° K</option>\n");
406 } else if (strcmp(temps
,"K") == 0) {
407 tempf
= (strtod (answer
, 0)) + 273;
408 printf (" UPS Temp: %.1f \n</pre>\n</td>\n<td>\n", tempf
);
409 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
410 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n",monhost
);
411 printf (" <input type=\"hidden\" name=\"img1\" value=\"%d\" />\n",img1
);
412 printf (" <input type=\"hidden\" name=\"img2\" value=\"%d\" />\n",img2
);
413 printf (" <input type=\"hidden\" name=\"img3\" value=\"%d\" />\n",img3
);
414 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
415 printf (" <select onchange=\"this.form.submit()\" name=\"temp\">\n");
416 printf (" <option value=\"C\">° C</option>\n");
417 printf (" <option value=\"F\">° F</option>\n");
418 printf (" <option selected=\"selected\" value=\"K\">° K</option>\n");
421 printf (" UPS Temp: %s \n</pre>\n</td>\n<td>\n", answer
);
422 printf (" <form method=\"get\" action=\"upsstats.cgi\"><div>\n");
423 printf (" <input type=\"hidden\" name=\"host\" value=\"%s\" />\n",monhost
);
424 printf (" <input type=\"hidden\" name=\"img1\" value=\"%d\" />\n",img1
);
425 printf (" <input type=\"hidden\" name=\"img2\" value=\"%d\" />\n",img2
);
426 printf (" <input type=\"hidden\" name=\"img3\" value=\"%d\" />\n",img3
);
427 printf (" <input type=\"hidden\" name=\"refresh\" value=\"%d\" />\n",refresh
);
428 printf (" <select onchange=\"this.form.submit()\" name=\"temp\">\n");
429 printf (" <option selected=\"selected\" value=\"C\">° C</option>\n");
430 printf (" <option value=\"F\">° F</option>\n");
431 printf (" <option value=\"K\">° K</option>\n");
436 puts (" </div></form>");
437 puts ("</td></tr></table>");
440 puts ("<tr><td colspan=\"4\"><b>Recent Events</b><br />");
441 puts ("<textarea rows=\"5\" cols=\"95\">");
443 fetch_events(monhost
);
446 puts ("</textarea>");
449 puts ("</table></div>");