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.*.*
215 ###############################################################################
219 mail.runner version $VERSION
220 -----------------------
222 mail.runner is a script for sending and receiving email.
227 The main features of mail.runner are
229 - good performance over very slow links
230 - secure mail transfer via rsync and ssh
231 - incremental transfer in case the link is lost
232 - no mta installation needed on the client
238 To use mail.runner you need the following:
240 - a working 'rsync' and 'ssh' installation
242 - the 'movemail' utility
243 - the 'formail' utility
244 - the Linux 'pidof' utility
245 - a working 'procmail' installation for mail delivery on the client
246 - a working 'sendmail' (or equivalent) installation on the server for sending
248 - optionally you may use the 'frm' utility
254 To install mail.runner you need to do the following:
256 - install the mail.runner script on both the server and client
257 - create a .mail.runner configuration file on the server and client (see
258 the CONFIGURATION section of this help for details)
259 - tell your email program to use "mail.runner sendmail" as the local
260 program to send email with
262 How you do the last step depends on your email program. I use RMAIL in
263 emacs to read and send email, so I used the following in my .emacs:
264 (setq sendmail-program "~/bin/mail.sendmail")
265 and then I created a one line script called 'mail.sendmail' that runs
266 'mail.runner sendmail'.
272 Once installed, you should just run 'mail.runner' to fetch any
273 outstanding emails from the server and send any pending messages. You
274 can also ask mail.runner to just send or fetch by using:
279 Any diagnostics messages should be self explanatory.
284 You should configure mail.runner using a file called .mail.runner in
285 your home directory on both the client and the server. The minimal
286 configuration would contain the single option MAIL_HOST like this:
288 MAIL_HOST="your.mail.server"
293 This specifies the remote shell to use for rsync. Defaults to "ssh"
296 This specifies the name of the directory where you store mail on
297 both the client and the server. This should be a relative path,
298 relative to your home directory. The default is "Mail".
301 This specifies the location of your mail inbox on your mail server.
302 The default is '\$HOME/InBox'
305 This specifies the location of the mail.runner script on the
306 server, relative to your home directory. The default is "mail.runner".
309 This specifies the number of seconds to wait for transfers. It is
310 passed as a timeout parameter to rsync. The default is 300.
313 This specifies the name of your sendmail program on the
314 server. This program should accept raw emails on stdin and send
315 them. The default is "/usr/lib/sendmail"
318 This specifies additional command line options to be passed to
319 sendmail. The default is no additional options.
322 If this is set to "1" then mail.runner will use the 'frm' utility
323 to display the subject and sender of incoming emails as they are
327 If this is set to "1" then mail.runner will display the last 10
328 lines of your '\$MAIL_DIR/procmail.log' after processing incoming
332 This defaults to "$RSYNC_OPTS", you may wish to remove the
333 -v and add -q for quieter operation
336 This sets the command used to deliver mail locally.
337 It defaults to "$PROCMAIL_COMMAND"
341 1 - Summary of messages sent and received.
342 2 - Additional whitespace and output when no mail to send.
345 If this is set to "1" no "pidof" checking is done. You should set
346 this to "1" if you don't have pidof or your pidof is broken in
353 mail.runner is released under the GNU General Public License, version
354 2 or later. Please see http://www.gnu.org/ for a full copy of the license.
360 mail.runner was written by Andrew Tridgell <tridge@samba.org>
366 ###############################################################################
367 # START OF MAIN SCRIPT
368 ###############################################################################
370 # See if user is just after help, if so display and exit
371 if [ "$1" = "-h" -o "$1" = "--help" -o $HAVE_MAIL_RUNNER_CONFIG == 0 ]; then
376 # we rely on expansion to a null list
379 # make sure the necessary variables are defined
380 if [ "$MAIL_HOST" = "" ]; then
381 error_msg "You must define a MAIL_HOST in $HOME/.mail.runner";
382 error_msg "Use -h for more help";
386 # when an argument is passed then call the corresponding mail_* function
387 # with the remaining arguments. This is used to invoke the right function
388 # remotely, but can also be used to do things like "mail.runner send" from
398 # the default is to fetch then send