Merge pull request #2680 from masterwishx/work2471-eco_addon
[networkupstools.git] / server / netinstcmd.c
blob00923c41a47f1acc517431eb194bff9c9e69c340
1 /* netinstcmd.c - INSTCMD handler 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"
26 #include "user.h" /* for user_checkinstcmd */
27 #include "neterr.h"
29 #include "netinstcmd.h"
31 static void send_instcmd(nut_ctype_t *client, const char *upsname,
32 const char *cmdname, const char *value, const char *tracking_id)
34 int found, have_tracking_id = 0;
35 upstype_t *ups;
36 const cmdlist_t *ctmp;
37 char sockcmd[SMALLBUF], esc[SMALLBUF];
39 ups = get_ups_ptr(upsname);
41 if (!ups) {
42 send_err(client, NUT_ERR_UNKNOWN_UPS);
43 return;
46 if (!ups_available(ups, client))
47 return;
49 ctmp = sstate_getcmdlist(ups);
51 found = 0;
53 while (ctmp) {
54 if (!strcasecmp(ctmp->name, cmdname)) {
55 found = 1;
56 break;
59 ctmp = ctmp->next;
62 if (!found) {
63 send_err(client, NUT_ERR_CMD_NOT_SUPPORTED);
64 return;
67 /* see if this user is allowed to do this command */
68 if (!user_checkinstcmd(client->username, client->password, cmdname)) {
69 send_err(client, NUT_ERR_ACCESS_DENIED);
70 return;
73 /* Format the base command */
74 snprintf(sockcmd, sizeof(sockcmd), "INSTCMD %s", cmdname);
76 /* see if the user has also passed a value for this command */
77 if (value != NULL)
78 snprintfcat(sockcmd, sizeof(sockcmd), " %s", pconf_encode(value, esc, sizeof(esc)));
80 /* see if the user want execution tracking for this command */
81 if (tracking_id && *tracking_id) {
82 snprintfcat(sockcmd, sizeof(sockcmd), " TRACKING %s", tracking_id);
83 /* Add an entry in the tracking structure */
84 tracking_add(tracking_id);
85 have_tracking_id = 1;
88 /* add EOL */
89 snprintfcat(sockcmd, sizeof(sockcmd), "\n");
91 upslogx(LOG_INFO, "Instant command: %s@%s did %s%s%s on %s (tracking ID: %s)",
92 client->username, client->addr, cmdname,
93 (value != NULL)?" with value ":"",
94 (value != NULL)?value:"",
95 ups->name,
96 (have_tracking_id) ? tracking_id : "disabled");
98 if (!sstate_sendline(ups, sockcmd)) {
99 upslogx(LOG_INFO, "Set command send failed");
100 send_err(client, NUT_ERR_INSTCMD_FAILED);
101 return;
104 /* return the result, possibly including tracking_id */
105 if (have_tracking_id)
106 sendback(client, "OK TRACKING %s\n", tracking_id);
107 else
108 sendback(client, "OK\n");
111 void net_instcmd(nut_ctype_t *client, size_t numarg, const char **arg)
113 const char *devname = NULL;
114 const char *cmdname = NULL;
115 const char *cmdparam = NULL;
116 char tracking_id[UUID4_LEN] = "";
118 if (numarg < 2) {
119 send_err(client, NUT_ERR_INVALID_ARGUMENT);
120 return;
123 /* INSTCMD <ups> <cmdname> [cmdparam] */
124 /* Check arguments */
125 devname = arg[0];
126 cmdname = arg[1];
127 if (numarg == 3)
128 cmdparam = arg[2];
130 if (client->tracking) {
131 /* Generate a tracking ID, if client requested status tracking */
132 nut_uuid_v4(tracking_id);
135 send_instcmd(client, devname, cmdname, cmdparam, tracking_id);
137 return;