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