changeset 124:47c7223bea76

Move bsmtp2dma to sbin. This is because Bacula's bsmtp lives in sbin also.
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 16 Oct 2019 00:49:48 +0200
parents 397bf58e85d2
children 8f91de3c121b
files Makefile bin/bsmtp2dma pkg-plist sbin/bsmtp2dma
diffstat 4 files changed, 348 insertions(+), 347 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Oct 16 00:23:53 2019 +0200
+++ b/Makefile	Wed Oct 16 00:49:48 2019 +0200
@@ -30,7 +30,8 @@
 
 do-extract:
 	${MKDIR} ${WRKSRC}/bin
-.for _rp in bin/check-ports bin/fjail bin/fpkg bin/bsmtp2dma
+	${MKDIR} ${WRKSRC}/sbin
+.for _rp in bin/check-ports bin/fjail bin/fpkg sbin/bsmtp2dma
 	${CP} -v ${SRC}/${_rp} ${WRKSRC}/${_rp}
 	${SED} -i "" -E -e "s|\\\$$Date\\\$$|\$$Date: ${HGDATE} \$$|" ${WRKSRC}/${_rp}
 	${SED} -i "" -E -e "s|\\\$$Revision\\\$$|\$$Revision: ${HGREVISION} \$$|" ${WRKSRC}/${_rp}
@@ -53,7 +54,7 @@
 .endfor
 
 do-install:
-.for _rp in bin/check-ports bin/fjail bin/fpkg bin/bsmtp2dma
+.for _rp in bin/check-ports bin/fjail bin/fpkg sbin/bsmtp2dma
 	${INSTALL_SCRIPT} ${WRKSRC}/${_rp} ${STAGEDIR}${PREFIX}/${_rp}
 .endfor
 	${MKDIR} ${STAGEDIR}${ETCDIR}
