aboutsummaryrefslogtreecommitdiff
path: root/net/socat
diff options
context:
space:
mode:
authorEmanuel Haupt <ehaupt@FreeBSD.org>2018-07-07 11:33:50 +0000
committerEmanuel Haupt <ehaupt@FreeBSD.org>2018-07-07 11:33:50 +0000
commit778e0ad74ff3398d5b94767c47911fae02af963d (patch)
treed311a53f381bc6375b8a4fc6fac2491fcfa89aba /net/socat
parent1388dc54c94c6aa80065575a70fb648c8b9147d1 (diff)
downloadports-778e0ad74ff3398d5b94767c47911fae02af963d.tar.gz
ports-778e0ad74ff3398d5b94767c47911fae02af963d.zip
Add multi-instances rc(8) support by using a config file.
PR: 226405 Submitted by: Harald Schmalzbauer <bugzilla.freebsd@omnilan.de>
Notes
Notes: svn path=/head/; revision=474074
Diffstat (limited to 'net/socat')
-rw-r--r--net/socat/Makefile6
-rw-r--r--net/socat/files/socat-instances.conf.sample43
-rw-r--r--net/socat/files/socat.in148
3 files changed, 192 insertions, 5 deletions
diff --git a/net/socat/Makefile b/net/socat/Makefile
index b72f861ca223..27768dbdca5b 100644
--- a/net/socat/Makefile
+++ b/net/socat/Makefile
@@ -3,7 +3,7 @@
PORTNAME= socat
PORTVERSION= 1.7.3.2
-PORTREVISION= 3
+PORTREVISION= 4
CATEGORIES= net ipv6
MASTER_SITES= http://www.dest-unreach.org/socat/download/ \
LOCAL/ehaupt
@@ -22,7 +22,8 @@ CPE_VENDOR= dest-unreach
PORTSCOUT= skipv:2.0.0-b2
-PLIST_FILES= bin/filan bin/procan bin/socat man/man1/socat.1.gz
+PLIST_FILES= bin/filan bin/procan bin/socat man/man1/socat.1.gz \
+ "@sample etc/socat-instances.conf.sample"
PORTDOCS= EXAMPLES README SECURITY FAQ
OPTIONS_DEFINE= DOCS READLINE
@@ -48,5 +49,6 @@ do-install:
${INSTALL_MAN} ${WRKSRC}/doc/${PORTNAME}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1
@${MKDIR} ${STAGEDIR}${DOCSDIR}
cd ${WRKSRC} && ${INSTALL_DATA} ${PORTDOCS} ${STAGEDIR}${DOCSDIR}
+ ${INSTALL_DATA} ${FILESDIR}/socat-instances.conf.sample ${STAGEDIR}${PREFIX}/etc
.include <bsd.port.post.mk>
diff --git a/net/socat/files/socat-instances.conf.sample b/net/socat/files/socat-instances.conf.sample
new file mode 100644
index 000000000000..ff4c20d1e814
--- /dev/null
+++ b/net/socat/files/socat-instances.conf.sample
@@ -0,0 +1,43 @@
+# socat-instances.conf.sample
+# This config file is evaluated by the rc script from the FreeBSD
+# port of net/socat.
+# It is not related to socat(1) itself!
+# This file is shell syntax.
+
+# Each instance to be daemonized must be defined with a line starting
+# with [instancename]. instancename can be any alnum and is case insensitive
+# (will internally be converted to upper case).
+
+#[ntp4]
+# Default socat_daemonuser=nobody won't be able to open sockets with port numbers
+# below 1024.
+#daemonuser=root
+#flags="UDP4-RECVFROM:123,fork,bind=192.0.2.20 UDP4-SENDTO:169.254.0.53:123"
+
+#[ntp6]
+#daemonuser=root
+#flags="UDP6-RECVFROM:123,fork,bind=[2001:DB8::1:2:3] UDP4-SENDTO:169.254.0.53:123"
+
+
+#
+# Variable definitions:
+#
+# daemonuser (optional):
+# Overrides socat_daemonuser= from rc.conf if defined or the
+# rc scripts builtin default (nobody).
+# daemon(8) will run socat as this user.
+#
+# pidfile (optional):
+# If not defined, /var/run/socat_INSTANCENAME.pid will be used
+# (will be derived from rc script's default, which is /var/run/socat.pid).
+#
+# flags (mandatory):
+# See socat(1).
+#
+# service(8)/rc(8) "start" commands will skip instances without flags defined,
+# while "stop" commands will try to stop any present instance section.
+#
+# To control a single instance, you can append one instance name to the
+# rc(8) command.
+# Otherwise all uncommented instance definitions in this file will be processed.
+
diff --git a/net/socat/files/socat.in b/net/socat/files/socat.in
index 4decee3198a0..7419b8325f36 100644
--- a/net/socat/files/socat.in
+++ b/net/socat/files/socat.in
@@ -11,7 +11,8 @@
# Add the following lines to /etc/rc.conf to enable socat:
# socat_enable="YES"
-# socat_flags="<set as needed>"
+# socat_daemonuser="root" for priviledged ports e.g.
+# socat_flags="<set as needed>" or create /usr/local/etc/socat-instances.conf
. /etc/rc.subr
@@ -21,12 +22,16 @@ rcvar=socat_enable
load_rc_config $name
: ${socat_enable="NO"}
+: ${socat_daemonuser:=nobody}
+: ${socat_config:=%%PREFIX%%/etc/socat-instances.conf}
start_precmd="socat_prestart"
pidfile=/var/run/socat.pid
procname="%%PREFIX%%/bin/socat"
command=/usr/sbin/daemon
-command_args=" -f -p ${pidfile} ${procname} ${socat_flags}"
+command_args=' -f -p ${pidfile} -u ${socat_daemonuser} ${procname} ${socat_flags}'
+
+[ -n "${2}" ] && socat_instance_arg=`echo "${2}" | tr '[:lower:]' '[:upper:]'`
socat_prestart()
{
@@ -36,4 +41,141 @@ socat_prestart()
rc_flags=""
}
-run_rc_command "$1"
+socat_parse_instances()
+{
+ local _line _section_search
+
+ socat_instances=`grep -Eo "^[[:blank:]]*\[[[:alnum:]_]+\]" ${socat_config} |
+ tr '[:lower:]' '[:upper:]'`
+
+ if [ -n "${socat_instance_arg}" ] && ! echo "${socat_instances}" |
+ grep -q -E '(^|[[:blank:]])\['${socat_instance_arg}'\]([[:blank:]]|$)'
+ then
+ echo -n "$name: Can't find instance definition " >&2
+ echo "\"[${1}]\" in config file ${socat_config}." >&2
+ return 1
+ fi
+
+ [ -n "${socat_instance_arg}" ] && socat_instances="[${socat_instance_arg}]"
+
+ for i in ${socat_instances}; do
+ _section_search=1
+ _instance=${i#[}
+ _instance=${_instance%]}
+
+ # Process each line of the optional config file, which
+ # matches the regex, defined at the end of the loop.
+ # There we filter to only process definitions and section separators.
+ while read -r _line; do
+
+ # Look for ${i} section until found
+ if [ ${_section_search} ]; then
+ if echo "${_line}" | grep -qi "^[[:blank:]]*\[${_instance}\]"; then
+ unset _section_search
+ continue # Nothing to do with section identifiers
+ else
+ # Continue with next line s_instance we haven't reached our section yet
+ continue
+ fi
+ fi
+
+ # Stop processing if the current line is another section identifier.
+ echo "${_line}" | grep -q "^[[:blank:]]*\[[^]]*\]" && break
+
+ # Only proceed with lines which contain variable declaration.
+ echo "${_line}" | grep -q -E \
+ -e "^[[:blank:]]*[[:alpha:]_][[:alnum:]_]{0,30}=" ||
+ continue
+ # Filter malformed lines (which could cause command execution)
+ # (shell exits with test result, wich is false as soon as
+ # there's a 2nd argument (1st is considered as 0))
+ eval sh -c \'[ \$# -eq 0 ]\' "${_line}" \|\| continue
+
+ eval socat_${_instance}_${_line%%=*}=${_line#*=}
+
+ done << EOCFF
+$(cat "${socat_config}")
+EOCFF
+ done
+}
+
+# Check if daemon(8) handles title and syslog parameters
+# (as in FreeBSD 11).
+if [ "${1%start}" != "${1}" ]; then
+ daemon_extended_args=" -l daemon"
+ ${command} -t "test" ${daemon_extended_args} -f -u nobody true \
+ > /dev/null 2>&1 || unset daemon_extended_args
+fi
+
+
+# If we can read the config file, handle multiple instances,
+# else just process a single instance.
+if [ -r ${socat_config} ]; then
+
+ # T O D O : Check rc(8) how restarts are handled and make
+ # all-instaces restart working.
+ # For now refuse restart commands without instance argument.
+ #
+ if [ "${1%restart}" != "${1}" ] && [ -z "${socat_instance_arg}" ]; then
+ echo -n "$name: Restart command requires a instance argument,"
+ echo "since config file is in use."
+ exit 1
+ fi
+
+ if [ -n "${socat_flags}" ]; then
+ echo -n "${name}: WARNING:"
+ echo -n " Ignoring \"socat_flags\" in rc.conf because"
+ echo " \"${socat_config}\" is present."
+ fi
+
+ socat_parse_instances "${2}" || exit 1
+
+ default_pidfile="${pidfile}"
+ default_socat_daemonuser="${socat_daemonuser}"
+ eval default_command_args=\'${command_args}\'
+
+ for i in ${socat_instances}; do
+ _instance=${i#[}
+ _instance=${_instance%]}
+
+ eval socat_flags=\"\$\{socat_${_instance}_flags\}\"
+
+ # We need to have socat_flags to start, else skip start commands
+ if [ "${1%start}" != "${1}" ] && [ -z "${socat_flags}" ]; then
+ echo -n "$name: Missing \"flags\" definition for"
+ echo " instance ${i}, skipping \"${1}\" command."
+ continue
+ fi
+
+ eval pidfile=\"\$\{socat_${_instance}_pidfile\}\"
+ [ -n "${pidfile}" ] ||
+ pidfile="${default_pidfile%.pid}_${_instance}.pid"
+
+ eval socat_daemonuser=\"\$\{socat_${_instance}_daemonuser\}\"
+ [ -n "${socat_daemonuser}" ] ||
+ socat_daemonuser="${default_socat_daemonuser}"
+
+ eval command_args=\"${default_command_args}\"
+ if [ -n "${daemon_extended_args}" ]; then
+ # A bit confusing, but to keep 80 chars line break:
+ command_args="(${_instance})\" ${command_args}"
+ command_args="-t \"${procname} ${command_args}"
+ command_args="${daemon_extended_args} ${command_args}"
+ fi
+
+ run_rc_command "$1"
+ done
+
+else
+
+ if [ -n "${socat_instance_arg}" ]; then
+ echo -n "$name: Missing config file (${socat_config}), " >&2
+ echo "can't handle instance \"${2}\"." >&2
+ exit 1
+ fi
+
+ eval command_args=\"${daemon_extended_args} ${command_args}\"
+ run_rc_command "$1"
+
+fi
+