From owner-svn-ports-head@freebsd.org Sat Jul 7 11:33:51 2018 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 751B61038387; Sat, 7 Jul 2018 11:33:51 +0000 (UTC) (envelope-from ehaupt@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2784E715F5; Sat, 7 Jul 2018 11:33:51 +0000 (UTC) (envelope-from ehaupt@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 089B016D6A; Sat, 7 Jul 2018 11:33:51 +0000 (UTC) (envelope-from ehaupt@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w67BXouG069343; Sat, 7 Jul 2018 11:33:50 GMT (envelope-from ehaupt@FreeBSD.org) Received: (from ehaupt@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w67BXoYc069341; Sat, 7 Jul 2018 11:33:50 GMT (envelope-from ehaupt@FreeBSD.org) Message-Id: <201807071133.w67BXoYc069341@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ehaupt set sender to ehaupt@FreeBSD.org using -f From: Emanuel Haupt Date: Sat, 7 Jul 2018 11:33:50 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r474074 - in head/net/socat: . files X-SVN-Group: ports-head X-SVN-Commit-Author: ehaupt X-SVN-Commit-Paths: in head/net/socat: . files X-SVN-Commit-Revision: 474074 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Jul 2018 11:33:51 -0000 Author: ehaupt Date: Sat Jul 7 11:33:50 2018 New Revision: 474074 URL: https://svnweb.freebsd.org/changeset/ports/474074 Log: Add multi-instances rc(8) support by using a config file. PR: 226405 Submitted by: Harald Schmalzbauer Added: head/net/socat/files/socat-instances.conf.sample (contents, props changed) Modified: head/net/socat/Makefile head/net/socat/files/socat.in Modified: head/net/socat/Makefile ============================================================================== --- head/net/socat/Makefile Sat Jul 7 11:15:43 2018 (r474073) +++ head/net/socat/Makefile Sat Jul 7 11:33:50 2018 (r474074) @@ -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 Added: head/net/socat/files/socat-instances.conf.sample ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/socat/files/socat-instances.conf.sample Sat Jul 7 11:33:50 2018 (r474074) @@ -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. + Modified: head/net/socat/files/socat.in ============================================================================== --- head/net/socat/files/socat.in Sat Jul 7 11:15:43 2018 (r474073) +++ head/net/socat/files/socat.in Sat Jul 7 11:33:50 2018 (r474074) @@ -11,7 +11,8 @@ # Add the following lines to /etc/rc.conf to enable socat: # socat_enable="YES" -# socat_flags="" +# socat_daemonuser="root" for priviledged ports e.g. +# socat_flags="" or create /usr/local/etc/socat-instances.conf . /etc/rc.subr @@ -21,13 +22,17 @@ 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() { # socat_flags gets applied too early if we don't do this. @@ -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 +