--- a/bin/bsmtp2dma	Wed Oct 16 00:23:53 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-#!/bin/sh
-# -*- indent-tabs-mode: nil; -*-
-: 'A simple replacement for Bacula `bsmtp` when the underlying mailer does
-not listen on TCP ports (e.g. `dma`, `ssmtp` et al.).
-
-:Author:    Franz Glasner
-:Copyright: (c) 2019 Franz Glasner.
-            All rights reserved.
-:License:   BSD 3-Clause "New" or "Revised" License.
-            See LICENSE for details.
-            If you cannot find LICENSE see
-            <https://opensource.org/licenses/BSD-3-Clause>
-:ID:        @(#)@@PKGORIGIN@@ $HGid$
-
-'
-
-VERSION="@@VERSION@@"
-
-USAGE='
-USAGE: bsmtp2dma [OPTIONS] RECIPIENT ...
-
-Options:
-
-  -V           Show the program version and usage and exit.
-
-  -8           Does nothing. Just a compatibility option for `bsmtp`.
-
-  -c ADDRESS   Set then "CC:" header.
-
-  -d n         Does nothing. Just a compatibility option for `bsmtp`.
-
-  -f ADDRESS   Set the "From:" header.
-
-  -h MAILHOST:PORT  Does nothing. Just a compatibility option for `bsmtp`.
-
-  -l NUMBER    Does nothing. Just a compatibility option for `bsmtp`.
-
-  -r ADDRESS   Set the "Reply-To:" header
-
-  -s SUBJECT   Set the "Subject:" header
-
-
-Usage:
-
-  The body of the email message is read from standard input. Message is
-  ended by sending the `EOF` character (`Ctrl-D` on many systems) on the
-  start of a new line, much like many `mail` commands.
-
-
-Files:
-
-  The shell style configuration file in 
-
-      @@ETCDIR@@/bsmtp2dma.conf is
-
-  sourced in at script start.
-
-'
-
-#
-# Configuration directory
-#
-: ${CONFIGDIR:=@@ETCDIR@@}
-
-test -r "${CONFIGDIR}/bsmtp2dma.conf" && . "${CONFIGDIR}/bsmtp2dma.conf"
-
-
-#
-# Default configuration values
-#
-# `sendmail` is also valid for `dma` because of the mapping within
-#  `/etc/mail/mailer.conf`
-#
-: ${MAILER:=/usr/sbin/sendmail}
-
-
-parse_addr() {
-    : 'Parse an possibly complex email address.
-
-    Addresses can be of the form
-
-    - Name Parts <user@domain.tld>
-    - user@domain.tld
-
-    `Name Parts` may not contain ``<`` or ``>`` characters.
-
-    Args:
-        _addr: the complex email address
-
-    Returns:
-        0 on success, 1 on errors
-
-    Output (Globals):
-        email_name: the name part (or empty)
-        email_addr: the technical address part (or empty)
-
-    '
-    local _addr
-
-    _addr="$1"
-    test -n "${_addr}" || return 1
-
-    if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+<[^<>]+@[^<>]+>$'; then
-        email_name=$(printf '%s' "${_addr}" | sed -E -e 's/[[:space:]]*<.+$//')
-        email_addr=$(printf '%s' "${_addr}" | sed -E -e 's/^[^<>]+<//' | sed -E -e 's/>$//')
-        return 0
-    fi
-    if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+@[^<>]+$'; then
-        email_name=""
-        email_addr="${_addr}"
-        return 0
-    fi
-    return 1
-}
-
-
-send_mail() {
-    : 'Send the mail via the underlying configured mailer (dma, sendmail et al.).
-
-    Args:
-        _recipient: The recipient name.
-
-                    Will be written into the "To:" header also.
-
-    Input (Globals):
-        MAILER
-        MAILCONTENT
-        MAILFIFO_STDIN
-        MAILFIFO_STDOUT
-        CC
-        FROM
-        REPLYTO
-        SUBJECT
-
-    Returns:
-        0 on success, other values on errors or the error exit code from the
-        underlying mailer
-
-    This procedure starts the configured mailer as coproc and sends
-    email headers and contents to the started mailer.
-
-    '
-    local _recipient _rc _oifs _text _pid_mailer _recipient_addr
-    local _from_from _from_addr _sender_addr _dummy
-
-    _recipient="$1"
-    _rc=0
-
-    if parse_addr "${_recipient}"; then
-        _recipient_addr="${email_addr}"
-    else
-        echo "ERROR: unknown recipient address format in \`${_recipient}'" >&2
-        return 1
-    fi
-    _sender_addr="$(whoami)@$(hostname -f)"
-    if [ -z "${FROM}" ]; then
-        _from_addr="${_sender_addr}"
-        _from_from="${_from_addr}"
-    else
-       if parse_addr "${FROM}"; then
-           _from_from="${FROM}"
-           _from_addr="${email_addr}"
-       else
-           echo "ERROR: unknown sender name in \`${FROM}'" >&2
-           return 1
-       fi
-    fi
-
-    mkfifo -m 0600 "${MAILFIFO_STDIN}"
-    _rc=$?
-    if [ ${_rc} -ne 0 ]; then
-        return ${_rc}
-    fi
-    mkfifo -m 0600 "${MAILFIFO_STDOUT}"
-    _rc=$?
-    if [ ${_rc} -ne 0 ]; then
-        rm -f "${MAILFIFO_STDIN}"
-        return ${_rc}
-    fi
-
-    #
-    # Start the mailer **before** opening the pipe; otherwise a
-    # deadlock occurs
-    #
-    "$MAILER" -f "${_sender_addr}" "${_recipient_addr}" <${MAILFIFO_STDIN} >${MAILFIFO_STDOUT} &
-    _pid_mailer=$!
-
-    exec 3>"${MAILFIFO_STDIN}"
-    exec 4<"${MAILFIFO_STDOUT}"
-
-    printf "To: %s\n" "${_recipient}" >&3
-    printf "From: %s\n" "${_from_from}" >&3
-    if [ "${_sender_addr}" != "${_from_addr}" ]; then
-        printf "Sender: %s\n" "${_sender_addr}" >&3
-    fi
-    if [ -n "${SUBJECT}" ]; then
-        printf "Subject: %s\n" "${SUBJECT}" >&3
-    fi
-    if [ -n "${REPLYTO}" ]; then
-        #
-        # XXX TBD proper Reply-To header value checks:
-        #     a comma separated list of full mail addresses
-        #
-        printf "Reply-To: %s\n" "${REPLYTO}" >&3
-    fi
-    if [ -n "${CC}" ]; then
-        #
-        # XXX TBD proper CC header value checks:
-        #     a comma separated list of full mail addresses
-        #
-        printf "Cc: %s\n" "${CC}" >&3
-    fi
-    printf "\n" >&3
-
-    # preserve leading white space when reading with `read`
-    _oifs="$IFS"
-    IFS="
-"
-    cat "${MAILCONTENT}" |
-        while read _text; do
-            printf "%s\n" "$_text" >&3
-        done
-    # not all mailer recognize this
-    # printf ".\n" >&3
-    IFS="$_oifs"
-
-    # close the fd to the pipe: coproc should get EOF and terminate
-    exec 3>&-
-    # read eventually remaining stuff from the mailer until EOF
-    IFS='' read _dummy <&4
-    exec 4<&-
-
-    wait $_pid_mailer
-    _rc=$?
-
-    # we are done with the named pipes
-    rm -f "${MAILFIFO_STDIN}"
-    rm -f "${MAILFIFO_STDOUT}"
-
-    return ${_rc}
-}
-
-
-while getopts "V8c:d:f:h:l:nr:s:" _opt; do
-    case ${_opt} in
-        V)
-            echo "bsmtp2dma v${VERSION} (rv:@@HGREVISION@@)"
-            echo "$USAGE"
-            exit 0;
-            ;;
-        8)
-            : # VOID
-            ;;
-        c)
-            CC="$OPTARG"
-            ;;
-        d)
-            : # VOID
-            ;;
-        f)
-            FROM="$OPTARG"
-            ;;
-        h)
-            : # VOID
-            ;;
-        l)
-            : # VOID
-            ;;
-        r)
-            REPLYTO="$OPTARG"
-            ;;
-        s)
-            SUBJECT="$OPTARG"
-            ;;
-        \?)
-            exit 2;
-            ;;
-        *)
-            echo "ERROR: inconsistent option handling" >&2
-            exit 2;
-            ;;
-    esac
-done
-
-# return code
-_rc=0
-
-MAILTMPDIR="$(mktemp -d)"
-MAILFIFO_STDIN="${MAILTMPDIR}/mail-stdin"
-MAILFIFO_STDOUT="${MAILTMPDIR}/mail-stdout"
-MAILCONTENT="${MAILTMPDIR}/mail-text"
-
-#
-# Clean up existing temporary stuff on all sorts of exit
-# (including the "exit" call (signal 0))
-#
-trap 'if [ -d "${MAILTMPDIR}" ]; then rm -rf "${MAILTMPDIR}"; fi; exit;' 0 1 2 15
-
-test -d "${MAILTMPDIR}" || { echo "ERROR: no existing private tmp dir" >&2; exit 1; }
-
-#
-# Reset the Shell's option handling system to prepare for handling
-# other arguments and probably command-local options
-#
-shift $((OPTIND-1))
-OPTIND=1
-
-# early check whether some recipients are given
-if [ $# -eq 0 ]; then
-    echo "ERROR: no recipient given" >&2
-    exit 2;
-fi
-
-#
-# Collect the mail text from stdin into a temporary file
-#
-exec 3>"${MAILCONTENT}"
-# preserve leading white space when reading with `read`
-_oifs="$IFS"
-IFS="
-"
-while read _text; do
-    if [ "${_text}" = "." ]; then
-        break
-    else
-        printf "%s\n" "${_text}" >&3
-    fi
-done
-exec 3>&-
-IFS="$_oifs"
-
-#
-# Now send the content of the collected mail content to all recipients
-#
-until [ $# -eq 0 ]; do
-    send_mail "$1"
-    _rcsm=$?
-    if [ \( ${_rcsm} -ne 0 \) -a \( ${_rc} -eq 0 \) ]; then
-        _rc=${_rcsm}
-    fi
-    shift
-done
-
-exit ${_rc}
--- a/pkg-plist	Wed Oct 16 00:23:53 2019 +0200
+++ b/pkg-plist	Wed Oct 16 00:49:48 2019 +0200
@@ -1,10 +1,10 @@
 @comment DIRECTORIES
 @dir %%ETCDIR%%
 @comment FILES
-bin/bsmtp2dma
 bin/check-ports
 bin/fjail
 bin/fpkg
+sbin/bsmtp2dma
 @sample %%ETCDIR%%/tools.conf.sample
 @sample %%ETCDIR%%/package-mapping.conf.sample
 @sample %%ETCDIR%%/bsmtp2dma.conf.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/bsmtp2dma	Wed Oct 16 00:49:48 2019 +0200
@@ -0,0 +1,344 @@
+#!/bin/sh
+# -*- indent-tabs-mode: nil; -*-
+: 'A simple replacement for Bacula `bsmtp` when the underlying mailer does
+not listen on TCP ports (e.g. `dma`, `ssmtp` et al.).
+
+:Author:    Franz Glasner
+:Copyright: (c) 2019 Franz Glasner.
+            All rights reserved.
+:License:   BSD 3-Clause "New" or "Revised" License.
+            See LICENSE for details.
+            If you cannot find LICENSE see
+            <https://opensource.org/licenses/BSD-3-Clause>
+:ID:        @(#)@@PKGORIGIN@@ $HGid$
+
+'
+
+VERSION="@@VERSION@@"
+
+USAGE='
+USAGE: bsmtp2dma [OPTIONS] RECIPIENT ...
+
+Options:
+
+  -V           Show the program version and usage and exit.
+
+  -8           Does nothing. Just a compatibility option for `bsmtp`.
+
+  -c ADDRESS   Set then "CC:" header.
+
+  -d n         Does nothing. Just a compatibility option for `bsmtp`.
+
+  -f ADDRESS   Set the "From:" header.
+
+  -h MAILHOST:PORT  Does nothing. Just a compatibility option for `bsmtp`.
+
+  -l NUMBER    Does nothing. Just a compatibility option for `bsmtp`.
+
+  -r ADDRESS   Set the "Reply-To:" header
+
+  -s SUBJECT   Set the "Subject:" header
+
+
+Usage:
+
+  The body of the email message is read from standard input. Message is
+  ended by sending the `EOF` character (`Ctrl-D` on many systems) on the
+  start of a new line, much like many `mail` commands.
+
+
+Files:
+
+  The shell style configuration file in 
+
+      @@ETCDIR@@/bsmtp2dma.conf is
+
+  sourced in at script start.
+
+'
+
+#
+# Configuration directory
+#
+: ${CONFIGDIR:=@@ETCDIR@@}
+
+test -r "${CONFIGDIR}/bsmtp2dma.conf" && . "${CONFIGDIR}/bsmtp2dma.conf"
+
+
+#
+# Default configuration values
+#
+# `sendmail` is also valid for `dma` because of the mapping within
+#  `/etc/mail/mailer.conf`
+#
+: ${MAILER:=/usr/sbin/sendmail}
+
+
+parse_addr() {
+    : 'Parse an possibly complex email address.
+
+    Addresses can be of the form
+
+    - Name Parts <user@domain.tld>
+    - user@domain.tld
+
+    `Name Parts` may not contain ``<`` or ``>`` characters.
+
+    Args:
+        _addr: the complex email address
+
+    Returns:
+        0 on success, 1 on errors
+
+    Output (Globals):
+        email_name: the name part (or empty)
+        email_addr: the technical address part (or empty)
+
+    '
+    local _addr
+
+    _addr="$1"
+    test -n "${_addr}" || return 1
+
+    if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+<[^<>]+@[^<>]+>$'; then
+        email_name=$(printf '%s' "${_addr}" | sed -E -e 's/[[:space:]]*<.+$//')
+        email_addr=$(printf '%s' "${_addr}" | sed -E -e 's/^[^<>]+<//' | sed -E -e 's/>$//')
+        return 0
+    fi
+    if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+@[^<>]+$'; then
+        email_name=""
+        email_addr="${_addr}"
+        return 0
+    fi
+    return 1
+}
+
+
+send_mail() {
+    : 'Send the mail via the underlying configured mailer (dma, sendmail et al.).
+
+    Args:
+        _recipient: The recipient name.
+
+                    Will be written into the "To:" header also.
+
+    Input (Globals):
+        MAILER
+        MAILCONTENT
+        MAILFIFO_STDIN
+        MAILFIFO_STDOUT
+        CC
+        FROM
+        REPLYTO
+        SUBJECT
+
+    Returns:
+        0 on success, other values on errors or the error exit code from the
+        underlying mailer
+
+    This procedure starts the configured mailer as coproc and sends
+    email headers and contents to the started mailer.
+
+    '
+    local _recipient _rc _oifs _text _pid_mailer _recipient_addr
+    local _from_from _from_addr _sender_addr _dummy
+
+    _recipient="$1"
+    _rc=0
+
+    if parse_addr "${_recipient}"; then
+        _recipient_addr="${email_addr}"
+    else
+        echo "ERROR: unknown recipient address format in \`${_recipient}'" >&2
+        return 1
+    fi
+    _sender_addr="$(whoami)@$(hostname -f)"
+    if [ -z "${FROM}" ]; then
+        _from_addr="${_sender_addr}"
+        _from_from="${_from_addr}"
+    else
+       if parse_addr "${FROM}"; then
+           _from_from="${FROM}"
+           _from_addr="${email_addr}"
+       else
+           echo "ERROR: unknown sender name in \`${FROM}'" >&2
+           return 1
+       fi
+    fi
+
+    mkfifo -m 0600 "${MAILFIFO_STDIN}"
+    _rc=$?
+    if [ ${_rc} -ne 0 ]; then
+        return ${_rc}
+    fi
+    mkfifo -m 0600 "${MAILFIFO_STDOUT}"
+    _rc=$?
+    if [ ${_rc} -ne 0 ]; then
+        rm -f "${MAILFIFO_STDIN}"
+        return ${_rc}
+    fi
+
+    #
+    # Start the mailer **before** opening the pipe; otherwise a
+    # deadlock occurs
+    #
+    "$MAILER" -f "${_sender_addr}" "${_recipient_addr}" <${MAILFIFO_STDIN} >${MAILFIFO_STDOUT} &
+    _pid_mailer=$!
+
+    exec 3>"${MAILFIFO_STDIN}"
+    exec 4<"${MAILFIFO_STDOUT}"
+
+    printf "To: %s\n" "${_recipient}" >&3
+    printf "From: %s\n" "${_from_from}" >&3
+    if [ "${_sender_addr}" != "${_from_addr}" ]; then
+        printf "Sender: %s\n" "${_sender_addr}" >&3
+    fi
+    if [ -n "${SUBJECT}" ]; then
+        printf "Subject: %s\n" "${SUBJECT}" >&3
+    fi
+    if [ -n "${REPLYTO}" ]; then
+        #
+        # XXX TBD proper Reply-To header value checks:
+        #     a comma separated list of full mail addresses
+        #
+        printf "Reply-To: %s\n" "${REPLYTO}" >&3
+    fi
+    if [ -n "${CC}" ]; then
+        #
+        # XXX TBD proper CC header value checks:
+        #     a comma separated list of full mail addresses
+        #
+        printf "Cc: %s\n" "${CC}" >&3
+    fi
+    printf "\n" >&3
+
+    # preserve leading white space when reading with `read`
+    _oifs="$IFS"
+    IFS="
+"
+    cat "${MAILCONTENT}" |
+        while read _text; do
+            printf "%s\n" "$_text" >&3
+        done
+    # not all mailer recognize this
+    # printf ".\n" >&3
+    IFS="$_oifs"
+
+    # close the fd to the pipe: coproc should get EOF and terminate
+    exec 3>&-
+    # read eventually remaining stuff from the mailer until EOF
+    IFS='' read _dummy <&4
+    exec 4<&-
+
+    wait $_pid_mailer
+    _rc=$?
+
+    # we are done with the named pipes
+    rm -f "${MAILFIFO_STDIN}"
+    rm -f "${MAILFIFO_STDOUT}"
+
+    return ${_rc}
+}
+
+
+while getopts "V8c:d:f:h:l:nr:s:" _opt; do
+    case ${_opt} in
+        V)
+            echo "bsmtp2dma v${VERSION} (rv:@@HGREVISION@@)"
+            echo "$USAGE"
+            exit 0;
+            ;;
+        8)
+            : # VOID
+            ;;
+        c)
+            CC="$OPTARG"
+            ;;
+        d)
+            : # VOID
+            ;;
+        f)
+            FROM="$OPTARG"
+            ;;
+        h)
+            : # VOID
+            ;;
+        l)
+            : # VOID
+            ;;
+        r)
+            REPLYTO="$OPTARG"
+            ;;
+        s)
+            SUBJECT="$OPTARG"
+            ;;
+        \?)
+            exit 2;
+            ;;
+        *)
+            echo "ERROR: inconsistent option handling" >&2
+            exit 2;
+            ;;
+    esac
+done
+
+# return code
+_rc=0
+
+MAILTMPDIR="$(mktemp -d)"
+MAILFIFO_STDIN="${MAILTMPDIR}/mail-stdin"
+MAILFIFO_STDOUT="${MAILTMPDIR}/mail-stdout"
+MAILCONTENT="${MAILTMPDIR}/mail-text"
+
+#
+# Clean up existing temporary stuff on all sorts of exit
+# (including the "exit" call (signal 0))
+#
+trap 'if [ -d "${MAILTMPDIR}" ]; then rm -rf "${MAILTMPDIR}"; fi; exit;' 0 1 2 15
+
+test -d "${MAILTMPDIR}" || { echo "ERROR: no existing private tmp dir" >&2; exit 1; }
+
+#
+# Reset the Shell's option handling system to prepare for handling
+# other arguments and probably command-local options
+#
+shift $((OPTIND-1))
+OPTIND=1
+
+# early check whether some recipients are given
+if [ $# -eq 0 ]; then
+    echo "ERROR: no recipient given" >&2
+    exit 2;
+fi
+
+#
+# Collect the mail text from stdin into a temporary file
+#
+exec 3>"${MAILCONTENT}"
+# preserve leading white space when reading with `read`
+_oifs="$IFS"
+IFS="
+"
+while read _text; do
+    if [ "${_text}" = "." ]; then
+        break
+    else
+        printf "%s\n" "${_text}" >&3
+    fi
+done
+exec 3>&-
+IFS="$_oifs"
+
+#
+# Now send the content of the collected mail content to all recipients
+#
+until [ $# -eq 0 ]; do
+    send_mail "$1"
+    _rcsm=$?
+    if [ \( ${_rcsm} -ne 0 \) -a \( ${_rc} -eq 0 \) ]; then
+        _rc=${_rcsm}
+    fi
+    shift
+done
+
+exit ${_rc}