Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
comparison bin/bsmtp2dma @ 111:fa73423234bf
bsmtp2dma is feature-complete
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Mon, 14 Oct 2019 14:38:04 +0200 |
| parents | af4eeb94144a |
| children | dad9f2d80c10 |
comparison
equal
deleted
inserted
replaced
| 110:af4eeb94144a | 111:fa73423234bf |
|---|---|
| 19 USAGE=' | 19 USAGE=' |
| 20 USAGE: bsmtp2dma [OPTIONS] RECIPIENT ... | 20 USAGE: bsmtp2dma [OPTIONS] RECIPIENT ... |
| 21 | 21 |
| 22 Options: | 22 Options: |
| 23 | 23 |
| 24 -V Show the program version and usage and exit. | |
| 25 | |
| 24 -8 Does nothing. Just a compatibility option for `bsmtp`. | 26 -8 Does nothing. Just a compatibility option for `bsmtp`. |
| 25 | 27 |
| 28 -c ADDRESS Set then "CC:" header. | |
| 29 | |
| 26 -d n Does nothing. Just a compatibility option for `bsmtp`. | 30 -d n Does nothing. Just a compatibility option for `bsmtp`. |
| 27 | 31 |
| 28 -f ADDRESS Set the "From:" header. | 32 -f ADDRESS Set the "From:" header. |
| 29 | 33 |
| 30 -h MAILHOST:PORT Does nothing. Just a compatibility option for `bsmtp`. | 34 -h MAILHOST:PORT Does nothing. Just a compatibility option for `bsmtp`. |
| 31 | 35 |
| 32 -n Do a dry-run: just print out what would be done | 36 -l NUMBER Does nothing. Just a compatibility option for `bsmtp`. |
| 37 | |
| 38 -r ADDRESS Set the "Reply-To:" header | |
| 33 | 39 |
| 34 -s SUBJECT Set the "Subject:" header | 40 -s SUBJECT Set the "Subject:" header |
| 35 | |
| 36 -r ADDRESS Set the "Reply-To:" header | |
| 37 | |
| 38 -l NUMBER Does nothing. Just a compatibility option for `bsmtp`. | |
| 39 | |
| 40 -V Show the program version and usage and exit. | |
| 41 | 41 |
| 42 | 42 |
| 43 Usage: | 43 Usage: |
| 44 | 44 |
| 45 The body of the email message is read from standard input. Message is | 45 The body of the email message is read from standard input. Message is |
| 54 : ${CONFIGDIR:=@@ETCDIR@@} | 54 : ${CONFIGDIR:=@@ETCDIR@@} |
| 55 | 55 |
| 56 test -r "${CONFIGDIR}/bsmtp2dma.conf" && . "${CONFIGDIR}/bsmtp2dma.conf" | 56 test -r "${CONFIGDIR}/bsmtp2dma.conf" && . "${CONFIGDIR}/bsmtp2dma.conf" |
| 57 | 57 |
| 58 | 58 |
| 59 # | |
| 59 # Default configuration values | 60 # Default configuration values |
| 61 # | |
| 62 # `sendmail` is also valid for `dma` because of the mapping within | |
| 63 # `/etc/mail/mailer.conf` | |
| 64 # | |
| 60 : ${MAILER:=/usr/sbin/sendmail} | 65 : ${MAILER:=/usr/sbin/sendmail} |
| 61 | 66 |
| 62 | 67 |
| 63 parse_addr() { | 68 parse_addr() { |
| 64 : 'Parse an possibly complex email address. | 69 : 'Parse an possibly complex email address. |
| 82 | 87 |
| 83 ' | 88 ' |
| 84 local _addr | 89 local _addr |
| 85 | 90 |
| 86 _addr="$1" | 91 _addr="$1" |
| 92 test -n "${_addr}" || return 1 | |
| 87 | 93 |
| 88 if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+<[^<>]+@[^<>]+>$'; then | 94 if printf "%s" "${_addr}" | grep -q -E -e '^[^<>]+<[^<>]+@[^<>]+>$'; then |
| 89 email_name=$(printf '%s' "${_addr}" | sed -E -e 's/[[:space:]]*<.+$//') | 95 email_name=$(printf '%s' "${_addr}" | sed -E -e 's/[[:space:]]*<.+$//') |
| 90 email_addr=$(printf '%s' "${_addr}" | sed -E -e 's/^[^<>]+<//' | sed -E -e 's/>$//') | 96 email_addr=$(printf '%s' "${_addr}" | sed -E -e 's/^[^<>]+<//' | sed -E -e 's/>$//') |
| 91 return 0 | 97 return 0 |
| 118 | 124 |
| 119 Returns: | 125 Returns: |
| 120 0 on success, other values on errors or the error exit code from the | 126 0 on success, other values on errors or the error exit code from the |
| 121 underlying mailer | 127 underlying mailer |
| 122 | 128 |
| 129 This procedure starts the configured mailer as coproc and sends | |
| 130 email headers and contents to the started mailer. | |
| 131 | |
| 123 ' | 132 ' |
| 124 local _recipient _rc _oifs _text _pid_mailer | 133 local _recipient _rc _oifs _text _pid_mailer _recipient_addr |
| 134 local _from_from _from_addr _sender_addr | |
| 125 | 135 |
| 126 _recipient="$1" | 136 _recipient="$1" |
| 127 _rc=0 | 137 _rc=0 |
| 138 | |
| 139 if parse_addr "${_recipient}"; then | |
| 140 _recipient_addr="${email_addr}" | |
| 141 else | |
| 142 echo "ERROR: unknown recipient address format in \`${_recipient}'" >&2 | |
| 143 return 1 | |
| 144 fi | |
| 145 _sender_addr="$(whoami)@$(hostname -f)" | |
| 146 if [ -z "${FROM}" ]; then | |
| 147 _from_addr="${_sender_addr}" | |
| 148 _from_from="${_from_addr}" | |
| 149 else | |
| 150 if parse_addr "${FROM}"; then | |
| 151 _from_from="${FROM}" | |
| 152 _from_addr="${email_addr}" | |
| 153 else | |
| 154 echo "ERROR: unknown sender name in \`${FROM}'" >&2 | |
| 155 return 1 | |
| 156 fi | |
| 157 fi | |
| 128 | 158 |
| 129 mkfifo -m 0600 "${MAILFIFO}" | 159 mkfifo -m 0600 "${MAILFIFO}" |
| 130 _rc=$? | 160 _rc=$? |
| 131 if [ ${_rc} -ne 0 ]; then | 161 if [ ${_rc} -ne 0 ]; then |
| 132 return ${_rc} | 162 return ${_rc} |
| 133 fi | 163 fi |
| 134 | 164 |
| 135 exec 3<>"${MAILFIFO}" | 165 exec 3<>"${MAILFIFO}" |
| 136 | 166 |
| 137 "$MAILER" -f bacula@fmgapp7-bacula9.intern.feldmann-mg.com hostmaster@feldmann-mg.com <&3 & | 167 "$MAILER" -f "${_sender_addr}" "${_recipient_addr}" <&3 & |
| 138 _pid_mailer=$! | 168 _pid_mailer=$! |
| 139 | 169 |
| 140 # preserve leading white space when reading | 170 printf "To: %s\n" "${_recipient}" >&3 |
| 171 printf "From: %s\n" "${_from_from}" >&3 | |
| 172 if [ "${_sender_addr}" != "${_from_addr}" ]; then | |
| 173 printf "Sender: %s\n" "${_sender_addr}" >&3 | |
| 174 fi | |
| 175 if [ -n "${SUBJECT}" ]; then | |
| 176 printf "Subject: %s\n" "${SUBJECT}" >&3 | |
| 177 fi | |
| 178 if [ -n "${REPLYTO}" ]; then | |
| 179 # XXX TBD proper Reply-To header value checks | |
| 180 printf "Reply-To: %s\n" "${REPLYTO}" >&3 | |
| 181 fi | |
| 182 if [ -n "${CC}" ]; then | |
| 183 # XXX TBD proper CC header value checks | |
| 184 printf "Cc: %s\n" "${CC}" >&3 | |
| 185 fi | |
| 186 printf "\n" >&3 | |
| 187 | |
| 188 # preserve leading white space when reading with `read` | |
| 141 _oifs="$IFS" | 189 _oifs="$IFS" |
| 142 IFS=" | 190 IFS=" |
| 143 " | 191 " |
| 144 cat "${MAILCONTENT}" | | 192 cat "${MAILCONTENT}" | |
| 145 while read _text; do | 193 while read _text; do |
| 160 | 208 |
| 161 return ${_rc} | 209 return ${_rc} |
| 162 } | 210 } |
| 163 | 211 |
| 164 | 212 |
| 165 while getopts "V8c:f:h:l:nr:s:" _opt; do | 213 while getopts "V8c:d:f:h:l:nr:s:" _opt; do |
| 166 case ${_opt} in | 214 case ${_opt} in |
| 167 V) | 215 V) |
| 168 echo "bsmtp2dma v${VERSION} (rv:@@HGREVISION@@)" | 216 echo "bsmtp2dma v${VERSION} (rv:@@HGREVISION@@)" |
| 169 echo "$USAGE" | 217 echo "$USAGE" |
| 170 exit 0; | 218 exit 0; |
| 173 : # VOID | 221 : # VOID |
| 174 ;; | 222 ;; |
| 175 c) | 223 c) |
| 176 CC="$OPTARG" | 224 CC="$OPTARG" |
| 177 ;; | 225 ;; |
| 226 d) | |
| 227 : # VOID | |
| 228 ;; | |
| 178 f) | 229 f) |
| 179 FROM="$OPTARG" | 230 FROM="$OPTARG" |
| 180 ;; | 231 ;; |
| 181 h) | 232 h) |
| 182 : # VOID | 233 : # VOID |
| 183 ;; | 234 ;; |
| 184 l) | 235 l) |
| 185 : # VOID | 236 : # VOID |
| 186 ;; | |
| 187 n) | |
| 188 DRYRUN="YES" | |
| 189 ;; | 237 ;; |
| 190 r) | 238 r) |
| 191 REPLYTO="$OPTARG" | 239 REPLYTO="$OPTARG" |
| 192 ;; | 240 ;; |
| 193 s) | 241 s) |
| 204 done | 252 done |
| 205 | 253 |
| 206 # return code | 254 # return code |
| 207 _rc=0 | 255 _rc=0 |
| 208 | 256 |
| 209 DRYRUN="NO" | |
| 210 | |
| 211 MAILTMPDIR="$(mktemp -d)" | 257 MAILTMPDIR="$(mktemp -d)" |
| 212 MAILFIFO="${MAILTMPDIR}/mail-stdin" | 258 MAILFIFO="${MAILTMPDIR}/mail-stdin" |
| 213 MAILCONTENT="${MAILTMPDIR}/mail-text" | 259 MAILCONTENT="${MAILTMPDIR}/mail-text" |
| 214 | 260 |
| 215 # | 261 # |
| 216 # Clean up existing temporary stuff on all sorts of exit | 262 # Clean up existing temporary stuff on all sorts of exit |
| 217 # (including the "exit" call (signal 0)) | 263 # (including the "exit" call (signal 0)) |
| 218 # | 264 # |
| 219 trap 'if [ -d "${MAILTMPDIR}" ]; then rm -r "${MAILTMPDIR}"; fi; exit;' 0 1 2 15 | 265 trap 'if [ -d "${MAILTMPDIR}" ]; then rm -rf "${MAILTMPDIR}"; fi; exit;' 0 1 2 15 |
| 220 | 266 |
| 221 test -d "${MAILTMPDIR}" || { echo "ERROR: no existing private tmp dir" >&2; exit 1; } | 267 test -d "${MAILTMPDIR}" || { echo "ERROR: no existing private tmp dir" >&2; exit 1; } |
| 222 | 268 |
| 223 # | 269 # |
| 224 # Reset the Shell's option handling system to prepare for handling | 270 # Reset the Shell's option handling system to prepare for handling |
| 235 | 281 |
| 236 # | 282 # |
| 237 # Collect the mail text from stdin into a temporary file | 283 # Collect the mail text from stdin into a temporary file |
| 238 # | 284 # |
| 239 exec 3>"${MAILCONTENT}" | 285 exec 3>"${MAILCONTENT}" |
| 240 # preserve leading white space when reading | 286 # preserve leading white space when reading with `read` |
| 241 _oifs="$IFS" | 287 _oifs="$IFS" |
| 242 IFS=" | 288 IFS=" |
| 243 " | 289 " |
| 244 while read _text; do | 290 while read _text; do |
| 245 if [ "${_text}" = "." ]; then | 291 if [ "${_text}" = "." ]; then |
