summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysutils/Makefile1
-rw-r--r--sysutils/apcctrl/Makefile79
-rw-r--r--sysutils/apcctrl/distinfo3
-rw-r--r--sysutils/apcctrl/files/apcctrl.in83
-rw-r--r--sysutils/apcctrl/files/patch-configure76
-rw-r--r--sysutils/apcctrl/files/patch-include_tcpd.h238
-rw-r--r--sysutils/apcctrl/files/patch-platforms_etc_Makefile21
-rw-r--r--sysutils/apcctrl/files/patch-src_cgi_Makefile15
-rw-r--r--sysutils/apcctrl/files/pkg-message.in32
-rw-r--r--sysutils/apcctrl/pkg-descr15
-rw-r--r--sysutils/apcctrl/pkg-plist30
-rw-r--r--sysutils/apcupsd/Makefile2
12 files changed, 595 insertions, 0 deletions
diff --git a/sysutils/Makefile b/sysutils/Makefile
index 3d8f22cb495e..7d824a14951a 100644
--- a/sysutils/Makefile
+++ b/sysutils/Makefile
@@ -46,6 +46,7 @@
SUBDIR += anvil
SUBDIR += apache-mesos
SUBDIR += apachetop
+ SUBDIR += apcctrl
SUBDIR += apcpwr
SUBDIR += apcupsd
SUBDIR += aptly
diff --git a/sysutils/apcctrl/Makefile b/sysutils/apcctrl/Makefile
new file mode 100644
index 000000000000..40bfb81df0b8
--- /dev/null
+++ b/sysutils/apcctrl/Makefile
@@ -0,0 +1,79 @@
+# Created by: Lars Köller <Lars.Koeller@Uni-Bielefeld.DE>
+# $FreeBSD$
+
+PORTNAME= apcctrl
+PORTVERSION= 0.8.21
+CATEGORIES= sysutils
+MASTER_SITES= SF/${PORTNAME}
+
+MAINTAINER= lobo@bsd.com.br
+COMMENT= Fork of apcupsd 3.14.x with support for Brazilian APC nobreaks
+
+LICENSE= GPLv2
+LICENSE_FILE= ${WRKSRC}/COPYING
+
+USES= gmake
+GNU_CONFIGURE= yes
+CONFIGURE_ARGS= --sbindir=${PREFIX}/sbin \
+ --with-nologin=/var/run \
+ --disable-install-distdir \
+ --sysconfdir=${ETCDIR}
+
+CONFIGURE_ENV+= LD="${CXX}" \
+ ac_cv_path_SHUTDOWN="/sbin/shutdown"
+
+USE_RC_SUBR= apcctrl
+SUB_FILES= pkg-message
+
+CONFLICTS_INSTALL= apcupsd
+
+OPTIONS_DEFINE= APCDUMB_DRV APCSMART_DRV BRAZIL_DRV CGI GAPCMON MODBUS \
+ MODBUS_USB PCNET_DRV SHUTDOWN_POWEROFF SNMP_DRV SNMP_DRV_OLD \
+ TCP_WRAPPERS TEST_DRV USB_DRV
+OPTIONS_DEFAULT= BRAZIL_DRV
+OPTIONS_SUB= yes
+
+APCDUMB_DRV_DESC= Dumb UPS driver support
+APCSMART_DRV_DESC= APC SmartUPS serial driver support
+BRAZIL_DRV_DESC= Brazilian APC-Microsol support
+CGI_DESC= Build CGI programs to show status
+GAPCMON_DESC= Build GTK GUI front-end
+MODBUS_DESC= MODBUS driver support
+MODBUS_USB_DESC= MODBUS USB driver support
+PCNET_DRV_DESC= PowerChute Network Shutdown driver support
+SHUTDOWN_POWEROFF_DESC= Shutdown behavior with Halt and Power off
+SNMP_DRV_DESC= SNMP driver support
+SNMP_DRV_OLD_DESC= Old SNMP driver support
+TCP_WRAPPERS_DESC= ${LIBWRAP_DESC}
+TEST_DRV_DESC= Test driver support
+USB_DRV_DESC= USB driver support
+
+APCDUMB_DRV_CONFIGURE_ENABLE= dumb
+APCSMART_DRV_CONFIGURE_ENABLE= apcsmart
+BRAZIL_DRV_CONFIGURE_ENABLE= brazil
+CGI_CONFIGURE_ENABLE= cgi
+CGI_CONFIGURE_ON= --with-cgi-bin=${ETCDIR}/cgi
+CGI_LIB_DEPENDS= libgd.so:graphics/gd
+GAPCMON_CONFIGURE_ENABLE= gapcmon
+GAPCMON_USES= gnome pkgconfig xorg
+GAPCMON_USE= GNOME=cairo,gconf2,gdkpixbuf2 XORG=x11,xext
+GAPCMON_LIB_DEPENDS= libfontconfig.so:x11-fonts/fontconfig \
+ libfreetype.so:print/freetype2
+GAPCMON_CONFLICTS= gapcmon
+MODBUS_CONFIGURE_ENABLE= modbus
+MODBUS_USB_CONFIGURE_ENABLE= modbus-usb
+PCNET_DRV_CONFIGURE_ENABLE= pcnet
+SNMP_DRV_CONFIGURE_ENABLE= snmp
+SNMP_DRV_OLD_CONFIGURE_ENABLE= net-snmp
+SNMP_DRV_OLD_LIB_DEPENDS= libnetsnmp.so:net-mgmt/net-snmp
+TCP_WRAPPERS_CONFIGURE_WITH= libwrap=yes
+TEST_DRV_CONFIGURE_ENABLE= test
+USB_DRV_CONFIGURE_ENABLE= usb
+
+.include <bsd.port.options.mk>
+
+post-patch-SHUTDOWN_POWEROFF-on:
+ ${REINPLACE_CMD} -e 's|-h now|-p now|' \
+ ${WRKSRC}/platforms/freebsd/apccontrol.in
+
+.include <bsd.port.mk>
diff --git a/sysutils/apcctrl/distinfo b/sysutils/apcctrl/distinfo
new file mode 100644
index 000000000000..fc2e99d48e8a
--- /dev/null
+++ b/sysutils/apcctrl/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1572562006
+SHA256 (apcctrl-0.8.21.tar.gz) = ad3bc43de922f25e98db6e97390034600d094b257458b25ee8677b1c63b0f1bf
+SIZE (apcctrl-0.8.21.tar.gz) = 3531048
diff --git a/sysutils/apcctrl/files/apcctrl.in b/sysutils/apcctrl/files/apcctrl.in
new file mode 100644
index 000000000000..56fd4f3b557a
--- /dev/null
+++ b/sysutils/apcctrl/files/apcctrl.in
@@ -0,0 +1,83 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+# PROVIDE: apcctrl
+# REQUIRE: SERVERS
+# BEFORE: DAEMON
+# KEYWORD: shutdown
+#
+# Add the following line to /etc/rc.conf[.local] to enable apcctrl
+#
+# apcctrl_enable (bool): Set to "NO" by default.
+# Set it to "YES" to enable apcctrl.
+# apcctrl_flags (str): Custom additional arguments to be passed
+# to apcctrl (default --kill-on-powerfail).
+# apcctrl_configs (str): A list of configs to run multiple instances.
+#
+
+. /etc/rc.subr
+
+name=apcctrl
+rcvar=apcctrl_enable
+
+load_rc_config $name
+
+: ${apcctrl_enable="NO"}
+: ${apcctrl_flags="--kill-on-powerfail"}
+
+pidfile=/var/run/${name}.pid
+required_files="${apcctrl_configs:-%%ETCDIR%%/apcctrl.conf}"
+command=%%PREFIX%%/sbin/${name}
+restart_cmd=${name}_restart_cmd
+
+apcctrl_precmd()
+{
+ config=$1
+
+ dn="`/usr/bin/dirname ${pidfile}`"
+ if [ -n "${config}" ]; then
+ # Specific config
+ base="`/usr/bin/basename ${config} .conf`"
+ pidfile="${dn}/${base}.pid"
+ command_args="-f ${config} -P ${pidfile}"
+ else
+ # Default config
+ command_args=""
+ fi
+}
+
+apcctrl_restart_cmd()
+{
+ if [ -n "${apcctrl_configs}" ]; then
+ # One or more named configs
+ for config in ${apcctrl_configs}; do
+ apcctrl_precmd ${config}
+ run_rc_command stop
+ done
+ for config in ${apcctrl_configs}; do
+ apcctrl_precmd ${config}
+ run_rc_command start
+ done
+ else
+ # Default config
+ apcctrl_precmd
+ run_rc_command stop
+ run_rc_command start
+ fi
+}
+
+if [ "$1" = restart ]; then
+ apcctrl_precmd
+ run_rc_command $1
+elif [ -n "${apcctrl_configs}" ]; then
+ # One or more named configs
+ for config in ${apcctrl_configs}; do
+ apcctrl_precmd ${config}
+ run_rc_command $1
+ done
+else
+ # Default config
+ apcctrl_precmd
+ run_rc_command $1
+fi
diff --git a/sysutils/apcctrl/files/patch-configure b/sysutils/apcctrl/files/patch-configure
new file mode 100644
index 000000000000..f85b164c2cb2
--- /dev/null
+++ b/sysutils/apcctrl/files/patch-configure
@@ -0,0 +1,76 @@
+--- configure.orig 2016-04-18 20:26:31 UTC
++++ configure
+@@ -7470,7 +7470,7 @@
+ $as_echo_n "checking for libwrap... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+- #include <tcpd.h>
++ #include "tcpd.h"
+ int deny_severity = 0;
+ int allow_severity = 0;
+ struct request_info *req;
+@@ -7493,7 +7493,7 @@
+ LIBS="$saved_LIBS -lwrap -lnsl"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+- #include <tcpd.h>
++ ##include "tcpd.h"
+ int deny_severity = 0;
+ int allow_severity = 0;
+ struct request_info *req;
+@@ -8548,55 +8548,6 @@
+ ;;
+ esac
+
+-if test -n "$GCC"; then
+- # Starting with GCC 3.0, you must link C++ programs against either
+- # libstdc++ (shared by default), or libsupc++ (always static). If
+- # you care about binary portability between Linux distributions,
+- # you need to either 1) build your own GCC with static C++ libraries
+- # or 2) link using gcc and libsupc++. We choose the latter since
+- # CUPS doesn't (currently) use any of the stdc++ library.
+- #
+- # Previous versions of GCC do not have the reliance on the stdc++
+- # or g++ libraries, so the extra supc++ library is not needed.
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libsupc++ is required" >&5
+-$as_echo_n "checking if libsupc++ is required... " >&6; }
+-
+- SUPC="`$CXX -print-file-name=libsupc++.a 2>/dev/null`"
+- case "$SUPC" in
+- libsupc++.a*)
+- # Library not found, so this is an older GCC...
+- LD="$CXX"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+- ;;
+- *)
+- # This is gcc 3.x, and it knows of libsupc++, so we need it
+- LIBS="$LIBS -lsupc++"
+- LD="$CC"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+- # See if this system has a broken libsupc++ that requires
+- # a workaround (FreeBSD 5.x, 6.x)
+- case $host in
+- *-*-freebsd*)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libsupc++ is missing __terminate_handler" >&5
+-$as_echo_n "checking if libsupc++ is missing __terminate_handler... " >&6; }
+- nm -C --defined-only "$SUPC" 2>/dev/null | grep __terminate_handler > /dev/null
+- if test $? -eq 0 ; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+- else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes -- will attempt workaround" >&5
+-$as_echo "yes -- will attempt workaround" >&6; }
+- LIBEXTRAOBJ="$LIBEXTRAOBJ libsupc++fix.cpp"
+- fi
+- ;;
+- esac
+- ;;
+- esac
+-fi
+-
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-exceptions" >&5
+ $as_echo_n "checking whether C compiler accepts -fno-exceptions... " >&6; }
+ if ${ax_cv_check_cflags___fno_exceptions+:} false; then :
diff --git a/sysutils/apcctrl/files/patch-include_tcpd.h b/sysutils/apcctrl/files/patch-include_tcpd.h
new file mode 100644
index 000000000000..f10f683e157a
--- /dev/null
+++ b/sysutils/apcctrl/files/patch-include_tcpd.h
@@ -0,0 +1,238 @@
+--- include/tcpd.h.orig 2016-06-15 10:03:22 UTC
++++ include/tcpd.h
+@@ -0,0 +1,235 @@
++ /*
++ * @(#) tcpd.h 1.5 96/03/19 16:22:24
++ *
++ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
++ */
++
++/*
++ * This version of the file has been hacked over by
++ * Kern Sibbald to make it compatible with C++ for
++ * the few functions that Bacula uses. 19 April 2002
++ * It now compiles with C++ but remains untested.
++ * A correct fix would require significantly more work.
++ */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Structure to describe one communications endpoint. */
++
++#define STRING_LENGTH 128 /* hosts, users, processes */
++
++struct host_info {
++ char name[STRING_LENGTH]; /* access via eval_hostname(host) */
++ char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */
++ struct sockaddr_in *sin; /* socket address or 0 */
++ struct t_unitdata *unit; /* TLI transport address or 0 */
++ struct request_info *request; /* for shared information */
++};
++
++/* Structure to describe what we know about a service request. */
++
++struct request_info {
++ int fd; /* socket handle */
++ char user[STRING_LENGTH]; /* access via eval_user(request) */
++ char daemon[STRING_LENGTH]; /* access via eval_daemon(request) */
++ char pid[10]; /* access via eval_pid(request) */
++ struct host_info client[1]; /* client endpoint info */
++ struct host_info server[1]; /* server endpoint info */
++ void (*sink) (void); /* datagram sink function or 0 */
++ void (*hostname) (void); /* address to printable hostname */
++ void (*hostaddr) (void); /* address to printable address */
++ void (*cleanup) (void); /* cleanup function or 0 */
++ struct netconfig *config; /* netdir handle */
++};
++
++/* Common string operations. Less clutter should be more readable. */
++
++#define STRN_CPY(d,s,l) { strncpy((d),(s),(l)); (d)[(l)-1] = 0; }
++
++#define STRN_EQ(x,y,l) (strncasecmp((x),(y),(l)) == 0)
++#define STRN_NE(x,y,l) (strncasecmp((x),(y),(l)) != 0)
++#define STR_EQ(x,y) (strcasecmp((x),(y)) == 0)
++#define STR_NE(x,y) (strcasecmp((x),(y)) != 0)
++
++ /*
++ * Initially, all above strings have the empty value. Information that
++ * cannot be determined at runtime is set to "unknown", so that we can
++ * distinguish between `unavailable' and `not yet looked up'. A hostname
++ * that we do not believe in is set to "paranoid".
++ */
++
++#define STRING_UNKNOWN "unknown" /* lookup failed */
++#define STRING_PARANOID "paranoid" /* hostname conflict */
++
++extern char unknown[];
++extern char paranoid[];
++
++#define HOSTNAME_KNOWN(s) (STR_NE((s),unknown) && STR_NE((s),paranoid))
++
++#define NOT_INADDR(s) (s[strspn(s,"01234567890./")] != 0)
++
++/* Global functions. */
++
++#if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT)
++extern void fromhost(); /* get/validate client host info */
++#else
++#define fromhost sock_host /* no TLI support needed */
++#endif
++
++extern int hosts_access(struct request_info *); /* access control */
++extern void shell_cmd(void); /* execute shell command */
++extern char *percent_x(void); /* do %<char> expansion */
++extern void rfc931(void); /* client name from RFC 931 daemon */
++extern void clean_exit(void); /* clean up and exit */
++extern void refuse(void); /* clean up and exit */
++extern char *xgets(void); /* fgets() on steroids */
++extern char *split_at(void); /* strchr() and split */
++extern unsigned long dot_quad_addr(void); /* restricted inet_addr() */
++
++/* Global variables. */
++
++extern int allow_severity; /* for connection logging */
++extern int deny_severity; /* for connection logging */
++extern char *hosts_allow_table; /* for verification mode redirection */
++extern char *hosts_deny_table; /* for verification mode redirection */
++extern int hosts_access_verbose; /* for verbose matching mode */
++extern int rfc931_timeout; /* user lookup timeout */
++extern int resident; /* > 0 if resident process */
++
++ /*
++ * Routines for controlled initialization and update of request structure
++ * attributes. Each attribute has its own key.
++ */
++
++#ifdef __STDC__
++extern struct request_info *request_init(struct request_info *,...);
++extern struct request_info *request_set(struct request_info *,...);
++#else
++extern struct request_info *request_init(); /* initialize request */
++extern struct request_info *request_set(); /* update request structure */
++#endif
++
++#define RQ_FILE 1 /* file descriptor */
++#define RQ_DAEMON 2 /* server process (argv[0]) */
++#define RQ_USER 3 /* client user name */
++#define RQ_CLIENT_NAME 4 /* client host name */
++#define RQ_CLIENT_ADDR 5 /* client host address */
++#define RQ_CLIENT_SIN 6 /* client endpoint (internal) */
++#define RQ_SERVER_NAME 7 /* server host name */
++#define RQ_SERVER_ADDR 8 /* server host address */
++#define RQ_SERVER_SIN 9 /* server endpoint (internal) */
++
++ /*
++ * Routines for delayed evaluation of request attributes. Each attribute
++ * type has its own access method. The trivial ones are implemented by
++ * macros. The other ones are wrappers around the transport-specific host
++ * name, address, and client user lookup methods. The request_info and
++ * host_info structures serve as caches for the lookup results.
++ */
++
++extern char *eval_user(void); /* client user */
++extern char *eval_hostname(void); /* printable hostname */
++extern char *eval_hostaddr(void); /* printable host address */
++extern char *eval_hostinfo(void); /* host name or address */
++extern char *eval_client(struct request_info *); /* whatever is available */
++extern char *eval_server(void); /* whatever is available */
++#define eval_daemon(r) ((r)->daemon) /* daemon process name */
++#define eval_pid(r) ((r)->pid) /* process id */
++
++/* Socket-specific methods, including DNS hostname lookups. */
++
++extern void sock_host(struct request_info *);
++extern void sock_hostname(void); /* translate address to hostname */
++extern void sock_hostaddr(void); /* address to printable address */
++#define sock_methods(r) \
++ { (r)->hostname = sock_hostname; (r)->hostaddr = sock_hostaddr; }
++
++/* The System V Transport-Level Interface (TLI) interface. */
++
++#if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT)
++extern void tli_host(); /* look up endpoint addresses etc. */
++#endif
++
++ /*
++ * Problem reporting interface. Additional file/line context is reported
++ * when available. The jump buffer (tcpd_buf) is not declared here, or
++ * everyone would have to include <setjmp.h>.
++ */
++
++#ifdef __STDC__
++extern void tcpd_warn(char *, ...); /* report problem and proceed */
++extern void tcpd_jump(char *, ...); /* report problem and jump */
++#else
++extern void tcpd_warn();
++extern void tcpd_jump();
++#endif
++
++struct tcpd_context {
++ char *file; /* current file */
++ int line; /* current line */
++};
++extern struct tcpd_context tcpd_context;
++
++ /*
++ * While processing access control rules, error conditions are handled by
++ * jumping back into the hosts_access() routine. This is cleaner than
++ * checking the return value of each and every silly little function. The
++ * (-1) returns are here because zero is already taken by longjmp().
++ */
++
++#define AC_PERMIT 1 /* permit access */
++#define AC_DENY (-1) /* deny_access */
++#define AC_ERROR AC_DENY /* XXX */
++
++ /*
++ * In verification mode an option function should just say what it would do,
++ * instead of really doing it. An option function that would not return
++ * should clear the dry_run flag to inform the caller of this unusual
++ * behavior.
++ */
++
++extern void process_options(void); /* execute options */
++extern int dry_run; /* verification flag */
++
++/* Bug workarounds. */
++
++#ifdef INET_ADDR_BUG /* inet_addr() returns struct */
++#define inet_addr fix_inet_addr
++extern long fix_inet_addr(void);
++#endif
++
++#ifdef BROKEN_FGETS /* partial reads from sockets */
++#define fgets fix_fgets
++extern char *fix_fgets(void);
++#endif
++
++#ifdef RECVFROM_BUG /* no address family info */
++#define recvfrom fix_recvfrom
++extern int fix_recvfrom(void);
++#endif
++
++#ifdef GETPEERNAME_BUG /* claims success with UDP */
++#define getpeername fix_getpeername
++extern int fix_getpeername(void);
++#endif
++
++#ifdef SOLARIS_24_GETHOSTBYNAME_BUG /* lists addresses as aliases */
++#define gethostbyname fix_gethostbyname
++extern struct hostent *fix_gethostbyname(void);
++#endif
++
++#ifdef USE_STRSEP /* libc calls strtok(void) */
++#define strtok fix_strtok
++extern char *fix_strtok(void);
++#endif
++
++#ifdef LIBC_CALLS_STRTOK /* libc calls strtok() */
++#define strtok my_strtok
++extern char *my_strtok(void);
++#endif
++
++#ifdef __cplusplus
++}
++#endif
diff --git a/sysutils/apcctrl/files/patch-platforms_etc_Makefile b/sysutils/apcctrl/files/patch-platforms_etc_Makefile
new file mode 100644
index 000000000000..5ce0d6cd4e26
--- /dev/null
+++ b/sysutils/apcctrl/files/patch-platforms_etc_Makefile
@@ -0,0 +1,21 @@
+--- platforms/etc/Makefile.orig 2014-04-09 22:15:34 UTC
++++ platforms/etc/Makefile
+@@ -8,12 +8,12 @@ all-uninstall: uninstall-etc
+
+ install-etc:
+ $(call MKDIR,$(sysconfdir))
+- $(call INSTNEW,644,apcctrl.conf,$(sysconfdir))
+- $(call INSTORIG,744,changeme,$(sysconfdir))
+- $(call INSTORIG,744,commfailure,$(sysconfdir))
+- $(call INSTORIG,744,commok,$(sysconfdir))
+- $(call INSTORIG,744,offbattery,$(sysconfdir))
+- $(call INSTORIG,744,onbattery,$(sysconfdir))
++ $(call INSTDATA,644,apcctrl.conf,$(sysconfdir)/apcctrl.conf.sample)
++ $(call INSTDATA,744,changeme,$(sysconfdir)/changeme.sample)
++ $(call INSTDATA,744,commfailure,$(sysconfdir)/commfailure.sample)
++ $(call INSTDATA,744,commok,$(sysconfdir)/commok.sample)
++ $(call INSTDATA,744,offbattery,$(sysconfdir)/offbattery.sample)
++ $(call INSTDATA,744,onbattery,$(sysconfdir)/onbattery.sample)
+
+ uninstall-etc:
+
diff --git a/sysutils/apcctrl/files/patch-src_cgi_Makefile b/sysutils/apcctrl/files/patch-src_cgi_Makefile
new file mode 100644
index 000000000000..d27a7f4cf4d2
--- /dev/null
+++ b/sysutils/apcctrl/files/patch-src_cgi_Makefile
@@ -0,0 +1,15 @@
+--- src/cgi/Makefile.orig 2014-11-04 19:17:43 UTC
++++ src/cgi/Makefile
+@@ -43,9 +43,9 @@ install-cgi:
+ $(call INSTPROG,755,upsfstats.cgi,$(cgibin))
+ $(call INSTPROG,755,upsimage.cgi,$(cgibin))
+ $(call MKDIR,$(sysconfdir))
+- $(call INSTNEW,644,apcctrl.css,$(sysconfdir))
+- $(call INSTNEW,644,$(topdir)/platforms/etc/hosts.conf,$(sysconfdir))
+- $(call INSTNEW,644,$(topdir)/platforms/etc/multimon.conf,$(sysconfdir))
++ $(call INSTDATA,644,apcctrl.css,$(sysconfdir)/apcctrl.css.sample)
++ $(call INSTDATA,644,$(topdir)/platforms/etc/hosts.conf,$(sysconfdir)/hosts.conf.sample)
++ $(call INSTDATA,644,$(topdir)/platforms/etc/multimon.conf,$(sysconfdir)/multimon.conf.sample)
+
+ uninstall-cgi:
+ $(call UNINST,$(cgibin)/multimon.cgi)
diff --git a/sysutils/apcctrl/files/pkg-message.in b/sysutils/apcctrl/files/pkg-message.in
new file mode 100644
index 000000000000..1c627be5ba81
--- /dev/null
+++ b/sysutils/apcctrl/files/pkg-message.in
@@ -0,0 +1,32 @@
+[
+{ type: install
+ message: <<EOM
+
+Sample files and scripts are installed in %%ETCDIR%%.
+
+Some examples of devices:
+ /dev/ttyU0 /dev/ttyUSB.nobreak
+ /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2
+ /dev/ttyACM0 /dev/ttyACM1 /dev/ttyACM2
+
+Add apcctrl_enable=YES to your /etc/rc.conf[.local] to have apcctrl
+starting up at boot time.
+
+For default, apcctrl starts with `--kill-on-powerfail` parameter.
+Please, read its man page, and if this is not the intended behavior you want,
+change it accordingly.
+
+In some systems where the shutdown can take a while (like in bhyve environment),
+you may want to change this behavior as follows:
+
+Set apcctrl_flags="--term-on-powerfail" on your /etc/rc.conf[.local].
+
+Add this to /etc/rc.shutdown, after the "Insert other shutdown procedures here"
+line:
+ test -f /var/run/powerfail && /usr/local/sbin/apcctrl --hibernate
+ or
+ test -f /var/run/powerfail && /usr/local/sbin/apcctrl --power-off
+
+EOM
+}
+]
diff --git a/sysutils/apcctrl/pkg-descr b/sysutils/apcctrl/pkg-descr
new file mode 100644
index 000000000000..d6310595e940
--- /dev/null
+++ b/sysutils/apcctrl/pkg-descr
@@ -0,0 +1,15 @@
+ApcCtrl is an unofficial branch from apcupsd 3.14.x. It can be
+used for controlling Brazilian APC UPS models (herited from Microsol).
+
+Models supported or in tests:
+ - BACK-UPS BR 1200VA (BZ1200BI-BR)
+ - BACK-UPS BR 1500VA (BZ1500PBI-BR)
+ - BACK-UPS BR 2200VA (BZ2200BI-BR and BZ2200I-BR)
+ - SMART-UPS BR 1000VA (SUA1000BI-BR and SOLIS1000BI)
+ - SMART-UPS BR 1500VA (SUA1500BI-BR and SOLIS1500BI)
+ - SMART-UPS BR 2000VA (SUA2000BI-BR)
+ - SMART-UPS BR 3000VA (SUA3000BI-BR)
+ - STAY 800 (PS800)
+ - STAY 700 (PS700)
+
+WWW: http://www.apcctrl.com.br
diff --git a/sysutils/apcctrl/pkg-plist b/sysutils/apcctrl/pkg-plist
new file mode 100644
index 000000000000..73c895c891ef
--- /dev/null
+++ b/sysutils/apcctrl/pkg-plist
@@ -0,0 +1,30 @@
+sbin/apcctrl
+sbin/apcaccess
+sbin/apctest
+@sample %%ETCDIR%%/apcctrl.conf.sample
+%%ETCDIR%%/apccontrol
+@sample %%ETCDIR%%/changeme.sample
+@sample %%ETCDIR%%/commfailure.sample
+@sample %%ETCDIR%%/commok.sample
+@sample %%ETCDIR%%/onbattery.sample
+@sample %%ETCDIR%%/offbattery.sample
+%%CGI%%@sample %%ETCDIR%%/apcctrl.css.sample
+%%CGI%%@sample %%ETCDIR%%/hosts.conf.sample
+%%CGI%%@sample %%ETCDIR%%/multimon.conf.sample
+%%CGI%%%%ETCDIR%%/cgi/multimon.cgi
+%%CGI%%%%ETCDIR%%/cgi/upsfstats.cgi
+%%CGI%%%%ETCDIR%%/cgi/upsimage.cgi
+%%CGI%%%%ETCDIR%%/cgi/upsstats.cgi
+%%GAPCMON%%bin/gapcmon
+%%GAPCMON%%share/applications/gapcmon.desktop
+%%GAPCMON%%share/pixmaps/apcctrl.png
+%%GAPCMON%%share/pixmaps/charging.png
+%%GAPCMON%%share/pixmaps/gapc_prefs.png
+%%GAPCMON%%share/pixmaps/onbatt.png
+%%GAPCMON%%share/pixmaps/online.png
+%%GAPCMON%%share/pixmaps/unplugged.png
+man/man5/apcctrl.conf.5.gz
+man/man8/apcaccess.8.gz
+man/man8/apccontrol.8.gz
+man/man8/apctest.8.gz
+man/man8/apcctrl.8.gz
diff --git a/sysutils/apcupsd/Makefile b/sysutils/apcupsd/Makefile
index 6fba358ca225..032547162290 100644
--- a/sysutils/apcupsd/Makefile
+++ b/sysutils/apcupsd/Makefile
@@ -27,6 +27,8 @@ CONFIGURE_ENV+= LD="${CXX}" \
USE_RC_SUBR= apcupsd
SUB_FILES= pkg-message
+CONFLICTS_INSTALL= apcctrl
+
OPTIONS_DEFINE= APCDUMB_DRV APCSMART_DRV CGI CLIENT_ONLY DOCS GAPCMON MODBUS \
MODBUS_USB PCNET_DRV SHUTDOWN_POWEROFF SNMP_DRV SNMP_DRV_OLD \
TCP_WRAPPERS TEST_DRV USB_DRV