home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / mailagnt / part02 < prev    next >
Encoding:
Text File  |  1992-11-19  |  54.8 KB  |  1,308 lines

  1. Newsgroups: comp.sources.misc
  2. From: ram@eiffel.com (Raphael Manfredi)
  3. Subject:  v33i094:  mailagent - Rule Based Mail Filtering, Part02/17
  4. Message-ID: <1992Nov20.050216.13327@sparky.imd.sterling.com>
  5. X-Md4-Signature: 3b96012bffc64dfaa060f55f36844d95
  6. Date: Fri, 20 Nov 1992 05:02:16 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ram@eiffel.com (Raphael Manfredi)
  10. Posting-number: Volume 33, Issue 94
  11. Archive-name: mailagent/part02
  12. Environment: Perl, Sendmail, UNIX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  agent/man/mailagent.SH.b agent/pl/add_log.pl
  19. # Wrapped by kent@sparky on Wed Nov 18 22:42:19 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 2 (of 17)."'
  23. if test -f 'agent/man/mailagent.SH.b' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'agent/man/mailagent.SH.b'\"
  25. else
  26.   echo shar: Extracting \"'agent/man/mailagent.SH.b'\" \(50897 characters\)
  27.   sed "s/^X//" >'agent/man/mailagent.SH.b' <<'END_OF_FILE'
  28. Xno such line exists, then assume the mail was directed to the user (which
  29. Xseems a reasonable assumption :-).
  30. X.TP
  31. X.I Sender:
  32. XUser who sent the mail. This may differ from the \fIFrom:\fR line. If no
  33. Xsuch field exists, then the address in the first From line is used.
  34. X.TP
  35. X.I Reply-To:
  36. XWhere any reply should be sent. If no \fIReply-To:\fR field is present, then
  37. Xthe \fIReturn-Path\fR is used (with <> stripped out), or the \fIFrom:\fR
  38. Xline is parsed to extract the e-mail address of the author.
  39. X.PD
  40. X'''
  41. X.SS "Variables"
  42. X.PP
  43. XThe mailagent supports user-defined variables, which are globals. They are
  44. Xset via the ASSIGN command and referred to with the %# macro. Assuming we
  45. Xset a variable \fIhost\fR, then %#\fIhost\fR would be replaced by the actual
  46. Xvalue of the variable. This enables some variable propagation across the rules.
  47. X.PP
  48. XFor example, let's say the user receives cron outputs from various machines
  49. Xand wishes to save them on a per-machine basis, differentiating between
  50. Xdaily outputs and weekly ones. Here is a solution:
  51. X.sp
  52. X.in +5
  53. X.nf
  54. XSubject: /output for host (\\\\w+)/    { ASSIGN host %1; REJECT };
  55. XSubject: /^Daily output/    { SAVE %#host/daily.%D };
  56. XSubject: /^Weekly output/    { SAVE %#host/weekly.%m-%d };
  57. X.fi
  58. X.in -5
  59. X.sp
  60. XBesides variable interpolation via the %# escape, it is also possible to
  61. Xperform substitutions and translations on the content of a variable (or a
  62. Xbackreference, i.e. a number between 1 and 99). The two commands SUBST and
  63. XTR will respectively perform in-place substitutions and translations. In that
  64. Xcase however, the name of the variable must be preceded by a single #. This
  65. Xdifferentiates the backreference \fI1\fR from the variable \fI#1\fR, although
  66. X\fI1\fR is a funny name for a variable. The need for # also prevents the
  67. Xcommon mistake of writing %#, as the mailagent will loudly complain if the
  68. Xfirst parameter of SUBST or TR is not a digit between 1 and 99 or does not
  69. Xstart with a #.
  70. X.PP
  71. XHere are some actions to cannonicalize the host name into lower case and
  72. Xstrip down the domain name, if any:
  73. X.sp
  74. X.in +5
  75. X.nf
  76. X{ TR #host /A-Z/a-z/; SUBST #host /^([^.]*)\\\\..*/\$1/ };
  77. X.fi
  78. X.in -5
  79. X.sp
  80. XThose actions are directly translated into their \fIperl\fR equivalent, and
  81. Xany error in the specification of the regular expression will be reported.
  82. X.PP
  83. XIf the variable name begins with a colon ':', then the variable is made
  84. Xpersistent. That is to say it will keep its value accross different mailagent
  85. Xinvocations. The variable is simply stored (with the leading ':' removed) in
  86. Xthe mailagent's database and is thus subject to the aging policy set up in
  87. Xthe ~/.mailagent.
  88. X.PP
  89. XWithin PERL commands or mail hooks using perl (see the MAIL HOOKS section),
  90. Xyou can manipulate those (so-called) external variables via a set of
  91. Xinterface functions located in the \fIextern\fR package (i.e. you must
  92. Xprefix each of the function name with its package name, \fIset\fR becoming
  93. X\fIextern'set\fR). The following three interface functions are provided:
  94. X.PD
  95. X.TP 10
  96. Xval(name)
  97. XReturn the value of the variable \fIname\fR (the leading ':' is not part of the
  98. Xname, in any of these three interface functions).
  99. X.TP
  100. Xset(name, value)
  101. XSet the external variable \fIname\fR to hold \fIvalue\fR. No interpretation
  102. Xis done by the function on the actual content of the \fIvalue\fR you are
  103. Xproviding.
  104. X.TP
  105. Xage(name)
  106. XReturns the age of the variable, i.e. the elapsed time in seconds since the
  107. Xlast modification made by \fIset\fR.
  108. X.PP
  109. XThere is currently no way for erasing a variable from the database. But if
  110. Xyou do not use the variable any more, it will be removed when its age
  111. Xbecomes greater than the maximum age specified by the \fIagemax\fR configuration
  112. Xvariable.
  113. X'''
  114. X.SS "Regular Expressions"
  115. X.PP
  116. XAll the regular expressions follow the V8 syntax, as in \fIperl\fR, with all
  117. Xthe \fIperl\fR extensions. If a bracketing construct (...) is used inside a
  118. Xrule, then the %\fIdigit\fR macro matches the \fIdigit\fR's substring held
  119. Xinside the bracket. All those backreferences are memorized on a per-rule basis,
  120. Xnumbered from left to right. However, great care must be taken when using
  121. Xa backreference in multiply present selectors, as all the matches will be
  122. Xperformed up-to the first match, and backreferences are computed on the fly
  123. Xwhile doing pattern matching.
  124. X.PP
  125. XFor instance:
  126. X.in +5
  127. X.sp
  128. X.nf
  129. XTo: /(.*)/, Subject: /Output from (\\\\w+)/ { ASSIGN to %1; SAVE %2 };
  130. X.fi
  131. X.sp
  132. X.in -5
  133. Xwill save the To: field in variable 'to' and save the mail in a folder derived
  134. Xfrom the host name specified in the subject. However, if we say:
  135. X.in +5
  136. X.sp
  137. X.nf
  138. XSubject: /host (\\\\w+)/, /from (\\\\w+)/ { ASSIGN match %1 };
  139. X.fi
  140. X.sp
  141. X.in -5
  142. Xthen there will be only one backreference set, and it will come from the first
  143. Xpattern matching if it succeeds, or from the second. Should the second or
  144. Xthe first pattern have no bracketing construct and still match, then the
  145. Xbackreference would not be recorded at all, which means the following is
  146. Xprobably not what you want:
  147. X.in +5
  148. X.sp
  149. X.nf
  150. XSubject: /from/, /host (\\\\w+)/, To: /(.*)/ { SAVE %1; REJECT };
  151. X.fi
  152. X.sp
  153. X.in -5
  154. Xas if the /from/ pattern matches then /host (\\\\w+)/ will not be checked
  155. X(identical selectors are \fIor\fR'ed and that is optimized), then %1 would refer
  156. Xto the To: field whereas if /host (\\\\w+)/ matches, then %1 will be the host
  157. Xname.
  158. X.PP
  159. XHowever, this behaviour can be used to selectively store a news article
  160. Xwhich has been mailed to you in a folder whose name is the newsgroup name
  161. Xin dot form. Assuming we want to give priority to comp.lang.perl, we
  162. Xcould say:
  163. X.in +5
  164. X.sp
  165. X.nf
  166. XNewgroups:
  167. X    /(comp.lang.perl)/,
  168. X    /(comp.mail.mh)/,
  169. X    /(comp.compilers)/,
  170. X    /([^,]*)/        { SAVE %1 };
  171. X.fi
  172. X.sp
  173. X.in -5
  174. XAn article cross-posted to both comp.lang.perl and comp.mail.mh would
  175. Xbe saved in a comp.lang.perl folder, since this is what would match first.
  176. XThe last rules takes care of other articles: the folder used being
  177. Xwhatever newsgroup appears first.
  178. X.PP
  179. XThere is also a special macro %&, which lists (it's a comma separated list)
  180. Xall the selectors specified via a regular expression which indeed matched.
  181. XFor instance:
  182. X.sp
  183. X.in +5
  184. X.nf
  185. XRe.*: /york/        { ASSIGN which %& };
  186. X.sp
  187. X.in -5
  188. X.fi
  189. Xwould assign to \fIwhich\fR the list of all the fields matching the /Re.*/
  190. Xpattern which contained 'york', be it a Received: field or a Resent-From:
  191. Xfield (as both match the selector specification). Assuming both those fields
  192. Xcontained the word \fIyork\fR, the value of %& would be 'Received,Resent-From;'
  193. X(the fields are alphabetically sorted).
  194. X.PP
  195. XShould you have more than one such specified selector within a single rule,
  196. Xthen it might be worth knowing that all the set of matching selectors are
  197. Xrecorded within %&, each set terminated with a ';'. If a negated selector is
  198. Xused, then %& will record all the fields which did not contain the pattern,
  199. Xassuming the selection succeeded (otherwise nothing is recorded).
  200. X'''
  201. X.SS "Available Actions"
  202. X.PP
  203. XThe following actions are available as filtering commands. Case is irrelevant
  204. Xalthough the recommended style is to spell them upper-cased. As explained
  205. Xlater, most of the actions record their exit status in a special variable
  206. Xwhich may be tested via the \fB\-t\fR and \fB\-f\fR options of ABORT, REJECT
  207. Xand RESTART. For every command which returns such an exit status, the failure
  208. Xor success conditions are given at the end of each description. If nothing is
  209. Xspecified, then the command does not return a meaningful status.
  210. X.TP 10
  211. XABORT [-tf] [\fImode\fR]
  212. XAbort application of filtering rules immediately. See REJECT for the meaning
  213. Xof the optional parameters. (Does not modify existing status)
  214. X.TP
  215. XANNOTATE [-d] \fIfield value\fR
  216. XAnnotate message by adding \fIfield\fR into the mail header, whith the
  217. Xsupplied \fIvalue\fR. This is like the MH command \fIanno\fR, but the
  218. Xannotation is performed at the end of the header, whereas MH does it at the
  219. Xtop. Normally, an extra \fIfield\fR is added, with the current date as
  220. Xfield value. This can be suppressed by using the \fB\-d\fR option. If
  221. X\fIvalue\fR is ommitted, only the date field is generated (hence it is an
  222. Xerror to use the \fB\-d\fR option without supplying a \fIvalue\fR). As with
  223. Xall the commands which alter the header, a RESYNC is necessary for the filter
  224. Xpart to actually see the new header. (Does not modify existing status)
  225. X.TP
  226. XASSIGN \fIvar value\fR
  227. XAssign the value to the user-defined variable \fIvar\fR, which may further be
  228. Xaccessed as \fI%#var\fR for macro substitution or \fI#var\fR in the TR and
  229. XSUBST commands in place of the variable name. Note that there is no leading
  230. X\fI#\fR in front of the variable name. The \fIvalue\fR you provide is first
  231. Xran through \fIperl\fR to see if it contains some arithmetic operations. If the
  232. Xevaluation is successful, the resulting value is used instead. If an error
  233. Xoccurs in this evaluation process, then the litteral value provided is used.
  234. XTo avoid the evaluation, you may enclose the whole value in simple quotes. Those
  235. Xwill be trimmed before the assignment takes place. If you actually want simple
  236. Xquotes in the first AND last position, you have to double each of them.
  237. X(Does not modify existing status)
  238. X.TP
  239. XBACK \fIcommand\fR
  240. XExecute \fIcommand\fR and take its output as new actions to be performed on
  241. Xthe mail (hence performing something analogous to \fI\`command\`\fR in shell).
  242. XIf there is no output, nothing is done. BACK commands can be nested, although
  243. Xthis may lead to surprises this manpage will not disclose (but I assure you
  244. Xit will be funny, assuming we have the same sense of humour... :-). Note that
  245. Xboth the standard output and the standard error from the command are used.
  246. XIf the command fails, the output is mailed back to the user and no action is
  247. Xperformed. Furthermore, normal feedback does not occur here: any output from
  248. Xthe command is taken as filter actions, which means the semantics of PASS,
  249. Xfor instance, is changed: we do not take a body back but commands.
  250. X(The execution status is that of the \fIcommand\fR)
  251. X.TP
  252. XBEGIN \fIstate\fR
  253. XEnter a new state. An explicit REJECT or RESTART is necessary to abort the
  254. Xprocessing of the current rule. The processing begins in state INITIAL.
  255. X(Does not modify existing status)
  256. X.TP
  257. XBOUNCE \fIaddress(es)
  258. XBounce the message to the specified address(es) and acts as if a save has
  259. Xbeen done. The only difference with FORWARD is that no Resent-like lines are
  260. Xadded to the header. If an address is specified in double quotes, it is taken
  261. Xas the name of a file to be loaded to get addresses (one address per line, shell
  262. Xcomments (#) allowed). The file name resolving is the same as the one used
  263. Xfor pattern loading.
  264. X(Fails if mail cannot be resent)
  265. X.TP
  266. XDELETE
  267. XDelete the current message. Actually, this does not do anything, it just marks
  268. Xthe mail as saved. If no further action involving saving is done, then the
  269. Xmail will never show up in the mailbox.
  270. X(Never fails)
  271. X.TP
  272. XFEED \fIprogram\fR
  273. XFeed the whole message to a program and get the output back as the new
  274. Xmessage. The header structure used by the rules is not updated: an explicit
  275. XRESYNC is necessary. Hence the program appears as a filter for the whole
  276. Xmessage.
  277. X(Returns the status of \fIprogram\fR)
  278. X.TP
  279. XFORWARD \fIaddress(es)\fR
  280. XForward mail to the specified address(es). This acts as if a save had been
  281. Xdone, in order to avoid the DELETE. Usually when you forward a mail, you do not
  282. Xwish to keep it. The command adds Resent-like lines in the header. As for
  283. XBOUNCE, file inclusion is possible (i.e. use an address \fI"forward_list"\fR
  284. Xto forward a mail to all the users listed in the file \fIforward_list\fR).
  285. X(Fails if mail cannot be resent)
  286. X.TP
  287. XGIVE \fIprogram\fR
  288. XGive the body of the message to the specified program by feeding its standard
  289. Xinput. Any output is mailed to the user who runs the \fImailagent\fR.
  290. X(Returns the status of \fIprogram\fR)
  291. X.TP
  292. XKEEP \fIheader_fields_list\fR
  293. XKeeps only the corresponding lines in the header of the mail. For instance,
  294. Xa "KEEP From To Cc Subject" will keep only the principal fields from the
  295. Xmail message. This is suitable for archving mailing lists messages.
  296. XYou may add a ':' after each header field name if you wish, but that is not
  297. Xstrictly necessary.
  298. X(Does not modify existing status)
  299. X.TP
  300. XLEAVE
  301. XLeave incoming mail in the system mailbox. This is the default action if no
  302. Xrule matched or if no saving occurred.
  303. X(Fails if mail cannot be saved)
  304. X.TP
  305. XMESSAGE \fIfile\fR
  306. XSend message \fIfile\fR back to the sender of the message (as derived from the
  307. Xheader of the message). The text of the message is run through the macro
  308. Xsubstitution mechanism (described later on).
  309. X(Fails if message cannot be sent)
  310. X.TP
  311. XNOP
  312. XNo operation. If this seems a bit odd, think of it in terms of a ONCE command.
  313. X(Does not alter existing status)
  314. X.TP
  315. XNOTIFY \fIaddress\fR \fIfile\fR
  316. XSend a notification message \fIfile\fR to a given address. The text of the
  317. Xmessage is run through the macro substitution mechanism (described later on).
  318. X(Fails if message cannot be sent)
  319. X.TP
  320. XONCE \fI(name, tag, period) command\fR
  321. XExecute the specified filter command once per \fIperiod\fR. The \fIname\fR and
  322. X\fItag\fR fields are used to record timestamps of the last ONCE command.
  323. XMore on this later. (Propagates status from \fIcommand\fR. If the command is
  324. Xnot executed, always return success)
  325. X.TP
  326. XPASS \fIprogram\fR
  327. XFeed the body of the message to the specified program and get a new body
  328. Xback from the output of the program.
  329. X(Returns the status of \fIprogram\fR)
  330. X.TP
  331. XPERL \fIscript\fR [\fIarguments\fR]
  332. XEscape to a perl \fIscript\fR to perform some actions on the message. This
  333. Xis fully described further in the manpage, and is very different from a
  334. X\fIRUN perl script\fR command. (Returns failure if the script did not compile
  335. Xor returned a non-zero status).
  336. X.TP
  337. XPIPE \fIprogram\fR
  338. XPipe the whole message to the specified program, but do not get anything
  339. Xback. Any output is mailed to the user who runs the \fImailagent\fR.
  340. X(Returns the status of \fIprogram\fR)
  341. X.TP
  342. XPOST [-l] \fInewsgroup(s)\fR
  343. XPost the message to the specified newsgroup(s) after having cleaned-up the
  344. Xheader (by removing mail-related fields like Received: or To:). This acts
  345. Xas a saving. If the first name is \fB\-l\fR as in "POST -l comp.mail.mh",
  346. Xthen a "Distribution: local" header is added to force a local delivery.
  347. XOtherwise, the default \fIinews\fR distribution will be used (world,
  348. Xusually).
  349. X(Fails if message cannot be posted)
  350. X.TP
  351. XPROCESS
  352. XRun the mailagent processing which looks for @SH commands and executes
  353. Xthem. This was described before in the section dealing with default rules.
  354. XThe action associated by default to a mail having [Cc]ommand as its
  355. Xsubject is PROCESS.
  356. X(Always returns success)
  357. X.TP
  358. XPURIFY \fIprogram\fR
  359. XFeed the header into a program and get new header back. No RESYNC is done.
  360. XThis may be used to indeed purify the header by removing all the verbose
  361. Xstuff added by so many mail transport agents (X-400 like lines for instance).
  362. X(Returns the status of \fIprogram\fR)
  363. X.TP
  364. XQUEUE
  365. XQueue mail again. A successful queuing counts as if mail had been saved.
  366. XMail queued that way will not be processed during the next 30 minutes. Note
  367. Xthat unless the mailagent is invoked on a regular basis by \fIcron\fR, the
  368. Xmail will remain in the queue until another mail arrives.
  369. X(Fails when mail cannot be queued)
  370. X.TP
  371. XRECORD [-acr] [\fImode\fR]
  372. XRecord message in the history and enters mode _SEEN_ if the messsage was
  373. Xalready present there. If the message is recorded for the first time, processing
  374. Xcontinues normally. Otherwise a REJECT is performed. This behaviour may be
  375. Xsomewhat modified by using some options. See UNIQUE for a complete description
  376. Xof the options and arguments. Naturally, when a \fImode\fR is specified, that
  377. Xoverrides the default _SEEN_.
  378. X(Returns a failure status if mail was already recorded)
  379. X.TP
  380. XREJECT [-tf] [\fImode\fR]
  381. XAbort execution of current action, and continue matching. If \fB\-t\fR is
  382. Xspecified, the reject will occur only if the previous action was successfully
  383. Xcompleted (return status of true), whilst \fB\-f\fR would cause the reject only
  384. Xwhen a failure occured. If a \fImode\fR is specified, we enter that mode before
  385. Xrejection. REJECT resets the matching flag, which means that if no further
  386. Xmatch occurs, the default action will apply.
  387. X(Does not alter execution status)
  388. X.TP
  389. XRESTART [-tf] [\fImode\fR]
  390. XAbort execution of current action and restart the matching process from the
  391. Xbeginning. To avoid loops, each rule may be walked through once in a given
  392. Xmode. See REJECT for the meaning of the optional parameters. RESTART resets
  393. Xthe matching flag, which means that the default action will apply, should
  394. Xno further match occur.
  395. X(Does not alter execution status)
  396. X.TP
  397. XRESYNC
  398. XResynchronize header used for matching with the header of the mail. This is
  399. Xprobably useful only when a FEED command was run.
  400. X(Does not alter execution status)
  401. X.TP
  402. XRUN \fIprogram\fR
  403. XRun the specified program and mail any output to the user who runs the
  404. X\fImailagent\fR.
  405. X(Returns the status of \fIprogram\fR)
  406. X.TP
  407. XSAVE \fIfolder\fR
  408. XSave message in the specified folder.
  409. X(Fails if message cannot be saved)
  410. X.TP
  411. XSELECT (\fIstart .. end\fR) \fIcommand\fR
  412. XExecute the \fIcommand\fR only within the time selection period specified.
  413. XDates can be sepecified in a wide range of formats. The output of the
  414. X\fIdate\fR(1) command is an example of a valid specification. If the date,
  415. Xthe year or the month is missing, then the current one is substituted in place
  416. Xof it. The following dates are valid specifications: '10:04:25', 'now'
  417. X,'April 1 1992', 'Dec 25', 'July 14 1789, 07:40' (er... it's valid according
  418. Xto the grammar, but it's before the Epoch so it does not mean anything). Other
  419. Xfancy dates like 'last month - 5 minutes' or '3 weeks ago' are also enabled.
  420. X(Isn't that great to have a \fBreal\fR parser? The filtering rules could have
  421. Xbeen more elaborated if only I had known about this Berkley \fIyacc\fR
  422. Xproducing a \fIperl\fR parser...). (Returns the status of \fIcommand\fR, if run,
  423. Xotherwise returns true).
  424. X.TP
  425. XSPLIT [-adeiw] \fIfolder\fR
  426. XSplit a mail in digest format into the specified folder. If no folder is
  427. Xspecified, each digest item is queued and will be analyzed as a single mail
  428. Xby itself. The \fB\-d\fR option deletes the digest header. The \fB\-i\fR
  429. Xoption means split is done in-place and the original mail is discarded. All the
  430. Xoptions may be used simultaneously provided they are stuck together at the
  431. Xbeginning (option parsing being really rudimentary).
  432. XIf the mail is not in digest format and a folder is specified, then it is saved
  433. Xin that folder. Otherwise, the SPLIT action fails and nothing occurs (the
  434. Xfilter continues its processing though). The SPLIT command will correctly
  435. Xburst RFC-934 digest messages and will try to do its best otherwise. If the
  436. Xdigest was not RFC-934 compliant and there is a chance SPLIT might have
  437. Xproduced something incorrect, then the original message is also saved
  438. Xif \fB\-i\fR, otherwise it is not tagged as saved (so that the default LEAVE
  439. Xcommand may apply). The \fB\-w\fR (watch) requests special care and will detect
  440. Xevery non RFC-934 digest, even when the non-compliance is otherwise harmless;
  441. Xfurthermore, any trailing garbage longer that 100 bytes will be saved as a
  442. Xdigest item by itself.
  443. XThe \fB\-a\fR option annotates every digest item with an X-Digest-To: header
  444. Xline, which is the concatenation of the To: and Cc: fields of the original
  445. Xdigest message. This may be used for instance to burst the digest into the
  446. Xqueue and then re-process each of its items according to this added field.
  447. XFinally, the \fB\-e\fR option will discard the digest
  448. Xheader only if its body is empty (i.e. the moderator did not include any
  449. Xleading comment).
  450. X(Returns success if mail was in digest format and correctly split without any
  451. Xerror)
  452. X.TP
  453. XSTORE \fIfolder\fR
  454. XSave message in the specified folder and leave a copy in the system mailbox.
  455. X(Fails if message cannot be saved either in the \fIfolder\fR or in the mailbox)
  456. X.TP
  457. XSTRIP \fIheader_fields_list\fR
  458. XRemove the corresponding lines in the header of the mail. For instance,
  459. Xa "STRIP Newsgroups Apparently-To" will remove the appropriate lines to wipe
  460. Xout any Newsgroups: or Apparently-To: header. You may add a ':' after each
  461. Xheader field name if you wish, but that is not strictly necessary.
  462. X(Does not alter execution status)
  463. X.TP
  464. XSUBST \fIvar expression\fR
  465. XSubstitutes the expression on the specified user-defined variable (name
  466. Xstarting with a #) or backreference (digit). For instance, 'SUBST #foo /w/y/g'
  467. Xwould substitute in user-defined variable \fIfoo\fR all the \fIw\fR by \fIy\fR.
  468. XSee also ASSIGN and TR.
  469. X(Fails if error in \fIexpresssion\fR)
  470. X.TP
  471. XTR \fIvar translation\fR
  472. XPerform the translation on the specified variable or backreference. For
  473. Xinstance, 'TR 1 /A-Z/a-z/' would cannonicalize content of reference 1 into
  474. Xlowercase. See also ASSIGN and SUBST.
  475. X(Fails if error in \fItranslation\fR)
  476. X.TP
  477. XUNIQUE [-acr] [\fImode\fR]
  478. XRecord message in the history and tag message as saved if it was
  479. Xalready present there. If the message is recorded for the first time, processing
  480. Xcontinues normally. Otherwise a REJECT is performed. If \fB\-r\fR was used,
  481. Xa RESTART is used instead whilst \fB\-a\fR would run an ABORT.
  482. XFor instance, to remove duplicate messages from mailing lists, run a
  483. XUNIQUE -a before saving the mail. The \fB\-c\fR option may be used alone to
  484. Xactually prevent the command from disturbing the execution flow, and to later
  485. Xuse the return status to see what happened:
  486. XUNIQUE returns a failure status if the message was already recorded.
  487. XIf an optional \fImode\fR argument is given, then the automaton will enter that
  488. Xmode if the mail was previously in the database.
  489. XSee also RECORD. (Fails if mail was already recorded)
  490. X.TP
  491. XVACATION \fIon/off\fR
  492. XAllow or disallow a vacation message. When vacation mode is turned on via the
  493. Xconfiguration file, a message is sent whenever the user receives a mail
  494. Xmeeting some requirements, as explained under the section \fBVACATION MODE\fR.
  495. XOne of the conditions is that the vacation flag modified by this command be
  496. Xtrue. This makes it easy to disallow vacation messages, ever, to a group
  497. Xof people for instance.
  498. X(Does not alter execution status)
  499. X.TP
  500. XWRITE \fIfolder\fR
  501. XWrite the message in the specified folder, removing any pre-existing folder
  502. Xwith the same name. Hence, successive WRITE commands will overwrite the
  503. Xprevious one. This is useful to store output of system commands ran by
  504. X\fIcron\fR.
  505. X(Fails if message cannot be written)
  506. X'''
  507. X.SS "Execution Status"
  508. X.PP
  509. XAlmost all the actions modify a variable which keeps track of the execution
  510. Xstatus (analogous to the \$? variable in the shell).
  511. XThis variable can be tested via the \fB\-t\fR or \fB\-f\fR option of
  512. Xthe REJECT command for instance. To give but a single example, the SAVE
  513. Xaction would return \fIfailed\fR if it could not save the mail in the specified
  514. Xfolder. If that SAVE command was followed by a "REJECT -f FAILED", then the
  515. Xexecution of the current rule would stop and the automaton would continue to
  516. Xanalyze the mail in the FAILED mode.
  517. X.PP
  518. XSome of the actions however do not modify this last execution status. Typically,
  519. Xthose are actions which make decisions based on that status, or simply actions
  520. Xwhich may never fail. Those special actions are: ABORT, ASSIGN, BEGIN, KEEP,
  521. XNOP, REJECT, RESTART, RESYNC, STRIP and VACATION.
  522. X.PP
  523. XIt is unfortunate that ONCE or SELECT commands cannot make the difference
  524. Xbetween a non-execution and a successful execution of the specified command.
  525. XThere may be a change in the way this scheme works, but it should remain
  526. Xbackward compatible.
  527. X'''
  528. X.SS "Perl Escape"
  529. X.PP
  530. XBy using the PERL command, you have the ability to perform filtering and other
  531. Xsophisticated actions directly in \fIperl\fR. This is really different from
  532. Xwhat you could do by feeding your mail to a perl script. First of all, no
  533. Xextra process is created: the script is loaded directly in the mailagent and
  534. Xcompiled in a special package called \fImailhook\fR. Secondly, you have a
  535. Xperl interface to all the filtering commands: each filtering action is
  536. Xassociated to a perl function (spelled lower-cased). Finally, some pre-defined
  537. Xvariables are set for you by the mailagent.
  538. X.PP
  539. XBefore we go any further, please note that as there is no extra process created,
  540. Xyou \fBmust not\fR call the perl \fIexit\fR function. Use \fI&exit\fR instead,
  541. Xso that the exit may be trapped. \fI&exit\fR takes one argument, the exit code.
  542. XIf you use 0, this is understood as a success, any other value meaning failure
  543. X(i.e. the PERL command will return a failure status). Using the perl \fIexit\fR
  544. Xfunction directly would kill \fImailagent\fR and would probably incur some
  545. Xmail looses.
  546. X.PP
  547. XThe scripts used should remain simple. In particular, you should avoid the use
  548. Xof the \fIpackage\fR directive or define functions with a package name other
  549. Xthan \fImailhook\fR (i.e. the package where your script is loaded). Failure
  550. Xto do so may raise some name clashes with \fImailagent\fR's own routines.
  551. XIn particular, avoid the \fImain\fR package. Note that since the compilation
  552. Xenvironment is set-up to \fImailhook\fR, not specifying package names in your
  553. Xvariables and subroutine is fine (in fact, it's meant to work that way).
  554. X.PP
  555. XYour script is free to do whatever it wants to the mail. Most of the time
  556. Xhowever, you end up using the \fImailagent\fR primitives to save the mail
  557. Xor forward it (but you are free to redesign your own and call them instead,
  558. Xof course). The interface is simple: each function takes but one argument,
  559. Xa string, which is the arguments to the command, if any. For instance, in
  560. Xa perl escape script, you would express:
  561. X.sp
  562. X.in +5
  563. X.nf
  564. X{ SAVE list; FORWARD "users"; FEED ~/bin/newmail -tty; REJECT }
  565. X.sp
  566. X.in -5
  567. X.fi
  568. Xwith:
  569. X.sp
  570. X.in +5
  571. X.nf
  572. X&save('list');
  573. X&forward('"users"');
  574. X&feed('~/bin/newmail -tty');
  575. X&reject;
  576. X.sp
  577. X.in -5
  578. X.fi
  579. XThe rule is simple: each command is replaced by a function call, with the
  580. Xremaining parameters enclosed in a string, if any. Alternatively, you may
  581. Xsepecify parameters as a list: all the arguments you provide are joined
  582. Xinto a big happy string, using a space character as separator. The macro
  583. Xsubsititution mechanism is then ran on this resulting argument string.
  584. X.PP
  585. XEach function returns a boolean
  586. Xsuccess status of the command (i.e. 1 means success). For those functions which
  587. Xusually do not modify the filter's last execution status variable, a success is
  588. Xalways returned. This makes it possible to (intuitively) write:
  589. X.sp
  590. X.in +5
  591. X.nf
  592. X&exit(0) if &save('uucp');
  593. X&bounce('root') || &save('emergency');
  594. X.sp
  595. X.in -5
  596. X.fi
  597. Xand get the expected result. The mail will be saved in the emergency folder
  598. Xonly when saving in uucp folder failed and the mail could not be bounced to
  599. Xroot.
  600. X.PP
  601. XIt is important to understand that these commands have \fIexactly\fR the
  602. Xsame effect on the filtering process when they are run from a perl escape
  603. Xscript or from within the rule file as regular actions.
  604. XA \fI&reject\fR call will simply abandon the execution of the current perl
  605. Xscript and the filter automaton will regain control and attempt a new match.
  606. XBut \fIperl\fR brings you much more power, in particular system calls,
  607. Xcontrol structures like \fBif\fR and \fBfor\fR, raw regular expressions, etc...
  608. X.PP
  609. XThe special \fIperl\fR @INC array (which controls the search path for
  610. X\fIrequire\fR) is slightly modified by prepending the mailagent's own private
  611. Xlibrary path. This leaves the door open for future mailagent library perl
  612. Xscripts which may be required by the perl script. Furthermore,
  613. Xthe following special variables are set-up by perl before invoking your
  614. Xscript:
  615. X.sp
  616. X.PD 0
  617. X.TP 15
  618. X.I @ARGV
  619. XThe arguments of the script, which were given by the PERL command. This array
  620. Xis set up the exact same way you would expect it to be set up if you invoked
  621. Xthe command directly from the shell.
  622. X.TP
  623. X.I \$address
  624. XThe address part of the From: line.
  625. X.TP
  626. X.I \$cc
  627. XThe raw content of the Cc: line.
  628. X.TP
  629. X.I @cc
  630. XThe list of addresses on the Cc: line, with comments suppressed.
  631. X.TP
  632. X.I \$friendly
  633. XThe comment part of the From: line, if any.
  634. X.TP
  635. X.I \$from
  636. XThe content of the From: line, with address and comment part.
  637. X.TP
  638. X.I %header
  639. XThis table, indexed by field name, returns the raw content on the
  640. Xcorresponding header line. See below.
  641. X.TP
  642. X.I \$login
  643. XThe login name of the address on the From: line.
  644. X.TP
  645. X.I \$precedence
  646. XThe content of the Precendence: line, if any at all.
  647. X.TP
  648. X.I \$sender
  649. XThe sender of the message (may have a comment), derived in the same way the
  650. XSender: line is computed by the mailagent.
  651. X.TP
  652. X.I \$subject
  653. XThe subject of the message.
  654. X.TP
  655. X.I \$to
  656. XThe raw content of the To: line.
  657. X.TP
  658. X.I @to
  659. XThe list of addresses on the To: line, with comments suppressed.
  660. X.PD
  661. X.PP
  662. XThe associative array \fI%header\fR gives you access to all the fields in
  663. Xthe header of the message. For instance, \fI\$to\fR is really the value of
  664. X\fI\$header{'To'}\fR. The key is specified using a normalized case, i.e.
  665. Xthe first letter of each word is uppercased, the remaining being lowercased.
  666. XThis is independant of the actual physical representation in the message
  667. Xitself.
  668. X.PP
  669. XThe pseudo keys \fIHead\fR, \fIBody\fR and \fIAll\fR respectively gives you
  670. Xaccess to the raw header of the message, the body and the whole message.
  671. XThe \fI%header\fR array is really a reference to the \fImailagent\fR's internal
  672. Xdata structure, so modifying the values will influence the filtering process.
  673. XFor instance, the SAVE command writes the \fIHead\fR, the \fIX-Filter:\fR line,
  674. Xthe end of header (a single newline) and then the \fIBody\fR (this is an
  675. Xexample only, not a documented feature :-).
  676. X.PP
  677. XAs a final note, resist the temptation of reading the internals of the
  678. Xmailagent and directly calling the routines you need. If it is not documented
  679. Xin the manual page, it may be changed without notice by any further patch.
  680. X(And this does not say that documented features may not change also... It's
  681. Xjust more unlikely, and patches would clearly state that, of course.)
  682. X'''
  683. X.SS "Program Environment"
  684. X.PP
  685. XAll the programs started by the mailagent via RUN and friends inherit the
  686. Xfollowing environment variables: HOME, USER and NAME, respectively set from
  687. Xthe configuration parameters \fIhome\fR, \fIuser\fR and \fIname\fR. If the
  688. Xmailagent is invoked by the \fIfilter\fR, then the PATH is also set according
  689. Xto the configuration file (if you are using the C filter) or to whatever you
  690. Xset PATH (if you are using the shell filter).
  691. X.PP
  692. XAll the programs are executed from within the \fIhome\fR directory. This
  693. Xincludes scripts started via the PERL command and mail hooks. The latter will
  694. Xbe described in detail further down.
  695. X'''
  696. X.SS "Macros Substitutions"
  697. X.PP
  698. XAll the commands go through a macro substitution mechanism before being
  699. Xexecuted. The following macros are available:
  700. X.sp
  701. X.PD 0
  702. X.TP 10
  703. X%%
  704. XA real percent sign
  705. X.TP
  706. X%D
  707. XDay of the week (0-6)
  708. X.TP
  709. X%H
  710. XHost name (name of the machine on which the \fImailagent\fR runs)
  711. X.TP
  712. X%L
  713. XLength of the body part, in bytes
  714. X.TP
  715. X%N
  716. XFull name of the sender (login name if none)
  717. X.TP
  718. X%R
  719. XSubject of the original message with leading Re: suppressed
  720. X.TP
  721. X%S
  722. XRe: subject of original message
  723. X.TP
  724. X%T
  725. XTime of the last modification on mailed file (commands MESSAGE and NOTIFY)
  726. X.TP
  727. X%U
  728. XFull name of the user
  729. X.TP
  730. X%_
  731. XA white space (useful to put white spaces in single patterns)
  732. X.TP
  733. X%&
  734. XList of selectors which incurred match (among those specified via a regular
  735. Xexpression such as 'X-*: /foo/i'. If we find the \fIfoo\fR substring in the
  736. XX-Mailer: header line, then %& will be set to this value). Values in the list
  737. Xare comma separated.
  738. X.TP
  739. X%~
  740. XA null character, wiped out from the resulting string.
  741. X.TP
  742. X%\fIdigit\fR
  743. XValue of the corresponding back reference from the last match.
  744. X.TP
  745. X%#\fIvar\fR
  746. XValue of user-defined variable \fIvar\fR
  747. X.TP
  748. X%d
  749. XDay of the month (01-31)
  750. X.TP
  751. X%f
  752. XContents of the "From:" line, something like %N <%r> or %r (%N) depending
  753. Xon how the mailer is configured.
  754. X.TP
  755. X%h
  756. XHour of the day (00-23)
  757. X.TP
  758. X%i
  759. XMessage ID, if available (otherwise, this is a null string)
  760. X.TP
  761. X%l
  762. XNumber of lines in the message
  763. X.TP
  764. X%m
  765. XMonth of the year (01-12)
  766. X.TP
  767. X%n
  768. XLower-case login name of sender
  769. X.TP
  770. X%o
  771. XOrganization (where \fImailagent\fR runs)
  772. X.TP
  773. X%r
  774. XReturn address of message
  775. X.TP
  776. X%s
  777. XSubject of original message
  778. X.TP
  779. X%t
  780. XCurrent hour and minute (in HH:MM format)
  781. X.TP
  782. X%u
  783. XLogin name of the user
  784. X.TP
  785. X%y
  786. XYear (last two digits)
  787. X.TP
  788. X%[To]
  789. XValue of the header field (here To:)
  790. X.PD
  791. X'''
  792. X.SS "Using Once Commands"
  793. X.PP
  794. XThe ONCE constructs lets you specify a given command to be run once every
  795. Xperiod (day, week...). The command is identified by a \fIname\fR and a
  796. X\fItag\fR, the combination of the two being unique. Why not just a single
  797. Xidentifier? Well, that would be fine, but assume you want to send a message
  798. Xin reply to someone once every week. You could use the e-mail address of the
  799. Xperson as the command identifier. But what if you also want to send another
  800. Xmessage to the same address, this time once a month?
  801. X.PP
  802. XHere is a prototypical usage of a ONCE, which acts like the vacation program,
  803. Xexcepted that it sends a reply only once a day for a given address:
  804. X.sp
  805. X.in +5
  806. X{ ONCE (%r, message, 1d) MESSAGE ~/.message };
  807. X.in -5
  808. X.sp
  809. XThis relies on the macro substitution mechanism to send only once a day the
  810. Xmessage held in \fI~/.message\fR. Do not use the tag \fIvacation\fR, unless
  811. Xyou know what you are doing: this is the tag used internally by the mailagent
  812. Xin vacation mode. Recall that no selector nor pattern is understood as
  813. X"Subject: *", hence the rule is always executed because that pattern always
  814. Xmatches.
  815. X.PP
  816. XThe timestamps associated with each commands are kept in files under the Hash
  817. Xdirectory. The name is used as a hashing key to compute the name of the file
  818. X(the two first letters are used). Inside the file, timestamps are sorted by
  819. Xname, then by tag. Of course, you could say (inverting tag and name):
  820. X.sp
  821. X.in +5
  822. X{ ONCE (message, %r, 1d) MESSAGE ~/.message };
  823. X.in -5
  824. X.sp
  825. Xbut that would be likely to be less efficient, as the first hashing would be
  826. Xdone on a fixed word, hence all the timestamps would be located in the file
  827. X\fIHash/m/e\fR (where \fIHash\fR is the name of your hashing directory, which
  828. Xis the \fIhash\fR parameter in the configuration file).
  829. X'''
  830. X.SS "Specifying A Period"
  831. X.PP
  832. XThe period parameter of the ONCE commands or the \fIvacperiod\fR parameter
  833. Xof your configuration file has the following format: a number followed by a
  834. Xmodifier. The modifier is an atomic period like a day or a week, the number
  835. Xis the number of atomic periods the final period should be equal to. The
  836. Xavailable modifiers are:
  837. X.sp
  838. X.PD 0
  839. X.TP 10
  840. Xm
  841. Xminute
  842. X.TP
  843. Xh
  844. Xhour (60 minutes)
  845. X.TP
  846. Xd
  847. Xday (24 hours)
  848. X.TP
  849. Xw
  850. Xweek (7 days)
  851. X.TP
  852. XM
  853. Xmonth (30 days)
  854. X.TP
  855. Xy
  856. Xyear (365 days)
  857. X.PD
  858. X.PP
  859. XAll the periods are converted internally in seconds, although you do not
  860. Xreally care... Examples of valid periods range from "1m" to "136y" on a 32 bits
  861. Xmachine (why ?).
  862. X'''
  863. X.SS "Timeouts"
  864. X.PP
  865. XIn order to avoid having a \fImailagent\fR waiting for a command forever, a
  866. Xmaximum execution time of one hour is allowed. Past that amount of time, the
  867. Xchild is sent a SIGTERM signal. If it does not die within the next 30 seconds,
  868. Xa SIGKILL is sent. Output from the program, if any so far, is mailed back to
  869. Xthe user.
  870. X'''
  871. X.SS "Avoiding Loops"
  872. X.PP
  873. XThe \fImailagent\fR leaves an "X-Filter:" header on each filtered message,
  874. Xwhich in turn is used to detect loops. If a message already filtered is
  875. Xto be processed, the \fImailagent\fR enters a special state _SEEN_. This
  876. Xstate is special in the sense it is built-in, it is not matched by ALL, and
  877. Xsome actions are not made available, namely: BACK, BOUNCE, FEED, FORWARD, GIVE,
  878. XNOTIFY, PASS, PIPE, POST, PURIFY, QUEUE and RUN. Also note that although the
  879. XONCE and SELECT constructs are enabled, they will not let you execute
  880. Xdisallowed commands.
  881. X.PP
  882. XThe _SEEN_ mode makes it easy to deal with mails which loop because of an
  883. Xalias loop you have no control on. If no action is found in the _SEEN_ mode,
  884. Xthe mail is left in the mailbox, as usual. Moreover, if no saving is done,
  885. Xa LEAVE is executed. This is the normal behavior.
  886. X'''
  887. X.SS "Message Files"
  888. X.PP
  889. XThe text of the message to be sent back (for MESSAGE or NOTIFY) is read from
  890. Xa file and passed through the macro substitution mechanism. The special macro
  891. X\fI%T\fR is set to the date of last modification made on that file. The format
  892. Xis \fImonth/day\fR, and the year is added before the month only if it differs
  893. Xfrom the current year.
  894. X.PP
  895. XAt the head of the message, you may put header lines. Those lines will
  896. Xoverwrite the default supplied lines. That may be useful to change the default
  897. Xsubject or add some additional fields like the name of your organization.
  898. XThe end of your header is given by the first blank line encountered.
  899. XIf the top of the message you wish to send looks like a mail header, you may
  900. Xprotect it by adding a blank line at the very top of the file. This dummy line
  901. Xwill be removed from the message and the whole file will be sent as a body
  902. Xpart.
  903. X.PP
  904. XHere is an example of a vacation file. We add a carbon copy as well as the
  905. Xname of our organization in the header:
  906. X.sp
  907. X.in +5
  908. X.nf
  909. XOrganization: %o
  910. XCc: ram
  911. X
  912. X[Last revision made on %T]
  913. X
  914. XDear %N:
  915. X
  916. XI've received your mail regarding "%R".
  917. XIt will be read as soon as I come back from vacation.
  918. X
  919. XSincerely,
  920. X--
  921. X%U <%u@%H>
  922. X.fi
  923. X.in -5
  924. X.sp
  925. X.SH "VACATION MODE"
  926. X.PP
  927. XWhen it's time to take some vacation, it is possible to set up the mailagent
  928. Xin vacation mode. Every \fIvacperiod\fR, the message \fIvacfile\fR will be
  929. Xsent back to the user (with macros substitutions) if the user is explicitely
  930. Xlisted in the \fITo\fR or \fICc\fR field and if the sender is not a special
  931. Xuser (\fIroot\fR, \fIuucp\fR, \fInews\fR, \fIdaemon\fR, \fIpostmaster\fR,
  932. X\fInewsmaster\fR, \fIusenet\fR, \fIMAILER-DAEMON\fR or \fInobody\fR).
  933. XMatches are done in a case insentive manner, so \fIMailer-Daemon\fR will also
  934. Xbe recognized as a special user.
  935. XFurthermore, any message tagged with a \fIPrecendence:\fR field set to
  936. X\fIbulk\fR or \fIjunk\fR will not trigger a vacation message. This built-in
  937. Xbehaviour can of course be overloaded by suitable rules (by testing and
  938. Xissuing the vacation message yourself via MESSAGE).
  939. X.PP
  940. XInternally, the mailagent uses a ONCE
  941. Xcommand tagged \fI(%r, vacation, \$vacperiod)\fR. This implies you must not
  942. Xuse the \fIvacation\fR tag in your own ONCE commands, unless you know what
  943. Xyou are doing.
  944. X.PP
  945. XBesides, the vacation message is sent only if no "VACATION off" commands were
  946. Xissued, or if another "VACATION on" overwrote the previous one. Note that
  947. Xwhether a rule matched or not is irrelevant to the algorithm. By default, of
  948. Xcourse, the vacation message is allowed when the \fIvacation\fR configuration
  949. Xparameter is set to \fIon\fR.
  950. X.PP
  951. XIf you are not pleased by the fact that a vacation message is sent to people
  952. Xwho addressed you a carbon copy only, then you may write at the top of your
  953. Xrule file:
  954. X.sp
  955. X.in +5
  956. X.nf
  957. XCc: ram  { VACATION off; REJECT };
  958. X.fi
  959. X.in -5
  960. X.sp
  961. XOf course, you have to susbstitute your own login name in place of \fIram\fR.
  962. XYou cannot use the same scheme to allow vacation messages to special
  963. Xusers like \fIroot\fR, because the test for "specialness" occurs after the
  964. Xvacation mode flag. This is construed as a feature as it prevents stupid
  965. Xmistakes, like using \fIr*\fR instead of \fIram\fR in the previous rule.
  966. X.SH VARIABLES
  967. XThe following variables are paid attention to: they may come from the
  968. Xenvironment or be set in the rule file:
  969. X.TP 10
  970. X.I mailfilter
  971. Xindicates where loaded patterns are to be looked for, if the name of the
  972. Xfile is not fully qualified. If it is not set, \fImaildir\fR will be used
  973. Xinstead. If \fImaildir\fR is not set either, the home directory is used.
  974. X.TP
  975. X.I maildir
  976. Xis the location of your mail folders. Any relative path is understood as
  977. Xstarting from \fImaildir\fR. If it is not set, \fI~/Mail\fR is used.
  978. X.SH "AUTOMATIC ACKNOWLEDGMENTS"
  979. XAnywhere in the mail, there can be an @RR left-justified line which will
  980. Xsend back an acknowledgment to the sender of the mail. The @RR may optionally
  981. Xbe followed by an address, in which case the acknowledgment will be sent
  982. Xto that address instead.
  983. XIn fact (but let's keep that a secret), this is a way for me to be able to
  984. Xsee who runs my mailagent program and who doesn't...
  985. X.PP
  986. XThe \fIsendmail\fR program usually implements such a feature via a
  987. XReturn-Receipt-To: header line, which sends the whole header back upon
  988. Xsuccessful delivery. However, this is not implemented on all mail transport
  989. Xagents, and @RR is a good alternative :-).
  990. X.SH "NOTA BENE"
  991. XThroughout this manual page, I have always written header fields with the first
  992. Xletter of each word uppercased, as in \fIReturn-Receipt-To\fR. But RFC-822 does
  993. Xnot impose this spelling convention, and a mailer could legally rewrite the
  994. Xprevious field as \fIreturn-receipt-to\fR (and in fact so does \fIsendmail\fR
  995. Xin its own private mail queue files).
  996. X.PP
  997. XHowever, you must always specify the headers in what could be called a
  998. X\fInormalized\fR case (for headers anyway). The mailagent will correctly
  999. Xrecognize \fIcc:\fR, \fICC:\fR or \fICc:\fR in a mail message and will allow
  1000. Xyou to select those fields via the normalized \fICc:\fR selector. In fact, it
  1001. Xoperates the normalization for you, and a \fIcc:\fR selector would not be
  1002. Xrecognized as such. Of course, no physical alteration is ever made on the
  1003. Xheader itself.
  1004. X.PP
  1005. XThis is also true for headers specified in the STRIP or KEEP command. If you
  1006. Xwrite \fISTRIP Cc\fR, it will correctly remove any \fIcc:\fR line. Likewise,
  1007. Xif you use regular expressions to specify a selector, \fIRe.*:\fR would match
  1008. Xboth original \fIreceived:\fR and \fIReturn-path:\fR fields, internally known
  1009. Xthrough their normalized representation.
  1010. X.SH "MAIL HOOKS"
  1011. XThe mail hooks allow the mailagent to transparently invoke some scripts or
  1012. Xperform further processing on the message. Those hooks are activated via
  1013. Xthe SAVE, STORE or LEAVE commands. Namely, saving in a folder whose executable
  1014. Xbit is set will raise a special processing. By default, the folder is taken
  1015. Xas a program where the mail should be piped to. If the "folder" program
  1016. Xreturns a zero status, then the message is considered \fIsaved\fR by the
  1017. Xmailagent. Otherwise, all the processing attached to failed save commands is
  1018. Xstarted (including emergency saving attempts). Executable folders provide a
  1019. Xtransparent way (from the rule file point of view) to deal with special
  1020. Xkind of messages.
  1021. X.PP
  1022. XIn fact, five different types of hooks are available. The first one is the
  1023. Xplain executable folder we have just spoken about. But in fact, here is what
  1024. Xreally happens when a saving command detects an executable folder: the
  1025. Xmailagent starts a program called \fImailhook\fR which will be responsible of
  1026. Xthe delivery to the hook folder. This program looks at the first line of the
  1027. Xfolder (in fact, the first 128 bytes) and looks for something starting with
  1028. X#: and followed by a single word, describing a special kind of hook. This is
  1029. Xsimilar in the way the kernel deals with the #! hook in executable programs.
  1030. XIf no #: is found or #: is followed by some garbage, then \fImailhook\fR decides
  1031. Xit is a simple program and feeds the mail message to this program. End of the
  1032. Xstory.
  1033. X.PP
  1034. XBut if the #: token is followed (spaces allowed, case is irrelevant) by one of
  1035. Xthe following words, then special actions are taken:
  1036. X.PD
  1037. X.TP 10
  1038. X.I rules
  1039. XThe file holds a set of mailagent rules which are to be applied. A new mailagent
  1040. Xprocess is created to actually deal with those and the exit status is
  1041. Xpropagated back to the original mailagent through mailhook.
  1042. X.TP
  1043. X.I audit
  1044. XThis is similar in spirit to what Martin Streicher's audit.pl package does,
  1045. Xhence the name of this hook. The special variables which are set up by the
  1046. XPERL filter commands are initialized and the script is called. You do not
  1047. Xhave an interface to the mailagent filtering commands though, but the work is
  1048. Xdone directly by \fImailhook\fR. As with PERL commands, the script is loaded
  1049. Xin the special \fImailhook\fR package name space.
  1050. X.TP
  1051. X.I deliver
  1052. XSame thing as for the \fIaudit\fR hook, but the standard output of your script
  1053. Xis monitored by \fImailhook\fR and understood as mailagent filtering commands.
  1054. XUpon successful return, a mailagent process will be invoked to actually execute
  1055. Xthose commands on the message. Again, this is similar in spirit to Chip
  1056. XSalzenberg's \fIdeliver\fR package and gave the name of this hook.
  1057. X.TP
  1058. X.I perl
  1059. XThis hook is the same as \fIaudit\fR but it is executed by a mailagent, so
  1060. Xyou have the perl interface to the mailagent's filtering commands. There is
  1061. Xno difference with the PERL command, because it is implemented that way, by
  1062. Xcalling a mailagent and forcing the PERL command to be executed. This is
  1063. Xsimilar in spirit to Larry Wall's famous \fIperl\fR language and it is
  1064. Xresponsible for the name of this hook :-).
  1065. X.PP
  1066. XAs mentionned earlier in this manual page, the hook is invoked from with the
  1067. X\fIhome\fR directory specified in your ~/.mailagent (which may differ from
  1068. Xyour real home directory, as far as \fImailagent\fR or \fImailhook\fR are
  1069. Xconcerned).
  1070. X.PP
  1071. XFor those hooks which are finally ran by perl, the special @INC array has
  1072. Xthe mailagent's own private library path prepended to it, so that \fIrequire\fR
  1073. Xfirst looks in this place.
  1074. X.SH EXAMPLES
  1075. XHere are some examples of rule files. First, if you do not specify a rule
  1076. Xfile or if it is empty, the following built-in rule applies:
  1077. X.sp
  1078. X.in +5
  1079. X.nf
  1080. XAll: /^Subject: [Cc]ommand/ { LEAVE; PROCESS };
  1081. X.fi
  1082. X.in -5
  1083. X.sp
  1084. XEvery mail is left in the mailbox. Besides, mail with "Subject: Command"
  1085. Xanywhere in the message are processed.
  1086. X.PP
  1087. XThe following rule file is the one I am currently using:
  1088. X.sp
  1089. X.in +5
  1090. X.nf
  1091. Xmaildir = ~/mail;
  1092. X
  1093. XAll: /^Subject: [Cc]ommand/    { SAVE cmds; PROCESS };
  1094. X
  1095. XTo: gue@eiffel.fr        { POST -l mail.gue };
  1096. XApparently-To: ram,
  1097. XNewsgroups: mail.gue        { BOUNCE gue@eiffel.fr };
  1098. X
  1099. X<_SEEN_>
  1100. X    Apparently-To: ram,
  1101. X    Newsgroups: mail.gue    { DELETE };
  1102. X
  1103. XFrom: root, To: root        { BEGIN ROOT; REJECT };
  1104. X<ROOT> /^Daily run output/    { WRITE ~/var/log/york/daily.%D };
  1105. X<ROOT> /^Weekly run output/    { WRITE ~/var/log/york/weekly };
  1106. X<ROOT> /^Monthly run output/    { WRITE ~/var/log/york/monthly };
  1107. X
  1108. XFrom: ram        { BEGIN RAM; REJECT };
  1109. X<RAM> To: ram        { LEAVE };
  1110. X<RAM> X-Mailer: /mailagent/    { LEAVE };
  1111. X<RAM>            { DELETE };
  1112. X.fi
  1113. X.in -5
  1114. X.PP
  1115. XThe folder directory is set to \fI~/mail\fR. All command mails are saved
  1116. Xin the folder \fI~/mail/cmds\fR and processed. They do not show up in
  1117. Xmy mailbox. Mails directed to the \fIgue\fR mailing list (French Eiffel's
  1118. XUsers Group, namely Groupe des Utilisateurs Eiffel) are posted on the local
  1119. Xnewsgroup \fImail.gue\fR and do not appear in my mailbox either. Any follow-up
  1120. Xmade on this group is mailed to me by \fIinews\fR (and not directly to the
  1121. Xmailing list, because those mails would get back to me again and be fed to the
  1122. Xnewsgroup, which in turn would have them mailed back to the list, and so on,
  1123. Xand so forth).
  1124. XHence the next rule which catches those follow-ups and bounces them to the
  1125. Xmailing list. Those mails will indeed come back, but the _SEEN_ rule will
  1126. Xsimply delete them.
  1127. X.PP
  1128. XOn my machine, the mails for \fIroot\fR are forwarded to me. However,
  1129. Xeveryday, the \fIcron\fR daemon starts some processes to do some
  1130. Xadministration clean-up (rotating log files, etc...), and mails the results
  1131. Xback. They are redirected into specific folders with the WRITE command, to
  1132. Xensure they do not grow up without limit. Note the macro substitution for the
  1133. Xdaily output (on Mondays, the output is stored in \fIdaily.1\fR for instance).
  1134. X.PP
  1135. XThe next group of rules prevents the mail system from sending back mails when
  1136. XI am in a group alias expansion. This is a \fIsendmail\fR option which I
  1137. Xdisabled on my machine. Care is taken however to keep mails coming from the
  1138. Xmailagent which I receive as a blind carbon copy.
  1139. X.SH CAVEAT
  1140. XIn order to limit the load overhead on the system, only \fBone\fR mailagent
  1141. Xprocess is allowed to run the commands. If some new mail arrives while another
  1142. Xmailagent is running, that mail is queued and will be processed later by the
  1143. X\fImain\fR mailagent.
  1144. X.PP
  1145. XFor the same reason, the mails sent back by the mailagent are queued by
  1146. X\fIsendmail\fR, to avoid the cost of mail transfer while processing commands.
  1147. X.SH "SECURITY"
  1148. XTo avoid any problems, the \fIfilter\fR will refuse to run if the configuration
  1149. Xfile \fI~/.mailagent\fR or the rule file specified are world writable or not
  1150. Xowned by the user. Those tests are enforced even if the the \fIfilter\fR does
  1151. Xnot run setuid, because they compromise the security of your account.
  1152. XThe \fImailagent\fR will also perform those checks.
  1153. X.PP
  1154. XIndeed, if someone can write into your \fI~/.mailagent\fR file, then he can
  1155. Xeasily change your \fIrules\fR configuration parameter to point to another
  1156. Xfaked rule file and then send you a mail, which will trigger the mailagent,
  1157. Xrunning as you. Via the RUN command, this potential intruder could run any
  1158. Xcommand, using your privileges, and could set a trojan horse for later
  1159. Xperusal. Applying the same logic, the rule file must also be protected tightly.
  1160. X.SH FILES
  1161. X.PD 0
  1162. X.TP 20
  1163. X~/.mailagent
  1164. Xconfiguration file for mailagent.
  1165. X.TP
  1166. X~/mbox.filter
  1167. Xmailbox used by \fIfilter\fR in case of error
  1168. X.TP
  1169. X~/mbox.urgent
  1170. Xmailbox used by \fImailagent\fR in case of error
  1171. X.TP
  1172. X~/mbox.<username>
  1173. Xmailbox used if writing access is denied in the mail spool directory
  1174. X.TP
  1175. X$privlib/mailagent
  1176. Xdirectory holding templates and samples.
  1177. X.TP
  1178. XLog/agentlog
  1179. Xmailagent's log file.
  1180. X.TP
  1181. XQueue/agent.wait
  1182. Xlist of mails waiting to be processed and stored outside of the mailagent's
  1183. Xspool directory.
  1184. X.TP
  1185. XQueue/qmXXXXX
  1186. Xmail spooled by \fIfilter\fR.
  1187. X.TP
  1188. XQueue/fmXXXXX
  1189. Xmail spooled by the \fImailagent\fR.
  1190. X.TP
  1191. XHash/X/Y
  1192. Xhash files used by RECORD, UNIQUE, ONCE commands and vacation mode.
  1193. X.PD
  1194. X.SH BUGS
  1195. XThere is a small chance that mail arrives while the \fImain\fR mailagent
  1196. Xis about to finish its processing. That mail will be queued and not
  1197. Xprocessed until another mail arrives (the \fImain\fR mailagent always
  1198. Xprocesses the queue after having dealt with the message that invoked it).
  1199. X.PP
  1200. XA version number must currently contain a dot. Moreover, an old system
  1201. X(i.e. a system with an \fIo\fR in the patches column) must have a version
  1202. Xnumber, so that the mailagent can compute the name of the directory which
  1203. Xholds the patches.
  1204. X.PP
  1205. XThe lock file is deliberately ignored when \fB\-q\fR option is used (in fact,
  1206. Xit is ignored whenever an option is specified).
  1207. XThis may result in having mails processed more than once.
  1208. X.PP
  1209. XThe mailagent is at the mercy of any \fIperl\fR bug, and there is little I
  1210. Xcan do about it. Some spurious warnings may be emitted by the dataloaded
  1211. Xversion, although they do not appear with the plain version.
  1212. X.PP
  1213. XParsing of the rule file should be done by a real parser and not lexically.
  1214. XOr at least, it should be possible to escape otherwise meaningful characters
  1215. Xlike ';' or '}' within the rules.
  1216. X.SH AUTHOR
  1217. XRaphael Manfredi <ram@eiffel.com>.
  1218. X.SH "SEE ALSO"
  1219. Xmaildist($manext), mailhelp($manext), maillist($manext), mailpatch($manext),
  1220. Xperl(1).
  1221. X!GROK!THIS!
  1222. Xchmod 444 mailagent.$manext
  1223. END_OF_FILE
  1224.  if test 50897 -ne `wc -c <'agent/man/mailagent.SH.b'`; then
  1225.     echo shar: \"'agent/man/mailagent.SH.b'\" unpacked with wrong size!
  1226.  elif test -f 'agent/man/mailagent.SH.a'; then
  1227.     echo shar: Combining  \"'agent/man/mailagent.SH'\" \(91668 characters\)
  1228.     cat 'agent/man/mailagent.SH.a' 'agent/man/mailagent.SH.b' > 'agent/man/mailagent.SH'
  1229.     if test 91668 -ne `wc -c <'agent/man/mailagent.SH'`; then
  1230.       echo shar: \"'agent/man/mailagent.SH'\" combined with wrong size!
  1231.     else
  1232.       chmod u+x agent/man/mailagent.SH
  1233.       rm agent/man/mailagent.SH.a agent/man/mailagent.SH.b
  1234.     fi
  1235.   fi
  1236.   # end of 'agent/man/mailagent.SH.b'
  1237. fi
  1238. if test -f 'agent/pl/add_log.pl' -a "${1}" != "-c" ; then 
  1239.   echo shar: Will not clobber existing file \"'agent/pl/add_log.pl'\"
  1240. else
  1241.   echo shar: Extracting \"'agent/pl/add_log.pl'\" \(1214 characters\)
  1242.   sed "s/^X//" >'agent/pl/add_log.pl' <<'END_OF_FILE'
  1243. X;# $Id: add_log.pl,v 2.9 92/07/14 16:49:34 ram Exp $
  1244. X;#
  1245. X;#  Copyright (c) 1991, Raphael Manfredi
  1246. X;#
  1247. X;#  You may redistribute only under the terms of the GNU General Public
  1248. X;#  Licence as specified in the README file that comes with dist.
  1249. X;#
  1250. X;# $Log:    add_log.pl,v $
  1251. X;# Revision 2.9  92/07/14  16:49:34  ram
  1252. X;# 3.0 beta baseline.
  1253. X;# 
  1254. X# Add an entry to logfile
  1255. X# There is no need to lock logfile as print is sandwiched betweeen
  1256. X# an open and a close (kernel will flush at the end of the file).
  1257. Xsub add_log {
  1258. X    &write_log;        # Inderection needed, so that we may remap on stderr_log
  1259. X}
  1260. X
  1261. X# When mailagent is used interactively, log messages are also printed on
  1262. X# the standard error.
  1263. X# NB: this function is not called directly, but via a type glob *add_log.
  1264. Xsub stderr_log {
  1265. X    print STDERR "$prog_name: $_[0]\n";
  1266. X    &write_log;
  1267. X}
  1268. X
  1269. X# Log message into logfile, using jobnum to identify process.
  1270. Xsub write_log {
  1271. X    local($date);
  1272. X    local($log);
  1273. X
  1274. X    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
  1275. X        localtime(time);
  1276. X    $date = sprintf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d",
  1277. X        $year,++$mon,$mday,$hour,$min,$sec);
  1278. X    $log = $date . " $prog_name[$jobnum]: $_[0]\n";
  1279. X
  1280. X    open(LOGFILE, ">>$cf'logfile");
  1281. X    print LOGFILE $log;
  1282. X    close LOGFILE;
  1283. X}
  1284. X
  1285. END_OF_FILE
  1286.   if test 1214 -ne `wc -c <'agent/pl/add_log.pl'`; then
  1287.     echo shar: \"'agent/pl/add_log.pl'\" unpacked with wrong size!
  1288.   fi
  1289.   # end of 'agent/pl/add_log.pl'
  1290. fi
  1291. echo shar: End of archive 2 \(of 17\).
  1292. cp /dev/null ark2isdone
  1293. MISSING=""
  1294. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; do
  1295.     if test ! -f ark${I}isdone ; then
  1296.     MISSING="${MISSING} ${I}"
  1297.     fi
  1298. done
  1299. if test "${MISSING}" = "" ; then
  1300.     echo You have unpacked all 17 archives.
  1301.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1302. else
  1303.     echo You still must unpack the following archives:
  1304.     echo "        " ${MISSING}
  1305. fi
  1306. exit 0
  1307. exit 0 # Just in case...
  1308.