Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3410 dpurdie 1
#!/bin/sh
2
 
3
# script to email files as attachments.
4
# ------------------------------------
5
 
6
# Additional documentation for this script, including a brief introduction 
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
# Amended: David Purdie, 25-Oct-04
46
#          Changed the location of the sendmail executible from
47
#          /usr/bin/sendmail to /usr/sbin/sendmail
48
#
49
#          Determine the user name via various mechanisms
50
#           LOGNAME, USERNAME
51
#
52
#          Generalise the attachment boundary/types
53
#
54
#          Added -m "message" to allow command line messages to replace
55
#          redirected input
56
 
57
 
58
# Usage:   mail_files [-t] mailid [ -c mailid ] [ -s subject ] [ -f mailid ] 
59
#          [-n file_list] [-u file_list] [-b file_list] [-M file_list ] file_list
60
#
61
#    -f      : The mailid of the sender ( defaults to your userid )
62
#              Only userids that have been defined as "trusted" in the sendmail
63
#              config file can make use of the -f option. For non-trusted users
64
#              any value specified by this parameter will be ignored by 
65
#              sendmail.
66
#    -t      : The mailid of the recipient. Mandatory, no default
67
#              multiple mailids can be specified, separated by commas.
68
#    -c      : The mailid of any carbon-copy recipients. Optional.
69
#              multiple mailids can be specified, separated by commas.
70
#    -s      : The subject string. Optional, default = "Not specified".
71
#              Enclose in quotes.
72
#    -n      : no-encode: indicates a list of files which are NOT to be base64
73
#              or uuencode encoded. Multiple files may be enclosed in double
74
#              quotes. Usual wildcard notation can be used. This option is
75
#              for completeness and can be omitted because the default action 
76
#              is not to encode the file-list.
77
#    -b      : base64 encoding: indicates a list of files which are to be 
78
#              base64 encoded. Multiple files may be enclosed in double quotes.
79
#              Usual wildcard notation can be used.
80
#    -u      : uuencode encoding: indicates a list of files which are to be 
81
#              uuencode encoded. Multiple files may be enclosed in double 
82
#              quotes. Usual wildcard notation can be used.
83
#    -T      : All files are text, create "text/plain" content
84
#    -m      : Small text message to use in place of console input
85
#    -M      : List of files to be included in the body of the message
86
#
87
#
88
#  file_list : The list of files to send as attachments with no-encoding
89
#              (same as -n option, but the file list does not need to be
90
#              enclosed in quotes if more than one file specified). 
91
#              Usual wildcard notation can be used.
92
 
93
# The program will also prompt for text to be supplied on standard input
94
# as the main text of the message.
95
 
96
# eg.
97
#      1) mail_files Dave.Wotton -b file9.gif t*.htm < /dev/null
98
#
99
#         email file9.gif as a base64 encoded attachment and the t*.htm
100
#         files unencoded.
101
#
102
#      2) mail_files Dave.Wotton -s "my test" -b "file1.gif file2.gif" \
103
#                    < /dev/null
104
#
105
#         email file1.gif and file2.gif as base64 encoded attachments.
106
 
107
# The script makes use of perl's MIME package to perform the base-64 
108
# encoding/decoding. 
109
 
110
# Note that files destined for Windows environments should have a name of
111
# the form aaaa.bbb where aaaa is up to 8 characters long, and bbb is a
112
# 3 character sufix. The suffix determines which program is used to
113
# display/process the data at the remote end.
114
 
115
# Simple text files can be emailed unencoded. Binary files, or text files
116
# with long lines ( ie > 1000 chars ) should use the  base64 or uuencode 
117
# encoding procedures. Base64 is preferred because it is more universally
118
# supported. In particular, most PC mail-clients can automatically decode
119
# base64 encoded attachments. Note that simple text files with short lines 
120
# which are destined for PC environments should not be base64 encoded.
121
# This is because PCs use a different line-break character to Unix.
122
# If the text is base64 encoded, the line-breaks are not converted
123
# automatically and so the data arrives at the remote end without
124
# line-breaks.
125
 
126
# set up a 'usage' routine
127
# ------------------------
128
 
129
usage()
130
{
131
  [ "$1" ] && ( echo $* ; echo "" )
132
 
133
  cat <<!
134
  Usage:   mail_files [-t] mailid [-T] [ -c mailid ] [ -s subject ] [ -f mailid ]
135
           [-n file_list] [-u file_list] [-b file_list] [[-m msg]|[-M file_list]] file_list
136
!
137
  exit 4
138
}
139
 
140
# Initialise main variables ...
141
# -------------------------
142
 
143
FROM=${LOGNAME:=${USERNAME}}
144
SUBJ=${SUBJ:-"Subject not specified"}
145
BDATE=` date +%S-%H-%M.%d-%m-%Y `
146
BOUNDARY="DDP.Boundary.$BDATE"
147
CONTENT_TYPE="application/octet-stream"
148
 
149
TO="" ; CC="" ; NOENC="" ; BASE64="" ; UUE="" ;UMSG=""; CMSG=""
150
 
151
# First parse the command line options. Using getopts means the parameters
152
# can be supplied in any order. But first we handle the first parameter,
153
# which may be a recipient, without a -t flag...
154
 
155
case "$1" in
156
   -* ) : ;;                   # ignore it, let getopts handle flags
157
    * ) TO=$1 ; shift ;;
158
esac
159
 
160
while getopts Tf:s:t:c:n:b:u:m:M: OPT
161
do
162
     case $OPT in
163
         "f" ) FROM=$OPTARG ;;
