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
26 #include "user.h" /* for user_checkinstcmd */
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;
36 const cmdlist_t
*ctmp
;
37 char sockcmd
[SMALLBUF
], esc
[SMALLBUF
];
39 ups
= get_ups_ptr(upsname
);
42 send_err(client
, NUT_ERR_UNKNOWN_UPS
);
46 if (!ups_available(ups
, client
))
49 ctmp
= sstate_getcmdlist(ups
);
54 if (!strcasecmp(ctmp
->name
, cmdname
)) {
63 send_err(client
, NUT_ERR_CMD_NOT_SUPPORTED
);
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
);
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 */
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
);
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
:"",
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
);
104 /* return the result, possibly including tracking_id */
105 if (have_tracking_id
)
106 sendback(client
, "OK TRACKING %s\n", tracking_id
);
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
] = "";
119 send_err(client
, NUT_ERR_INVALID_ARGUMENT
);
123 /* INSTCMD <ups> <cmdname> [cmdparam] */
124 /* Check arguments */
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
);