UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / examples / newslave.c
blobd8b5e7c570d5734e639183317cd32796a1103fa1
1 /*
2 * Client test program for apcnisd to be used
3 * as a base for the new master/slave code.
5 * Build it with: cc newslave.c ../lib/libapc.a -o newclient
7 * Execute: ./newslave [host[:port]]
9 * The two commands currently (Apr 2001) accepted by the
10 * server are "status" and "events".
14 #include "apc.h"
16 #ifdef HAVE_NISLIB
18 /* Default values, can be changed on command line */
19 #define SERV_TCP_PORT 3551
20 #define SERV_HOST_ADDR "127.0.0.1"
22 #define BIGBUF 4096
23 char statbuf[BIGBUF];
24 int statlen = BIGBUF;
26 /* List of variables that can be read by getupsvar()
27 * First field is that name given to getupsvar(),
28 * Second field is our internal name as produced by the STATUS
29 * output from apcupsd.
30 * Third field, if 0 returns everything to the end of the
31 * line, and if 1 returns only to first space (e.g. integers,
32 * and floating point values.
34 static struct {
35 const char *request;
36 const char *upskeyword;
37 int nfields;
38 } cmdtrans[] = {
39 {"model", "MODEL", 0},
40 {"upsmodel", "UPSMODEL", 0},
41 {"date", "DATE", 0},
42 {"battcap", "BCHARGE", 1},
43 {"mbattchg", "MBATTCHG", 1},
44 {"battvolt", "BATTV", 1},
45 {"nombattv", "NOMBATTV", 1},
46 {"utility", "LINEV", 1},
47 {"upsload", "LOADPCT", 1},
48 {"loadpct", "LOADPCT", 1},
49 {"outputv", "OUTPUTV", 1},
50 {"status", "STATFLAG", 1},
51 {"linemin", "MINLINEV", 1},
52 {"linemax", "MAXLINEV", 1},
53 {"upstemp", "ITEMP", 1},
54 {"outputfreq", "LINEFREQ", 1},
55 {"translo", "LOTRANS", 1},
56 {"transhi", "HITRANS", 1},
57 {"runtime", "TIMELEFT", 1},
58 {"mintimel", "MINTIMEL", 1},
59 {"retpct", "RETPCT", 1}, /* min batt to turn on UPS */
60 {"sense", "SENSE", 1},
61 {"hostname", "HOSTNAME", 1},
62 {"battdate", "BATTDATE", 1},
63 {"serialno", "SERIALNO", 1},
64 {"lastxfer", "LASTXFER", 0}, /* reason for last xfer to batteries */
65 {"selftest", "SELFTEST", 1}, /* results of last self test */
66 {"laststest", "LASTSTEST", 0},
67 {"version", "VERSION", 1},
68 {"upsname", "UPSNAME", 1},
69 {"lowbatt", "DLOWBATT", 1}, /* low battery power off delay */
70 {"battpct", "BCHARGE", 1},
71 {"highxfer", "HITRANS", 1},
72 {"lowxfer", "LOTRANS", 1},
73 {"cable", "CABLE", 0},
74 {"firmware", "FIRMWARE", 0},
75 {NULL, NULL}
78 int fetch_data(char *host, int port);
79 int getupsvar(char *host, int port, const char *request, char *answer, int anslen);
80 int fill_buffer(int sockfd);
82 extern int net_errno;
84 void error_abort(char *msg)
86 fprintf(stderr, msg);
87 exit(1);
90 int main(int argc, char *argv[])
92 int port;
93 char host[200];
94 char msg[200], *p;
95 char hostname[100];
96 char release[100];
97 char upsname[100];
98 char status[100];
100 strcpy(host, SERV_HOST_ADDR);
101 port = SERV_TCP_PORT;
103 if (argc > 1) {
104 strcpy(host, argv[1]); /* get host from command line */
105 p = strchr(host, ':');
106 if (p) {
107 *p++ = 0;
108 port = atoi(p);
112 if (getupsvar(host, port, "hostname", msg, sizeof(msg)) <= 0) {
113 printf("Error getting variable\n");
114 exit(1);
116 strcpy(hostname, msg);
118 if (getupsvar(host, port, "version", msg, sizeof(msg)) <= 0) {
119 printf("Error getting variable\n");
120 exit(1);
122 strcpy(release, msg);
124 if (getupsvar(host, port, "upsname", msg, sizeof(msg)) <= 0) {
125 printf("Error getting variable\n");
126 exit(1);
128 strcpy(upsname, msg);
130 if (getupsvar(host, port, "status", msg, sizeof(msg)) <= 0) {
131 printf("Error getting variable\n");
132 exit(1);
134 strcpy(status, msg);
136 printf("For host=%s ups=%s apcupsd version=%s, the Status=%s\n",
137 hostname, upsname, release, status);
139 exit(0);
144 * Read data into memory buffer to be used by getupsvar()
145 * Returns 0 on error
146 * Returns 1 if data fetched
148 int fetch_data(char *host, int port)
150 int sockfd;
151 int stat;
153 if ((sockfd = net_open(host, NULL, port)) < 0) {
154 printf("fetch_data: tcp_open failed for %s port %d", host, port);
155 return 0;
158 stat = fill_buffer(sockfd); /* fill statbuf */
159 net_close(sockfd);
160 return stat;
166 * Returns 1 if var found
167 * answer has var
168 * Returns 0 if variable name not found
169 * answer has "Not found" is variable name not found
170 * answer may have "N/A" if the UPS does not support this
171 * feature
172 * Returns -1 if network problem
173 * answer has "N/A" if host is not available or network error
175 int getupsvar(char *host, int port, const char *request, char *answer, int anslen)
177 int i;
178 const char *stat_match = NULL;
179 char *find;
180 int nfields = 0;
182 if (!fetch_data(host, port)) {
183 strcpy(answer, "N/A");
184 return -1;
187 for (i=0; cmdtrans[i].request; i++)
188 if (!(strcmp(cmdtrans[i].request, request))) {
189 stat_match = cmdtrans[i].upskeyword;
190 nfields = cmdtrans[i].nfields;
193 if (stat_match != NULL) {
194 if ((find=strstr(statbuf, stat_match)) != NULL) {
195 if (nfields == 1) /* get one field */
196 sscanf (find, "%*s %*s %s", answer);
197 else { /* get everything to eol */
198 i = 0;
199 find += 11; /* skip label */
200 while (*find != '\n')
201 answer[i++] = *find++;
202 answer[i] = 0;
204 if (strcmp(answer, "N/A") == 0)
205 return 0;
206 return 1;
210 strcpy(answer, "Not found");
211 return 0;
214 #define MAXLINE 512
216 /* Fill buffer with data from UPS network daemon
217 * Returns 0 on error
218 * Returns 1 if OK
220 int fill_buffer(int sockfd)
222 int n, stat = 1;
223 char buf[1000];
225 statbuf[0] = 0;
226 statlen = 0;
227 if (net_send(sockfd, "status", 6) != 6) {
228 printf("fill_buffer: write error on socket\n");
229 return 0;
232 while ((n = net_recv(sockfd, buf, sizeof(buf)-1)) > 0) {
233 buf[n] = 0;
234 strcat(statbuf, buf);
236 if (n < 0)
237 stat = 0;
239 statlen = strlen(statbuf);
240 return stat;
244 #else /* HAVE_NISLIB */
246 int main(int argc, char *argv[]) {
247 printf("Sorry, NIS code is not compiled in apcupsd.\n");
248 return 1;
251 #endif /* HAVE_NISLIB */