mediratb@p4.cs.man.ac.uk (12/06/90)
From: mediratb@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@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@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@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