Merge pull request #2680 from masterwishx/work2471-eco_addon
[networkupstools.git] / server / netget.c
blob1fd4d2475a06f3340f091f570a26aa1fabd79b98
1 /* netget.c - GET handlers for upsd
3 Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
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.
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.
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
20 #include "common.h"
22 #include "upsd.h"
23 #include "sstate.h"
24 #include "state.h"
25 #include "desc.h"
26 #include "neterr.h"
28 #include "netget.h"
30 static void get_numlogins(nut_ctype_t *client, const char *upsname)
32 const upstype_t *ups;
34 ups = get_ups_ptr(upsname);
36 if (!ups) {
37 send_err(client, NUT_ERR_UNKNOWN_UPS);
38 return;
41 if (!ups_available(ups, client))
42 return;
44 sendback(client, "NUMLOGINS %s %d\n", upsname, ups->numlogins);
47 static void get_upsdesc(nut_ctype_t *client, const char *upsname)
49 const upstype_t *ups;
50 char esc[SMALLBUF];
52 ups = get_ups_ptr(upsname);
54 if (!ups) {
55 send_err(client, NUT_ERR_UNKNOWN_UPS);
56 return;
59 if (ups->desc) {
60 pconf_encode(ups->desc, esc, sizeof(esc));
61 sendback(client, "UPSDESC %s \"%s\"\n", upsname, esc);
63 } else {
65 sendback(client, "UPSDESC %s \"Unavailable\"\n", upsname);
69 static void get_desc(nut_ctype_t *client, const char *upsname, const char *var)
71 const upstype_t *ups;
72 const char *desc;
74 ups = get_ups_ptr(upsname);
76 if (!ups) {
77 send_err(client, NUT_ERR_UNKNOWN_UPS);
78 return;
81 if (!ups_available(ups, client))
82 return;
84 desc = desc_get_var(var);
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);
92 static void get_cmddesc(nut_ctype_t *client, const char *upsname, const char *cmd)
94 const upstype_t *ups;
95 const char *desc;
97 ups = get_ups_ptr(upsname);
99 if (!ups) {
100 send_err(client, NUT_ERR_UNKNOWN_UPS);
101 return;
104 if (!ups_available(ups, client))
105 return;
107 desc = desc_get_cmd(cmd);
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);
116 static void get_type(nut_ctype_t *client, const char *upsname, const char *var)
118 char buf[SMALLBUF];
119 const upstype_t *ups;
120 const st_tree_t *node;
122 ups = get_ups_ptr(upsname);
124 if (!ups) {
125 send_err(client, NUT_ERR_UNKNOWN_UPS);
126 return;
129 if (!ups_available(ups, client))
130 return;
132 node = sstate_getnode(ups, var);
134 if (!node) {
135 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
136 return;
139 snprintf(buf, sizeof(buf), "TYPE %s %s", upsname, var);
141 if (node->flags & ST_FLAG_RW)
142 snprintfcat(buf, sizeof(buf), " RW");
144 if (node->enum_list) {
145 snprintfcat(buf, sizeof(buf), " ENUM");
148 if (node->range_list) {
149 snprintfcat(buf, sizeof(buf), " RANGE");
152 if (node->flags & ST_FLAG_STRING) {
153 sendback(client, "%s STRING:%ld\n", buf, node->aux);
154 return;
157 /* Any variable that is not string | range | enum is just a simple
158 * numeric value */
160 if (!(node->flags & ST_FLAG_NUMBER)) {
161 upsdebugx(3, "%s: assuming that UPS[%s] variable %s which has no type flag is a NUMBER",
162 __func__, upsname, var);
165 sendback(client, "%s NUMBER\n", buf);
168 static void get_var_server(nut_ctype_t *client, const char *upsname, const char *var)
170 #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
171 #pragma GCC diagnostic push
172 #endif
173 #ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
174 #pragma GCC diagnostic ignored "-Wunreachable-code"
175 #endif
176 #ifdef __clang__
177 #pragma clang diagnostic push
178 #pragma clang diagnostic ignored "-Wunreachable-code"
179 #endif
180 int pkgurlHasNutOrg = PACKAGE_URL ? (strstr(PACKAGE_URL, "networkupstools.org") != NULL) : 0;
182 if (!strcasecmp(var, "server.info")) {
183 /* NOTE: Some compilers deduce that macro-based decisions about
184 * NUT_VERSION_IS_RELEASE make one of codepaths unreachable in
185 * a particular build. So we pragmatically handwave this away.
187 sendback(client, "VAR %s server.info "
188 "\"Network UPS Tools upsd %s - "
189 "%s%s%s\"\n",
190 upsname, UPS_VERSION,
191 PACKAGE_URL ? PACKAGE_URL : "",
192 (PACKAGE_URL && !pkgurlHasNutOrg) ? " or " : "",
193 pkgurlHasNutOrg ? "" : "https://www.networkupstools.org/"
195 return;
197 #ifdef __clang__
198 #pragma clang diagnostic pop
199 #endif
200 #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
201 #pragma GCC diagnostic pop
202 #endif
204 if (!strcasecmp(var, "server.version")) {
205 sendback(client, "VAR %s server.version \"%s\"\n",
206 upsname, UPS_VERSION);
207 return;
210 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
213 static void get_var(nut_ctype_t *client, const char *upsname, const char *var)
215 const upstype_t *ups;
216 const char *val;
218 /* ignore upsname for server.* variables */
219 if (!strncasecmp(var, "server.", 7)) {
220 get_var_server(client, upsname, var);
221 return;
224 ups = get_ups_ptr(upsname);
226 if (!ups) {
227 send_err(client, NUT_ERR_UNKNOWN_UPS);
228 return;
231 if (!ups_available(ups, client))
232 return;
234 val = sstate_getinfo(ups, var);
236 if (!val) {
237 send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
238 return;
241 /* handle special case for status */
242 if ((!strcasecmp(var, "ups.status")) && (ups->fsd))
243 sendback(client, "VAR %s %s \"FSD %s\"\n", upsname, var, val);
244 else
245 sendback(client, "VAR %s %s \"%s\"\n", upsname, var, val);
248 void net_get(nut_ctype_t *client, size_t numarg, const char **arg)
250 if (numarg < 1) {
251 send_err(client, NUT_ERR_INVALID_ARGUMENT);
252 return;
255 /* GET TRACKING [ID] */
256 if (!strcasecmp(arg[0], "TRACKING")) {
257 if (numarg < 2) {
258 sendback(client, "%s\n", (client->tracking) ? "ON" : "OFF");
260 else {
261 if (client->tracking)
262 sendback(client, "%s\n", tracking_get(arg[1]));
263 else
264 send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED);
266 return;
269 if (numarg < 2) {
270 send_err(client, NUT_ERR_INVALID_ARGUMENT);
271 return;
274 /* GET NUMLOGINS UPS */
275 if (!strcasecmp(arg[0], "NUMLOGINS")) {
276 get_numlogins(client, arg[1]);
277 return;
280 /* GET UPSDESC UPS */
281 if (!strcasecmp(arg[0], "UPSDESC")) {
282 get_upsdesc(client, arg[1]);
283 return;
286 if (numarg < 3) {
287 send_err(client, NUT_ERR_INVALID_ARGUMENT);
288 return;
291 /* GET VAR UPS VARNAME */
292 if (!strcasecmp(arg[0], "VAR")) {
293 get_var(client, arg[1], arg[2]);
294 return;
297 /* GET TYPE UPS VARNAME */
298 if (!strcasecmp(arg[0], "TYPE")) {
299 get_type(client, arg[1], arg[2]);
300 return;
303 /* GET DESC UPS VARNAME */
304 if (!strcasecmp(arg[0], "DESC")) {
305 get_desc(client, arg[1], arg[2]);
306 return;
309 /* GET CMDDESC UPS CMDNAME */
310 if (!strcasecmp(arg[0], "CMDDESC")) {
311 get_cmddesc(client, arg[1], arg[2]);
312 return;
315 send_err(client, NUT_ERR_INVALID_ARGUMENT);
316 return;