164
         "t" ) TO="$TO,$OPTARG" ;;
165
         "T" ) CONTENT_TYPE="text/plain" ;;
166
         "c" ) CC="$CC,$OPTARG" ;;
167
         "s" ) SUBJ=$OPTARG ;;
168
         "n" ) NOENC="$NOENC $OPTARG" ;;
169
         "b" ) BASE64="$BASE64 $OPTARG" ;;
170
         "u" ) UUE="$UUE $OPTARG" ;;
171
         "m" ) UMSG=$OPTARG ;;
172
         "M" ) CMSG=$OPTARG ;;
173
          *  ) usage ;;
174
     esac
175
done
176
 
177
shift `expr $OPTIND - 1`
178
 
179
if [ "$TO" = "" ]
180
then
181
    usage "An addressee must be specified"
182
fi
183
 
184
# All remaining parameters are files not requiring encoding ...
185
# ---------------------------------------------------------
186
 
187
# Build up $FILES as the list of non-encoded files. Use sed to remove
188
# any leading space from the variable.
189
 
190
FILES=`echo $NOENC $*|sed 's/^ //'`
191
 
192
#if [ "$BASE64" = "" -a "$FILES" = "" -a "$UUE" = "" ]
193
#then
194
#    usage "At least one file must be specified"
195
#fi
196
 
197
# Remove leading commas from TO, CC  ...
198
# ---------------------------------
199
 
200
TO=`echo $TO | sed 's/^,//'`
201
CC=`echo $CC | sed 's/^,//'`
202
 
203
# Validate that the files exist ...
204
# -----------------------------
205
 
206
for F in $FILES $BASE64 $UUE
207
do
208
   if [ ! -r $F ]
209
   then
210
      echo "Error: File $F does not exist / is not readable."
211
      echo "Exiting. ( Mail not sent )."
212
      exit
213
   fi
214
done
215
 
216
[ ! "$UMSG$CMSG" ] && tty -s && echo "Enter text of main message ( finish with CTRL-D ) ..."
217
 
218
# Now do the work ...
219
# ---------------
220
 
221
# The generated mail message is output onto standard out, which is then
222
# piped in to sendmail.
223
 
224
(
225
cat <<!
226
From: $FROM
227
Subject: $SUBJ
228
To: $TO
229
!
230
 
231
[ "$CC" ] && echo "Cc: $CC"
232
 
233
cat <<!
234
Mime-Version: 1.0
235
Content-Type: multipart/mixed; boundary="${BOUNDARY}"
236
 
237
This is a Mime message, which your mail program may not understand. Parts
238
of the message will appear as text. If the remainder appears as random
239
characters in the message body, instead of as attachments, then you'll
240
have to extract these parts and decode them manually.
241
 
242
--${BOUNDARY}
243
Content-Type: text/plain; name="message.txt"; charset=US-ASCII
244
Content-Disposition: inline; filename="message.txt"
245
Content-Transfer-Encoding: 7bit
246
 
247
!
248
 
249
# Read the standard input as the main text of the message ...
250
# -------------------------------------------------------
251
 
252
if [ "$UMSG" ] ; then
253
    echo $UMSG
254
elif [ "$CMSG" ] ; then
255
    cat $CMSG
256
else
257
    cat -
258
fi
259
echo
260
 
261
# Now process the non-encrypted attachments ...
262
# -----------------------------------------
263
 
264
if [ "$FILES" ]
265
then
266
    for F in $FILES
267
    do
268
 
269
       BASE=`basename $F`
270
 
271
       echo --${BOUNDARY}
272
       echo Content-Type: ${CONTENT_TYPE}\; name=\"$BASE\"
273
       echo Content-Disposition: attachment\; filename=\"$BASE\"
274
       echo Content-Transfer-Encoding: 7bit
275
       echo
276
 
277
       cat $F
278
 
279
    done
280
fi
281
 
282
# Now process the base64 encrypted attachments ...
283
# --------------------------------------------
284
 
285
if [ "$BASE64" ]
286
then
287
    for F in $BASE64
288
    do
289
 
290
       BASE=`basename $F`
291
 
292
       echo --${BOUNDARY}
293
       echo Content-Type: ${CONTENT_TYPE}\; name=\"$BASE\"
294
       echo Content-Disposition: attachment\; filename=\"$BASE\"
295
       echo Content-Transfer-Encoding: base64
296
       echo
297
 
298
       perl -e '
299
       use MIME::Base64 qw(encode_base64);
300
       local($/) = undef;
301
       print encode_base64(<STDIN>);' < $F
302
 
303
    done
304
fi
305
 
306
# Now process the uuencode encrypted attachments ...
307
# ----------------------------------------------
308
 
309
# Sorry, this bit is untested - I haven't got a mail-client which can
310
# handle uuencoded MIME messages automatically, so can't test if the
311
# 'Content-Transfer-Encoding: uuencode' line is correct and whether I
312
# need the uuencode "begin" and "end" lines.
313
 
314
if [ "$UUE" ]
315
then
316
    for F in $UUE
317
    do
318
 
319
       BASE=`basename $F`
320
 
321
       echo --${BOUNDARY}
322
       echo Content-Type: ${CONTENT_TYPE}\; name=\"$BASE\"
323
       echo Content-Disposition: attachment\; filename=\"$BASE\"
324
       echo Content-Transfer-Encoding: uuencode
325
       echo
326
 
327
       uuencode < $F xxx 
328
 
329
    done
330
fi
331
 
332
# append the final boundary line ...
333
 
334
echo --${BOUNDARY}--
335
 
336
) | /usr/lib/sendmail -t