| 1 |
#!/bin/sh |
| 2 |
|
| 3 |
# script to email files as attachments. |
| 4 |
# ------------------------------------ |
| 5 |
|
| 6 |
# Additional documentation for this script, including a brief introdcution |
| 7 |
# to MIME can be found at: http://home.clara.net/dwotton/unix/mail_files.htm |
| 8 |
|
| 9 |
# Written: Dave Wotton, July 1998, (Cambridge UK) |
| 10 |
# This script comes with no warranty or support. You are |
| 11 |
# free to modify it as you wish, but please retain an |
| 12 |
# acknowledgement of my original authorship. |
| 13 |
|
| 14 |
# Amended: Dave Wotton, 6/3/99 |
| 15 |
# -t flag now optional. subject also optional |
| 16 |
# |
| 17 |
# Amended: Dave Wotton, 3/8/00 |
| 18 |
# added -b and -u options. By default a file-list which is not |
| 19 |
# preceded by a -n, -b, or -u flag is now NOT encoded (the previous |
| 20 |
# default was to base64 encode it.). |
| 21 |
# |
| 22 |
# Amended: Dave Wotton, 10/10/00 |
| 23 |
# added a -c (cc:) option. |
| 24 |
# Added a tty -s test to prevent the prompt to enter the text body |
| 25 |
# being displayed when not connected to a tty. (The text body is |
| 26 |
# still required though. /dev/null will suffice.) |
| 27 |
# |
| 28 |
# Amended: Dave Wotton, 24/2/01 |
| 29 |
# Now uses perl to perform the base64 encoding, as it comes as |
| 30 |
# standard on most modern Unixes. (You need the perl MIME package |
| 31 |
# though, which I believe is standard. ) |
| 32 |
|
| 33 |
# Amended: Dave Wotton, 22/09/01 |
| 34 |
# Now creates a "To:" header and uses the sendmail -t flag to |
| 35 |
# duplicate this as the envelope recipients, rather than using the |
| 36 |
# user supplied list of addresses simply as envelope recipients. |
| 37 |
# This confused some mail clients, specifically Lotus Notes. |
| 38 |
|
| 39 |
# Amended: Dave Wotton, 30/09/01 |
| 40 |
# Now initialises the main variables, so that previously set |
| 41 |
# environment variable values (eg. $CC) aren't used instead. |
| 42 |
# Enable multiple occurrences of the -t and -c flags. Thanks to |
| 43 |
# Jason Judge for these suggestions. |
| 44 |
|
| 45 |
|
| 46 |
# Usage: mail_files [-t] mailid [ -c mailid ] [ -s subject ] [ -f mailid ] |
| 47 |
# [-n file_list] [-u file_list] [-b file_list] file_list |
| 48 |
# |
| 49 |
# -f : The mailid of the sender ( defaults to your userid ) |
| 50 |
# Only userids that have been defined as "trusted" in the sendmail |
| 51 |
# config file can make use of the -f option. For non-trusted users |
| 52 |
# any value specified by this parameter will be ignored by |
| 53 |
# sendmail. |
| 54 |
# -t : The mailid of the recipient. Mandatory, no default |
| 55 |
# multiple mailids can be specified, separated by commas. |
| 56 |
# -c : The mailid of any carbon-copy recipients. Optional. |
| 57 |
# multiple mailids can be specified, separated by commas. |
| 58 |
# -s : The subject string. Optional, default = "Not specified". |
| 59 |
# Enclose in quotes. |
| 60 |
# -n : no-encode: indicates a list of files which are NOT to be base64 |
| 61 |
# or uuencode encoded. Multiple files may be enclosed in double |
| 62 |
# quotes. Usual wildcard notation can be used. This option is |
| 63 |
# for completeness and can be omitted because the default action |
| 64 |
# is not to encode the file-list. |
| 65 |
# -b : base64 encoding: indicates a list of files which are to be |
| 66 |
# base64 encoded. Multiple files may be enclosed in double quotes. |
| 67 |
# Usual wildcard notation can be used. |
| 68 |
# -u : uuencode encoding: indicates a list of files which are to be |
| 69 |
# uuencode encoded. Multiple files may be enclosed in double |
| 70 |
# quotes. Usual wildcard notation can be used. |
| 71 |
# file_list : The list of files to send as attachments with no-encoding |
| 72 |
# (same as -n option, but the file list does not need to be |
| 73 |
# enclosed in quotes if more than one file specified). |
| 74 |
# Usual wildcard notation can be used. |
| 75 |
|
| 76 |
# The program will also prompt for text to be supplied on standard input |
| 77 |
# as the main text of the message. |
| 78 |
|
| 79 |
# eg. |
| 80 |
# 1) mail_files Dave.Wotton -b file9.gif t*.htm < /dev/null |
| 81 |
# |
| 82 |
# email file9.gif as a base64 encoded attachment and the t*.htm |
| 83 |
# files unencoded. |
| 84 |
# |
| 85 |
# 2) mail_files Dave.Wotton -s "my test" -b "file1.gif file2.gif" \ |
| 86 |
# < /dev/null |
| 87 |
# |
| 88 |
# email file1.gif and file2.gif as base64 encoded attachments. |
| 89 |
|
| 90 |
# The script makes use of perl's MIME package to perform the base-64 |
| 91 |
# encoding/decoding. |
| 92 |
|
| 93 |
# Note that files destined for Windows environments should have a name of |
| 94 |
# the form aaaa.bbb where aaaa is up to 8 characters long, and bbb is a |
| 95 |
# 3 character sufix. The suffix determines which program is used to |
| 96 |
# display/process the data at the remote end. |
| 97 |
|
| 98 |
# Simple text files can be emailed unencoded. Binary files, or text files |
| 99 |
# with long lines ( ie > 1000 chars ) should use the base64 or uuencode |
| 100 |
# encoding procedures. Base64 is preferred because it is more universally |
| 101 |
# supported. In particular, most PC mail-clients can automatically decode |
| 102 |
# base64 encoded attachments. Note that simple text files with short lines |
| 103 |
# which are destined for PC environments should not be base64 encoded. |
| 104 |
# This is because PCs use a different line-break character to Unix. |
| 105 |
# If the text is base64 encoded, the line-breaks are not converted |
| 106 |
# automatically and so the data arrives at the remote end without |
| 107 |
# line-breaks. |
| 108 |
|
| 109 |
# set up a 'usage' routine |
| 110 |
# ------------------------ |
| 111 |
|
| 112 |
usage() |
| 113 |
{ |
| 114 |
[ "$1" ] && ( echo $* ; echo "" ) |
| 115 |
|
| 116 |
cat <<! |
| 117 |
Usage: mail_files [-t] mailid [ -c mailid ] [ -s subject ] [ -f mailid ] |
| 118 |
[-n file_list] [-u file_list] [-b file_list] file_list |
| 119 |
! |
| 120 |
exit 4 |
| 121 |
} |
| 122 |
|
| 123 |
# Initialise main variables ... |
| 124 |
# ------------------------- |
| 125 |
|
| 126 |
FROM=$LOGNAME |
| 127 |
SUBJ=${SUBJ:-"Not specified"} |
| 128 |
|
| 129 |
TO="" ; CC="" ; SUBJ="" ; NOENC="" ; BASE64="" ; UUE="" |
| 130 |
|
| 131 |
# First parse the command line options. Using getopts means the parameters |
| 132 |
# can be supplied in any order. But first we handle the first parameter, |
| 133 |
# which may be a recipient, without a -t flag... |
| 134 |
|
| 135 |
case "$1" in |
| 136 |
-* ) : ;; # ignore it, let getopts handle flags |
| 137 |
* ) TO=$1 ; shift ;; |
| 138 |
esac |
| 139 |
|
| 140 |
while getopts f:s:t:c:n:b:u: OPT |
| 141 |
do |
| 142 |
case $OPT in |
| 143 |
"f" ) FROM=$OPTARG ;; |
| 144 |
"t" ) TO="$TO,$OPTARG" ;; |
| 145 |
"c" ) CC="$CC,$OPTARG" ;; |
| 146 |
"s" ) SUBJ=$OPTARG ;; |
| 147 |
"n" ) NOENC="$NOENC $OPTARG" ;; |
| 148 |
"b" ) BASE64="$BASE64 $OPTARG" ;; |
| 149 |
"u" ) UUE="$UUE $OPTARG" ;; |
| 150 |
* ) usage ;; |
| 151 |
esac |
| 152 |
done |
| 153 |
|
| 154 |
shift `expr $OPTIND - 1` |
| 155 |
|
| 156 |
if [ "$TO" = "" ] |
| 157 |
then |
| 158 |
usage "An addressee must be specified" |
| 159 |
fi |
| 160 |
|
| 161 |
# All remaining parameters are files not requiring encoding ... |
| 162 |
# --------------------------------------------------------- |
| 163 |
|
| 164 |
# Build up $FILES as the list of non-encoded files. Use sed to remove |
| 165 |
# any leading space from the variable. |
| 166 |
|
| 167 |
FILES=`echo $NOENC $*|sed 's/^ //'` |
| 168 |
|
| 169 |
if [ "$BASE64" = "" -a "$FILES" = "" -a "$UUE" = "" ] |
| 170 |
then |
| 171 |
usage "At least one file must be specified" |
| 172 |
fi |
| 173 |
|
| 174 |
# Remove leading commas from TO, CC ... |
| 175 |
# --------------------------------- |
| 176 |
|
| 177 |
TO=`echo $TO | sed 's/^,//'` |
| 178 |
CC=`echo $CC | sed 's/^,//'` |
| 179 |
|
| 180 |
# Validate that the files exist ... |
| 181 |
# ----------------------------- |
| 182 |
|
| 183 |
for F in $FILES $BASE64 $UUE |
| 184 |
do |
| 185 |
if [ ! -r $F ] |
| 186 |
then |
| 187 |
echo "Error: File $F does not exist / is not readable." |
| 188 |
echo "Exiting. ( Mail not sent )." |
| 189 |
exit |
| 190 |
fi |
| 191 |
done |
| 192 |
|
| 193 |
tty -s && echo "Enter text of main message ( finish with CTRL-D ) ..." |
| 194 |
|
| 195 |
# Now do the work ... |
| 196 |
# --------------- |
| 197 |
|
| 198 |
# The generated mail message is output onto standard out, which is then |
| 199 |
# piped in to sendmail. |
| 200 |
|
| 201 |
( |
| 202 |
cat <<! |
| 203 |
From: $FROM |
| 204 |
Subject: $SUBJ |
| 205 |
To: $TO |
| 206 |
! |
| 207 |
|
| 208 |
[ "$CC" ] && echo "Cc: $CC" |
| 209 |
|
| 210 |
cat <<! |
| 211 |
Mime-Version: 1.0 |
| 212 |
Content-Type: multipart/mixed; boundary="DMW.Boundary.605592468" |
| 213 |
|
| 214 |
This is a Mime message, which your mail program may not understand. Parts |
| 215 |
of the message will appear as text. If the remainder appears as random |
| 216 |
characters in the message body, instead of as attachments, then you'll |
| 217 |
have to extract these parts and decode them manually. |
| 218 |
|
| 219 |
--DMW.Boundary.605592468 |
| 220 |
Content-Type: text/plain; name="message.txt"; charset=US-ASCII |
| 221 |
Content-Disposition: inline; filename="message.txt" |
| 222 |
Content-Transfer-Encoding: 7bit |
| 223 |
|
| 224 |
! |
| 225 |
|
| 226 |
# Read the standard input as the main text of the message ... |
| 227 |
# ------------------------------------------------------- |
| 228 |
|
| 229 |
cat - |
| 230 |
|
| 231 |
# Now process the non-encrypted attachments ... |
| 232 |
# ----------------------------------------- |
| 233 |
|
| 234 |
if [ "$FILES" ] |
| 235 |
then |
| 236 |
for F in $FILES |
| 237 |
do |
| 238 |
|
| 239 |
BASE=`basename $F` |
| 240 |
|
| 241 |
echo --DMW.Boundary.605592468 |
| 242 |
echo Content-Type: application/octet-stream\; name=\"$BASE\" |
| 243 |
echo Content-Disposition: attachment\; filename=\"$BASE\" |
| 244 |
echo Content-Transfer-Encoding: 7bit |
| 245 |
echo |
| 246 |
|
| 247 |
cat $F |
| 248 |
|
| 249 |
done |
| 250 |
fi |
| 251 |
|
| 252 |
# Now process the base64 encrypted attachments ... |
| 253 |
# -------------------------------------------- |
| 254 |
|
| 255 |
if [ "$BASE64" ] |
| 256 |
then |
| 257 |
for F in $BASE64 |
| 258 |
do |
| 259 |
|
| 260 |
BASE=`basename $F` |
| 261 |
|
| 262 |
echo --DMW.Boundary.605592468 |
| 263 |
echo Content-Type: application/octet-stream\; name=\"$BASE\" |
| 264 |
echo Content-Disposition: attachment\; filename=\"$BASE\" |
| 265 |
echo Content-Transfer-Encoding: base64 |
| 266 |
echo |
| 267 |
|
| 268 |
perl -e ' |
| 269 |
use MIME::Base64 qw(encode_base64); |
| 270 |
local($/) = undef; |
| 271 |
print encode_base64(<STDIN>);' < $F |
| 272 |
|
| 273 |
done |
| 274 |
fi |
| 275 |
|
| 276 |
# Now process the uuencode encrypted attachments ... |
| 277 |
# ---------------------------------------------- |
| 278 |
|
| 279 |
# Sorry, this bit is untested - I haven't got a mail-client which can |
| 280 |
# handle uuencoded MIME messages automatically, so can't test if the |
| 281 |
# 'Content-Transfer-Encoding: uuencode' line is correct and whether I |
| 282 |
# need the uuencode "begin" and "end" lines. |
| 283 |
|
| 284 |
if [ "$UUE" ] |
| 285 |
then |
| 286 |
for F in $UUE |
| 287 |
do |
| 288 |
|
| 289 |
BASE=`basename $F` |
| 290 |
|
| 291 |
echo --DMW.Boundary.605592468 |
| 292 |
echo Content-Type: application/octet-stream\; name=\"$BASE\" |
| 293 |
echo Content-Disposition: attachment\; filename=\"$BASE\" |
| 294 |
echo Content-Transfer-Encoding: uuencode |
| 295 |
echo |
| 296 |
|
| 297 |
uuencode < $F xxx |
| 298 |
|
| 299 |
done |
| 300 |
fi |
| 301 |
|
| 302 |
# append the final boundary line ... |
| 303 |
|
| 304 |
echo --DMW.Boundary.605592468-- |
| 305 |
|
| 306 |
) | /usr/lib/sendmail -t |
| 307 |
|