Index: head/net/socat/Makefile =================================================================== --- head/net/socat/Makefile (revision 474073) +++ head/net/socat/Makefile (revision 474074) @@ -1,52 +1,54 @@ # Created by: ijliao # $FreeBSD$ 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 MAINTAINER= ehaupt@FreeBSD.org COMMENT= Multipurpose relay and more LICENSE= GPLv2 LICENSE_FILE= ${WRKSRC}/COPYING USES= compiler cpe ssl tar:bzip2 GNU_CONFIGURE= yes USE_RC_SUBR= socat 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 READLINE_CONFIGURE_ENABLE= readline READLINE_USES= readline .include .if ${SSL_DEFAULT} != base CFLAGS+= -I${LOCALBASE}/include LDFLAGS+= -L${LOCALBASE}/lib .endif .if ${COMPILER_TYPE} == "clang" CFLAGS+= -Wno-unused-comparison .endif do-install: .for f in filan procan socat ${INSTALL_PROGRAM} ${WRKSRC}/${f} ${STAGEDIR}${PREFIX}/bin .endfor ${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 Index: head/net/socat/files/socat-instances.conf.sample =================================================================== --- head/net/socat/files/socat-instances.conf.sample (nonexistent) +++ head/net/socat/files/socat-instances.conf.sample (revision 474074) @@ -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. + Property changes on: head/net/socat/files/socat-instances.conf.sample ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/net/socat/files/socat.in =================================================================== --- head/net/socat/files/socat.in (revision 474073) +++ head/net/socat/files/socat.in (revision 474074) @@ -1,39 +1,181 @@ #!/bin/sh # # Author: Emanuel Haupt # # $FreeBSD$ # # PROVIDE: socat # REQUIRE: LOGIN # KEYWORD: shutdown # 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 name="socat" 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. # I didn't want to force people to update their rc.conf files # and change the socat_flags to something else. 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 +