Mail Spooler

mediratb at p4.cs.man.ac.uk mediratb at p4.cs.man.ac.uk
Thu Dec 6 23:28:16 AEST 1990


From: mediratb at p4.cs.man.ac.uk (Bharat Mediratta)
Organization: University of Manchester Computer Science Department
Subject: A mail spooling program

The following shell script allows you to spool large quantities of files
to be mailed on a daily basis without any hassle.  This is a first release
of the shell script and it might have bugs in it.  It is very easy to use.

1) Create a subdirectory in your home directory called 'spool'
2) Inside this directory, create a subdirectory for each person you want
   spooled mail sent to.  This subdirectory should be the pathname of the
   person the mail is being sent to.  It is usually best if this is a mail
   alias, although this is not necessary.
3) Inside the ^/spool/<name> directory place the files you wish to be mailed.

Example Directories:
% ls -l spool
total 4
drwx------  4 mediratb      512 Dec  3 11:48 ./
drwxr-xr-x 15 mediratb     1024 Dec  5 13:01 ../
drwx------  2 mediratb      512 Dec  5 12:55 alistair/
drwx------  2 mediratb     1024 Dec  5 12:56 jeff/
% ls -l spool/alistair
total 3
-rw-------  1 mediratb      908 Dec  3 11:50 simpsons
-rw-------  1 mediratb      288 Dec  3 11:51 smoking_prohibited
-rw-------  1 mediratb     1200 Dec  3 11:51 software_development.M
% grep alistair ^/.mailrc
alias alistair acampbell%his-site at relay.etc
%

To run the program you can either stick it in cron, which is difficult for
some people, or put a line in your .login so that it runs every time you
log in.  Right now, the program is set to exit if you try to run it more than
once per day.  So if you stick it in your .login, it won't send off mail every
time you log in - just once a day.  If you don't want to see the output, use
a line like this:

((nice +10 ^mediratb/bin/cmd/spoolmail) >/dev/null &) >/dev/null

It is important to nice the job - especially on a workstation - or there will
be considerable slowdown...
It will be difficult to reach me to give me bug reports because I am finishing
a semester in Manchester and am about to begin a semester in Wales, for which
I don't know my e-mail address.  You can send email to my account back in the
states (bmediratta at colgateu.bitnet) and I'll read it in June.  Alternatively,
you can send mail here and I will try to log on from time to time and check it.

Enjoy!
  -Bharat

+------------------+------------------------------------------------------+
| Bharat Mediratta | mediratb at p4.cs.man.ac.uk                             |
+------------------+------------------------------------------------------+
| "When the going gets weird, the weird turn pro" - Hunter S. Thompson    |
| "You want it all, but you can't have it" - Faith No More (Epic)         |
| "On a clear disk you can seek forever..."                               |
|                                                                         |
|   (@@@@)    /-----------------------\                                   |
|  (@@@@@@)   | I'm Bharat Simpson!   |                                   |
|  (@@@@@@)   | Don't Eat a Cow, Dude!|                                   |
|  |      |   \-----------------------/                                   |
|  | (o)(o)   /                                                           |
|  C      _) /                                                            |
|   | ,___| -                                                             |
|   |   /                                                                 |
|  /____\                                                                 |
| /      \                                                                |
+-------------------------------------------------------------------------+

------------- CUT HERE ---------------- CUT HERE --------------------
#!/bin/csh -f
#                                  SpoolMail
# Description:
#   Allows you to send large quantities of files over the network without
#   boosting the bandwith.  The program sends out a chunk (preset to 50K)
#   a day.
#
# Author:
#   Bharat Mediratta, Colgate '92
#   Written at the Univ. of  Manchester when I wanted to ship all
#   of my neat stuff back to Colgate after a year abroad - without
#   killing the bandwith.
#
# Usage:
#   Create a spool directory in your home directory (you can adjust
#   this by changing the variables set below.)  Inside the spool
#   directory, create a directory for each person you wish to have
#   mail spooled to.  The name of this directory should be the pathname
#   you wish the mail sent to.  It is probably good to use an alias
#   that you define in your .mailrc file, etc. although this is not
#   necessary.  Any file put inside this directory will be sent to the
#   appropriate person and then either a) removed or b) renamed to
#   <file>.M depending on the option you define below.  Optional logging
#   can be toggled below also.  When logging is on, you will receive a
#   complete report of all files mailed that day via mail itself.
#
# Dependencies:
#   csh, dc, awk, grep, ls, mail, date
#
# Files:
#   $HOME/.spooldate    - keep track of the last time the program was run
#   /tmp/spoollog.<pid> - temporary file for the spool report
#
# Bugs:
#   An annoying tendency to split the files in such a way as to create
#   a last file with only a few K in it.  Then it goes on to put a header
#   at the top of the file saying something like 'File: Part 7 out of 6'
#   Solution?  Use a better file splitting program and a smart algorithm.
#
# Variables
set rmormv = mv                 # Remove or Move?  rm|mv
set logging = on                #  on|off
set log = /tmp/spoollog.$$      # Temporary file for log
set spool = $HOME/spool         # Spool directory
set datefile = $HOME/.spooldate # Date file to keep track of last run
set MAX = 51200                 # Maximum (bytes) sent to one person

