changeset 110:af4eeb94144a

Begin bsmtp2dma tool
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 14 Oct 2019 09:47:34 +0200
parents 0bd594fb56f8
children fa73423234bf
files Makefile bin/bsmtp2dma etc/bsmtp2dma.conf.sample pkg-plist
diffstat 4 files changed, 282 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue Oct 08 09:35:30 2019 +0200
+++ b/Makefile	Mon Oct 14 09:47:34 2019 +0200
@@ -30,7 +30,7 @@
 
 do-extract:
 	${MKDIR} ${WRKSRC}/bin
-.for _rp in bin/check-ports bin/fjail bin/fpkg
+.for _rp in bin/check-ports bin/fjail bin/fpkg bin/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}
@@ -46,18 +46,18 @@
 	${SED} -i "" -e "s|@@PKGORIGIN@@|${PKGORIGIN}|" ${WRKSRC}/${_rp}
 .endfor
 	${MKDIR} ${WRKSRC}/etc
-.for _ef in etc/package-mapping.conf.sample etc/tools.conf.sample
+.for _ef in etc/package-mapping.conf.sample etc/tools.conf.sample etc/bsmtp2dma.conf.sample
 	${CP} -v ${SRC}/${_ef} ${WRKSRC}/${_ef}
 	${SED} -i "" -e "s|\\\$$HGid\\\$$|\$$HGid: ${HGPATH}/${_ef} ${HGREVISION} ${HGDATE} ${HGAUTHOR} ${HGPHASE} \$$|" ${WRKSRC}/${_ef}
 	${SED} -i "" -e "s|@@PKGORIGIN@@|${PKGORIGIN}|" ${WRKSRC}/${_ef}
 .endfor
 
 do-install:
-.for _rp in bin/check-ports bin/fjail bin/fpkg
+.for _rp in bin/check-ports bin/fjail bin/fpkg bin/bsmtp2dma
 	${INSTALL_SCRIPT} ${WRKSRC}/${_rp} ${STAGEDIR}${PREFIX}/${_rp}
 .endfor
 	${MKDIR} ${STAGEDIR}${ETCDIR}
-.for _ef in package-mapping.conf.sample tools.conf.sample
+.for _ef in package-mapping.conf.sample tools.conf.sample bsmtp2dma.conf.sample
 	${INSTALL_DATA} ${WRKSRC}/etc/${_ef} ${STAGEDIR}${ETCDIR}/${_ef}
 .endfor
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/bsmtp2dma	Mon Oct 14 09:47:34 2019 +0200
@@ -0,0 +1,266 @@
+#!/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:
+
+  -8           Does nothing. Just a compatibility option for `bsmtp`.
+
+  -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`.
+
+  -n           Do a dry-run: just print out what would be done
+
+  -s SUBJECT   Set the "Subject:" header
+
+  -r ADDRESS   Set the "Reply-To:" header
+
+  -l NUMBER    Does nothing. Just a compatibility option for `bsmtp`.
+
+  -V           Show the program version and usage and exit.
+
+
+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.
+
+'
+
+#
+# Configuration directory
+#
+: ${CONFIGDIR:=@@ETCDIR@@}
+
+test -r "${CONFIGDIR}/bsmtp2dma.conf" && . "${CONFIGDIR}/bsmtp2dma.conf"
+
+
+# Default configuration values
+: ${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"
+
+    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
+        CC
+        FROM
+        REPLYTO
+        SUBJECT
+
+    Returns:
+        0 on success, other values on errors or the error exit code from the
+        underlying mailer
+
+    '
+    local _recipient _rc _oifs _text _pid_mailer
+
+    _recipient="$1"
+    _rc=0
+
+    mkfifo -m 0600 "${MAILFIFO}"
+    _rc=$?
+    if [ ${_rc} -ne 0 ]; then
+        return ${_rc}
+    fi
+
+    exec 3<>"${MAILFIFO}"
+
+    "$MAILER" -f bacula@fmgapp7-bacula9.intern.feldmann-mg.com hostmaster@feldmann-mg.com <&3 &
+    _pid_mailer=$!
+
+    # preserve leading white space when reading
+    _oifs="$IFS"
+    IFS="
+"
+    cat "${MAILCONTENT}" |
+        while read _text; do
+            printf "%s\n" "$_text" >&3
+        done
+    printf ".\n" >&3
+
+    IFS="$_oifs"
+
+    # close the fd to the pipe: coproc should get EOF
+    exec 3>&-
+
+    wait $_pid_mailer
+    _rc=$?
+
+    # we are done with the named pipe
+    rm -f "${MAILFIFO}"
+
+    return ${_rc}
+}
+
+
+while getopts "V8c: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"
+            ;;
+        f)
+            FROM="$OPTARG"
+            ;;
+        h)
+            : # VOID
+            ;;
+        l)
+            : # VOID
+            ;;
+        n)
+            DRYRUN="YES"
+            ;;
+        r)
+            REPLYTO="$OPTARG"
+            ;;
+        s)
+            SUBJECT="$OPTARG"
+            ;;
+        \?)
+            exit 2;
+            ;;
+        *)
+            echo "ERROR: inconsistent option handling" >&2
+            exit 2;
+            ;;
+    esac
+done
+
+# return code
+_rc=0
+
+DRYRUN="NO"
+
+MAILTMPDIR="$(mktemp -d)"
+MAILFIFO="${MAILTMPDIR}/mail-stdin"
+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 -r "${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
+_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}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/bsmtp2dma.conf.sample	Mon Oct 14 09:47:34 2019 +0200
@@ -0,0 +1,10 @@
+#
+# Configure bsmtp2dma tool.
+#
+# Is is sourced by `bsmtp2dma`.
+#
+# @(#)@@PKGORIGIN@@ $HGid$
+#
+
+#MAILER="/usr/sbin/sendmail"
+#MAILER="/usr/libexec/dma"
--- a/pkg-plist	Tue Oct 08 09:35:30 2019 +0200
+++ b/pkg-plist	Mon Oct 14 09:47:34 2019 +0200
@@ -1,8 +1,10 @@
 @comment DIRECTORIES
 @dir %%ETCDIR%%
 @comment FILES
+bin/bsmtp2dma
 bin/check-ports
 bin/fjail
 bin/fpkg
 @sample %%ETCDIR%%/tools.conf.sample
 @sample %%ETCDIR%%/package-mapping.conf.sample
+@sample %%ETCDIR%%/bsmtp2dma.conf.sample