4 # a simple mail delivery and transmission system
5 # Copyright Andrew Tridgell <tridge@samba.org> 1997-2002
6 # released under the GNU General Public License version 2 or later
10 # setup the default configuration
13 MAIL_INBOX="$HOME/InBox"
14 MAIL_RUNNER="mail.runner"
15 SENDMAIL="/usr/lib/sendmail"
19 PROCMAIL_COMMAND="formail -s procmail"
23 # sensible paths are often not setup when invoking commands remotely
24 export PATH=$PATH:$HOME/bin:/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin
27 # define an empty sendmail hook - replace this in .mail.runner for
28 # interesting multi-host tricks
29 mail_sendmail_hook() {
34 # load the user specific config
35 if [ -f $HOME/.mail.runner ]; then
36 HAVE_MAIL_RUNNER_CONFIG=1
39 echo "YOU MUST HAVE A .mail.runner config!" 1>&2
40 HAVE_MAIL_RUNNER_CONFIG=0
43 if [ ! -z "$MAIL_RUNNER_CONF" -a -r "$MAIL_RUNNER_CONF" ]; then
47 if [ -z "$MAIL_OUT_DIR" ]; then
48 MAIL_OUT_DIR="$MAIL_DIR"
53 # processing now continues in MAIN SCRIPT section at bottom of file
56 ##############################################################
57 # print a message if the level <= $MAIL_VERBOSE
60 if [ $level -le $MAIL_VERBOSE ]; then
66 ##################################
67 # print an error message to stderr
73 ##############################################################
74 # try to make sure two copies of this script don't run at once
76 if [ "$MAIL_NO_PIDOF" == 1 ]; then
79 pids=`pidof -x -o $$ mail.runner`;
82 pid_owner=`stat -c"%u" /proc/$p/stat`
83 if [ x$pid_owner = x$myid ]; then
84 echo "mail.runner is already running - pid $p"
93 ###############################################################################
94 # send all pending mail, invoking mail.deliver at the other end
98 list=`echo $HOME/$MAIL_OUT_DIR/mail.out.*.*[0-9]`
100 if [ "$list" = "" ]; then
101 debug_msg 2 "No messages to send";
104 debug_msg 1 "Sending `echo $list | wc -w` messages";
106 if rsync --rsync-path="$MAIL_RUNNER remote_deliver" \
107 --timeout=$MAIL_TIMEOUT $RSYNC_OPTS -e "$MAIL_SSH" \
108 $list $MAIL_HOST:$MAIL_DIR/; then
114 ###############################################################################
115 # fetch mail from the remote host and deliver it via procmail
119 if ! rsync --timeout=$MAIL_TIMEOUT $RSYNC_OPTS -e "$MAIL_SSH" \
120 --rsync-path="$MAIL_RUNNER remote_send" \
121 $MAIL_HOST:$MAIL_DIR/EMPTY_FILE $HOME/$MAIL_DIR/; then
122 error_msg "transfer failed";
126 if [ "`echo $HOME/$MAIL_DIR/mail.in.*.*`" = "" ]; then
128 debug_msg 1 "No mail to retrieve";
132 for f in $HOME/$MAIL_DIR/mail.in.*.*; do
133 if cat $f | $PROCMAIL_COMMAND; then
134 # it is useful seeing what mail is being processed
135 if [ "$MAIL_FRM" = "1" ]; then
142 # this is useful for seeing where procmail has put things ...
143 if [ "$MAIL_PROCMAIL_TAIL" = "1" ]; then
146 debug_msg 2 `tail $HOME/$MAIL_DIR/procmail.log`;
153 ###############################################################################
154 # a sendmail-like call. This just places the mail in a known location for
157 msg=$HOME/$MAIL_DIR/mail.out.$RANDOM.$$
161 mail_sendmail_hook $msg
166 ##############################################################################
167 # a rsync wrapper function that delivers mail on the remote host
168 mail_remote_deliver() {
174 if [ $status != 0 ]; then
178 for f in $HOME/$MAIL_DIR/mail.out.*.*[0-9]; do
179 if $SENDMAIL $SENDMAIL_OPTS < $f; then
182 error_msg "Mail of $f failed $status";
188 ###############################################################################
189 # a rsync wrapper function for fetching mail from the remote host
193 # atomically move mail from InBox to a temporary file
194 if test -s $MAIL_INBOX; then
195 movemail $MAIL_INBOX $HOME/$MAIL_DIR/mail.in.$RANDOM.$$ > /dev/null
198 # by using an empty file we avoid error messages from rsync about not
199 # having any files to transfer
200 if [ ! -f $HOME/$MAIL_DIR/EMPTY_FILE ]; then
201 touch $HOME/$MAIL_DIR/EMPTY_FILE
204 rsync $* $HOME/$MAIL_DIR/mail.in.*.*
206 if [ $status != 0 ]; then
210 rm -f $HOME/$MAIL_DIR/mail.in.*.*
214 ###############################
215 # show the outgoing mail queue
216 ###############################
218 for f in $HOME/$MAIL_DIR/mail.out.*.*; do
220 egrep '^(From|To|Subject):' $f | sed 's/^/ /'
226 ###############################################################################
230 mail.runner version $VERSION
231 -----------------------
233 mail.runner is a script for sending and receiving email.
238 The main features of mail.runner are
240 - good performance over very slow links
241 - secure mail transfer via rsync and ssh
242 - incremental transfer in case the link is lost
243 - no mta installation needed on the client
249 To use mail.runner you need the following:
251 - a working 'rsync' and 'ssh' installation
253 - the 'movemail' utility
254 - the 'formail' utility
255 - the Linux 'pidof' utility
256 - a working 'procmail' installation for mail delivery on the client
257 - a working 'sendmail' (or equivalent) installation on the server for sending
259 - optionally you may use the 'frm' utility
265 To install mail.runner you need to do the following:
267 - install the mail.runner script on both the server and client
268 - create a .mail.runner configuration file on the server and client (see
269 the CONFIGURATION section of this help for details)
270 - tell your email program to use "mail.runner sendmail" as the local
271 program to send email with
273 How you do the last step depends on your email program. I use RMAIL in
274 emacs to read and send email, so I used the following in my .emacs:
275 (setq sendmail-program "~/bin/mail.sendmail")
276 and then I created a one line script called 'mail.sendmail' that runs
277 'mail.runner sendmail'.
283 Once installed, you should just run 'mail.runner' to fetch any
284 outstanding emails from the server and send any pending messages. You
285 can also ask mail.runner to just send or fetch by using:
290 Any diagnostics messages should be self explanatory.
295 If you use an Emacs-based email program then you should set the
296 variable mail-interactive to t. This means that the email program
297 will notice when 'mail.runner sendmail' fails to queue a message,
298 perhaps if mail.runner exits (with non-0 status) because another
299 instance is already running (possibly doing 'mail.runner send').
300 Otherwise it may look like 'mail.runner sendmail' has queued a
301 message, but it has really been discarded!
306 You should configure mail.runner using a file called .mail.runner in
307 your home directory on both the client and the server. The minimal
308 configuration would contain the single option MAIL_HOST like this:
310 MAIL_HOST="your.mail.server"
315 This specifies the remote shell to use for rsync. Defaults to "ssh"
318 This specifies the name of the directory where you store mail on
319 both the client and the server. This should be a relative path,
320 relative to your home directory. The default is "Mail".
323 This specifies the location of your mail inbox on your mail server.
324 The default is '\$HOME/InBox'
327 This specifies the location of the mail.runner script on the
328 server, relative to your home directory. The default is "mail.runner".
331 This specifies the number of seconds to wait for transfers. It is
332 passed as a timeout parameter to rsync. The default is 300.
335 This specifies the name of your sendmail program on the
336 server. This program should accept raw emails on stdin and send
337 them. The default is "/usr/lib/sendmail"
340 This specifies additional command line options to be passed to
341 sendmail. The default is no additional options.
344 If this is set to "1" then mail.runner will use the 'frm' utility
345 to display the subject and sender of incoming emails as they are
349 If this is set to "1" then mail.runner will display the last 10
350 lines of your '\$MAIL_DIR/procmail.log' after processing incoming
354 This defaults to "$RSYNC_OPTS", you may wish to remove the
355 -v and add -q for quieter operation
358 This sets the command used to deliver mail locally.
359 It defaults to "$PROCMAIL_COMMAND"
363 1 - Summary of messages sent and received.
364 2 - Additional whitespace and output when no mail to send.
367 If this is set to "1" no "pidof" checking is done. You should set
368 this to "1" if you don't have pidof or your pidof is broken in
375 mail.runner is released under the GNU General Public License, version
376 2 or later. Please see http://www.gnu.org/ for a full copy of the license.
382 mail.runner was written by Andrew Tridgell <tridge@samba.org>
388 ###############################################################################
389 # START OF MAIN SCRIPT
390 ###############################################################################
392 # See if user is just after help, if so display and exit
393 if [ "$1" = "-h" -o "$1" = "--help" -o $HAVE_MAIL_RUNNER_CONFIG == 0 ]; then
398 # we rely on expansion to a null list
401 # make sure the necessary variables are defined
402 if [ "$MAIL_HOST" = "" ]; then
403 error_msg "You must define a MAIL_HOST in $HOME/.mail.runner";
404 error_msg "Use -h for more help";
408 # when an argument is passed then call the corresponding mail_* function
409 # with the remaining arguments. This is used to invoke the right function
410 # remotely, but can also be used to do things like "mail.runner send" from
420 # the default is to fetch then send