diff --git a/NEWS.adoc b/NEWS.adoc index e64c4c49e2..a8be705969 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -86,19 +86,26 @@ https://github.com/networkupstools/nut/milestone/11 in certain cases against high voltage transfer, we only fixed-up one of them. [#1245] - - development iterations of NUT should now identify with not only the semantic - version of a preceding release, but with git-derived information about the - amount of iterations that followed (if available): the three-number "semver" - would be seen on release snapshots, while other builds would expose the - added components: one with the amount of commits on the main development - trunk since the preceding release which are ancestors of the built code - base, and in case of feature development branches -- another component - with the amount of commits unique to this branch (which are not part of - the development trunk). This allows to produce more relevant (monotonously - growing) version identifiers for packages and similar artifacts, with more - meaningful upgrades via development snapshots, eventually. A copy of the - current version information would be embedded into "dist" archives as a - `VERSION_DEFAULT` file. [#1949] + - SEMVER, know thyself! + * development iterations of NUT should now identify with not only the + semantic version of a preceding release, but with git-derived information + about the amount of iterations that followed (if available): + the three-number "semver" would be seen on release snapshots, while + other builds would expose the added components: one with the amount + of commits on the main development trunk since the preceding release + which are ancestors of the built code base, and in case of feature + development branches -- another component with the amount of commits + unique to this branch (which are not part of the development trunk yet). + This allows to produce more relevant (monotonously growing) version + identifiers for packages and similar artifacts, with more meaningful + upgrades via development snapshots, eventually. A copy of the current + version information would be embedded into "dist" archives as a + `VERSION_DEFAULT` file, among provisions for packager tuning. [#1949] + * SMF manifests and systemd units now refer to man pages and their online + variants under `NUT_WEBSITE_BASE` dependent on codebase maturity + (development or release snapshot); many programs now display such + references in their command-line usage help, method `suggest_doc_links()` + was introduced for this purpose. [issue #722, PR #2733] - the `upsnotify()` common code introduced in recent NUT releases (integrating with service management frameworks, etc.) was a bit cryptic when it reported diff --git a/clients/upsc.c b/clients/upsc.c index d99d18085a..d2422944a2 100644 --- a/clients/upsc.c +++ b/clients/upsc.c @@ -62,6 +62,8 @@ static void usage(const char *prog) printf(" -h - display this help text\n"); nut_report_config_flags(); + + printf("\n%s", suggest_doc_links(prog, NULL)); } static void printvar(const char *var) diff --git a/clients/upscmd.c b/clients/upscmd.c index 3745014906..c9a04e8071 100644 --- a/clients/upscmd.c +++ b/clients/upscmd.c @@ -68,6 +68,8 @@ static void usage(const char *prog) printf(" [] Additional data for command - number of seconds, etc.\n"); nut_report_config_flags(); + + printf("\n%s", suggest_doc_links(prog, "upsd.users")); } static void print_cmd(char *cmdname) diff --git a/clients/upslog.c b/clients/upslog.c index f1d36b9fcc..33b8505822 100644 --- a/clients/upslog.c +++ b/clients/upslog.c @@ -176,11 +176,10 @@ static void help(const char *prog) printf("format string defaults to:\n"); printf("%s\n", DEFAULT_LOGFORMAT); - printf("\n"); - printf("See the upslog(8) man page for more information.\n"); - nut_report_config_flags(); + printf("\n%s", suggest_doc_links(prog, NULL)); + exit(EXIT_SUCCESS); } diff --git a/clients/upsmon.c b/clients/upsmon.c index 8c6a7876d2..786dc3b294 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -3021,6 +3021,8 @@ static void help(const char *arg_progname) nut_report_config_flags(); + printf("\n%s", suggest_doc_links(arg_progname, "upsmon.conf")); + exit(EXIT_SUCCESS); } diff --git a/clients/upsrw.c b/clients/upsrw.c index 892e6825e3..e1de6d6343 100644 --- a/clients/upsrw.c +++ b/clients/upsrw.c @@ -69,6 +69,8 @@ static void usage(const char *prog) printf("Call without -s to show all possible read/write variables (same as -l).\n"); nut_report_config_flags(); + + printf("\n%s", suggest_doc_links(prog, "upsd.users")); } static void clean_exit(void) diff --git a/clients/upssched.c b/clients/upssched.c index eb822f0cd2..d636af6bf1 100644 --- a/clients/upssched.c +++ b/clients/upssched.c @@ -1505,6 +1505,8 @@ static void help(const char *arg_progname) nut_report_config_flags(); + printf("\n%s", suggest_doc_links(arg_progname, "upsmon.conf")); + exit(EXIT_SUCCESS); } diff --git a/common/common.c b/common/common.c index b4f1b5456f..a71cb70f1d 100644 --- a/common/common.c +++ b/common/common.c @@ -659,6 +659,45 @@ int print_banner_once(const char *prog, int even_if_disabled) return ret; } +const char *suggest_doc_links(const char *progname, const char *progconf) { + static char buf[LARGEBUF]; + + buf[0] = '\0'; + + if (progname) { + char *s = NULL, *buf2 = xstrdup(xbasename(progname)); + size_t i; + + for (i = 0; buf2[i]; i++) { + buf2[i] = tolower(buf2[i]); + } + + if ((s = strstr(buf2, ".exe")) && strcmp(buf2, "nut.exe")) + *s = '\0'; + + snprintf(buf, sizeof(buf), + "For more information please "); +#if defined(WITH_DOCS) && WITH_DOCS + snprintfcat(buf, sizeof(buf), + "Read The Fine Manual ('man %s') and/or ", + buf2); +#endif + snprintfcat(buf, sizeof(buf), + "see\n\t%s/docs/man/%s.html\n", + NUT_WEBSITE_BASE, buf2); + + free(buf2); + } + + if (progconf) + snprintfcat(buf, sizeof(buf), + "%s check documentation and samples of %s\n", + progname ? "Also" : "Please", + progconf); + + return buf; +} + /* enable writing upslog_with_errno() and upslogx() type messages to the syslog */ void syslogbit_set(void) diff --git a/configure.ac b/configure.ac index f69bce4b19..c6672cba23 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,16 @@ AC_INIT([nut], dnl See docs/maintainer-guide.txt about releases - updating the version dnl above is a small part of the consistent ritual! +dnl PACKAGE_URL="https://www.networkupstools.org/" for development iterations +dnl or "https://www.networkupstools.org/historic/v1.2.3/index.html" for release +dnl snapshots further set in stone. Either way, there should be a slash and +dnl either a filename, or nothing. Adding a bogus filename and chopping it +dnl off by `dirname` should do the trick. +dnl NOTE: the resulting NUT_WEBSITE_BASE string does not end with a slash! +NUT_WEBSITE_BASE="`dirname "${PACKAGE_URL}index.html"`" +dnl Fallback, no trailing slash! +[ -n "${NUT_WEBSITE_BASE-}" ] || NUT_WEBSITE_BASE='https://www.networkupstools.org' + dnl Note: this refers to GITREV at the time of configure script running dnl primarily for better messaging in the script itself (also to render dnl the PDF documentation revision history via docs/docinfo.xml.in). @@ -747,6 +757,8 @@ AS_IF([test x"${NUT_SOURCE_GITREV}" = x], [NUT_REPORT([configured version], [${PACKAGE_VERSION} ${NUT_SOURCE_GITREV_DEVREL}])], [NUT_REPORT([configured version], [${PACKAGE_VERSION} (${NUT_SOURCE_GITREV}) ${NUT_SOURCE_GITREV_DEVREL}])]) ]) +NUT_REPORT([Documentation website base URL], [${NUT_WEBSITE_BASE}]) +AC_DEFINE_UNQUOTED([NUT_WEBSITE_BASE], "${NUT_WEBSITE_BASE}", [Documentation website base URL, no trailing slash]) dnl Note: the compiler/pragma/attr methods below are custom for NUT codebase: NUT_COMPILER_FAMILY @@ -4832,6 +4844,7 @@ AC_SUBST(NUT_SOURCE_GITREV) AC_SUBST(NUT_SOURCE_GITREV_IS_RELEASE) AC_SUBST(NUT_SOURCE_GITREV_SEMVER) AC_SUBST(NUT_SOURCE_GITREV_NUMERIC) +AC_SUBST(NUT_WEBSITE_BASE) AC_SUBST(LIBSSL_CFLAGS) AC_SUBST(LIBSSL_LIBS) AC_SUBST(LIBSSL_LDFLAGS_RPATH) diff --git a/drivers/blazer_ser.c b/drivers/blazer_ser.c index 8bdc2c423f..e33a455d24 100644 --- a/drivers/blazer_ser.c +++ b/drivers/blazer_ser.c @@ -106,7 +106,6 @@ ssize_t blazer_command(const char *cmd, char *buf, size_t buflen) void upsdrv_help(void) { - printf("Read The Fine Manual ('man 8 blazer_ser')\n"); } diff --git a/drivers/blazer_usb.c b/drivers/blazer_usb.c index f2cf3432aa..826eb78176 100644 --- a/drivers/blazer_usb.c +++ b/drivers/blazer_usb.c @@ -579,8 +579,6 @@ void upsdrv_help(void) } printf("\n\n"); #endif /* TESTING */ - - printf("Read The Fine Manual ('man 8 blazer_usb')\n"); } diff --git a/drivers/main.c b/drivers/main.c index f89142372c..23716c3385 100644 --- a/drivers/main.c +++ b/drivers/main.c @@ -130,7 +130,8 @@ static int nut_debug_level_protocol = -1; #ifndef DRIVERS_MAIN_WITHOUT_MAIN /* everything else */ static char *pidfn = NULL; -static int dump_data = 0; /* Store the update_count requested */ +static int help_only = 0, + dump_data = 0; /* Store the update_count requested */ #endif /* DRIVERS_MAIN_WITHOUT_MAIN */ /* pre-declare some private methods used */ @@ -292,6 +293,8 @@ static void help_msg(void) } upsdrv_help(); + + printf("\n%s", suggest_doc_links(progname, "ups.conf")); } #endif /* DRIVERS_MAIN_WITHOUT_MAIN */ @@ -1812,7 +1815,7 @@ static void exit_cleanup(void) { dstate_setinfo("driver.state", "cleanup.exit"); - if (!dump_data) { + if (!dump_data && !help_only) { upsnotify(NOTIFY_STATE_STOPPING, "exit_cleanup()"); } @@ -1983,7 +1986,10 @@ int main(int argc, char **argv) pid_t oldpid = -1; #else /* FIXME: *actually* handle WIN32 builds too */ - const char * cmd = NULL; + const char *cmd = NULL; + + const char *drv_name; + char *dot; #endif const char optstring[] = "+a:s:kDFBd:hx:Lqr:u:g:Vi:c:" @@ -2006,6 +2012,10 @@ int main(int argc, char **argv) case 'd': dump_data = atoi(optarg); break; + case 'h': + /* Avoid notification at exit */ + help_only = 1; + break; default: break; } @@ -2062,12 +2072,11 @@ int main(int argc, char **argv) progname = xbasename(argv[0]); #ifdef WIN32 - const char * drv_name; drv_name = xbasename(argv[0]); /* remove trailing .exe */ - char * dot = strrchr(drv_name,'.'); - if( dot != NULL ) { - if(strcasecmp(dot, ".exe") == 0 ) { + dot = strrchr(drv_name,'.'); + if (dot != NULL) { + if (strcasecmp(dot, ".exe") == 0) { progname = strdup(drv_name); char * t = strrchr(progname,'.'); *t = 0; diff --git a/drivers/nutdrv_qx.c b/drivers/nutdrv_qx.c index 3d6b7db654..e7874d8e28 100644 --- a/drivers/nutdrv_qx.c +++ b/drivers/nutdrv_qx.c @@ -2921,7 +2921,7 @@ void upsdrv_help(void) printf(", "); printf("%s", usbsubdriver[i].name); } - printf("\n\n"); + printf("\n"); # endif /* QX_USB*/ /* Protocols are the first token from "name" field in @@ -2944,10 +2944,8 @@ void upsdrv_help(void) printf(", "); printf("%s", subdrv_name); } - printf("\n\n"); + printf("\n"); #endif /* TESTING */ - - printf("Read The Fine Manual ('man 8 nutdrv_qx')\n"); } /* Adding flags/vars */ diff --git a/drivers/upsdrvctl.c b/drivers/upsdrvctl.c index e0662e3088..be5d1d86c1 100644 --- a/drivers/upsdrvctl.c +++ b/drivers/upsdrvctl.c @@ -1237,6 +1237,11 @@ static void help(const char *arg_progname) printf(" Fields: UPSNAME UPSDRV RUNNING PF_PID S_RESPONSIVE S_PID S_STATUS\n"); printf(" (PF_* = according to PID file, if any; S_* = via socket protocol)\n"); + printf("\n%s", suggest_doc_links(arg_progname, "ups.conf")); +#if (defined(WITH_SOLARIS_SMF) && WITH_SOLARIS_SMF) || (defined(HAVE_SYSTEMD) && HAVE_SYSTEMD) + printf("NOTE: On this system you should prefer upsdrvsvcctl and nut-driver-enumerator\n"); +#endif + exit(EXIT_SUCCESS); } diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c index 3ec95d2bed..539f52c7e5 100644 --- a/drivers/usbhid-ups.c +++ b/drivers/usbhid-ups.c @@ -1025,9 +1025,7 @@ void upsdrv_help(void) printf(", "); printf("\"%s\"", subdriver_list[i]->name); } - printf("\n\n"); - - printf("Read The Fine Manual ('man 8 usbhid-ups')\n"); + printf("\n"); } void upsdrv_makevartable(void) diff --git a/include/common.h b/include/common.h index 77b81934c3..c8ff6f7093 100644 --- a/include/common.h +++ b/include/common.h @@ -208,6 +208,13 @@ extern const char *UPS_VERSION; * have an end-of-line char of its own. */ const char *describe_NUT_VERSION_once(void); +/* Return a buffer with a (possibly multiline) string that can be printed + * as part of program help/usage message. Caller should not free() the buffer. + * Optional "progconf" allows to suggest config file(s) to study as well. + * NOTE: the string in buffer starts with text and ends with one EOL char. + */ +const char *suggest_doc_links(const char *progname, const char *progconf); + /* Based on NUT_QUIET_INIT_BANNER envvar (present and empty or "true") * hide the NUT tool name+version banners; show them by default */ int banner_is_disabled(void); diff --git a/scripts/Solaris/nut-driver-enumerator.xml.in b/scripts/Solaris/nut-driver-enumerator.xml.in index f935b8c066..fc5097a410 100644 --- a/scripts/Solaris/nut-driver-enumerator.xml.in +++ b/scripts/Solaris/nut-driver-enumerator.xml.in @@ -2,14 +2,14 @@ - + - + - + - +