UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / examples / nagios_plugin_check_apcupsd.c
blob05e3ca5209a2f47334e7416645c7097e09b734ad
1 /*
2 * Check-Plugin for Nagios to check status of an APC-UPS
3 * monitored by APCUPSD
5 * Written by Christian Masopust, November 2005
7 * Build it with: cc check_apcupsd.c ../lib/libapc.a -o check_apcupsd
9 * Execute: ./check_apcupsd [host[:port]]
13 #include "apc.h"
15 #ifdef HAVE_NISLIB
17 /* Default values, can be changed on command line */
18 #define SERV_TCP_PORT 3551
19 #define SERV_HOST_ADDR "127.0.0.1"
21 #define BIGBUF 4096
22 char statbuf[BIGBUF];
23 int statlen = BIGBUF;
25 #define NAGIOS_OK 0
26 #define NAGIOS_WARNING 1
27 #define NAGIOS_CRITICAL 2
28 #define NAGIOS_UNKNOWN 3
29 #define S_NAGIOS_OK "OK: "
30 #define S_NAGIOS_WARNING "WARNING: "
31 #define S_NAGIOS_CRITICAL "CRITICAL: "
32 #define S_NAGIOS_UNKNOWN "UNKNOWN: "
35 /* List of variables that can be read by getupsvar()
36 * First field is that name given to getupsvar(),
37 * Second field is our internal name as produced by the STATUS
38 * output from apcupsd.
39 * Third field, if 0 returns everything to the end of the
40 * line, and if 1 returns only to first space (e.g. integers,
41 * and floating point values.
43 static struct {
44 char *request;
45 char *upskeyword;
46 int nfields;
47 } cmdtrans[] = {
48 {"model", "MODEL", 0},
49 {"upsmodel", "UPSMODEL", 0},
50 {"date", "DATE", 0},
51 {"battcap", "BCHARGE", 1},
52 {"mbattchg", "MBATTCHG", 1},
53 {"battvolt", "BATTV", 1},
54 {"nombattv", "NOMBATTV", 1},
55 {"utility", "LINEV", 1},
56 {"upsload", "LOADPCT", 1},
57 {"loadpct", "LOADPCT", 1},
58 {"outputv", "OUTPUTV", 1},
59 {"status", "STATFLAG", 1},
60 {"linemin", "MINLINEV", 1},
61 {"linemax", "MAXLINEV", 1},
62 {"upstemp", "ITEMP", 1},
63 {"outputfreq", "LINEFREQ", 1},
64 {"translo", "LOTRANS", 1},
65 {"transhi", "HITRANS", 1},
66 {"runtime", "TIMELEFT", 1},
67 {"mintimel", "MINTIMEL", 1},
68 {"retpct", "RETPCT", 1}, /* min batt to turn on UPS */
69 {"sense", "SENSE", 1},
70 {"hostname", "HOSTNAME", 1},
71 {"battdate", "BATTDATE", 1},
72 {"serialno", "SERIALNO", 1},
73 {"lastxfer", "LASTXFER", 0}, /* reason for last xfer to batteries */
74 {"selftest", "SELFTEST", 1}, /* results of last self test */
75 {"laststest", "LASTSTEST", 0},
76 {"version", "VERSION", 1},
77 {"upsname", "UPSNAME", 1},
78 {"lowbatt", "DLOWBATT", 1}, /* low battery power off delay */
79 {"battpct", "BCHARGE", 1},
80 {"highxfer", "HITRANS", 1},
81 {"lowxfer", "LOTRANS", 1},
82 {"cable", "CABLE", 0},
83 {"firmware", "FIRMWARE", 0},
84 {NULL, NULL}
87 int fetch_data(char *host, int port);
88 int getupsvar(char *host, int port, char *request, char *answer, int anslen);
89 int fill_buffer(int sockfd);
91 extern int net_errno;
93 struct sockaddr_in tcp_serv_addr;
95 void error_abort(char *msg)
97 fprintf(stdout, msg);
98 exit(NAGIOS_CRITICAL);
101 int main(int argc, char *argv[])
103 int port;
104 char host[200];
105 char msg[200], *p;
106 char hostname[100];
107 char model[100];
108 char upsname[100];
109 char status[1000];
110 int iStatus;
111 char sStatus[10];
112 char loadpct[100];
113 char runtime[100];
114 int retVal;
116 retVal = NAGIOS_UNKNOWN;
117 strcpy (sStatus, S_NAGIOS_UNKNOWN);
119 strcpy(host, SERV_HOST_ADDR);
120 port = SERV_TCP_PORT;
122 if (argc > 1) {
123 strcpy(host, argv[1]); /* get host from command line */
124 p = strchr(host, ':');
125 if (p) {
126 *p++ = 0;
127 port = atoi(p);
131 if (getupsvar(host, port, "hostname", msg, sizeof(msg)) <= 0) {
132 printf("%scannot get hostname from UPS-Server\n", S_NAGIOS_CRITICAL);
133 exit(NAGIOS_CRITICAL);
135 strcpy(hostname, msg);
137 if (getupsvar(host, port, "model", msg, sizeof(msg)) <= 0) {
138 printf("%scannot get model from UPS-Server\n", S_NAGIOS_CRITICAL);
139 exit(NAGIOS_CRITICAL);
141 strcpy(model, msg);
143 if (getupsvar(host, port, "upsname", msg, sizeof(msg)) <= 0) {
144 printf("%scannot get upsname from UPS-Server\n", S_NAGIOS_CRITICAL);
145 exit(NAGIOS_CRITICAL);
147 strcpy(upsname, msg);
149 if (getupsvar(host, port, "status", msg, sizeof(msg)) <= 0) {
150 printf("%scannot get status from UPS-Server\n", S_NAGIOS_CRITICAL);
151 exit(NAGIOS_CRITICAL);
153 iStatus = strtol(msg, 0, 16);
154 status[0] = '\0';
155 if (iStatus & UPS_calibration) {
156 strcat(status, "CALIBRATION ");
157 retVal = NAGIOS_OK;
158 strcpy(sStatus, S_NAGIOS_OK);
160 if (iStatus & UPS_trim) {
161 strcat(status, "SMART TRIM ");
162 retVal = NAGIOS_OK;
163 strcpy(sStatus, S_NAGIOS_OK);
165 if (iStatus & UPS_boost) {
166 strcat(status, "SMART BOOST ");
167 retVal = NAGIOS_OK;
168 strcpy(sStatus, S_NAGIOS_OK);
170 if (iStatus & UPS_online) {
171 strcat(status, "ONLINE ");
172 retVal = NAGIOS_OK;
173 strcpy(sStatus, S_NAGIOS_OK);
175 if (iStatus & UPS_onbatt) {
176 strcat(status, "ON BATTERY ");
177 retVal = NAGIOS_WARNING;
178 strcpy(sStatus, S_NAGIOS_WARNING);
180 if (iStatus & UPS_overload) {
181 strcat(status, "OVERLOADED ");
182 retVal = NAGIOS_CRITICAL;
183 strcpy(sStatus, S_NAGIOS_CRITICAL);
185 if (iStatus & UPS_battlow) {
186 strcat(status, "BATTERY LOW ");
187 retVal = NAGIOS_CRITICAL;
188 strcpy(sStatus, S_NAGIOS_CRITICAL);
190 if (iStatus & UPS_replacebatt) {
191 strcat(status, "REPLACE BATTERY ");
192 retVal = NAGIOS_WARNING;
193 strcpy(sStatus, S_NAGIOS_WARNING);
195 if (iStatus & UPS_commlost) {
196 strcat(status, "COMMUNICATION LOST ");
197 retVal = NAGIOS_CRITICAL;
198 strcpy(sStatus, S_NAGIOS_CRITICAL);
200 if (iStatus & UPS_shutdown) {
201 strcat(status, "SHUTDOWN ");
202 retVal = NAGIOS_OK;
203 strcpy(sStatus, S_NAGIOS_OK);
205 if (iStatus & UPS_slave) {
206 strcat(status, "SLAVE ");
207 retVal = NAGIOS_OK;
208 strcpy(sStatus, S_NAGIOS_OK);
211 if (strlen(status) > 0) {
212 status[strlen(status) - 1] = '\0';
215 if (getupsvar(host, port, "loadpct", msg, sizeof(msg)) <= 0) {
216 printf("%scannot get loadpct from UPS-Server\n", S_NAGIOS_CRITICAL);
217 exit(NAGIOS_CRITICAL);
219 strcpy(loadpct, msg);
221 if (getupsvar(host, port, "runtime", msg, sizeof(msg)) <= 0) {
222 printf("%scannot get runtime from UPS-Server\n", S_NAGIOS_CRITICAL);
223 exit(NAGIOS_CRITICAL);
225 strcpy(runtime, msg);
227 printf ("%sUPS: %s, Load: %s%%, Runtime: %smin, Status: %s\n", sStatus, model, loadpct, runtime, status);
228 /* printf("For host=%s ups=%s model=%s, the Status=%s, loadpct=%s, runtime=%s\n",
229 hostname, upsname, model, status, loadpct, runtime); */
231 exit(retVal);
236 * Read data into memory buffer to be used by getupsvar()
237 * Returns 0 on error
238 * Returns 1 if data fetched
240 int fetch_data(char *host, int port)
242 int sockfd;
243 int stat;
245 if ((sockfd = net_open(host, NULL, port)) < 0) {
246 printf("fetch_data: tcp_open failed for %s port %d", host, port);
247 return 0;
250 stat = fill_buffer(sockfd); /* fill statbuf */
251 net_close(sockfd);
252 return stat;
258 * Returns 1 if var found
259 * answer has var
260 * Returns 0 if variable name not found
261 * answer has "Not found" is variable name not found
262 * answer may have "N/A" if the UPS does not support this
263 * feature
264 * Returns -1 if network problem
265 * answer has "N/A" if host is not available or network error
267 int getupsvar(char *host, int port, char *request, char *answer, int anslen)
269 int i;
270 char *stat_match = NULL;
271 char *find;
272 int nfields = 0;
274 if (!fetch_data(host, port)) {
275 strcpy(answer, "N/A");
276 return -1;
279 for (i=0; cmdtrans[i].request; i++)
280 if (!(strcmp(cmdtrans[i].request, request))) {
281 stat_match = cmdtrans[i].upskeyword;
282 nfields = cmdtrans[i].nfields;
285 if (stat_match != NULL) {
286 if ((find=strstr(statbuf, stat_match)) != NULL) {
287 if (nfields == 1) /* get one field */
288 sscanf (find, "%*s %*s %s", answer);
289 else { /* get everything to eol */
290 i = 0;
291 find += 11; /* skip label */
292 while (*find != '\n')
293 answer[i++] = *find++;
294 answer[i] = 0;
296 if (strcmp(answer, "N/A") == 0)
297 return 0;
298 return 1;
302 strcpy(answer, "Not found");
303 return 0;
306 #define MAXLINE 512
308 /* Fill buffer with data from UPS network daemon
309 * Returns 0 on error
310 * Returns 1 if OK
312 int fill_buffer(int sockfd)
314 int n, stat = 1;
315 char buf[1000];
317 statbuf[0] = 0;
318 statlen = 0;
319 if (net_send(sockfd, "status", 6) != 6) {
320 printf("fill_buffer: write error on socket\n");
321 return 0;
324 while ((n = net_recv(sockfd, buf, sizeof(buf)-1)) > 0) {
325 buf[n] = 0;
326 strcat(statbuf, buf);
328 if (n < 0)
329 stat = 0;
331 statlen = strlen(statbuf);
332 return stat;
336 #else /* HAVE_NISLIB */
338 int main(int argc, char *argv[]) {
339 printf("Sorry, NIS code is not compiled in apcupsd.\n");
340 return 1;
343 #endif /* HAVE_NISLIB */