# First, check to see if the program has been run in the last day.  If it
# has been, simply exit - we only want to mail packets once a day.
if (-e $datefile) then
    set last = `awk ' print $3 ' < $datefile`
    set today = `date | awk ' print $3 '`
    if ($last == $today) then
        exit 0
    endif
endif

# Update the date executed file...
date > $datefile

# For each person in the spool directory, mail them MAX worth of files
# without splitting any of them up.  If a file in the spool directory
# is too large to be sent without being split, split it up into approximately
# 25K parts and then try again.
cd $spool
foreach foo (`/bin/ls`)
    set total = 0           # Total = number of bytes actually sent
    echo Checking $foo >> $log
    cd $foo
    set dir = `/bin/ls`     # for some stupid reason, csh won't let me
    if ("$dir" != "") then  # combine these two lines! :-(

        # First, check to see if any file in the directory exceeds
        # $MAX, if so, split it up into roughly MAX/2 K files
        foreach bar (`/bin/ls -s | sort -r | awk ' if (NR != 1) print $2 '`)
            if ("`echo $bar | grep .M`" == "") then
                set size = `ls -l $bar | awk ' print $4 '`
                set ok = `echo "$size $MAX <" | dc`
                if ("$ok" != "") then
                    # The file is too big!
                    echo $bar \($size\) is over $MAX >> $log
                    set howmany = `echo "$size $MAX 2 / / p" | dc`
                    set linetotal = `wc -l $bar | awk ' print $1 '`
                    set linespersplit = `echo "$linetotal $howmany / p" | dc`
                    echo Splitting $bar into $howmany pieces >> $log
                    split -$linespersplit $bar $bar.

                    # See if the sum of the parts = the whole
                    echo $bar \($size\) is now: >> $log
                    set parttotal = 0
                    foreach bletch (`/bin/ls $bar.*`)
                        set partsize = `ls -l $bletch | awk ' print $4 '`
                        echo $bletch \($partsize\) >> $log
                        set parttotal = `echo "$partsize $parttotal + p" | dc`
                    end

                    # If so, remove the whole, else remove the parts
                    if ($parttotal != $size) then
                        echo The parts don\'t add up\! >> $log
                        echo Removing `/bin/ls $bar.*` >> $log
                        rm $bar.*
                    else
                        echo Removing $bar... >> $log
                        rm $bar
                        # Stick a note in each file saying which one it is
                        # and how many are coming total.
                        set count = 1
                        foreach bletch (`/bin/ls $bar.*`)
                            echo "--- $bar Part $count out of $howmany ---"\
                                     >/tmp/$bletch
                            cat $bletch >> /tmp/$bletch
                            cp /tmp/$bletch $bletch
                            rm /tmp/$bletch
                            set count = `echo "$count 1 + p" | dc`
                        end
                    endif
                else
                    # We have found a file that is smaller than MAX.  Since
                    # the files were sorted in descending order, that means
                    # all the rest are smaller than MAX so skip them...
                    break
                endif
            endif
        end

        # Then attempt to send each file, without exceeding the size limit
        # Start with the largest file, and work down to the smallest
        foreach bar (`/bin/ls -s | sort -r | awk ' if (NR != 1) print $2 '`)
            if ("`echo $bar | grep .M`" == "") then
                set size = `ls -l $bar | awk ' print $4 '`
                set ok = `echo "$size $total + $MAX <" | dc`
                if ("$ok" == "") then
                    set total = `echo "$size $total + p" | dc`
                    echo Sending $bar \($size\), Total: $total >> $log
                    mail -s "$bar" $foo < $bar
                    if ("$rmormv" == "mv") then
                        echo $bar is now $bar.M >> $log
                        mv $bar $bar.M
                    else
                        echo Removing $bar >> $log
                        rm $bar
                    endif
                endif
            endif
        end
        if ($total == 0) then
            echo Sent nothing from $foo >> $log
        endif
    else
        echo $foo is empty >> $log
    endif
    cd $spool
end

# Mail a copy of the log to the user (if he wants it)
if ("$logging" == "on") then
    mail -s "Spool Log" $user < $log
    rm $log
endif



More information about the Alt.sources mailing list