1 /* netlist.c - LIST handlers for upsd
4 2003 Russell Kroll <rkroll@exploits.org>
5 2012 Arnaud Quette <arnaud.quette@free.fr>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 extern upstype_t
*firstups
; /* for list_ups */
32 extern nut_ctype_t
*firstclient
; /* for list_clients */
34 static int tree_dump(st_tree_t
*node
, nut_ctype_t
*client
, const char *ups
,
40 return 1; /* not an error */
43 ret
= tree_dump(node
->left
, client
, ups
, rw
, fsd
);
46 return 0; /* write failed in child */
51 /* only send this back if it's been flagged RW */
52 if (node
->flags
& ST_FLAG_RW
) {
53 ret
= sendback(client
, "RW %s %s \"%s\"\n",
54 ups
, node
->var
, node
->val
);
62 /* normal variable list only */
64 /* status is always a special case */
65 if ((fsd
== 1) && (!strcasecmp(node
->var
, "ups.status"))) {
66 ret
= sendback(client
, "VAR %s %s \"FSD %s\"\n",
67 ups
, node
->var
, node
->val
);
70 ret
= sendback(client
, "VAR %s %s \"%s\"\n",
71 ups
, node
->var
, node
->val
);
79 return tree_dump(node
->right
, client
, ups
, rw
, fsd
);
84 static void list_rw(nut_ctype_t
*client
, const char *upsname
)
88 ups
= get_ups_ptr(upsname
);
91 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
95 if (!ups_available(ups
, client
))
98 if (!sendback(client
, "BEGIN LIST RW %s\n", upsname
))
101 if (!tree_dump(ups
->inforoot
, client
, upsname
, 1, ups
->fsd
))
104 sendback(client
, "END LIST RW %s\n", upsname
);
107 static void list_var(nut_ctype_t
*client
, const char *upsname
)
109 const upstype_t
*ups
;
111 ups
= get_ups_ptr(upsname
);
114 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
118 if (!ups_available(ups
, client
))
121 if (!sendback(client
, "BEGIN LIST VAR %s\n", upsname
))
124 if (!tree_dump(ups
->inforoot
, client
, upsname
, 0, ups
->fsd
))
127 sendback(client
, "END LIST VAR %s\n", upsname
);
130 static void list_cmd(nut_ctype_t
*client
, const char *upsname
)
132 const upstype_t
*ups
;
135 ups
= get_ups_ptr(upsname
);
138 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
142 if (!ups_available(ups
, client
))
145 if (!sendback(client
, "BEGIN LIST CMD %s\n", upsname
))
148 for (ctmp
= ups
->cmdlist
; ctmp
!= NULL
; ctmp
= ctmp
->next
) {
149 if (!sendback(client
, "CMD %s %s\n", upsname
, ctmp
->name
))
153 sendback(client
, "END LIST CMD %s\n", upsname
);
156 static void list_enum(nut_ctype_t
*client
, const char *upsname
, const char *var
)
158 const upstype_t
*ups
;
159 const st_tree_t
*node
;
162 ups
= get_ups_ptr(upsname
);
165 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
169 if (!ups_available(ups
, client
))
172 node
= sstate_getnode(ups
, var
);
175 send_err(client
, NUT_ERR_VAR_NOT_SUPPORTED
);
179 if (!sendback(client
, "BEGIN LIST ENUM %s %s\n", upsname
, var
))
182 for (etmp
= node
->enum_list
; etmp
!= NULL
; etmp
= etmp
->next
) {
183 if (!sendback(client
, "ENUM %s %s \"%s\"\n",
184 upsname
, var
, etmp
->val
))
188 sendback(client
, "END LIST ENUM %s %s\n", upsname
, var
);
191 static void list_range(nut_ctype_t
*client
, const char *upsname
, const char *var
)
193 const upstype_t
*ups
;
194 const st_tree_t
*node
;
197 ups
= get_ups_ptr(upsname
);
200 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
204 if (!ups_available(ups
, client
))
207 node
= sstate_getnode(ups
, var
);
210 send_err(client
, NUT_ERR_VAR_NOT_SUPPORTED
);
214 if (!sendback(client
, "BEGIN LIST RANGE %s %s\n", upsname
, var
))
217 for (rtmp
= node
->range_list
; rtmp
!= NULL
; rtmp
= rtmp
->next
) {
218 if (!sendback(client
, "RANGE %s %s \"%i\" \"%i\"\n",
219 upsname
, var
, rtmp
->min
, rtmp
->max
))
223 sendback(client
, "END LIST RANGE %s %s\n", upsname
, var
);
226 static void list_ups(nut_ctype_t
*client
)
231 if (!sendback(client
, "BEGIN LIST UPS\n"))
240 pconf_encode(utmp
->desc
, esc
, sizeof(esc
));
241 ret
= sendback(client
, "UPS %s \"%s\"\n",
245 ret
= sendback(client
, "UPS %s \"Description unavailable\"\n",
255 sendback(client
, "END LIST UPS\n");
258 static void list_clients(nut_ctype_t
*client
, const char *upsname
)
260 const upstype_t
*ups
;
261 nut_ctype_t
*c
, *cnext
;
263 ups
= get_ups_ptr(upsname
);
266 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
270 if (!sendback(client
, "BEGIN LIST CLIENT %s\n", upsname
))
275 /* show connected clients */
276 for (c
= firstclient
; c
; c
= cnext
) {
277 if (c
->loginups
&& (!ups
|| !strcasecmp(c
->loginups
, ups
->name
))) {
278 ret
= sendback(client
, "CLIENT %s %s\n", c
->loginups
, c
->addr
);
285 sendback(client
, "END LIST CLIENT %s\n", upsname
);
288 void net_list(nut_ctype_t
*client
, size_t numarg
, const char **arg
)
291 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
296 if (!strcasecmp(arg
[0], "UPS")) {
302 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
307 if (!strcasecmp(arg
[0], "VAR")) {
308 list_var(client
, arg
[1]);
313 if (!strcasecmp(arg
[0], "RW")) {
314 list_rw(client
, arg
[1]);
319 if (!strcasecmp(arg
[0], "CMD")) {
320 list_cmd(client
, arg
[1]);
324 /* LIST CLIENT UPS */
325 if (!strcasecmp(arg
[0], "CLIENT")) {
326 list_clients(client
, arg
[1]);
331 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
335 /* LIST ENUM UPS VARNAME */
336 if (!strcasecmp(arg
[0], "ENUM")) {
337 list_enum(client
, arg
[1], arg
[2]);
341 /* LIST RANGE UPS VARNAME */
342 if (!strcasecmp(arg
[0], "RANGE")) {
343 list_range(client
, arg
[1], arg
[2]);
347 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);