1 /* netget.c - GET handlers for upsd
2
3 Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include "common.h"
21
22 #include "upsd.h"
23 #include "sstate.h"
24 #include "state.h"
25 #include "desc.h"
26 #include "neterr.h"
27
28 #include "netget.h"
29
get_numlogins(nut_ctype_t * client,const char * upsname)30 static void get_numlogins(nut_ctype_t *client, const char *upsname)
31 {
32 const upstype_t *ups;
33
34 ups = get_ups_ptr(upsname);
35
36 if (!ups) {
37 send_err(client, NUT_ERR_UNKNOWN_UPS);
38 return;
39 }
40
41 if (!ups_available(ups, client))
42 return;
43
44 sendback(client, "NUMLOGINS %s %d\n", upsname, ups->numlogins);
45 }
46
get_upsdesc(nut_ctype_t * client,const char * upsname)47 static void get_upsdesc(nut_ctype_t *client, const char *upsname)
48 {
49 const upstype_t *ups;
50 char esc[SMALLBUF];
51
52 ups = get_ups_ptr(upsname);
53
54 if (!ups) {
55 send_err(client, NUT_ERR_UNKNOWN_UPS);
56 return;
57 }
58
59 if (ups->desc) {
60 pconf_encode(ups->desc, esc, sizeof(esc));
61 sendback(client, "UPSDESC %s \"%s\"\n", upsname, esc);
62
63 } else {
64
65 sendback(client, "UPSDESC %s \"Unavailable\"\n", upsname);
66 }
67 }
68
get_desc(nut_ctype_t * client,const char * upsname,const char * var)69 static void get_desc(nut_ctype_t *client, const char *upsname, const char *var)
70 {
71 const upstype_t *ups;
72 const char *desc;
73
74 ups = get_ups_ptr(upsname);
75
76 if (!ups) {
77 send_err(client, NUT_ERR_UNKNOWN_UPS);
78 return;
79 }
80
81 if (!ups_available(ups, client))
82 return;
83
84 desc = desc_get_var(var);
85
86 if (desc)
87 sendback(client, "DESC %s %s \"%s\"\n", upsname, var, desc);
88 else
89 sendback(client, "DESC %s %s \"Description unavailable\"\n", upsname, var);
90 }
91
get_cmddesc(nut_ctype_t * client,const char * upsname,const char * cmd)92 static void get_cmddesc(nut_ctype_t *client, const char *upsname, const char *cmd)
93 {
94 const upstype_t *ups;
95 const char *desc;
96
97 ups = get_ups_ptr(upsname);
98
99 if (!ups) {
100 send_err(client, NUT_ERR_UNKNOWN_UPS);
101 return;
102 }
103
104 if (!ups_available(ups, client))
105 return;
106
107 desc = desc_get_cmd(cmd);
108
109 if (desc)
110 sendback(client, "CMDDESC %s %s \"%s\"\n", upsname, cmd, desc);
111 else
112 sendback(client, "CMDDESC %s %s \"Description unavailable\"\n",
113 upsname, cmd);
114 }
115
get_type(nut_ctype_t * client,const char * upsname,const char * var)116 static void get_type(nut_ctype_t *client, const char *upsname, const char *var)
117 {
118 char buf[SMALLBUF];
119 const upstype_t *ups;
120 const st_tree_t *node;
121
122 ups = get_ups_ptr(upsname);
123
124 if (!ups) {
125 send_err(client, NUT_ERR_UNKNOWN_UPS);
126 return;
127 }
128
129 if (!ups_available(ups, client))
130 return;
131
132 node = sstate_getnode(ups, var);
133
134 if (!node) {
135 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
136 return;
137 }
138
139 snprintf(buf, sizeof(buf), "TYPE %s %s", upsname, var);
140
141 if (node->flags & ST_FLAG_RW)
142 snprintfcat(buf, sizeof(buf), " RW");
143
144 if (node->enum_list) {
145 snprintfcat(buf, sizeof(buf), " ENUM");
146 }
147
148 if (node->range_list) {
149 snprintfcat(buf, sizeof(buf), " RANGE");
150 }
151
152 if (node->flags & ST_FLAG_STRING) {
153 sendback(client, "%s STRING:%ld\n", buf, node->aux);
154 return;
155 }
156
157 /* Any variable that is not string | range | enum is just a simple
158 * numeric value */
159
160 sendback(client, "%s NUMBER\n", buf);
161 }
162
get_var_server(nut_ctype_t * client,const char * upsname,const char * var)163 static void get_var_server(nut_ctype_t *client, const char *upsname, const char *var)
164 {
165 if (!strcasecmp(var, "server.info")) {
166 sendback(client, "VAR %s server.info "
167 "\"Network UPS Tools upsd %s - "
168 "http://www.networkupstools.org/\"\n",
169 upsname, UPS_VERSION);
170 return;
171 }
172
173 if (!strcasecmp(var, "server.version")) {
174 sendback(client, "VAR %s server.version \"%s\"\n",
175 upsname, UPS_VERSION);
176 return;
177 }
178
179 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
180 }
181
get_var(nut_ctype_t * client,const char * upsname,const char * var)182 static void get_var(nut_ctype_t *client, const char *upsname, const char *var)
183 {
184 const upstype_t *ups;
185 const char *val;
186
187 /* ignore upsname for server.* variables */
188 if (!strncasecmp(var, "server.", 7)) {
189 get_var_server(client, upsname, var);
190 return;
191 }
192
193 ups = get_ups_ptr(upsname);
194
195 if (!ups) {
196 send_err(client, NUT_ERR_UNKNOWN_UPS);
197 return;
198 }
199
200 if (!ups_available(ups, client))
201 return;
202
203 val = sstate_getinfo(ups, var);
204
205 if (!val) {
206 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
207 return;
208 }
209
210 /* handle special case for status */
211 if ((!strcasecmp(var, "ups.status")) && (ups->fsd))
212 sendback(client, "VAR %s %s \"FSD %s\"\n", upsname, var, val);
213 else
214 sendback(client, "VAR %s %s \"%s\"\n", upsname, var, val);
215 }
216
net_get(nut_ctype_t * client,size_t numarg,const char ** arg)217 void net_get(nut_ctype_t *client, size_t numarg, const char **arg)
218 {
219 if (numarg < 1) {
220 send_err(client, NUT_ERR_INVALID_ARGUMENT);
221 return;
222 }
223
224 /* GET TRACKING [ID] */
225 if (!strcasecmp(arg[0], "TRACKING")) {
226 if (numarg < 2) {
227 sendback(client, "%s\n", (client->tracking) ? "ON" : "OFF");
228 }
229 else {
230 if (client->tracking)
231 sendback(client, "%s\n", tracking_get(arg[1]));
232 else
233 send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED);
234 }
235 return;
236 }
237
238 if (numarg < 2) {
239 send_err(client, NUT_ERR_INVALID_ARGUMENT);
240 return;
241 }
242
243 /* GET NUMLOGINS UPS */
244 if (!strcasecmp(arg[0], "NUMLOGINS")) {
245 get_numlogins(client, arg[1]);
246 return;
247 }
248
249 /* GET UPSDESC UPS */
250 if (!strcasecmp(arg[0], "UPSDESC")) {
251 get_upsdesc(client, arg[1]);
252 return;
253 }
254
255 if (numarg < 3) {
256 send_err(client, NUT_ERR_INVALID_ARGUMENT);
257 return;
258 }
259
260 /* GET VAR UPS VARNAME */
261 if (!strncasecmp(arg[0], "VAR", 3)) {
262 get_var(client, arg[1], arg[2]);
263 return;
264 }
265
266 /* GET TYPE UPS VARNAME */
267 if (!strcasecmp(arg[0], "TYPE")) {
268 get_type(client, arg[1], arg[2]);
269 return;
270 }
271
272 /* GET DESC UPS VARNAME */
273 if (!strcasecmp(arg[0], "DESC")) {
274 get_desc(client, arg[1], arg[2]);
275 return;
276 }
277
278 /* GET CMDDESC UPS CMDNAME */
279 if (!strcasecmp(arg[0], "CMDDESC")) {
280 get_cmddesc(client, arg[1], arg[2]);
281 return;
282 }
283
284 send_err(client, NUT_ERR_INVALID_ARGUMENT);
285 return;
286 }
287