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
30 static void get_numlogins(nut_ctype_t
*client
, const char *upsname
)
34 ups
= get_ups_ptr(upsname
);
37 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
41 if (!ups_available(ups
, client
))
44 sendback(client
, "NUMLOGINS %s %d\n", upsname
, ups
->numlogins
);
47 static void get_upsdesc(nut_ctype_t
*client
, const char *upsname
)
52 ups
= get_ups_ptr(upsname
);
55 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
60 pconf_encode(ups
->desc
, esc
, sizeof(esc
));
61 sendback(client
, "UPSDESC %s \"%s\"\n", upsname
, esc
);
65 sendback(client
, "UPSDESC %s \"Unavailable\"\n", upsname
);
69 static void get_desc(nut_ctype_t
*client
, const char *upsname
, const char *var
)
74 ups
= get_ups_ptr(upsname
);
77 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
81 if (!ups_available(ups
, client
))
84 desc
= desc_get_var(var
);
87 sendback(client
, "DESC %s %s \"%s\"\n", upsname
, var
, desc
);
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
)
97 ups
= get_ups_ptr(upsname
);
100 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
104 if (!ups_available(ups
, client
))
107 desc
= desc_get_cmd(cmd
);
110 sendback(client
, "CMDDESC %s %s \"%s\"\n", upsname
, cmd
, desc
);
112 sendback(client
, "CMDDESC %s %s \"Description unavailable\"\n",
116 static void get_type(nut_ctype_t
*client
, const char *upsname
, const char *var
)
119 const upstype_t
*ups
;
120 const st_tree_t
*node
;
122 ups
= get_ups_ptr(upsname
);
125 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
129 if (!ups_available(ups
, client
))
132 node
= sstate_getnode(ups
, var
);
135 send_err(client
, NUT_ERR_VAR_NOT_SUPPORTED
);
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
);
157 /* Any variable that is not string | range | enum is just a simple
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
173 #ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
174 #pragma GCC diagnostic ignored "-Wunreachable-code"
177 #pragma clang diagnostic push
178 #pragma clang diagnostic ignored "-Wunreachable-code"
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 - "
190 upsname
, UPS_VERSION
,
191 PACKAGE_URL
? PACKAGE_URL
: "",
192 (PACKAGE_URL
&& !pkgurlHasNutOrg
) ? " or " : "",
193 pkgurlHasNutOrg
? "" : "https://www.networkupstools.org/"
198 #pragma clang diagnostic pop
200 #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
201 #pragma GCC diagnostic pop
204 if (!strcasecmp(var
, "server.version")) {
205 sendback(client
, "VAR %s server.version \"%s\"\n",
206 upsname
, UPS_VERSION
);
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
;
218 /* ignore upsname for server.* variables */
219 if (!strncasecmp(var
, "server.", 7)) {
220 get_var_server(client
, upsname
, var
);
224 ups
= get_ups_ptr(upsname
);
227 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
231 if (!ups_available(ups
, client
))
234 val
= sstate_getinfo(ups
, var
);
237 send_err(client
, NUT_ERR_VAR_NOT_SUPPORTED
);
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
);
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
)
251 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
255 /* GET TRACKING [ID] */
256 if (!strcasecmp(arg
[0], "TRACKING")) {
258 sendback(client
, "%s\n", (client
->tracking
) ? "ON" : "OFF");
261 if (client
->tracking
)
262 sendback(client
, "%s\n", tracking_get(arg
[1]));
264 send_err(client
, NUT_ERR_FEATURE_NOT_CONFIGURED
);
270 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
274 /* GET NUMLOGINS UPS */
275 if (!strcasecmp(arg
[0], "NUMLOGINS")) {
276 get_numlogins(client
, arg
[1]);
280 /* GET UPSDESC UPS */
281 if (!strcasecmp(arg
[0], "UPSDESC")) {
282 get_upsdesc(client
, arg
[1]);
287 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
291 /* GET VAR UPS VARNAME */
292 if (!strcasecmp(arg
[0], "VAR")) {
293 get_var(client
, arg
[1], arg
[2]);
297 /* GET TYPE UPS VARNAME */
298 if (!strcasecmp(arg
[0], "TYPE")) {
299 get_type(client
, arg
[1], arg
[2]);
303 /* GET DESC UPS VARNAME */
304 if (!strcasecmp(arg
[0], "DESC")) {
305 get_desc(client
, arg
[1], arg
[2]);
309 /* GET CMDDESC UPS CMDNAME */
310 if (!strcasecmp(arg
[0], "CMDDESC")) {
311 get_cmddesc(client
, arg
[1], arg
[2]);
315 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);