diff --git a/sysutils/nut-devel/Makefile b/sysutils/nut-devel/Makefile index b3d796bfec97..39a576b32ea6 100644 --- a/sysutils/nut-devel/Makefile +++ b/sysutils/nut-devel/Makefile @@ -1,172 +1,172 @@ PORTNAME= nut PORTVERSION= ${NUT_COMMIT_DATE} -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= sysutils PKGNAMESUFFIX= -devel # MASTER_SITES= http://www.networkupstools.org/source/${PORTVERSION:R}/ # DISTFILES= ${DISTNAME}${EXTRACT_SUFX} # EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX} MAINTAINER= cy@FreeBSD.org COMMENT= Network UPS Tools LICENSE= GPLv2+ GPLv3+ ART10 GPLv1+ LICENSE_COMB= multi LICENSE_FILE= ${WRKSRC}/COPYING CONFLICTS= nut-[0-9]* USE_GITHUB= yes GH_ACCOUNT= networkupstools GH_TAGNAME= 2ce9dfa4a NUT_COMMIT_DATE= 2022.08.25 MAKE_JOBS_UNSAFE= yes USE_GCC= yes GNU_CONFIGURE= yes USES= autoreconf:build compiler:c11 gmake libtool pkgconfig python USE_LDCONFIG= yes NUT_USER?= uucp NUT_GROUP?= uucp STATEDIR?= /var/db/nut PLIST_SUB+= NUT_USER=${NUT_USER} PLIST_SUB+= NUT_GROUP=${NUT_GROUP} CGIDIR?= ${PREFIX}/www/cgi-bin/${PORTNAME} CGIDIR_REL?= ${CGIDIR:S,^${PREFIX}/,,} PLIST_SUB+= CGIDIR="${CGIDIR_REL}" PLIST_SUB+= CGIETCDIR="etc/nut/" OPTIONS_DEFAULT= SERIAL USB SNMP NEON PDU MODBUS CGI BASH AVAHI FREEIPMI DOCS MANPAGES OPENSSL OPTIONS_DEFINE= SERIAL USB SNMP NEON PDU MODBUS CGI BASH AVAHI IPMIPSU FREEIPMI DOCS MANPAGES OPTIONS_SINGLE= SSL OPTIONS_SINGLE_SSL= SSL_OFF OPENSSL NSS OPTIONS_SUB= yes SERIAL_DESC= SERIAL support USB_DESC= USB support NEON_DESC= NEON XML/HTTP support PDU_DESC= Powerman PDU support MODBUS_DESC= Modbus support CGI_DESC= Web CGI interface FREEIPMI_DESC= freeipmi support IPMIPSU_DESC= Use nut-ipmipsu support (experimental) SSL_OFF_DESC= No SSL support USE_RC_SUBR= nut nut_upsmon nut_upslog SUB_LIST+= STATEDIR=${STATEDIR} PLIST_SUB+= STATEDIR=${STATEDIR} PORTDOCS= * TMPDIR?= /tmp INSTALL_TARGET= install-strip CONFIGURE_ARGS= --sysconfdir=${PREFIX}/etc/nut \ --program-transform-name="" \ --localstatedir=${STATEDIR} \ --datadir=${PREFIX}/etc/nut \ --with-devd-dir=${PREFIX}/etc/devd \ --with-drvpath=${PREFIX}/libexec/nut \ --with-statepath=${STATEDIR} \ --with-altpidpath=${STATEDIR} \ --with-pidpath=${STATEDIR} \ --with-pkgconfig-dir=${PREFIX}/libdata/pkgconfig \ --with-user=${NUT_USER} \ --with-group=${NUT_GROUP} \ --with-python=${PYTHON_CMD} \ --without-python2 \ --with-python3=${PYTHON_CMD} \ --with-dev \ --with-ltdl --with-nut-scanner CFLAGS+= -I${LOCALBASE}/include -L${LOCALBASE}/lib LIB_DEPENDS+= libltdl.so:devel/libltdl # XXX Remove this when copying this port to sysutils/nut. The GA version # XXX of nut ships with preformatted files and therefore does not need # XXX asciidoc. BUILD_DEPENDS= asciidoc:textproc/asciidoc MANPAGES_CONFIGURE_ON= --with-doc=man=auto MANPAGES_CONFIGURE_OFF= --with-doc=no CGI_LIB_DEPENDS= libgd.so:graphics/gd CGI_CONFIGURE_WITH= cgi CGI_CONFIGURE_ON= --with-cgipath=${CGIDIR} \ --with-htmlpath=${WWWDIR} \ --with-gd-includes=-I${LOCALBASE}/include \ --with-gd-libs="-L${LOCALBASE}/lib -lgd" SERIAL_CONFIGURE_WITH= serial USB_CONFIGURE_WITH= usb=auto SNMP_LIB_DEPENDS= libnetsnmp.so:net-mgmt/net-snmp SNMP_CONFIGURE_WITH= snmp NEON_LIB_DEPENDS= libneon.so:www/neon NEON_CONFIGURE_WITH= neon PDU_LIB_DEPENDS= libpowerman.so:sysutils/powerman PDU_CONFIGURE_WITH= powerman MODBUS_LIB_DEPENDS= libmodbus.so:comms/libmodbus MODBUS_CONFIGURE_WITH= modbus BASH_BUILD_DEPENDS= ${LOCALBASE}/share/bash-completion/bash_completion.sh:shells/bash-completion BASH_RUN_DEPENDS= ${LOCALBASE}/share/bash-completion/bash_completion.sh:shells/bash-completion AVAHI_BUILD_DEPENDS= ${LOCALBASE}/include/avahi-ui/avahi-ui.h:net/avahi-header AVAHI_BUILD_DEPENDS= avahi-daemon:net/avahi-app AVAHI_RUN_DEPENDS= avahi-daemon:net/avahi-app AVAHI_CONFIGURE_WITH= avahi FREEIPMI_LIB_DEPENDS= libfreeipmi.so:sysutils/freeipmi FREEIPMI_CONFIGURE_WITH=freeipmi IPMIPSU_LIB_DEPENDS= libfreeipmi.so:sysutils/freeipmi IPMIPSU_CONFIGURE_WITH= ipmi OPENSSL_USES= ssl OPENSSL_CONFIGURE_WITH= openssl NSS_LIB_DEPENDS= libnss3.so:security/nss NSS_CONFIGURE_WITH= nss .include post-patch: @${REINPLACE_CMD} -i '' -e 's|python|${PYTHON_CMD}|' ${WRKSRC}/autogen.sh @${FIND} ${WRKSRC} -type f | ${XARGS} ${REINPLACE_CMD} -i '' -e 's|/usr/bin/env python|${PYTHON_CMD}|' @${FIND} ${WRKSRC} -type f | ${XARGS} ${REINPLACE_CMD} -i '' -e 's|/usr/local/ups|${PREFIX}|' pre-configure: cd ${WRKSRC} && ./autogen.sh pre-install: @${MKDIR} ${STAGEDIR}${PREFIX}/libexec/nut @${REINPLACE_CMD} -e 's/device-name\*/cdev/g' ${WRKSRC}/scripts/devd/nut-usb.conf post-install: @${MKDIR} ${STAGEDIR}${STATEDIR} @${MKDIR} ${STAGEDIR}${PREFIX}/etc/syslog.d .if ${PORT_OPTIONS:MBASH} @${MKDIR} ${STAGEDIR}${PREFIX}/etc/bash_completion.d/ ${INSTALL_DATA} ${WRKSRC}/scripts/misc/nut.bash_completion ${STAGEDIR}${PREFIX}/etc/bash_completion.d/ .endif .if ${PORT_OPTIONS:MDOCS} @${MKDIR} ${STAGEDIR}${DOCSDIR}/cables ${INSTALL_DATA} ${WRKSRC}/docs/cables/*.txt ${STAGEDIR}${DOCSDIR}/cables ${INSTALL_DATA} ${WRKSRC}/docs/*.txt ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${WRKSRC}/docs/FAQ.txt ${STAGEDIR}${DOCSDIR} .for file in AUTHORS COPYING INSTALL MAINTAINERS NEWS README UPGRADING ${INSTALL_DATA} ${WRKSRC}/${file} ${STAGEDIR}${DOCSDIR} .endfor .endif @${MKDIR} ${STAGEDIR}${EXAMPLESDIR} ${INSTALL_DATA} ${PATCHDIR}/nut.syslog ${STAGEDIR}${EXAMPLESDIR}/syslog.sample ${INSTALL_DATA} ${PATCHDIR}/nut.newsyslog ${STAGEDIR}${EXAMPLESDIR}/newsyslog.sample ${INSTALL_DATA} ${PATCHDIR}/nut_upslog.sample ${STAGEDIR}${EXAMPLESDIR}/nut_upslog.sample ${MKDIR} ${STAGEDIR}/var/log/nut .include diff --git a/sysutils/nut-devel/files/patch-clients_upslog.c b/sysutils/nut-devel/files/patch-clients_upslog.c new file mode 100644 index 000000000000..c06eaf45e992 --- /dev/null +++ b/sysutils/nut-devel/files/patch-clients_upslog.c @@ -0,0 +1,291 @@ +--- clients/upslog.c.orig 2022-08-29 22:20:20.954722000 -0700 ++++ clients/upslog.c 2022-08-29 22:21:18.844395000 -0700 +@@ -32,6 +32,10 @@ + */ + + #include "common.h" ++#include ++#include ++#include ++#include + #include "nut_platform.h" + #include "upsclient.h" + +@@ -41,32 +45,49 @@ + #include "upslog.h" + + static int reopen_flag = 0, exit_flag = 0; +- static uint16_t port; +- static char *upsname, *hostname; +- static UPSCONN_t ups; ++ static char *upsname; ++ static UPSCONN_t *ups; + +- static FILE *logfile; +- static const char *logfn, *monhost; ++ static char *logfn, *monhost; + static sigset_t nut_upslog_sigmask; + static char logbuffer[LARGEBUF], *logformat; + + static flist_t *fhead = NULL; ++ struct monhost_ups { ++ char *monhost; ++ char *logfn; ++ char *upsname; ++ char *hostname; ++ uint16_t port; ++ UPSCONN_t *ups; ++ FILE *logfile; ++ struct monhost_ups *next; ++ }; ++ static struct monhost_ups *monhost_ups_anchor = NULL; ++ static struct monhost_ups *monhost_ups_current = NULL; ++ static struct monhost_ups *monhost_ups_prev = NULL; + ++ + #define DEFAULT_LOGFORMAT "%TIME @Y@m@d @H@M@S% %VAR battery.charge% " \ + "%VAR input.voltage% %VAR ups.load% [%VAR ups.status%] " \ + "%VAR ups.temperature% %VAR input.frequency%" + + static void reopen_log(void) + { +- if (logfile == stdout) { +- upslogx(LOG_INFO, "logging to stdout"); +- return; +- } ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ if (monhost_ups_current->logfile == stdout) { ++ upslogx(LOG_INFO, "logging to stdout"); ++ return; ++ } + +- fclose(logfile); +- logfile = fopen(logfn, "a"); +- if (logfile == NULL) +- fatal_with_errno(EXIT_FAILURE, "could not reopen logfile %s", logfn); ++ if ((monhost_ups_current->logfile = freopen( ++ monhost_ups_current->logfn, "a", ++ monhost_ups_current->logfile)) == NULL) ++ fatal_with_errno(EXIT_FAILURE, ++ "could not reopen logfile %s", logfn); ++ } + } + + static void set_reopen_flag(int sig) +@@ -131,6 +152,8 @@ + printf(" -p - Base name for PID file (defaults to \"%s\")\n", prog); + printf(" -s - Monitor UPS - @[:]\n"); + printf(" - Example: -s myups@server\n"); ++ printf(" -m - Monitor UPS \n"); ++ printf(" - Example: -m myups@server,/var/log/myups.log\n"); + printf(" -u - Switch to if started as root\n"); + + printf("\n"); +@@ -215,7 +238,7 @@ + query[2] = var; + numq = 3; + +- ret = upscli_get(&ups, numq, query, &numa, &answer); ++ ret = upscli_get(ups, numq, query, &numa, &answer); + + if ((ret < 0) || (numa < numq)) { + snprintfcat(logbuffer, sizeof(logbuffer), "NA"); +@@ -368,7 +391,7 @@ + } + + /* go through the list of functions and call them in order */ +-static void run_flist(void) ++static void run_flist(struct monhost_ups *monhost_ups_print) + { + flist_t *tmp; + +@@ -382,8 +405,8 @@ + tmp = tmp->next; + } + +- fprintf(logfile, "%s\n", logbuffer); +- fflush(logfile); ++ fprintf(monhost_ups_print->logfile, "%s\n", logbuffer); ++ fflush(monhost_ups_print->logfile); + } + + /* -s +@@ -396,6 +419,7 @@ + int main(int argc, char **argv) + { + int interval = 30, i, foreground = -1; ++ size_t monhost_len = 0; + const char *prog = xbasename(argv[0]); + time_t now, nextpoll = 0; + const char *user = NULL; +@@ -407,7 +431,7 @@ + + printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); + +- while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) { ++ while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FBm:")) != -1) { + switch(i) { + case 'h': + help(prog); +@@ -415,6 +439,33 @@ + break; + #endif + ++ case 'm': { /* var scope */ ++ char *m_arg, *s; ++ ++ monhost_ups_prev = monhost_ups_current; ++ monhost_ups_current = xmalloc(sizeof(struct monhost_ups)); ++ if (monhost_ups_anchor == NULL) ++ monhost_ups_anchor = monhost_ups_current; ++ else ++ monhost_ups_prev->next = monhost_ups_current; ++ monhost_ups_current->next = NULL; ++ monhost_len++; ++ ++ /* Be sure to not mangle original optarg, nor rely on its longevity */ ++ s = xstrdup(optarg); ++ m_arg = s; ++ monhost_ups_current->monhost = xstrdup(strsep(&m_arg, ",")); ++ if (!m_arg) ++ fatalx(EXIT_FAILURE, "Argument '-m upsspec,logfile' requires exactly 2 components in the tuple"); ++ monhost_ups_current->logfn = xstrdup(strsep(&m_arg, ",")); ++ if (m_arg) /* Had a third comma - also unexpected! */ ++ fatalx(EXIT_FAILURE, "Argument '-m upsspec,logfile' requires exactly 2 components in the tuple"); ++ if (upscli_splitname(monhost_ups_current->monhost, &(monhost_ups_current->upsname), &(monhost_ups_current->hostname), &(monhost_ups_current->port)) != 0) { ++ fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); ++ } ++ free(s); ++ } /* var scope */ ++ break; + case 's': + monhost = optarg; + break; +@@ -479,42 +530,59 @@ + snprintfcat(logformat, LARGEBUF, "%s ", argv[i]); + } + +- if (!monhost) +- fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s "); ++ if (monhost_ups_anchor == NULL) { ++ if (monhost) { ++ monhost_ups_current = xmalloc(sizeof(struct monhost_ups)); ++ monhost_ups_anchor = monhost_ups_current; ++ monhost_ups_current->next = NULL; ++ monhost_ups_current->monhost = monhost; ++ monhost_len=1; ++ } else { ++ fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s "); ++ } + +- if (!logfn) +- fatalx(EXIT_FAILURE, "No filename defined for logging - use -l "); ++ if (logfn) ++ monhost_ups_current->logfn = logfn; ++ else ++ fatalx(EXIT_FAILURE, "No filename defined for logging - use -l "); ++ } + + /* shouldn't happen */ + if (!logformat) + fatalx(EXIT_FAILURE, "No format defined - but this should be impossible"); + +- printf("logging status of %s to %s (%is intervals)\n", +- monhost, logfn, interval); ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ printf("logging status of %s to %s (%is intervals)\n", ++ monhost_ups_current->monhost, monhost_ups_current->logfn, interval); ++ if (upscli_splitname(monhost_ups_current->monhost, &(monhost_ups_current->upsname), &(monhost_ups_current->hostname), &(monhost_ups_current->port)) != 0) { ++ fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); ++ } + +- if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) { +- fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); +- } ++ monhost_ups_current->ups = xmalloc(sizeof(UPSCONN_t)); ++ if (upscli_connect(monhost_ups_current->ups, monhost_ups_current->hostname, monhost_ups_current->port, UPSCLI_CONN_TRYSSL) < 0) ++ fprintf(stderr, "Warning: initial connect failed: %s\n", ++ upscli_strerror(monhost_ups_current->ups)); + +- if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) +- fprintf(stderr, "Warning: initial connect failed: %s\n", +- upscli_strerror(&ups)); ++ if (strcmp(monhost_ups_current->logfn, "-") == 0) ++ monhost_ups_current->logfile = stdout; ++ else ++ monhost_ups_current->logfile = fopen(monhost_ups_current->logfn, "a"); + +- if (strcmp(logfn, "-") == 0) +- logfile = stdout; +- else +- logfile = fopen(logfn, "a"); ++ if (monhost_ups_current->logfile == NULL) ++ fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn); + +- if (logfile == NULL) +- fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn); ++ } + ++ + /* now drop root if we have it */ + new_uid = get_user_pwent(user); + + open_syslog(prog); + + if (foreground < 0) { +- if (logfile == stdout) { ++ if (monhost_ups_anchor->logfile == stdout) { + foreground = 1; + } else { + foreground = 0; +@@ -552,25 +620,35 @@ + reopen_flag = 0; + } + +- /* reconnect if necessary */ +- if (upscli_fd(&ups) < 0) { +- upscli_connect(&ups, hostname, port, 0); +- } ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ ups = monhost_ups_current->ups; /* XXX Not ideal */ ++ upsname = monhost_ups_current->upsname; /* XXX Not ideal */ ++ /* reconnect if necessary */ ++ if (upscli_fd(ups) < 0) { ++ upscli_connect(ups, monhost_ups_current->hostname, monhost_ups_current->port, 0); ++ } + +- run_flist(); ++ run_flist(monhost_ups_current); + +- /* don't keep connection open if we don't intend to use it shortly */ +- if (interval > 30) { +- upscli_disconnect(&ups); ++ /* don't keep connection open if we don't intend to use it shortly */ ++ if (interval > 30) { ++ upscli_disconnect(ups); ++ } + } + } + + upslogx(LOG_INFO, "Signal %d: exiting", exit_flag); ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { + +- if (logfile != stdout) +- fclose(logfile); ++ if (monhost_ups_current->logfile != stdout) ++ fclose(monhost_ups_current->logfile); + +- upscli_disconnect(&ups); ++ upscli_disconnect(monhost_ups_current->ups); ++ } + + exit(EXIT_SUCCESS); + } diff --git a/sysutils/nut-devel/files/patch-docs_man_upslog.txt b/sysutils/nut-devel/files/patch-docs_man_upslog.txt new file mode 100644 index 000000000000..9e139ccb6105 --- /dev/null +++ b/sysutils/nut-devel/files/patch-docs_man_upslog.txt @@ -0,0 +1,14 @@ +--- docs/man/upslog.txt.orig 2022-08-30 05:56:15.850373000 -0700 ++++ docs/man/upslog.txt 2022-08-30 06:01:45.955996000 -0700 +@@ -78,6 +78,11 @@ + Monitor this UPS. The format for this option is + +upsname[@hostname[:port]]+. The default hostname is "localhost". + ++*-m* 'tuple':: ++Monitor multiple UPSs. The format for this option is a tuple of ++ups and logfile separated by commas. An example would be: ++`upsname@hostname:9999,/var/log/nut/cps.log` ++ + *-u* 'username':: + + If started as root, upslog will *setuid*(2) to the user id diff --git a/sysutils/nut/Makefile b/sysutils/nut/Makefile index 1bad77416107..30eb3474f0c3 100644 --- a/sysutils/nut/Makefile +++ b/sysutils/nut/Makefile @@ -1,150 +1,150 @@ PORTNAME= nut PORTVERSION= 2.8.0 -PORTREVISION= 10 +PORTREVISION= 11 CATEGORIES= sysutils MASTER_SITES= http://www.networkupstools.org/source/${PORTVERSION:R}/ MAINTAINER= cy@FreeBSD.org COMMENT= Network UPS Tools LICENSE= GPLv2+ GPLv3+ ART10 GPLv1+ LICENSE_COMB= multi LICENSE_FILE= ${WRKSRC}/COPYING CONFLICTS= nut-devel-* GNU_CONFIGURE= yes USES= autoreconf:build compiler:c11 gmake libtool pkgconfig python:build USE_LDCONFIG= yes NUT_USER?= uucp NUT_GROUP?= uucp STATEDIR?= /var/db/nut PLIST_SUB+= NUT_USER=${NUT_USER} PLIST_SUB+= NUT_GROUP=${NUT_GROUP} CGIDIR?= ${PREFIX}/www/cgi-bin/${PORTNAME} CGIDIR_REL?= ${CGIDIR:S,^${PREFIX}/,,} PLIST_SUB+= CGIDIR="${CGIDIR_REL}" PLIST_SUB+= CGIETCDIR="etc/nut/" OPTIONS_DEFAULT=SERIAL USB SNMP NEON PDU MODBUS CGI BASH AVAHI FREEIPMI DOCS MANPAGES OPENSSL OPTIONS_DEFINE= SERIAL USB SNMP NEON PDU MODBUS CGI BASH AVAHI IPMIPSU FREEIPMI DOCS MANPAGES OPTIONS_SINGLE= IPMI SSL OPTIONS_SINGLE_SSL= SSL_OFF OPENSSL NSS OPTIONS_SUB= yes SERIAL_DESC= SERIAL support USB_DESC= USB support NEON_DESC= NEON XML/HTTP support PDU_DESC= Powerman PDU support MODBUS_DESC= Modbus support CGI_DESC= Web CGI interface FREEIPMI_DESC= freeipmi support IPMIPSU_DESC= Use nut-ipmipsu support (experimental) SSL_OFF_DESC= No SSL support USE_RC_SUBR= nut nut_upsmon nut_upslog SUB_LIST+= STATEDIR=${STATEDIR} PLIST_SUB+= STATEDIR=${STATEDIR} PORTDOCS= * TMPDIR?= /tmp INSTALL_TARGET= install-strip CONFIGURE_ARGS= --sysconfdir=${PREFIX}/etc/nut \ --program-transform-name="" \ --localstatedir=${STATEDIR} \ --datadir=${PREFIX}/etc/nut \ --with-devd-dir=${PREFIX}/etc/devd \ --with-drvpath=${PREFIX}/libexec/nut \ --with-statepath=${STATEDIR} \ --with-altpidpath=${STATEDIR} \ --with-pidpath=${STATEDIR} \ --with-pkgconfig-dir=${PREFIX}/libdata/pkgconfig \ --with-user=${NUT_USER} \ --with-group=${NUT_GROUP} \ --with-dev CFLAGS+= -I${LOCALBASE}/include -L${LOCALBASE}/lib LIB_DEPENDS+= libltdl.so:devel/libltdl MANPAGES_CONFIGURE_ON= --with-doc=man=auto MANPAGES_CONFIGURE_OFF= --with-doc=no CGI_LIB_DEPENDS= libgd.so:graphics/gd CGI_CONFIGURE_WITH= cgi CGI_CONFIGURE_ON= --with-cgipath=${CGIDIR} \ --with-htmlpath=${WWWDIR} \ --with-gd-includes=-I${LOCALBASE}/include \ --with-gd-libs="-L${LOCALBASE}/lib -lgd" SERIAL_CONFIGURE_WITH= serial USB_CONFIGURE_WITH= usb=auto SNMP_LIB_DEPENDS= libnetsnmp.so:net-mgmt/net-snmp SNMP_CONFIGURE_WITH= snmp NEON_LIB_DEPENDS+= libneon.so:www/neon NEON_CONFIGURE_WITH= neon PDU_LIB_DEPENDS+= libpowerman.so:sysutils/powerman PDU_CONFIGURE_WITH= powerman MODBUS_LIB_DEPENDS+= libmodbus.so:comms/libmodbus MODBUS_CONFIGURE_WITH= modbus BASH_BUILD_DEPENDS= ${LOCALBASE}/share/bash-completion/bash_completion.sh:shells/bash-completion BASH_RUN_DEPENDS= ${LOCALBASE}/share/bash-completion/bash_completion.sh:shells/bash-completion AVAHI_BUILD_DEPENDS= ${LOCALBASE}/include/avahi-ui/avahi-ui.h:net/avahi-header AVAHI_BUILD_DEPENDS= avahi-daemon:net/avahi-app AVAHI_RUN_DEPENDS= avahi-daemon:net/avahi-app AVAHI_CONFIGURE_WITH= avahi FREEIPMI_LIB_DEPENDS= libfreeipmi.so:sysutils/freeipmi FREEIPMI_CONFIGURE_WITH=freeipmi IPMIPSU_LIB_DEPENDS= libfreeipmi.so:sysutils/freeipmi IPMIPSU_CONFIGURE_WITH= ipmi OPENSSL_USES= ssl OPENSSL_CONFIGURE_WITH= openssl NSS_LIB_DEPENDS= libnss3.so:security/nss NSS_CONFIGURE_WITH= nss .include post-patch: @${FIND} ${WRKSRC} -type f | ${XARGS} ${REINPLACE_CMD} -i '' -e 's|/usr/bin/env python|${PYTHON_CMD}|' @${FIND} ${WRKSRC} -type f | ${XARGS} ${REINPLACE_CMD} -i '' -e 's|/usr/local/ups|${PREFIX}|' pre-install: @${MKDIR} ${STAGEDIR}${PREFIX}/libexec/nut post-install: @${MKDIR} ${STAGEDIR}${STATEDIR} @${MKDIR} ${STAGEDIR}${PREFIX}/etc/syslog.d .if ${PORT_OPTIONS:MBASH} @${MKDIR} ${STAGEDIR}${PREFIX}/etc/bash_completion.d/ ${INSTALL_DATA} ${WRKSRC}/scripts/misc/nut.bash_completion ${STAGEDIR}${PREFIX}/etc/bash_completion.d/ .endif .if ${PORT_OPTIONS:MDOCS} @${MKDIR} ${STAGEDIR}${DOCSDIR}/cables ${INSTALL_DATA} ${WRKSRC}/docs/cables/*.txt ${STAGEDIR}${DOCSDIR}/cables ${INSTALL_DATA} ${WRKSRC}/docs/*.txt ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${WRKSRC}/docs/FAQ.txt ${STAGEDIR}${DOCSDIR} .for file in AUTHORS COPYING ChangeLog INSTALL MAINTAINERS NEWS README UPGRADING ${INSTALL_DATA} ${WRKSRC}/${file} ${STAGEDIR}${DOCSDIR} .endfor .endif @${MKDIR} ${STAGEDIR}${EXAMPLESDIR} ${INSTALL_DATA} ${PATCHDIR}/nut.syslog ${STAGEDIR}${EXAMPLESDIR}/syslog.sample ${INSTALL_DATA} ${PATCHDIR}/nut.newsyslog ${STAGEDIR}${EXAMPLESDIR}/newsyslog.sample ${INSTALL_DATA} ${PATCHDIR}/nut_upslog.sample ${STAGEDIR}${EXAMPLESDIR}/nut_upslog.sample ${MKDIR} ${STAGEDIR}/var/log/nut @${RM} ${STAGEDIR}${PREFIX}/etc/nut/solaris-init/nut @${RMDIR} ${STAGEDIR}${PREFIX}/etc/nut/solaris-init .include diff --git a/sysutils/nut/files/patch-clients_upslog.c b/sysutils/nut/files/patch-clients_upslog.c new file mode 100644 index 000000000000..bcebe5bba28c --- /dev/null +++ b/sysutils/nut/files/patch-clients_upslog.c @@ -0,0 +1,291 @@ +--- clients/upslog.c.orig 2022-08-29 22:20:14.342137000 -0700 ++++ clients/upslog.c 2022-08-29 22:21:10.934419000 -0700 +@@ -32,6 +32,10 @@ + */ + + #include "common.h" ++#include ++#include ++#include ++#include + #include "nut_platform.h" + #include "upsclient.h" + +@@ -41,32 +45,49 @@ + #include "upslog.h" + + static int reopen_flag = 0, exit_flag = 0; +- static uint16_t port; +- static char *upsname, *hostname; +- static UPSCONN_t ups; ++ static char *upsname; ++ static UPSCONN_t *ups; + +- static FILE *logfile; +- static const char *logfn, *monhost; ++ static char *logfn, *monhost; + static sigset_t nut_upslog_sigmask; + static char logbuffer[LARGEBUF], *logformat; + + static flist_t *fhead = NULL; ++ struct monhost_ups { ++ char *monhost; ++ char *logfn; ++ char *upsname; ++ char *hostname; ++ uint16_t port; ++ UPSCONN_t *ups; ++ FILE *logfile; ++ struct monhost_ups *next; ++ }; ++ static struct monhost_ups *monhost_ups_anchor = NULL; ++ static struct monhost_ups *monhost_ups_current = NULL; ++ static struct monhost_ups *monhost_ups_prev = NULL; + ++ + #define DEFAULT_LOGFORMAT "%TIME @Y@m@d @H@M@S% %VAR battery.charge% " \ + "%VAR input.voltage% %VAR ups.load% [%VAR ups.status%] " \ + "%VAR ups.temperature% %VAR input.frequency%" + + static void reopen_log(void) + { +- if (logfile == stdout) { +- upslogx(LOG_INFO, "logging to stdout"); +- return; +- } ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ if (monhost_ups_current->logfile == stdout) { ++ upslogx(LOG_INFO, "logging to stdout"); ++ return; ++ } + +- fclose(logfile); +- logfile = fopen(logfn, "a"); +- if (logfile == NULL) +- fatal_with_errno(EXIT_FAILURE, "could not reopen logfile %s", logfn); ++ if ((monhost_ups_current->logfile = freopen( ++ monhost_ups_current->logfn, "a", ++ monhost_ups_current->logfile)) == NULL) ++ fatal_with_errno(EXIT_FAILURE, ++ "could not reopen logfile %s", logfn); ++ } + } + + static void set_reopen_flag(int sig) +@@ -131,6 +152,8 @@ + printf(" -p - Base name for PID file (defaults to \"%s\")\n", prog); + printf(" -s - Monitor UPS - @[:]\n"); + printf(" - Example: -s myups@server\n"); ++ printf(" -m - Monitor UPS \n"); ++ printf(" - Example: -m myups@server,/var/log/myups.log\n"); + printf(" -u - Switch to if started as root\n"); + + printf("\n"); +@@ -215,7 +238,7 @@ + query[2] = var; + numq = 3; + +- ret = upscli_get(&ups, numq, query, &numa, &answer); ++ ret = upscli_get(ups, numq, query, &numa, &answer); + + if ((ret < 0) || (numa < numq)) { + snprintfcat(logbuffer, sizeof(logbuffer), "NA"); +@@ -368,7 +391,7 @@ + } + + /* go through the list of functions and call them in order */ +-static void run_flist(void) ++static void run_flist(struct monhost_ups *monhost_ups_print) + { + flist_t *tmp; + +@@ -382,8 +405,8 @@ + tmp = tmp->next; + } + +- fprintf(logfile, "%s\n", logbuffer); +- fflush(logfile); ++ fprintf(monhost_ups_print->logfile, "%s\n", logbuffer); ++ fflush(monhost_ups_print->logfile); + } + + /* -s +@@ -396,6 +419,7 @@ + int main(int argc, char **argv) + { + int interval = 30, i, foreground = -1; ++ size_t monhost_len = 0; + const char *prog = xbasename(argv[0]); + time_t now, nextpoll = 0; + const char *user = NULL; +@@ -407,7 +431,7 @@ + + printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); + +- while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) { ++ while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FBm:")) != -1) { + switch(i) { + case 'h': + help(prog); +@@ -415,6 +439,33 @@ + break; + #endif + ++ case 'm': { /* var scope */ ++ char *m_arg, *s; ++ ++ monhost_ups_prev = monhost_ups_current; ++ monhost_ups_current = xmalloc(sizeof(struct monhost_ups)); ++ if (monhost_ups_anchor == NULL) ++ monhost_ups_anchor = monhost_ups_current; ++ else ++ monhost_ups_prev->next = monhost_ups_current; ++ monhost_ups_current->next = NULL; ++ monhost_len++; ++ ++ /* Be sure to not mangle original optarg, nor rely on its longevity */ ++ s = xstrdup(optarg); ++ m_arg = s; ++ monhost_ups_current->monhost = xstrdup(strsep(&m_arg, ",")); ++ if (!m_arg) ++ fatalx(EXIT_FAILURE, "Argument '-m upsspec,logfile' requires exactly 2 components in the tuple"); ++ monhost_ups_current->logfn = xstrdup(strsep(&m_arg, ",")); ++ if (m_arg) /* Had a third comma - also unexpected! */ ++ fatalx(EXIT_FAILURE, "Argument '-m upsspec,logfile' requires exactly 2 components in the tuple"); ++ if (upscli_splitname(monhost_ups_current->monhost, &(monhost_ups_current->upsname), &(monhost_ups_current->hostname), &(monhost_ups_current->port)) != 0) { ++ fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); ++ } ++ free(s); ++ } /* var scope */ ++ break; + case 's': + monhost = optarg; + break; +@@ -479,42 +530,59 @@ + snprintfcat(logformat, LARGEBUF, "%s ", argv[i]); + } + +- if (!monhost) +- fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s "); ++ if (monhost_ups_anchor == NULL) { ++ if (monhost) { ++ monhost_ups_current = xmalloc(sizeof(struct monhost_ups)); ++ monhost_ups_anchor = monhost_ups_current; ++ monhost_ups_current->next = NULL; ++ monhost_ups_current->monhost = monhost; ++ monhost_len=1; ++ } else { ++ fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s "); ++ } + +- if (!logfn) +- fatalx(EXIT_FAILURE, "No filename defined for logging - use -l "); ++ if (logfn) ++ monhost_ups_current->logfn = logfn; ++ else ++ fatalx(EXIT_FAILURE, "No filename defined for logging - use -l "); ++ } + + /* shouldn't happen */ + if (!logformat) + fatalx(EXIT_FAILURE, "No format defined - but this should be impossible"); + +- printf("logging status of %s to %s (%is intervals)\n", +- monhost, logfn, interval); ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ printf("logging status of %s to %s (%is intervals)\n", ++ monhost_ups_current->monhost, monhost_ups_current->logfn, interval); ++ if (upscli_splitname(monhost_ups_current->monhost, &(monhost_ups_current->upsname), &(monhost_ups_current->hostname), &(monhost_ups_current->port)) != 0) { ++ fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); ++ } + +- if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) { +- fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n"); +- } ++ monhost_ups_current->ups = xmalloc(sizeof(UPSCONN_t)); ++ if (upscli_connect(monhost_ups_current->ups, monhost_ups_current->hostname, monhost_ups_current->port, UPSCLI_CONN_TRYSSL) < 0) ++ fprintf(stderr, "Warning: initial connect failed: %s\n", ++ upscli_strerror(monhost_ups_current->ups)); + +- if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) +- fprintf(stderr, "Warning: initial connect failed: %s\n", +- upscli_strerror(&ups)); ++ if (strcmp(monhost_ups_current->logfn, "-") == 0) ++ monhost_ups_current->logfile = stdout; ++ else ++ monhost_ups_current->logfile = fopen(monhost_ups_current->logfn, "a"); + +- if (strcmp(logfn, "-") == 0) +- logfile = stdout; +- else +- logfile = fopen(logfn, "a"); ++ if (monhost_ups_current->logfile == NULL) ++ fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn); + +- if (logfile == NULL) +- fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn); ++ } + ++ + /* now drop root if we have it */ + new_uid = get_user_pwent(user); + + open_syslog(prog); + + if (foreground < 0) { +- if (logfile == stdout) { ++ if (monhost_ups_anchor->logfile == stdout) { + foreground = 1; + } else { + foreground = 0; +@@ -552,25 +620,35 @@ + reopen_flag = 0; + } + +- /* reconnect if necessary */ +- if (upscli_fd(&ups) < 0) { +- upscli_connect(&ups, hostname, port, 0); +- } ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { ++ ups = monhost_ups_current->ups; /* XXX Not ideal */ ++ upsname = monhost_ups_current->upsname; /* XXX Not ideal */ ++ /* reconnect if necessary */ ++ if (upscli_fd(ups) < 0) { ++ upscli_connect(ups, monhost_ups_current->hostname, monhost_ups_current->port, 0); ++ } + +- run_flist(); ++ run_flist(monhost_ups_current); + +- /* don't keep connection open if we don't intend to use it shortly */ +- if (interval > 30) { +- upscli_disconnect(&ups); ++ /* don't keep connection open if we don't intend to use it shortly */ ++ if (interval > 30) { ++ upscli_disconnect(ups); ++ } + } + } + + upslogx(LOG_INFO, "Signal %d: exiting", exit_flag); ++ for (monhost_ups_current = monhost_ups_anchor; ++ monhost_ups_current != NULL; ++ monhost_ups_current = monhost_ups_current->next) { + +- if (logfile != stdout) +- fclose(logfile); ++ if (monhost_ups_current->logfile != stdout) ++ fclose(monhost_ups_current->logfile); + +- upscli_disconnect(&ups); ++ upscli_disconnect(monhost_ups_current->ups); ++ } + + exit(EXIT_SUCCESS); + } diff --git a/sysutils/nut/files/patch-docs_man_upslog.8 b/sysutils/nut/files/patch-docs_man_upslog.8 new file mode 100644 index 000000000000..37b1379ca6bf --- /dev/null +++ b/sysutils/nut/files/patch-docs_man_upslog.8 @@ -0,0 +1,16 @@ +--- docs/man/upslog.8.orig 2022-08-30 05:56:02.734873000 -0700 ++++ docs/man/upslog.8 2022-08-30 06:09:47.928348000 -0700 +@@ -134,6 +134,13 @@ + upsname[@hostname[:port]]\&. The default hostname is "localhost"\&. + .RE + .PP ++\fB\-m\fR \fItuple\fR ++.RS 4 ++Monitor multiple UPSs\&. The format for this option is a tuple of ++ups and logfile separated by commas\&. An example would be: ++upsname@hostname:9999,/var/log/nut/cps.log ++.RE ++.PP + \fB\-u\fR \fIusername\fR + .RS 4 + If started as root, upslog will diff --git a/sysutils/nut/files/patch-docs_man_upslog.txt b/sysutils/nut/files/patch-docs_man_upslog.txt new file mode 100644 index 000000000000..e26d91e2d5f2 --- /dev/null +++ b/sysutils/nut/files/patch-docs_man_upslog.txt @@ -0,0 +1,14 @@ +--- docs/man/upslog.txt.orig 2022-08-30 05:56:02.761764000 -0700 ++++ docs/man/upslog.txt 2022-08-30 06:04:33.428455000 -0700 +@@ -78,6 +78,11 @@ + Monitor this UPS. The format for this option is + +upsname[@hostname[:port]]+. The default hostname is "localhost". + ++*-m* 'tuple':: ++Monitor multiple UPSs. The format for this option is a tuple of ++ups and logfile separated by commas. An example would be: ++`upsname@hostname:9999,/var/log/nut/cps.log` ++ + *-u* 'username':: + + If started as root, upslog will *setuid*(2) to the user id