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