Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Jul 2018 11:33:50 +0000 (UTC)
From:      Emanuel Haupt <ehaupt@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r474074 - in head/net/socat: . files
Message-ID:  <201807071133.w67BXoYc069341@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <bugzilla.freebsd@omnilan.de>

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 <bsd.port.post.mk>

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="<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,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
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807071133.w67BXoYc069341>