diff options
author | Emanuel Haupt <ehaupt@FreeBSD.org> | 2018-07-07 11:33:50 +0000 |
---|---|---|
committer | Emanuel Haupt <ehaupt@FreeBSD.org> | 2018-07-07 11:33:50 +0000 |
commit | 778e0ad74ff3398d5b94767c47911fae02af963d (patch) | |
tree | d311a53f381bc6375b8a4fc6fac2491fcfa89aba /net/socat | |
parent | 1388dc54c94c6aa80065575a70fb648c8b9147d1 (diff) | |
download | ports-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/Makefile | 6 | ||||
-rw-r--r-- | net/socat/files/socat-instances.conf.sample | 43 | ||||
-rw-r--r-- | net/socat/files/socat.in | 148 |
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 + |