diff --git a/clients/Makefile.am b/clients/Makefile.am index 7f0c7d8363..53e1d55361 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -53,7 +53,7 @@ endif # libupsclient version information # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -libupsclient_la_LDFLAGS = -version-info 4:0:0 +libupsclient_la_LDFLAGS = -version-info 5:0:0 # libnutclient version information libnutclient_la_SOURCES = nutclient.h nutclient.cpp diff --git a/clients/upsclient.c b/clients/upsclient.c index bbd7f47c6e..dd4c9486ae 100644 --- a/clients/upsclient.c +++ b/clients/upsclient.c @@ -1416,7 +1416,7 @@ int upscli_readline_timeout(UPSCONN_t *ups, char *buf, size_t buflen, unsigned i int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen) { - return upscli_readline_timeout(ups, buf, buflen, DEFAULT_TIMEOUT); + return upscli_readline_timeout(ups, buf, buflen, DEFAULT_NETWORK_TIMEOUT); } /* split upsname[@hostname[:port]] into separate components */ diff --git a/clients/upscmd.c b/clients/upscmd.c index cc500884cb..f8e237d429 100644 --- a/clients/upscmd.c +++ b/clients/upscmd.c @@ -32,8 +32,8 @@ static char *upsname = NULL, *hostname = NULL; static UPSCONN_t *ups = NULL; -static int status_info = 0; -static unsigned int timeout = 10; +static int tracking_enabled = 0; +static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT; struct list_t { char *name; @@ -54,7 +54,7 @@ static void usage(const char *prog) printf(" -p set password for command authentication\n"); printf(" -w wait for the completion of command by the driver\n"); printf(" and return its actual result from the device\n"); - printf(" -t set a timeout when using -w (in seconds, default \"10\")\n"); + printf(" -t set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT); printf("\n"); printf(" UPS identifier - [@[:]]\n"); printf(" Valid instant command - test.panel.start, etc.\n"); @@ -147,7 +147,7 @@ static void do_cmd(char **argv, const int argc) { int cmd_complete = 0; char buf[SMALLBUF]; - char status_id[UUID4_LEN]; + char tracking_id[UUID4_LEN]; time_t start, now; if (argc > 1) { @@ -171,16 +171,16 @@ static void do_cmd(char **argv, const int argc) /* check for status tracking id */ if ( - !status_info || - /* sanity check on the size: "OK " + UUID4_LEN */ - strlen(buf) != UUID4_LEN + 2 + !tracking_enabled || + /* sanity check on the size: "OK TRACKING " + UUID4_LEN */ + strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING ")) ) { /* reply as usual */ fprintf(stderr, "%s\n", buf); return; } - snprintf(status_id, sizeof(status_id), "%s", buf + 3); + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")); time(&start); /* send status tracking request, looping if status is PENDING */ @@ -191,7 +191,7 @@ static void do_cmd(char **argv, const int argc) if (difftime(now, start) >= timeout) fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout"); - snprintf(buf, sizeof(buf), "GET CMDSET_STATUS %s\n", status_id); + snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id); if (upscli_sendline(ups, buf, strlen(buf)) < 0) fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups)); @@ -252,7 +252,7 @@ int main(int argc, char **argv) break; case 'w': - status_info = 1; + tracking_enabled = 1; break; case 'V': @@ -371,9 +371,9 @@ int main(int argc, char **argv) } /* enable status tracking ID */ - if (status_info) { + if (tracking_enabled) { - snprintf(buf, sizeof(buf), "SET CMDSET_STATUS ON\n"); + snprintf(buf, sizeof(buf), "SET TRACKING ON\n"); if (upscli_sendline(ups, buf, strlen(buf)) < 0) { fatalx(EXIT_FAILURE, "Can't enable command status tracking: %s", upscli_strerror(ups)); diff --git a/clients/upsrw.c b/clients/upsrw.c index 018ff00e64..0d1906de51 100644 --- a/clients/upsrw.c +++ b/clients/upsrw.c @@ -32,8 +32,8 @@ static char *upsname = NULL, *hostname = NULL; static UPSCONN_t *ups = NULL; -static int status_info = 0; -static unsigned int timeout = 10; +static int tracking_enabled = 0; +static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT; struct list_t { char *name; @@ -54,7 +54,7 @@ static void usage(const char *prog) printf(" -p set password for command authentication\n"); printf(" -w wait for the completion of setting by the driver\n"); printf(" and return its actual result from the device\n"); - printf(" -t set a timeout when using -w (in seconds, default \"10\")\n"); + printf(" -t set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT); printf("\n"); printf(" UPS identifier - [@[:]]\n"); printf("\n"); @@ -76,7 +76,7 @@ static void do_set(const char *varname, const char *newval) { int cmd_complete = 0; char buf[SMALLBUF], enc[SMALLBUF]; - char status_id[UUID4_LEN]; + char tracking_id[UUID4_LEN]; time_t start, now; snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n", upsname, varname, pconf_encode(newval, enc, sizeof(enc))); @@ -96,16 +96,16 @@ static void do_set(const char *varname, const char *newval) /* check for status tracking id */ if ( - !status_info || - /* sanity check on the size: "OK " + UUID4_LEN */ - strlen(buf) != UUID4_LEN + 2 + !tracking_enabled || + /* sanity check on the size: "OK TRACKING " + UUID4_LEN */ + strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING ")) ) { /* reply as usual */ fprintf(stderr, "%s\n", buf); return; } - snprintf(status_id, sizeof(status_id), "%s", buf + 3); + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")); time(&start); /* send status tracking request, looping if status is PENDING */ @@ -116,7 +116,7 @@ static void do_set(const char *varname, const char *newval) if (difftime(now, start) >= timeout) fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout"); - snprintf(buf, sizeof(buf), "GET CMDSET_STATUS %s\n", status_id); + snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id); if (upscli_sendline(ups, buf, strlen(buf)) < 0) fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups)); @@ -227,9 +227,9 @@ static void do_setvar(const char *varname, char *uin, const char *pass) } /* enable status tracking ID */ - if (status_info) { + if (tracking_enabled) { - snprintf(temp, sizeof(temp), "SET CMDSET_STATUS ON\n"); + snprintf(temp, sizeof(temp), "SET TRACKING ON\n"); if (upscli_sendline(ups, temp, strlen(temp)) < 0) { fatalx(EXIT_FAILURE, "Can't enable set variable status tracking: %s", upscli_strerror(ups)); @@ -603,7 +603,7 @@ int main(int argc, char **argv) username = optarg; break; case 'w': - status_info = 1; + tracking_enabled = 1; break; case 'V': printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); diff --git a/conf/upsd.conf.sample b/conf/upsd.conf.sample index dbf0ad6cb6..5cb94062ce 100644 --- a/conf/upsd.conf.sample +++ b/conf/upsd.conf.sample @@ -22,8 +22,8 @@ # for notifications from upsd about staleness. # ======================================================================= -# CMDSETSTATUSDELAY -# CMDSETSTATUSDELAY 3600 +# TRACKINGDELAY +# TRACKINGDELAY 3600 # # This defaults to 1 hour. When instant commands and variables setting status # tracking is enabled, status execution information are kept during this diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index 0c0646bcd6..fef33f6db0 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -252,7 +252,9 @@ MAN3_DEV_PAGES = \ upscli_list_next.3 \ upscli_list_start.3 \ upscli_readline.3 \ + upscli_readline_timeout.3 \ upscli_sendline.3 \ + upscli_sendline_timeout.3 \ upscli_splitaddr.3 \ upscli_splitname.3 \ upscli_ssl.3 \ @@ -289,6 +291,12 @@ MAN3_DEV_PAGES = \ nutscan_get_serial_ports_list.3 \ nutscan_init.3 +upscli_readline_timeout.3: upscli_readline.3 + touch $@ + +upscli_sendline_timeout.3: upscli_sendline.3 + touch $@ + MAN1_DEV_PAGES = \ libupsclient-config.1 endif diff --git a/docs/man/upscli_readline.txt b/docs/man/upscli_readline.txt index 52106ade43..2d96240614 100644 --- a/docs/man/upscli_readline.txt +++ b/docs/man/upscli_readline.txt @@ -4,7 +4,7 @@ UPSCLI_READLINE(3) NAME ---- -upscli_readline - read a single response from a UPS +upscli_readline, upscli_readline_timeout - read a single response from a UPS SYNOPSIS -------- @@ -12,23 +12,28 @@ SYNOPSIS #include int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen); + int upscli_readline_timeout(UPSCONN_t *ups, char *buf, size_t buflen, unsigned int timeout); DESCRIPTION ----------- -The *upscli_readline()* function takes the pointer 'ups' to a -`UPSCONN_t` state structure, receives a single line from the server, and -copies up to 'buflen' bytes of the response into the buffer -'buf'. +The *upscli_readline()* and *upscli_readline_timeout()* functions take the +pointer 'ups' to a `UPSCONN_t` state structure, receive a single line from the +server, and copy up to 'buflen' bytes of the response into the buffer 'buf'. Some parsing of the string occurs during reception. In particular, ERR messages from linkman:upsd[8] are detected and will cause this function to return -1. +The difference between the two functions is that *upscli_readline_timeout()* +let the caller decide the amount of time ('timeout' seconds) after which it +should give up and return, whereas *upscli_readline()* does not offer this +freedom. + RETURN VALUE ------------ -The *upscli_readline()* function returns 0 on success, or -1 if an -error occurs. +The *upscli_readline()* and *upscli_readline_timeout()* functions return 0 on +success, or -1 if an error occurs. SEE ALSO -------- diff --git a/docs/man/upscli_sendline.txt b/docs/man/upscli_sendline.txt index c449c6dd5d..e5ce332c25 100644 --- a/docs/man/upscli_sendline.txt +++ b/docs/man/upscli_sendline.txt @@ -4,7 +4,7 @@ UPSCLI_SENDLINE(3) NAME ---- -upscli_sendline - send a single command to a UPS +upscli_sendline, upscli_sendline_timeout - send a single command to a UPS SYNOPSIS -------- @@ -13,22 +13,28 @@ SYNOPSIS #include int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen); + int upscli_sendline_timeout(UPSCONN_t *ups, const char *buf, size_t buflen, unsigned int timeout); DESCRIPTION ----------- -The *upscli_sendline()* function takes the pointer 'ups' to a -`UPSCONN_t` state structure and transmits a buffer 'buf' of size -'buflen' to the server. +The *upscli_sendline()* and *upscli_sendline_timeout()* functions take the +pointer 'ups' to a `UPSCONN_t` state structure and transmit a buffer 'buf' of +size 'buflen' to the server. The data in 'buf' must be a fully formatted protocol command as no parsing of the buffer occurs within this function. +The difference between the two functions is that *upscli_sendline_timeout()* +let the caller decide the amount of time ('timeout' seconds) after which it +should give up and return, whereas *upscli_sendline()* does not offer this +freedom. + RETURN VALUE ------------ -The *upscli_sendline()* function returns 0 on success, or -1 if an -error occurs. +The *upscli_sendline()* and *upscli_sendline_timeout()* functions return 0 on +success, or -1 if an error occurs. SEE ALSO -------- diff --git a/docs/man/upscmd.txt b/docs/man/upscmd.txt index 7bf2aee76d..78c4d0e7f5 100644 --- a/docs/man/upscmd.txt +++ b/docs/man/upscmd.txt @@ -45,7 +45,7 @@ like -u, and you will be prompted for it if necessary. *-w*:: Wait for the completion of command execution by the driver and return its actual result from the device. Note that this feature requires that upsd -supports CMDSET_STATUS (NUT version 2.7.5 or higher) or it will otherwise fail. +supports TRACKING (NUT version 2.7.5 or higher) or it will otherwise fail. The command will also block until an actual result is provided from the driver, or the timeout is reached (see *-t*). diff --git a/docs/man/upsd.conf.txt b/docs/man/upsd.conf.txt index 7af58b0c79..5947792f20 100644 --- a/docs/man/upsd.conf.txt +++ b/docs/man/upsd.conf.txt @@ -26,7 +26,7 @@ to make upsd wait longer. + Most users should leave this at the default value. -"CMDSETSTATUSDELAY 'seconds'":: +"TRACKINGDELAY 'seconds'":: When instant commands and variables setting status tracking is enabled, status execution information are kept during this amount of time, and then cleaned up. diff --git a/docs/man/upsrw.txt b/docs/man/upsrw.txt index cb9c3c9c4d..8271dad182 100644 --- a/docs/man/upsrw.txt +++ b/docs/man/upsrw.txt @@ -61,7 +61,7 @@ like -u, and you will be prompted for it if necessary. *-w*:: Wait for the completion of setting execution by the driver and return its actual result from the device. Note that this feature requires that upsd -supports CMDSET_STATUS (NUT version 2.7.5 or higher) or it will otherwise fail. +supports TRACKING (NUT version 2.7.5 or higher) or it will otherwise fail. The command will also block until an actual result is provided from the driver, or the timeout is reached (see *-t*). diff --git a/docs/net-protocol.txt b/docs/net-protocol.txt index 148ebc9561..91c62dbdc4 100644 --- a/docs/net-protocol.txt +++ b/docs/net-protocol.txt @@ -45,7 +45,7 @@ NUT network protocol, over the time: .2+|1.2 .2+|>= 2.6.4 |Add "LIST CLIENTS" and "NETVER" commands |Add ranges of values for writable variables .2+|1.3 .2+|>= 2.7.5 |Add "cmdparam" to "INSTCMD" - |Add "CMDSET_STATUS" commands (GET, SET) + |Add "TRACKING" commands (GET, SET) |=============================================================================== NOTE: any new version of the protocol implies an update of NUT_NETVERSION @@ -191,19 +191,19 @@ This is like DESC above, but it applies to the instant commands. This replaces the old "INSTCMDDESC" command. -CMDSET_STATUS -~~~~~~~~~~~~~ +TRACKING +~~~~~~~~ Form: - GET CMDSET_STATUS (activation status of CMDSET_STATUS) - GET CMDSET_STATUS (execution status of a command / setvar) - GET CMDSET_STATUS 1bd31808-cb49-4aec-9d75-d056e6f018d2 + GET TRACKING (activation status of TRACKING) + GET TRACKING (execution status of a command / setvar) + GET TRACKING 1bd31808-cb49-4aec-9d75-d056e6f018d2 Response: - ON (CMDSET_STATUS feature is enabled) - OFF (CMDSET_STATUS feature is disabled) + ON (TRACKING feature is enabled) + OFF (TRACKING feature is disabled) PENDING (command execution is pending) SUCCESS (command was successfully executed) ERR UNKNOWN (command execution failed with unknown error) @@ -409,19 +409,19 @@ Form: Response: - OK (if CMDSET_STATUS is not enabled) - OK (if CMDSET_STATUS is enabled) + OK (if TRACKING is not enabled) + OK TRACKING (if TRACKING is enabled) ERR [...] (see Error responses) -CMDSET_STATUS -~~~~~~~~~~~~~ +TRACKING +~~~~~~~~ Form: - SET CMDSET_STATUS - SET CMDSET_STATUS ON - SET CMDSET_STATUS OFF + SET TRACKING + SET TRACKING ON + SET TRACKING OFF Response: @@ -444,8 +444,8 @@ NOTE: is an additional and optional parameter for the command. Response: - OK (if CMDSET_STATUS is not enabled) - OK (if CMDSET_STATUS is enabled) + OK (if TRACKING is not enabled) + OK TRACKING (if TRACKING is enabled) ERR [...] (see Error responses) diff --git a/docs/nut.dict b/docs/nut.dict index c8a6660e22..e2d886829e 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 2439 utf-8 +personal_ws-1.1 en 2438 utf-8 AAS ACFAIL ACFREQ @@ -151,8 +151,6 @@ CLI CLOCAL CMDDESC CMDSCRIPT -CMDSET -CMDSETSTATUSDELAY CN COMLI COMMBAD @@ -1004,6 +1002,7 @@ TIOCMBIC TIOCMBIS TLS TODO +TRACKINGDELAY TRYSSL TSR TST diff --git a/docs/sock-protocol.txt b/docs/sock-protocol.txt index b56a9a4955..f951aae6d0 100644 --- a/docs/sock-protocol.txt +++ b/docs/sock-protocol.txt @@ -146,16 +146,16 @@ status information once this has been sent. This will be sent in the beginning of a dump if the data is stale, and may be repeated. It is cleared by DATAOK. -CMDSET_STATUS -~~~~~~~~~~~~~ +TRACKING +~~~~~~~~ - CMDSET_STATUS + TRACKING -This is sent in response to an INSTCMD or SET VAR that includes a STATUS_ID, +This is sent in response to an INSTCMD or SET VAR that includes a TRACKING, upon completion of request execution by the driver. is the integer return value from the driver handlers instcmd and setvar (see drivers/upshandler.h). The server is in charge of translating these codes into -strings, as per docs/net-protocol.txt GET CMDSET_STATUS. +strings, as per docs/net-protocol.txt GET TRACKING. Commands sent by the server @@ -178,30 +178,30 @@ server must not be passed on to the clients when this happens. INSTCMD ~~~~~~~ - INSTCMD [] [STATUS_ID ] + INSTCMD [] [TRACKING ] INSTCMD panel.test.start INSTCMD load.off 10 - INSTCMD load.on 10 STATUS_ID 1bd31808-cb49-4aec-9d75-d056e6f018d2 + INSTCMD load.on 10 TRACKING 1bd31808-cb49-4aec-9d75-d056e6f018d2 NOTE: * is an additional and optional parameter for the command, -* "STATUS_ID " can be provided to track commands execution status, if -CMDSET_STATUS was set to ON on upsd. In this case, driver will later return -the execution status, using CMDSET_STATUS. +* "TRACKING " can be provided to track commands execution status, if +TRACKING was set to ON on upsd. In this case, driver will later return +the execution status, using TRACKING. SET ~~~ - SET "" [STATUS_ID ] + SET "" [TRACKING ] SET ups.id "Data room" - SET ups.id "Data room" STATUS_ID 2dedb58a-3b91-4fab-831f-c8af4b90760a + SET ups.id "Data room" TRACKING 2dedb58a-3b91-4fab-831f-c8af4b90760a NOTE: -* "STATUS_ID " can be provided to track commands execution status, if -CMDSET_STATUS was set to ON on upsd. In this case, driver will later return -the execution status, using CMDSET_STATUS. +* "TRACKING " can be provided to track commands execution status, if +TRACKING was set to ON on upsd. In this case, driver will later return +the execution status, using TRACKING. DUMPALL ~~~~~~~ diff --git a/drivers/dstate.c b/drivers/dstate.c index 6e89d3a69b..51e41a052a 100644 --- a/drivers/dstate.c +++ b/drivers/dstate.c @@ -358,9 +358,9 @@ static int cmd_dump_conn(conn_t *conn) } -static void send_cmdset_status(conn_t *conn, const char *id, int value) +static void send_tracking(conn_t *conn, const char *id, int value) { - send_to_one(conn, "CMDSET_STATUS %s %i\n", id, value); + send_to_one(conn, "TRACKING %s %i\n", id, value); } static int sock_arg(conn_t *conn, int numarg, char **arg) @@ -401,19 +401,19 @@ static int sock_arg(conn_t *conn, int numarg, char **arg) return 0; } - /* INSTCMD [] [STATUS_ID ] */ + /* INSTCMD [] [TRACKING ] */ if (!strcasecmp(arg[0], "INSTCMD")) { int ret; char *cmdname = arg[1]; char *cmdparam = NULL; char *cmdid = NULL; - /* Check if and STATUS_ID were provided */ + /* Check if and TRACKING were provided */ if (numarg == 3) { cmdparam = arg[2]; - } else if (numarg == 4 && !strcasecmp(arg[2], "STATUS_ID")) { + } else if (numarg == 4 && !strcasecmp(arg[2], "TRACKING")) { cmdid = arg[3]; - } else if (numarg == 5 && !strcasecmp(arg[3], "STATUS_ID")) { + } else if (numarg == 5 && !strcasecmp(arg[3], "TRACKING")) { cmdparam = arg[2]; cmdid = arg[4]; } else if (numarg != 2) { @@ -422,7 +422,7 @@ static int sock_arg(conn_t *conn, int numarg, char **arg) } if (cmdid) - upsdebugx(3, "%s: STATUS_ID = %s", __func__, cmdid); + upsdebugx(3, "%s: TRACKING = %s", __func__, cmdid); /* try the new handler first if present */ if (upsh.instcmd) { @@ -430,7 +430,7 @@ static int sock_arg(conn_t *conn, int numarg, char **arg) /* send back execution result */ if (cmdid) - send_cmdset_status(conn, cmdid, ret); + send_tracking(conn, cmdid, ret); /* The command was handled, status is a separate consideration */ return 1; @@ -443,22 +443,22 @@ static int sock_arg(conn_t *conn, int numarg, char **arg) return 0; } - /* SET [STATUS_ID ] */ + /* SET [TRACKING ] */ if (!strcasecmp(arg[0], "SET")) { int ret; - char *cmdid = NULL; + char *setid = NULL; - /* Check if STATUS_ID was provided */ + /* Check if TRACKING was provided */ if (numarg == 5) { - if (!strcasecmp(arg[3], "STATUS_ID")) { - cmdid = arg[4]; + if (!strcasecmp(arg[3], "TRACKING")) { + setid = arg[4]; } else { upslogx(LOG_NOTICE, "Got SET with unsupported parameters (%s/%s)", arg[3], arg[4]); return 0; } - upsdebugx(3, "%s: STATUS_ID = %s", __func__, cmdid); + upsdebugx(3, "%s: TRACKING = %s", __func__, setid); } /* try the new handler first if present */ @@ -466,8 +466,8 @@ static int sock_arg(conn_t *conn, int numarg, char **arg) ret = upsh.setvar(arg[1], arg[2]); /* send back execution result */ - if (cmdid) - send_cmdset_status(conn, cmdid, ret); + if (setid) + send_tracking(conn, setid, ret); /* The command was handled, status is a separate consideration */ return 1; diff --git a/include/common.h b/include/common.h index 43aaf40879..4f99e13ec5 100644 --- a/include/common.h +++ b/include/common.h @@ -53,8 +53,11 @@ extern "C" { extern const char *UPS_VERSION; -/** @brief Default timeout (in seconds), as used by upsclient and nut-scanner. */ -#define DEFAULT_TIMEOUT 5 +/** @brief Default timeout (in seconds) for network opereations, as used by `upsclient` and `nut-scanner`. */ +#define DEFAULT_NETWORK_TIMEOUT 5 + +/** @brief Default timeout (in seconds) for retrieving the result of a `TRACKING`-enabled operation (e.g. `INSTCMD`, `SET VAR`). */ +#define DEFAULT_TRACKING_TIMEOUT 10 /* get the syslog ready for us */ void open_syslog(const char *progname); diff --git a/scripts/augeas/nutupsdconf.aug.in b/scripts/augeas/nutupsdconf.aug.in index 4a5c2ff65d..4c200039e8 100644 --- a/scripts/augeas/nutupsdconf.aug.in +++ b/scripts/augeas/nutupsdconf.aug.in @@ -39,7 +39,7 @@ let comment = Util.comment let path = word let upsd_maxage = [ opt_spc . key "MAXAGE" . sep_spc . store num . eol ] -let upsd_cmdsetstatusdelay = [ opt_spc . key "CMDSETSTATUSDELAY" . sep_spc . store num . eol ] +let upsd_trackingdelay = [ opt_spc . key "TRACKINGDELAY" . sep_spc . store num . eol ] let upsd_statepath = [ opt_spc . key "STATEPATH" . sep_spc . store path . eol ] let upsd_listen = [ opt_spc . key "LISTEN" . sep_spc . [ label "interface" . store ip ] @@ -50,14 +50,14 @@ let upsd_certfile = [ opt_spc . key "CERTFILE" . sep_spc . store path . eol ] (************************************************************************ * MAXAGE seconds - * CMDSETSTATUSDELAY seconds + * TRACKINGDELAY seconds * STATEPATH path * LISTEN interface port * Multiple LISTEN addresses may be specified. The default is to bind to 0.0.0.0 if no LISTEN addresses are specified. * LISTEN 127.0.0.1 LISTEN 192.168.50.1 LISTEN ::1 LISTEN 2001:0db8:1234:08d3:1319:8a2e:0370:7344 * *************************************************************************) -let upsd_other = upsd_maxage | upsd_cmdsetstatusdelay | upsd_statepath | upsd_listen_list | upsd_maxconn | upsd_certfile +let upsd_other = upsd_maxage | upsd_trackingdelay | upsd_statepath | upsd_listen_list | upsd_maxconn | upsd_certfile let upsd_lns = (upsd_other|comment|empty)* diff --git a/scripts/augeas/tests/test_nut.aug b/scripts/augeas/tests/test_nut.aug index f5ad7d3fc1..eb79b07bd3 100644 --- a/scripts/augeas/tests/test_nut.aug +++ b/scripts/augeas/tests/test_nut.aug @@ -27,7 +27,7 @@ test NutUpsConf.ups_lns get ups_conf = let upsd_conf = " MAXAGE 30 -CMDSETSTATUSDELAY 600 +TRACKINGDELAY 600 LISTEN 0.0.0.0 3493 MAXCONN 1024 " @@ -35,7 +35,7 @@ MAXCONN 1024 test NutUpsdConf.upsd_lns get upsd_conf = { } { "MAXAGE" = "30" } - { "CMDSETSTATUSDELAY" = "600" } + { "TRACKINGDELAY" = "600" } { "LISTEN" { "interface" = "0.0.0.0" } { "port" = "3493" } } diff --git a/server/conf.c b/server/conf.c index c62a372517..75723d141b 100644 --- a/server/conf.c +++ b/server/conf.c @@ -125,9 +125,9 @@ static int parse_upsd_conf_args(int numargs, char **arg) return 1; } - /* CMDSETSTATUSDELAY */ - if (!strcmp(arg[0], "CMDSETSTATUSDELAY")) { - cmdset_status_delay = atoi(arg[1]); + /* TRACKINGDELAY */ + if (!strcmp(arg[0], "TRACKINGDELAY")) { + tracking_delay = atoi(arg[1]); return 1; } diff --git a/server/netget.c b/server/netget.c index cccbb1fdcb..55a27a429c 100644 --- a/server/netget.c +++ b/server/netget.c @@ -221,14 +221,14 @@ void net_get(nut_ctype_t *client, int numarg, const char **arg) return; } - /* GET CMDSET_STATUS [STATUS_ID] */ - if (!strcasecmp(arg[0], "CMDSET_STATUS")) { + /* GET TRACKING [ID] */ + if (!strcasecmp(arg[0], "TRACKING")) { if (numarg < 2) { - sendback(client, "%s\n", (client->cmdset_status_enabled)?"ON":"OFF"); + sendback(client, "%s\n", (client->tracking) ? "ON" : "OFF"); } else { - if (client->cmdset_status_enabled) - sendback(client, "%s\n", cmdset_status_get(arg[1])); + if (client->tracking) + sendback(client, "%s\n", tracking_get(arg[1])); else send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED); } diff --git a/server/netinstcmd.c b/server/netinstcmd.c index f32d9c58e0..3c4ccc8212 100644 --- a/server/netinstcmd.c +++ b/server/netinstcmd.c @@ -29,9 +29,9 @@ #include "netinstcmd.h" static void send_instcmd(nut_ctype_t *client, const char *upsname, - const char *cmdname, const char *value, const char *status_id) + const char *cmdname, const char *value, const char *tracking_id) { - int found, have_status_id = 0; + int found, have_tracking_id = 0; upstype_t *ups; const cmdlist_t *ctmp; char sockcmd[SMALLBUF], esc[SMALLBUF]; @@ -78,11 +78,11 @@ static void send_instcmd(nut_ctype_t *client, const char *upsname, snprintfcat(sockcmd, sizeof(sockcmd), " %s", pconf_encode(value, esc, sizeof(esc))); /* see if the user want execution tracking for this command */ - if (status_id && *status_id) { - snprintfcat(sockcmd, sizeof(sockcmd), " STATUS_ID %s", status_id); + if (tracking_id && *tracking_id) { + snprintfcat(sockcmd, sizeof(sockcmd), " TRACKING %s", tracking_id); /* Add an entry in the tracking structure */ - cmdset_status_add(status_id); - have_status_id = 1; + tracking_add(tracking_id); + have_tracking_id = 1; } /* add EOL */ @@ -93,7 +93,7 @@ static void send_instcmd(nut_ctype_t *client, const char *upsname, (value != NULL)?" with value ":"", (value != NULL)?value:"", ups->name, - (have_status_id)?status_id:"disabled"); + (have_tracking_id) ? tracking_id : "disabled"); if (!sstate_sendline(ups, sockcmd)) { upslogx(LOG_INFO, "Set command send failed"); @@ -101,9 +101,9 @@ static void send_instcmd(nut_ctype_t *client, const char *upsname, return; } - /* return the result, possibly including status_id */ - if (have_status_id) - sendback(client, "OK %s\n", status_id); + /* return the result, possibly including tracking_id */ + if (have_tracking_id) + sendback(client, "OK TRACKING %s\n", tracking_id); else sendback(client, "OK\n"); } @@ -113,7 +113,7 @@ void net_instcmd(nut_ctype_t *client, int numarg, const char **arg) const char *devname = NULL; const char *cmdname = NULL; const char *cmdparam = NULL; - char status_id[UUID4_LEN] = ""; + char tracking_id[UUID4_LEN] = ""; if (numarg < 2) { send_err(client, NUT_ERR_INVALID_ARGUMENT); @@ -127,12 +127,12 @@ void net_instcmd(nut_ctype_t *client, int numarg, const char **arg) if (numarg == 3) cmdparam = arg[2]; - if (client->cmdset_status_enabled) { + if (client->tracking) { /* Generate a tracking ID, if client requested status tracking */ - nut_uuid_v4(status_id); + nut_uuid_v4(tracking_id); } - send_instcmd(client, devname, cmdname, cmdparam, status_id); + send_instcmd(client, devname, cmdname, cmdparam, tracking_id); return; } diff --git a/server/netset.c b/server/netset.c index 3e5eba7834..a69aa96ff4 100644 --- a/server/netset.c +++ b/server/netset.c @@ -28,14 +28,14 @@ #include "netset.h" static void set_var(nut_ctype_t *client, const char *upsname, const char *var, - const char *newval, const char *status_id) + const char *newval, const char *tracking_id) { upstype_t *ups; const char *val; const enum_t *etmp; const range_t *rtmp; char cmd[SMALLBUF], esc[SMALLBUF]; - int have_status_id = 0; + int have_tracking_id = 0; ups = get_ups_ptr(upsname); @@ -139,11 +139,11 @@ static void set_var(nut_ctype_t *client, const char *upsname, const char *var, var, pconf_encode(newval, esc, sizeof(esc))); /* see if the user want execution tracking for this command */ - if (status_id && *status_id) { - snprintfcat(cmd, sizeof(cmd), " STATUS_ID %s", status_id); + if (tracking_id && *tracking_id) { + snprintfcat(cmd, sizeof(cmd), " TRACKING %s", tracking_id); /* Add an entry in the tracking structure */ - cmdset_status_add(status_id); - have_status_id = 1; + tracking_add(tracking_id); + have_tracking_id = 1; } /* add EOL */ @@ -151,7 +151,7 @@ static void set_var(nut_ctype_t *client, const char *upsname, const char *var, upslogx(LOG_INFO, "Set variable: %s@%s set %s on %s to %s (tracking ID: %s)", client->username, client->addr, var, ups->name, newval, - (have_status_id)?status_id:"disabled"); + (have_tracking_id) ? tracking_id : "disabled"); if (!sstate_sendline(ups, cmd)) { upslogx(LOG_INFO, "Set command send failed"); @@ -159,16 +159,16 @@ static void set_var(nut_ctype_t *client, const char *upsname, const char *var, return; } - /* return the result, possibly including status_id */ - if (have_status_id) - sendback(client, "OK %s\n", status_id); + /* return the result, possibly including tracking_id */ + if (have_tracking_id) + sendback(client, "OK TRACKING %s\n", tracking_id); else sendback(client, "OK\n"); } void net_set(nut_ctype_t *client, int numarg, const char **arg) { - char status_id[UUID4_LEN] = ""; + char tracking_id[UUID4_LEN] = ""; /* Base verification, to ensure that we have at least the SET parameter */ if (numarg < 2) { @@ -183,37 +183,37 @@ void net_set(nut_ctype_t *client, int numarg, const char **arg) return; } - if (client->cmdset_status_enabled) { + if (client->tracking) { /* Generate a tracking ID, if client requested status tracking */ - nut_uuid_v4(status_id); + nut_uuid_v4(tracking_id); } - set_var(client, arg[1], arg[2], arg[3], status_id); + set_var(client, arg[1], arg[2], arg[3], tracking_id); return; } - /* SET CMDSET_STATUS VALUE */ - if (!strcasecmp(arg[0], "CMDSET_STATUS")) { + /* SET TRACKING VALUE */ + if (!strcasecmp(arg[0], "TRACKING")) { if (!strcasecmp(arg[1], "ON")) { /* general enablement along with for this client */ - cmdset_status_enabled = 1; - client->cmdset_status_enabled = 1; + client->tracking = tracking_enable(); } else if (!strcasecmp(arg[1], "OFF")) { /* disable status tracking for this client first */ - client->cmdset_status_enabled = 0; + client->tracking = 0; /* then only disable the general one if no other clients use it! - * Note: don't call cmdset_status_free() since we want info to - * persist, and cmdset_status_cleanup() takes care of cleaning */ - cmdset_status_enabled = cmdset_status_disable(); + * Note: don't call tracking_free() since we want info to + * persist, and tracking_cleanup() takes care of cleaning */ + tracking_disable(); } else { send_err(client, NUT_ERR_INVALID_ARGUMENT); return; } - upsdebugx(1, "%s: CMDSET_STATUS %s", __func__, - (cmdset_status_enabled == 1)?"enabled":"disabled"); + upsdebugx(1, "%s: TRACKING general %s, client %s.", __func__, + tracking_is_enabled() ? "enabled" : "disabled", + client->tracking ? "enabled" : "disabled"); sendback(client, "OK\n"); diff --git a/server/nut_ctype.h b/server/nut_ctype.h index 5e39a5f2be..54184d2baa 100644 --- a/server/nut_ctype.h +++ b/server/nut_ctype.h @@ -47,7 +47,7 @@ typedef struct nut_ctype_s { char *username; /* per client status info for commands and settings * (disabled by default) */ - int cmdset_status_enabled; + int tracking; #ifdef WITH_OPENSSL SSL *ssl; diff --git a/server/sstate.c b/server/sstate.c index 215f7c6313..0365cd30f6 100644 --- a/server/sstate.c +++ b/server/sstate.c @@ -117,14 +117,14 @@ static int parse_args(upstype_t *ups, int numargs, char **arg) return 1; } - /* CMDSET_STATUS */ - if (!strcasecmp(arg[0], "CMDSET_STATUS")) { - cmdset_status_set(arg[1], arg[2]); - upsdebugx(1, "CMDSET_STATUS: ID %s status %s", arg[1], arg[2]); + /* TRACKING */ + if (!strcasecmp(arg[0], "TRACKING")) { + tracking_set(arg[1], arg[2]); + upsdebugx(1, "TRACKING: ID %s status %s", arg[1], arg[2]); /* log actual result of instcmd / setvar */ if (strncmp(arg[2], "PENDING", 7) != 0) { - upslogx(LOG_INFO, "tracking ID: %s\tresult: %s", arg[1], cmdset_status_get(arg[1])); + upslogx(LOG_INFO, "tracking ID: %s\tresult: %s", arg[1], tracking_get(arg[1])); } return 1; } diff --git a/server/upsd.c b/server/upsd.c index b8e55902fb..a49b51110f 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -55,7 +55,7 @@ int deny_severity = LOG_WARNING; int maxage = 15; /* default to 1h before cleaning up status tracking entries */ - int cmdset_status_delay = 3600; + int tracking_delay = 3600; /* preloaded to {OPEN_MAX} in main, can be overridden via upsd.conf */ int maxconn = 0; @@ -88,14 +88,27 @@ typedef struct { void *data; } handler_t; + +/* Commands and settings status tracking */ + /* general enable/disable status info for commands and settings * (disabled by default) * Note that only client that requested it will have it enabled * (see nut_ctype.h) */ -int cmdset_status_enabled = 0; +static int tracking_enabled = 0; + +/* Commands and settings status tracking structure */ +typedef struct tracking_s { + char *id; + int status; + time_t request_time; /* for cleanup */ + /* doubly linked list */ + struct tracking_s *prev; + struct tracking_s *next; +} tracking_t; + +static tracking_t *tracking_list = NULL; -/* Commands and settings status tracking */ -cmdset_status_t *cmdset_status_list = NULL; /* pollfd */ static struct pollfd *fds = NULL; @@ -498,7 +511,7 @@ static void client_connect(stype_t *server) client->addr = xstrdup(inet_ntopW(&csock)); - client->cmdset_status_enabled = 0; + client->tracking = 0; pconf_init(&client->ctx, NULL); @@ -664,7 +677,7 @@ static void upsd_cleanup(void) server_free(); client_free(); driver_free(); - cmdset_status_free(); + tracking_free(); free(statepath); free(datapath); @@ -696,44 +709,44 @@ void poll_reload(void) /* instant command and setvar status tracking */ /* allocate a new status tracking entry */ -int cmdset_status_add(const char *id) +int tracking_add(const char *id) { - cmdset_status_t *cmdset_status; + tracking_t *item; - if ((!cmdset_status_enabled) || (!id)) + if ((!tracking_enabled) || (!id)) return 0; - cmdset_status = xcalloc(1, sizeof(*cmdset_status)); + item = xcalloc(1, sizeof(*item)); - cmdset_status->id = xstrdup(id); - cmdset_status->status = STAT_PENDING; - time(&cmdset_status->request_time); + item->id = xstrdup(id); + item->status = STAT_PENDING; + time(&item->request_time); - if (cmdset_status_list) { - cmdset_status_list->prev = cmdset_status; - cmdset_status->next = cmdset_status_list; + if (tracking_list) { + tracking_list->prev = item; + item->next = tracking_list; } - cmdset_status_list = cmdset_status; + tracking_list = item; return 1; } /* set status of a specific tracking entry */ -int cmdset_status_set(const char *id, const char *value) +int tracking_set(const char *id, const char *value) { - cmdset_status_t *cmdset_status, *cmdset_status_next; + tracking_t *item, *next_item; /* sanity checks */ - if ((!cmdset_status_list) || (!id) || (!value)) + if ((!tracking_list) || (!id) || (!value)) return 0; - for (cmdset_status = cmdset_status_list; cmdset_status; cmdset_status = cmdset_status_next) { + for (item = tracking_list; item; item = next_item) { - cmdset_status_next = cmdset_status->next; + next_item = item->next; - if (!strcmp(cmdset_status->id, id)) { - cmdset_status->status = atoi(value); + if (!strcasecmp(item->id, id)) { + item->status = atoi(value); return 1; } } @@ -742,101 +755,100 @@ int cmdset_status_set(const char *id, const char *value) } /* free a specific tracking entry */ -int cmdset_status_del(const char *id) +int tracking_del(const char *id) { - cmdset_status_t *cmdset_status, *cmdset_status_next; + tracking_t *item, *next_item; /* sanity check */ - if ((!cmdset_status_list) || (!id)) + if ((!tracking_list) || (!id)) return 0; upsdebugx(3, "%s: deleting id %s", __func__, id); - for (cmdset_status = cmdset_status_list; cmdset_status; cmdset_status = cmdset_status_next) { + for (item = tracking_list; item; item = next_item) { - cmdset_status_next = cmdset_status->next; + next_item = item->next; - if (!strcmp(cmdset_status->id, id)) { + if (strcasecmp(item->id, id)) + continue; - if (cmdset_status->prev) { - cmdset_status->prev->next = cmdset_status->next; - } else { - /* deleting first entry */ - cmdset_status_list = cmdset_status->next; - } + if (item->prev) + item->prev->next = item->next; + else + /* deleting first entry */ + tracking_list = item->next; - if (cmdset_status->next) { - cmdset_status->next->prev = cmdset_status->prev; - } + if (item->next) + item->next->prev = item->prev; - free(cmdset_status->id); - free(cmdset_status); + free(item->id); + free(item); + + return 1; - return 1; - } } return 0; /* id not found! */ } /* free all status tracking entries */ -void cmdset_status_free(void) +void tracking_free(void) { - cmdset_status_t *cmdset_status, *cmdset_status_next; + tracking_t *item, *next_item; /* sanity check */ - if (!cmdset_status_list) + if (!tracking_list) return; upsdebugx(3, "%s", __func__); - for (cmdset_status = cmdset_status_list; cmdset_status; cmdset_status = cmdset_status_next) { - cmdset_status_next = cmdset_status->next; - cmdset_status_del(cmdset_status->id); + for (item = tracking_list; item; item = next_item) { + next_item = item->next; + tracking_del(item->id); } } -/* cleanup status tracking entries according to their age and cmdset_status_delay */ -void cmdset_status_cleanup(void) +/* cleanup status tracking entries according to their age and tracking_delay */ +void tracking_cleanup(void) { - cmdset_status_t *cmdset_status, *cmdset_status_next; + tracking_t *item, *next_item; time_t now; /* sanity check */ - if (!cmdset_status_list) + if (!tracking_list) return; time(&now); upsdebugx(3, "%s", __func__); - for (cmdset_status = cmdset_status_list; cmdset_status; cmdset_status = cmdset_status_next) { + for (item = tracking_list; item; item = next_item) { - cmdset_status_next = cmdset_status->next; + next_item = item->next; - if (difftime(now, cmdset_status->request_time) > cmdset_status_delay) { - cmdset_status_del(cmdset_status->id); + if (difftime(now, item->request_time) > tracking_delay) { + tracking_del(item->id); } } } /* get status of a specific tracking entry */ -char *cmdset_status_get(const char *id) +char *tracking_get(const char *id) { - cmdset_status_t *cmdset_status, *cmdset_status_next; + tracking_t *item, *next_item; /* sanity checks */ - if ((!cmdset_status_list) || (!id)) + if ((!tracking_list) || (!id)) return "ERR UNKNOWN"; - for (cmdset_status = cmdset_status_list; cmdset_status; cmdset_status = cmdset_status_next) { + for (item = tracking_list; item; item = next_item) { - cmdset_status_next = cmdset_status->next; + next_item = item->next; - if (strcmp(cmdset_status->id, id)) + if (strcasecmp(item->id, id)) continue; - switch (cmdset_status->status) + switch (item->status) { case STAT_PENDING: return "PENDING"; @@ -854,21 +866,34 @@ char *cmdset_status_get(const char *id) return "ERR UNKNOWN"; /* id not found! */ } +/* enable general status tracking (tracking_enabled) and return its value (1). */ +int tracking_enable(void) +{ + tracking_enabled = 1; + + return tracking_enabled; +} + /* disable general status tracking only if no client use it anymore. - * return the new value for cmdset_status_enabled (0 if we can disable, 1 - * otherwise) */ -int cmdset_status_disable(void) + * return the new value for tracking_enabled */ +int tracking_disable(void) { nut_ctype_t *client, *cnext; for (client = firstclient; client; client = cnext) { cnext = client->next; - if (client->cmdset_status_enabled == 1) + if (client->tracking == 1) return 1; } return 0; } +/* return current general status of tracking (tracking_enabled). */ +int tracking_is_enabled(void) +{ + return tracking_enabled; +} + /* UUID v4 basic implementation * Note: 'dest' must be at least `UUID4_LEN` long */ int nut_uuid_v4(char *uuid_str) @@ -913,7 +938,7 @@ static void mainloop(void) } /* cleanup instcmd/setvar status tracking entries if needed */ - cmdset_status_cleanup(); + tracking_cleanup(); /* scan through driver sockets */ for (ups = firstups; ups && (nfds < maxconn); ups = ups->next) { diff --git a/server/upsd.h b/server/upsd.h index c08f00d851..2cd3eb399e 100644 --- a/server/upsd.h +++ b/server/upsd.h @@ -79,32 +79,22 @@ enum { }; /* Commands and settings status tracking functions */ -int cmdset_status_add(const char *id); -int cmdset_status_set(const char *id, const char *value); -int cmdset_status_del(const char *id); -void cmdset_status_free(void); -void cmdset_status_cleanup(void); -char *cmdset_status_get(const char *id); -int cmdset_status_disable(void); - -/* Commands and settings status tracking structure */ -typedef struct cmdset_status_s { - char *id; - int status; - time_t request_time; /* for cleanup */ - /* doubly linked list */ - struct cmdset_status_s *prev; - struct cmdset_status_s *next; -} cmdset_status_t; +int tracking_add(const char *id); +int tracking_set(const char *id, const char *value); +int tracking_del(const char *id); +void tracking_free(void); +void tracking_cleanup(void); +char *tracking_get(const char *id); +int tracking_enable(void); +int tracking_disable(void); +int tracking_is_enabled(void); /* declarations from upsd.c */ -extern int maxage, maxconn, cmdset_status_delay; +extern int maxage, maxconn, tracking_delay; extern char *statepath, *datapath; extern upstype_t *firstups; extern nut_ctype_t *firstclient; -extern int cmdset_status_enabled; -extern cmdset_status_t *cmdset_status_list; /* map commands onto signals */ diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index 9f622f67ba..25e39d9875 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -82,7 +82,7 @@ const struct option longopts[] = static nutscan_device_t *dev[TYPE_END]; -static long timeout = DEFAULT_TIMEOUT*1000*1000; /* in usec */ +static long timeout = DEFAULT_NETWORK_TIMEOUT * 1000 * 1000; /* in usec */ static char * start_ip = NULL; static char * end_ip = NULL; static char * port = NULL; @@ -167,7 +167,7 @@ void show_usage() printf(" -E, --eaton_serial : Scan serial Eaton devices (XCP, SHUT and Q1).\n"); printf("\nNetwork specific options:\n"); - printf(" -t, --timeout : network operation timeout (default %d).\n",DEFAULT_TIMEOUT); + printf(" -t, --timeout : network operation timeout (default %d).\n", DEFAULT_NETWORK_TIMEOUT); printf(" -s, --start_ip : First IP address to scan.\n"); printf(" -e, --end_ip : Last IP address to scan.\n"); printf(" -m, --mask_cidr : Give a range of IP using CIDR notation.\n"); @@ -268,8 +268,8 @@ int main(int argc, char *argv[]) case 't': timeout = atol(optarg)*1000*1000; /*in usec*/ if( timeout == 0 ) { - fprintf(stderr,"Illegal timeout value, using default %ds\n", DEFAULT_TIMEOUT); - timeout = DEFAULT_TIMEOUT*1000*1000; + fprintf(stderr,"Illegal timeout value, using default %ds\n", DEFAULT_NETWORK_TIMEOUT); + timeout = DEFAULT_NETWORK_TIMEOUT * 1000 * 1000; } break; case 's':