home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-convex / audit / README < prev    next >
Encoding:
Text File  |  1993-07-14  |  11.4 KB  |  346 lines

  1. The audit.pl package. 
  2. =====================
  3.  
  4. What this package does:
  5. =======================
  6. This package provides routines that parse an incoming mail message, divide
  7. it into a header and the body of the message and further decompose
  8. the mail header into its fields. The routines set variables that you
  9. can query and parse in your own PERL script to determine what to do with
  10. the incoming mail message.
  11.  
  12. To use the package, insert the following two PERL instructions to the very
  13. TOP of your PERL script:
  14.  
  15. require '/gmaster/home/strike/work/perl/deliver/audit.pl' || 
  16.         die "deliver: cannot include audit.pl: $@";
  17.  
  18. &initialize();
  19.  
  20.  
  21. Variables that &initialize() sets:
  22. ---------------------------------
  23. The routine &initialize() reads the incoming mail message and sets
  24. the following variables:
  25.  
  26. $sender        This is the sender shown on the "From " line.
  27.  
  28. %headers    An associative array containing the lines in the mail
  29.         header. $header{'Subject'} contains the Subject: line;
  30.         $header{'Date'} contains Date:, etc. 
  31.         
  32.         If the To: or Cc: line appeared more than once in the header,
  33.         those lines are concatenated together into a single
  34.         comma-separated list of names. Other header lines that
  35.         appear twice are clobbered.
  36.  
  37. There are also many variables and arrays set for your convenience if you
  38. dont want to parse the entries of %headers yourself.
  39.  
  40. $subject    The Subject: line.
  41.  
  42. $precedence    The Precedence: line.
  43.  
  44. $friendly    The friendly (human) name of the sender
  45.         (e.g., Martin Streicher)
  46.  
  47. $address    The email address of the sender 
  48.         (e.g., strike@pixel.convex.com)
  49.  
  50. $from        The login name of the sender with all addressing stripped. For
  51.         example, if $address was strike@pixel.convex.com, $from
  52.         is strike.
  53.  
  54. $organization    The name of the sender's organization. This is derived from
  55.         $address; for example strike@pixel.convex.com yields convex;
  56.         wizard!jim@uunet.uu.net yields wizard; jane@mach.site.co.uk
  57.         yields site.
  58.  
  59. @to        The list of names on the To: line(s). Note that the 
  60.         name listed on the Apparently-To: line also appears in @to.
  61.  
  62. @cc        The list of names on the Cc: line(s).
  63.  
  64. @received    The list of received headers in the mail message that
  65.         show the path the message traveled to be delivered.
  66.  
  67.  
  68. Routines that audit.pl provides:
  69. --------------------------------
  70. The package offers some canned routines for handling the incoming
  71. mail message:
  72.  
  73. &deliver()    Deliver the incoming mail message. &deliver() appends
  74.         the incoming mail message to the end of your UNIX mail
  75.         drop /usr/spool/mail/<user>, where <user> is the name
  76.         specified in the .forward file. 
  77.  
  78. &vacation()    Reply automatically to the sender if you have a vacation 
  79.         message in $HOME/.vacation.msg. If you do not have this
  80.         file, this routine does absolutely nothing. If you have
  81.         a .vacation.msg file, &vacation sends the sender of the
  82.         message an automatic reply containing that file.
  83.  
  84.         This routine also records who you sent 
  85.         vacation mail to; it will not send duplicate vacation messages
  86.         to the same person.  If you change your vacation message, the 
  87.         list is zeroed. The list of people you sent vacation mail to
  88.         is kept in $HOME/.vacation.log. 
  89.  
  90.         Some notes about &vacation():
  91.             - It will send you vacation mail. This is useful
  92.               to test your vacation message out.
  93.  
  94.             - It will not send vacation mail to anyone named
  95.               root, mailer-daemon, postmaster, daemon or mailer.
  96.               This are not considered to be real users.
  97.  
  98.             - It will not respond to mail that is labelled
  99.               with precendence bulk or junk.
  100.  
  101. &file_from() or 
  102. &file_from($dir)
  103.         This routine files the incoming mail message
  104.         in a hierarchy of mail folders. The top-level of the
  105.         hierarchy is specified in $dir; by default (if no
  106.         directory is specified) it is $HOME/log. The next level
  107.         of the hierachy is sorted by $organization; below this level
  108.         mail is sorted by the sender's login name.
  109.  
  110.         For example, say you receive a message from 
  111.         strike@pixel.convex.com; if you call &file_from(),
  112.         the corresponsing mail message will be filed into a mail
  113.         folder called $HOME/log/convex/strike. All mail sent to you
  114.         by strike@pixel.convex.com would be filed in this mail folder.
  115.  
  116.         You can &file_from to file all correspondence for future
  117.         reference.
  118.  
  119. &openpipe($command)
  120.         You can also use your own commands (scripts/programs)
  121.         to process an incoming mail message. &openpipe($command)
  122.         opens a PERL pipe to $command and pipes the mail message
  123.         to that command.
  124.  
  125. You can use none, one or all of these routines. You can also repeat
  126. and combine all of these functions to do more than one thing with a piece of 
  127. incoming mail (you probably only want to &deliver() the message once though).
  128.  
  129. For example, say you get a message from strike@pixel.convex.com. You want 
  130. to file the message away for auditing purposes, save the mail message in your 
  131. mail drop and send some vacation mail if you are gone. Use the &file_from(), 
  132. &deliver() and &vacation() functions to do all of these things to one message.
  133.  
  134. WARNING: IF YOU EXIT FROM THE PERL SCRIPT WITHOUT DOING SOMETHING
  135.      WITH THE MAIL MESSAGE, IT IS LOST FOREVER.
  136.  
  137. Actually, exiting the PERL script can be an effective way of dropping
  138. unwanted mail messages. See the example below.
  139.  
  140.  
  141. Other convenience functions for MH users:
  142. -----------------------------------------
  143. If you use MH, other convenience routines are provided to 
  144. pipe the incoming mail message to rcvstore, rcvdist and/or rcvtty.
  145. There is also a special refile routine to file incoming mail messages
  146. in folders according to the sender's organization and login. 
  147.  
  148. To access the MH functions, add the following line to the TOP of your script:
  149.  
  150. require '/gmaster/home/strike/work/perl/deliver/mh.pl' || 
  151.         die "deliver: cannot include mh.pl: $@";
  152.  
  153. This file provides the following functions:
  154.  
  155. &rcvstore($folder)    
  156.         Pipe the incoming mail message to rcvstore; the $folder
  157.         argument is the name of the folder to store the message
  158.         into.    
  159.  
  160. &rcvtty()    Pipe the incoming mail message to rcvtty. rcvtty
  161.         is MH's equivalent to biff and its output can be tailored
  162.         exactly like you can customize scan or inc. 
  163.  
  164. &rcvdist($names)
  165.         Pipe the incoming mail message to rcvdist. $names
  166.         is a blank separated list of names to send the
  167.         message to. You can use the &ali() command (see below)
  168.         to expand MH aliases.
  169.  
  170. &ali($alias)    Expand the MH alias name in $alias to the list
  171.         of addresses it stands for. Unlink all the other routines,
  172.         this routine returns an array of names, where
  173.         each element is an addressee on the alias.
  174.  
  175. &refile_from() or
  176. &refile_from($dir)
  177.         File a copy of the incoming mail message into a hierarchy of
  178.         MH folders. The top-level directory is "log" by default unless
  179.         you specify another folder (all this below you Mailpath folder,
  180.         of course). The next level is sorted by organization name
  181.         and the level below that is sorted by sender's login name.
  182.  
  183.  
  184.  
  185. Writing a PERL mail auditing script:
  186. ====================================
  187. The best way to show what all this can do is with a specific example. Here 
  188. is my script (with comments!):
  189.  
  190. ------ script starts here -------
  191. #! /usr/local/bin/perl
  192.  
  193. require '/gmaster/home/strike/work/perl/deliver/audit.pl' || 
  194.         die "deliver: cannot include audit.pl: $@";
  195.  
  196. require '/gmaster/home/strike/work/perl/deliver/mh.pl' || 
  197.         die "deliver: cannot include mh.pl: $@";
  198.  
  199. &initialize();
  200.  
  201.  
  202. # -----
  203. # My mail processing starts here
  204. #
  205.  
  206. # If this message came from the MAILER, deliver it to me directly
  207. # and do nothing else.
  208. #
  209. ($from =~ /MAILER/) && do { &deliver(); exit; };
  210.  
  211. # If this message is sent to xpixel (either To or Cc, deliver
  212. # the messsage to me and exit.
  213. #
  214. (grep(/^xpixel/, @to, @cc)) && do { &deliver(); exit; };
  215.  
  216. # If the message is from a place called "lupine", this
  217. # is really NCD.
  218. #
  219. $organization = "ncd" if ($organization eq "lupine");
  220.  
  221. # If the sender's name is in the password file, the organization
  222. # is CONVEX.
  223. #
  224. $organization = "convex" if ($logname = (getpwnam($from))[0]);
  225.  
  226. # If I am specifically named on the To or Cc line, do the default.
  227. # The routine &default is below: it delivers the message, refiles
  228. # it in an MH folder, sends vacation mail if I am gone, and
  229. # biffs me if I am logged in somewhere.
  230. #
  231. (grep(/^strike/, @to, @cc)) && do { 
  232.     &default();
  233.     exit;
  234. };
  235.  
  236. # If the mail message went to x<hostname> where hostname
  237. # is in our /etc/hosts, trash the message (JUST EXIT TO DROP
  238. # THE MESSAGE)
  239. #
  240. exit if (grep((/^x(.*)/ && (@n = gethostbyname($1))), @to, @cc));
  241.  
  242. # Throw away anything to anyone or any alias named avs-updates
  243. #
  244. exit if (grep(($_ eq "avs-updates"), @to));
  245.  
  246. # Throw away junk mail from AVS, Inc.
  247. #
  248. if ($organization eq "avs") {
  249.     exit if ($subject =~ /^(Opened|Assigned) to/);
  250.     exit if ($subject =~ /^(Edited|Fixed|Killed) by/);
  251. };
  252.  
  253.  
  254. # If the mail message went to an X Consortium alias,
  255. # deliver it to me if it is advisory board mail. Otherwise,
  256. # refile it into an archive and redistribute it to anyone at CONVEX
  257. # that subscribes to it through me.
  258. #
  259. $xcons = 0;
  260. @consortium = (
  261.     '/^advisory/',    '/^blend/',        '/^bug-trackers/',
  262.     '/^color/',    '/^fix-trackers/',    '/^fontwork/',
  263.     '/^imagework/',    '/^xlib/',        '/intrinsics/',
  264.     '/^mltalk/',    '/^pex-si/',        '/^pex-spec/',
  265.     '/^protocol/',    '/^security/',        '/^shape/',        
  266.     '/^trackers/',    '/^transport/',        '/^wmtalk/',        
  267.     '/^xbuffer/',    '/^xc/',        '/^xinput/',            
  268.     '/^xtest/',    '/^consortium/',    '/^serialwork/',
  269.     '/^xie_/',    '/^mtserver/'
  270. );
  271.  
  272. foreach $list (@consortium) {
  273.     for (grep(eval $list, @to, @cc)) {
  274.        &deliver() if ($_ =~ "^advisory");
  275.        $xcons++;
  276.        &rcvstore("XConsortium/$_"); 
  277.        @dist = &ali("XConsortium-$_");
  278.        &rcvdist(join(' ', @dist)) if ((@dist)); 
  279.     };
  280. };
  281. exit if $xcons;
  282.  
  283.  
  284. # this mail was not sent to me directly, so dont answer with vacation mail,
  285. #
  286. &deliver();
  287. &rcvtty();
  288.  
  289. # All done!
  290. #
  291. exit;
  292.  
  293.  
  294. # =====
  295. # Subroutine default
  296. #     defaults specifies what to do when I want to accept a piece
  297. #    of mail. It is a convenience.
  298. sub default {
  299.  
  300.     &deliver();
  301.     &vacation();
  302.     &rcvtty();
  303.     &refile_from();
  304. }
  305.  
  306. ------ script ends ----------
  307.  
  308.  
  309. Testing
  310. ========
  311. If you want to test your PERL script, put the following in your .forward file:
  312.  
  313.     <login>, "| <homedir>/<script> <login>
  314.  
  315. where <login> is your UNIX login, <homedir> is the absolute path name
  316. to your home directory and <script> is the name of your PERL mail
  317. auditing script. If you put this in .forward, incoming mail messages
  318. will be directly sent to your mail drop AND will be piped through your
  319. PERL script. You may get duplicates of some mail, but this is the best
  320. way to see what your script is doing.
  321.  
  322. Once you are satisifed that your script works, simply replace your
  323. .forward file with:
  324.  
  325.     "| <homedir>/<script> <login>
  326.  
  327. Please note that if your script has syntax errors, the mailer will
  328. not drop your incoming mail; instead it will send you a the incoming
  329. mail message and a note indicating that an unknown mailer error occurred.
  330.  
  331. Another way to test your script:
  332. --------------------------------
  333. You can also test your script by piping a UNIX mail folder (like your 
  334. mail drop) directly into your script. For example, say you are having
  335. problems with mail from a certain sender or network alias; to debug your
  336. script, copy your incoming mail box in /usr/spool/mail to a local file
  337. and then pipe it to your script ala:
  338.  
  339.     cat mail | perl -d ~/.audit
  340.  
  341. You can then step through the script and see how the mail message
  342. is being parsed. You can add breakpoints, print statements, etc. and see
  343. the script operate on the mail. If you use &vacation() or &file_from(),
  344. you can watch those routines operate as well. The mail message is processed 
  345. as if it came directly to your script courtesy of the delivery system.
  346.