home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume41 / mailagnt / part02 < prev    next >
Encoding:
Text File  |  1993-12-02  |  54.6 KB  |  1,263 lines

  1. Newsgroups: comp.sources.misc
  2. From: Raphael Manfredi <ram@acri.fr>
  3. Subject: v41i002:  mailagent - Flexible mail filtering and processing package, v3.0, Part02/26
  4. Message-ID: <1993Dec2.133451.17859@sparky.sterling.com>
  5. X-Md4-Signature: 24eb04dcb05bb329f71850d78dd2cc6d
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Advanced Computer Research Institute, Lyon, France.
  8. Date: Thu, 2 Dec 1993 13:34:51 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: Raphael Manfredi <ram@acri.fr>
  12. Posting-number: Volume 41, Issue 2
  13. Archive-name: mailagent/part02
  14. Environment: UNIX, Perl
  15. Supersedes: mailagent: Volume 33, Issue 93-109
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # Contents:  agent/man/mailagent.SH.02 agent/pl/unpack.pl
  24. # Wrapped by ram@soft208 on Mon Nov 29 16:49:54 1993
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. echo If this archive is complete, you will see the following message:
  27. echo '          "shar: End of archive 2 (of 26)."'
  28. if test -f 'agent/man/mailagent.SH.02' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'agent/man/mailagent.SH.02'\"
  30. else
  31.   echo shar: Extracting \"'agent/man/mailagent.SH.02'\" \(49983 characters\)
  32.   sed "s/^X//" >'agent/man/mailagent.SH.02' <<'END_OF_FILE'
  33. XSubject: /^Daily output/    { SAVE %#host/daily.%D };
  34. XSubject: /^Weekly output/    { SAVE %#host/weekly.%m-%d };
  35. X.Ef
  36. XBesides variable interpolation via the %# escape, it is also possible to
  37. Xperform substitutions and translations on the content of a variable (or a
  38. Xback-reference, i.e. a number between 1 and 99). The two commands SUBST and
  39. XTR will respectively perform in-place substitutions and translations. In that
  40. Xcase however, the name of the variable must be preceded by a single #. This
  41. Xdifferentiates the back-reference \fI1\fR from the variable \fI#1\fR, although
  42. X\fI1\fR is a funny name for a variable. The need for # also prevents the
  43. Xcommon mistake of writing %#, as the mailagent will loudly complain if the
  44. Xfirst parameter of SUBST or TR is not a digit between 1 and 99 or does not
  45. Xstart with a #.
  46. X.PP
  47. XHere are some actions to canonicalize the host name into lower case and
  48. Xstrip down the domain name, if any:
  49. X.Ex
  50. X{ TR #host /A-Z/a-z/; SUBST #host /^([^.]*)\\\\..*/\$1/ };
  51. X.Ef
  52. XThose actions are directly translated into their \fIperl\fR equivalent, and
  53. Xany error in the specification of the regular expression will be reported.
  54. X.PP
  55. XIf the variable name begins with a colon ':', then the variable is made
  56. Xpersistent. That is to say it will keep its value across different mailagent
  57. Xinvocations. The variable is simply stored (with the leading ':' removed) in
  58. Xthe mailagent's database and is thus subject to the aging policy set up in
  59. Xthe ~/.mailagent.
  60. X.PP
  61. XWithin PERL commands or mail hooks using perl (see the MAIL HOOKS section),
  62. Xyou can manipulate those (so-called) external variables via a set of
  63. Xinterface functions located in the \fIextern\fR package (i.e. you must
  64. Xprefix each of the function name with its package name, \fIset\fR becoming
  65. X\fIextern'set\fR). The following three interface functions are provided:
  66. X.PD
  67. X.TP 10
  68. Xval(name)
  69. XReturn the value of the variable \fIname\fR (the leading ':' is not part of the
  70. Xname, in any of these three interface functions).
  71. X.TP
  72. Xset(name, value)
  73. XSet the external variable \fIname\fR to hold \fIvalue\fR. No interpretation
  74. Xis done by the function on the actual content of the \fIvalue\fR you are
  75. Xproviding.
  76. X.TP
  77. Xage(name)
  78. XReturns the age of the variable, i.e. the elapsed time in seconds since the
  79. Xlast modification made by \fIset\fR.
  80. X.PP
  81. XThere is currently no way for erasing a variable from the database. But if
  82. Xyou do not use the variable any more, it will be removed when its age
  83. Xbecomes greater than the maximum age specified by the \fIagemax\fR configuration
  84. Xvariable.
  85. X'''
  86. X.SS "Regular Expressions"
  87. X.PP
  88. XAll the regular expressions follow the V8 syntax, as in \fIperl\fR, with all
  89. Xthe \fIperl\fR extensions. If a bracketing construct (...) is used inside a
  90. Xrule, then the %\fIdigit\fR macro matches the \fIdigit\fR's substring held
  91. Xinside the bracket. All those back-references are memorized on a per-rule basis,
  92. Xnumbered from left to right. However, great care must be taken when using
  93. Xa back-reference in multiply present selectors, as all the matches will be
  94. Xperformed up-to the first match, and back-references are computed on the fly
  95. Xwhile doing pattern matching.
  96. X.PP
  97. XFor instance:
  98. X.Ex
  99. XTo: /(.*)/, Subject: /Output from (\\\\w+)/ { ASSIGN to %1; SAVE %2 };
  100. X.Ef
  101. Xwill save the To: field in variable 'to' and save the mail in a folder derived
  102. Xfrom the host name specified in the subject. However, if we say:
  103. X.Ex
  104. XSubject: /host (\\\\w+)/, /from (\\\\w+)/ { ASSIGN match %1 };
  105. X.Ef
  106. Xthen there will be only one back-reference set, and it will come from the first
  107. Xpattern matching if it succeeds, or from the second. Should the second or
  108. Xthe first pattern have no bracketing construct and still match, then the
  109. Xback-reference would not be recorded at all, which means the following is
  110. Xprobably not what you want:
  111. X.Ex
  112. XSubject: /from/, /host (\\\\w+)/, To: /(.*)/ { SAVE %1; REJECT };
  113. X.Ef
  114. Xas if the /from/ pattern matches then /host (\\\\w+)/ will not be checked
  115. X(identical selectors are \fIor\fR'ed and that is optimized), then %1 would refer
  116. Xto the To: field whereas if /host (\\\\w+)/ matches, then %1 will be the host
  117. Xname.
  118. X.PP
  119. XHowever, this behavior can be used to selectively store a news article
  120. Xwhich has been mailed to you in a folder whose name is the newsgroup name
  121. Xin dot form. Assuming we want to give priority to comp.lang.perl, we
  122. Xcould say:
  123. X.Ex
  124. XNewsgroups:
  125. X    /(comp.lang.perl)/,
  126. X    /(comp.mail.mh)/,
  127. X    /(comp.compilers)/,
  128. X    /([^,]*)/        { SAVE %1 };
  129. X.Ef
  130. XAn article cross-posted to both comp.lang.perl and comp.mail.mh would
  131. Xbe saved in a comp.lang.perl folder, since this is what would match first.
  132. XThe last rules takes care of other articles: the folder used being
  133. Xwhatever newsgroup appears first.
  134. X.PP
  135. XThere is also a special macro %&, which lists (it's a comma separated list)
  136. Xall the selectors specified via a regular expression which indeed matched.
  137. XFor instance:
  138. X.Ex
  139. XRe.*: /york/        { ASSIGN which %& };
  140. X.Ef
  141. Xwould assign to \fIwhich\fR the list of all the fields matching the /Re.*/
  142. Xpattern which contained 'york', be it a Received: field or a Resent-From:
  143. Xfield (as both match the selector specification). Assuming both those fields
  144. Xcontained the word \fIyork\fR, the value of %& would be 'Received,Resent-From;'
  145. X(the fields are alphabetically sorted).
  146. X.PP
  147. XShould you have more than one such specified selector within a single rule,
  148. Xthen it might be worth knowing that all the set of matching selectors are
  149. Xrecorded within %&, each set terminated with a ';'. If a negated selector is
  150. Xused, then %& will record all the fields which did not contain the pattern,
  151. Xassuming the selection succeeded (otherwise nothing is recorded).
  152. X'''
  153. X.SS "Available Actions"
  154. X.PP
  155. XThe following actions are available as filtering commands. Case is irrelevant
  156. Xalthough the recommended style is to spell them upper-cased. As explained
  157. Xlater, most of the actions record their exit status in a special variable
  158. Xwhich may be tested via the \fB\-t\fR and \fB\-f\fR options of ABORT, REJECT
  159. Xand RESTART. For every command which returns such an exit status, the failure
  160. Xor success conditions are given at the end of each description. If nothing is
  161. Xspecified, then the command does not return a meaningful status.
  162. X.TP 10
  163. XABORT [-tf] [\fImode\fR]
  164. XAbort application of filtering rules immediately. See REJECT for the meaning
  165. Xof the optional parameters. (Does not modify existing status)
  166. X.TP
  167. XANNOTATE [-d] \fIfield value\fR
  168. XAnnotate message by adding \fIfield\fR into the mail header, with the
  169. Xsupplied \fIvalue\fR. This is like the MH command \fIanno\fR, but the
  170. Xannotation is performed at the end of the header, whereas MH does it at the
  171. Xtop. Normally, an extra \fIfield\fR is added, with the current date as
  172. Xfield value. This can be suppressed by using the \fB\-d\fR option. If
  173. X\fIvalue\fR is omitted, only the date field is generated (hence it is an
  174. Xerror to use the \fB\-d\fR option without supplying a \fIvalue\fR). As with
  175. Xall the commands which alter the header, a RESYNC is necessary for the filter
  176. Xpart to actually see the new header. (Does not modify existing status)
  177. X.TP
  178. XAPPLY \fIrulefile\fR
  179. XGet the rules held in \fIrulefile\fR and apply them to the current message.
  180. XThe filter will begin in whatever mode you were when using this command,
  181. Xbut no feed back will occur, i.e. any mode changing will be lost when
  182. Xreturning from the command. If mail is saved during the application of
  183. Xthe rules, then the corresponding flag is set in the main filter (the one
  184. Xthat started the APPLY command). You may nest them, of course.
  185. X(Fails if mail is not saved by the rules held in \fIrulefile\fR)
  186. X.TP
  187. XASSIGN \fIvar value\fR
  188. XAssign the value to the user-defined variable \fIvar\fR, which may further be
  189. Xaccessed as \fI%#var\fR for macro substitution or \fI#var\fR in the TR and
  190. XSUBST commands in place of the variable name. Note that there is no leading
  191. X\fI#\fR in front of the variable name. The \fIvalue\fR you provide is first
  192. Xran through \fIperl\fR to see if it contains some arithmetic operations. If the
  193. Xevaluation is successful, the resulting value is used instead. If an error
  194. Xoccurs in this evaluation process, then the literal value provided is used.
  195. XTo avoid the evaluation, you may enclose the whole value in simple quotes. Those
  196. Xwill be trimmed before the assignment takes place. If you actually want simple
  197. Xquotes in the first AND last position, you have to double each of them.
  198. X(Does not modify existing status)
  199. X.TP
  200. XBACK \fIcommand\fR
  201. XExecute \fIcommand\fR and take its output as new actions to be performed on
  202. Xthe mail (hence performing something analogous to \fI\`command\`\fR in shell).
  203. XIf there is no output, nothing is done. BACK commands can be nested, although
  204. Xthis may lead to surprises this manpage will not disclose (but I assure you
  205. Xit will be funny, assuming we have the same sense of humor... :-). Note that
  206. Xboth the standard output and the standard error from the command are used.
  207. XIf the command fails, the output is mailed back to the user and no action is
  208. Xperformed. Furthermore, normal feedback does not occur here: any output from
  209. Xthe command is taken as filter actions, which means the semantics of PASS,
  210. Xfor instance, is changed: we do not take a body back but commands.
  211. X(The execution status is that of the \fIcommand\fR)
  212. X.TP
  213. XBEGIN \fIstate\fR
  214. XEnter a new state. An explicit REJECT or RESTART is necessary to abort the
  215. Xprocessing of the current rule. The processing begins in state INITIAL.
  216. X(Does not modify existing status)
  217. X.TP
  218. XBOUNCE \fIaddress(es)
  219. XBounce the message to the specified address(es) and acts as if a save had
  220. Xbeen done. The only difference with FORWARD is that no Resent-like lines are
  221. Xadded to the header. If an address is specified in double quotes, it is taken
  222. Xas the name of a file to be loaded to get addresses (one address per line, shell
  223. Xcomments (#) allowed). The file name resolving is the same as the one used
  224. Xfor pattern loading.
  225. X(Fails if mail cannot be resent)
  226. X.TP
  227. XDELETE
  228. XDelete the current message. Actually, this does not do anything, it just marks
  229. Xthe mail as saved. If no further action involving saving is done, then the
  230. Xmail will never show up in the mailbox.
  231. X(Never fails)
  232. X.TP
  233. XFEED \fIprogram\fR
  234. XFeed the whole message to a program and get the output back as the new
  235. Xmessage. The header structure used by the rules is not updated: an explicit
  236. XRESYNC is necessary. Hence the program appears as a filter for the whole
  237. Xmessage.
  238. X(Returns the status of \fIprogram\fR)
  239. X.TP
  240. XFORWARD \fIaddress(es)\fR
  241. XForward mail to the specified address(es). This acts as if a save had been
  242. Xdone, in order to avoid the DELETE. Usually when you forward a mail, you do not
  243. Xwish to keep it. The command adds Resent-like lines in the header. As for
  244. XBOUNCE, file inclusion is possible (i.e. use an address \fI"forward_list"\fR
  245. Xto forward a mail to all the users listed in the file \fIforward_list\fR).
  246. X(Fails if mail cannot be resent)
  247. X.TP
  248. XGIVE \fIprogram\fR
  249. XGive the body of the message to the specified program by feeding its standard
  250. Xinput. Any output is mailed to the user who runs the \fImailagent\fR.
  251. X(Returns the status of \fIprogram\fR)
  252. X.TP
  253. XKEEP \fIheader_fields_list\fR
  254. XKeeps only the corresponding lines in the header of the mail. For instance,
  255. Xa "KEEP From To Cc Subject" will keep only the principal fields from the
  256. Xmail message. This is suitable for archiving mailing lists messages.
  257. XYou may add a ':' after each header field name if you wish, but that is not
  258. Xstrictly necessary. Headers may be specified using shell-style regular
  259. Xexpressions, and file inclusion is allowed to get headers from a file.
  260. X(Does not modify existing status)
  261. X.TP
  262. XLEAVE
  263. XLeave incoming mail in the system mailbox. This is the default action if no
  264. Xrule matched or if no saving occurred.
  265. X(Fails if mail cannot be saved)
  266. X.TP
  267. XMACRO [-rdp] \fIname\fR [= (\fIvalue\fR, \fItype\fR)]
  268. XLets you specify user-defined macros, of the form %-(\fIname\fR). See the
  269. Xparagraph on user-defined macros for explanation about the available types
  270. X(SCALAR, EXPR, CONST, FN, PROG, PROGC).
  271. XA perl interface to the underlying user macros is available for your perl
  272. Xcommands. The \fB\-r\fR option is used to replace an existing macro (instead of
  273. Xpushing a new instance on the stack), the \fB\-d\fR is to delete all the
  274. Xinstances of a named macro (in that case it takes only the first argument),
  275. Xand \fB\-p\fR pops the last instance of the macro from the stack and reverts
  276. Xto the previous definition, if any (otherwise, it acts as \fB\-d\fR).
  277. XIf you wish to define a simple SCALAR macro, you may omit the \fI= (value,
  278. Xtype)\fR part and simply continue with the macro value.
  279. X(Does not modify existing status)
  280. X.TP
  281. XMESSAGE \fIfile\fR
  282. XSend message \fIfile\fR back to the sender of the message (as derived from the
  283. Xheader of the message). The text of the message is run through the macro
  284. Xsubstitution mechanism (described later on).
  285. X(Fails if message cannot be sent)
  286. X.TP
  287. XNOP
  288. XNo operation. If this seems a bit odd, think of it in terms of a ONCE command.
  289. X(Does not alter existing status)
  290. X.TP
  291. XNOTIFY \fIfile\fR \fIaddress(es)\fR
  292. XSend a notification message \fIfile\fR to a given address list. The text of the
  293. Xmessage is run through the macro substitution mechanism (described later on).
  294. XAs with FORWARD, file inclusion for address specification is possible.
  295. X(Fails if message cannot be sent)
  296. X.TP
  297. XONCE \fI(name, tag, period) command\fR
  298. XExecute the specified filter command once per \fIperiod\fR. The \fIname\fR and
  299. X\fItag\fR fields are used to record timestamps of the last ONCE command.
  300. XMore on this later. (Propagates status from \fIcommand\fR. If the command is
  301. Xnot executed, always return success)
  302. X.TP
  303. XPASS \fIprogram\fR
  304. XFeed the body of the message to the specified program and get a new body
  305. Xback from the output of the program.
  306. X(Returns the status of \fIprogram\fR)
  307. X.TP
  308. XPERL \fIscript\fR [\fIarguments\fR]
  309. XEscape to a perl \fIscript\fR to perform some actions on the message. This
  310. Xis fully described further in the manpage, and is very different from a
  311. X\fIRUN perl script\fR command. (Returns failure if the script did not compile
  312. Xor returned a non-zero status).
  313. X.TP
  314. XPIPE \fIprogram\fR
  315. XPipe the whole message to the specified program, but do not get anything
  316. Xback. Any output is mailed to the user who runs the \fImailagent\fR.
  317. X(Returns the status of \fIprogram\fR)
  318. X.TP
  319. XPOST [-l] \fInewsgroup(s)\fR
  320. XPost the message to the specified newsgroup(s) after having cleaned-up the
  321. Xheader (by removing mail-related fields like Received: or To:). This acts
  322. Xas a saving. If the first name is \fB\-l\fR as in "POST -l comp.mail.mh",
  323. Xthen a "Distribution: local" header is added to force a local delivery.
  324. XOtherwise, the default \fIinews\fR distribution will be used (world,
  325. Xusually).
  326. XIf more than one newsgroup is specified, they should be space
  327. Xseparated. It is possible to get a newsgroup list via file inclusion.
  328. X(Fails if message cannot be posted)
  329. X.TP
  330. XPROCESS
  331. XRun the mailagent processing which looks for @SH commands and executes
  332. Xthem. This was described before in the section dealing with default rules.
  333. XThe action associated by default to a mail having [Cc]ommand as its
  334. Xsubject is PROCESS.
  335. X(Always returns success)
  336. X.TP
  337. XPURIFY \fIprogram\fR
  338. XFeed the header into a program and get new header back. No RESYNC is done.
  339. XThis may be used to indeed purify the header by removing all the verbose
  340. Xstuff added by so many mail transport agents (X-400 like lines for instance).
  341. X(Returns the status of \fIprogram\fR)
  342. X.TP
  343. XQUEUE
  344. XQueue mail again. A successful queuing counts as if mail had been saved.
  345. XMail queued that way will not be processed during the next 30 minutes. Note
  346. Xthat unless the mailagent is invoked on a regular basis by \fIcron\fR, the
  347. Xmail will remain in the queue until another mail arrives.
  348. X(Fails when mail cannot be queued)
  349. X.TP
  350. XRECORD [-acr] [\fImode\fR]
  351. XRecord message in the history and enters mode _SEEN_ if the message was
  352. Xalready present there. If the message is recorded for the first time, processing
  353. Xcontinues normally. Otherwise a REJECT is performed. This behavior may be
  354. Xsomewhat modified by using some options. See UNIQUE for a complete description
  355. Xof the options and arguments. Naturally, when a \fImode\fR is specified, that
  356. Xoverrides the default _SEEN_.
  357. X(Returns a failure status if mail was already recorded)
  358. X.TP
  359. XREJECT [-tf] [\fImode\fR]
  360. XAbort execution of current action, and continue matching. If \fB\-t\fR is
  361. Xspecified, the reject will occur only if the previous action was successfully
  362. Xcompleted (return status of true), whilst \fB\-f\fR would cause the reject only
  363. Xwhen a failure occurred. If a \fImode\fR is specified, we enter that mode before
  364. Xrejection. REJECT resets the matching flag, which means that if no further
  365. Xmatch occurs, the default action will apply.
  366. X(Does not alter execution status)
  367. X.TP
  368. XREQUIRE \fIfile\fR [\fIpackage\fR]
  369. XBehaves like the perl \fIrequire\fR operator by loading a perl file into
  370. Xmemory. By default, the file is read in the \fInewcmd\fR package, but you
  371. Xmay specify whatever package you wish to load it in. This command will only
  372. Xperform the loading once per (file, package) tuple. Unlike its perl
  373. Xequivalent, the file "value" is not important, i.e. it does not have to end
  374. Xwith a statement returning a true value.
  375. X(Fails if file cannot be loaded)
  376. X.TP
  377. XRESTART [-tf] [\fImode\fR]
  378. XAbort execution of current action and restart the matching process from the
  379. Xbeginning. To avoid loops, each rule may be walked through once in a given
  380. Xmode. See REJECT for the meaning of the optional parameters. RESTART resets
  381. Xthe matching flag, which means that the default action will apply, should
  382. Xno further match occur.
  383. X(Does not alter execution status)
  384. X.TP
  385. XRESYNC
  386. XRe-synchronize header used for matching with the header of the mail. This is
  387. Xprobably useful only when a FEED command was run.
  388. X(Does not alter execution status)
  389. X.TP
  390. XRUN \fIprogram\fR
  391. XRun the specified program and mail any output to the user who runs the
  392. X\fImailagent\fR.
  393. X(Returns the status of \fIprogram\fR)
  394. X.TP
  395. XSAVE \fIfolder\fR
  396. XSave message in the specified folder. If folder name starts with a '+', it is
  397. Xhandled as an MH-style folder and \fIrcvstore\fR is emulated to deliver the
  398. Xmessage into that folder. If folder is a directory, message is delivered in
  399. Xa single file within that directory. See the \fBFOLDERS\fR section.
  400. X(Fails if message cannot be saved)
  401. X.TP
  402. XSELECT (\fIstart .. end\fR) \fIcommand\fR
  403. XExecute the \fIcommand\fR only within the time selection period specified.
  404. XDates can be specified in a wide range of formats. The output of the
  405. X\fIdate\fR(1) command is an example of a valid specification. If the date,
  406. Xthe year or the month is missing, then the current one is substituted in place
  407. Xof it. The following dates are valid specifications: '10:04:25', 'now'
  408. X,'April 1 1992', 'Dec 25', 'July 14 1789, 07:40' (err... it's valid according
  409. Xto the grammar, but it's before the Epoch so it does not mean anything). Other
  410. Xfancy dates like 'last month - 5 minutes' or '3 weeks ago' are also enabled.
  411. X(Isn't that great to have a \fBreal\fR parser? The filtering rules could have
  412. Xbeen more elaborated if only I had known about this Berkeley \fIyacc\fR
  413. Xproducing a \fIperl\fR parser...). (Returns the status of \fIcommand\fR, if run,
  414. Xotherwise returns true).
  415. X.TP
  416. XSERVER [-t] [-d '\fIdisabled commands\fR']
  417. XActivate server processing. The body of the message is interpreted as a list
  418. Xof commands to execute. See section \fBGENERIC MAIL SERVER\fR for more
  419. Xinformation about the server itself. The \fB\-t\fR option turns the server
  420. Xinto \fItrusted mode\fR, where \fIpowers\fR may be gained. The \fB\-d\fR
  421. Xoption must be followed by a list of disabled commands, separated by spaces
  422. Xand or commas. The whole list must be enclosed within single quotes.
  423. X.TP
  424. XSPLIT [-adeiw] \fIfolder\fR
  425. XSplit a mail in digest format into the specified folder (same naming
  426. Xconventions as in SAVE). 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. XThe \fIfolder\fR parameter follows the same naming conventions as in SAVE.
  456. X(Fails if message cannot be saved either in the \fIfolder\fR or in the mailbox)
  457. X.TP
  458. XSTRIP \fIheader_fields_list\fR
  459. XRemove the corresponding lines in the header of the mail. For instance,
  460. Xa "STRIP Newsgroups Apparently-To" will remove the appropriate lines to wipe
  461. Xout any Newsgroups: or Apparently-To: header. You may add a ':' after each
  462. Xheader field name if you wish, but that is not strictly necessary. Headers
  463. Xmay be specified via shell-style regular expressions or via "file" inclusion.
  464. X(Does not alter execution status)
  465. X.TP
  466. XSUBST \fIvar expression\fR
  467. XSubstitutes the expression on the specified user-defined variable (name
  468. Xstarting with a #) or back-reference (digit). For instance, 'SUBST #foo /w/y/g'
  469. Xwould substitute in user-defined variable \fIfoo\fR all the \fIw\fR by \fIy\fR.
  470. XSee also ASSIGN and TR.
  471. X(Fails if error in \fIexpression\fR)
  472. X.TP
  473. XTR \fIvar translation\fR
  474. XPerform the translation on the specified variable or back-reference. For
  475. Xinstance, 'TR 1 /A-Z/a-z/' would canonicalize content of reference 1 into
  476. Xlowercase. See also ASSIGN and SUBST.
  477. X(Fails if error in \fItranslation\fR)
  478. X.TP
  479. XUNIQUE [-acr] [\fImode\fR]
  480. XRecord message in the history and tag message as saved if it was
  481. Xalready present there. If the message is recorded for the first time, processing
  482. Xcontinues normally. Otherwise a REJECT is performed. If \fB\-r\fR was used,
  483. Xa RESTART is used instead whilst \fB\-a\fR would run an ABORT.
  484. XFor instance, to remove duplicate messages from mailing lists, run a
  485. XUNIQUE -a before saving the mail. The \fB\-c\fR option may be used alone to
  486. Xactually prevent the command from disturbing the execution flow, and to later
  487. Xuse the return status to see what happened:
  488. XUNIQUE returns a failure status if the message was already recorded.
  489. XIf an optional \fImode\fR argument is given, then the automaton will enter that
  490. Xmode if the mail was previously in the database.
  491. XSee also RECORD. (Fails if mail was already recorded)
  492. X.TP
  493. XVACATION \fIon/off\fR
  494. XAllow or disallow a vacation message. When vacation mode is turned on via the
  495. Xconfiguration file, a message is sent whenever the user receives a mail
  496. Xmeeting some requirements, as explained under the section \fBVACATION MODE\fR.
  497. XOne of the conditions is that the vacation flag modified by this command be
  498. Xtrue. This makes it easy to disallow vacation messages, ever, to a group
  499. Xof people for instance.
  500. X(Does not alter execution status)
  501. X.TP
  502. XWRITE \fIfolder\fR
  503. XWrite the message in the specified folder, removing any pre-existing folder
  504. Xwith the same name. Hence, successive WRITE commands will overwrite the
  505. Xprevious one. This is useful to store output of system commands ran by
  506. X\fIcron\fR. Don't try to use it with an MH folder or a directory folder or
  507. Xit will behave like SAVE.
  508. X(Fails if message cannot be written)
  509. X'''
  510. X.SS "Execution Status"
  511. X.PP
  512. XAlmost all the actions modify a variable which keeps track of the execution
  513. Xstatus (analogous to the \$? variable in the shell).
  514. XThis variable can be tested via the \fB\-t\fR or \fB\-f\fR option of
  515. Xthe REJECT command for instance. To give but a single example, the SAVE
  516. Xaction would return \fIfailed\fR if it could not save the mail in the specified
  517. Xfolder. If that SAVE command was followed by a "REJECT -f FAILED", then the
  518. Xexecution of the current rule would stop and the automaton would continue to
  519. Xanalyze the mail in the FAILED mode.
  520. X.PP
  521. XSome of the actions however do not modify this last execution status. Typically,
  522. Xthose are actions which make decisions based on that status, or simply actions
  523. Xwhich may never fail. Those special actions are: ABORT, ASSIGN, BEGIN, KEEP,
  524. XMACRO, NOP, REJECT, RESTART, RESYNC, STRIP and VACATION.
  525. X.PP
  526. XIt is unfortunate that ONCE or SELECT commands cannot make the difference
  527. Xbetween a non-execution and a successful execution of the specified command.
  528. XThere may be a change in the way this scheme works, but it should remain
  529. Xbackward compatible.
  530. X'''
  531. X.SS "Perl Escape"
  532. X.PP
  533. XBy using the PERL command, you have the ability to perform filtering and other
  534. Xsophisticated actions directly in \fIperl\fR. This is really different from
  535. Xwhat you could do by feeding your mail to a perl script. First of all, no
  536. Xextra process is created: the script is loaded directly in the mailagent and
  537. Xcompiled in a special package called \fImailhook\fR. Secondly, you have a
  538. Xperl interface to all the filtering commands: each filtering action is
  539. Xassociated to a perl function (spelled lower-cased). Finally, some pre-defined
  540. Xvariables are set for you by the mailagent.
  541. X.PP
  542. XBefore we go any further, please note that as there is no extra process created,
  543. Xyou \fBmust not\fR call the perl \fIexit\fR function. Use \fI&exit\fR instead,
  544. Xso that the exit may be trapped. \fI&exit\fR takes one argument, the exit code.
  545. XIf you use 0, this is understood as a success, any other value meaning failure
  546. X(i.e. the PERL command will return a failure status). Using the perl \fIexit\fR
  547. Xfunction directly would kill \fImailagent\fR and would probably incur some
  548. Xmail looses.
  549. X.PP
  550. XThe scripts used should remain simple. In particular, you should avoid the use
  551. Xof the \fIpackage\fR directive or define functions with a package name other
  552. Xthan \fImailhook\fR (i.e. the package where your script is loaded). Failure
  553. Xto do so may raise some name clashes with \fImailagent\fR's own routines.
  554. XIn particular, avoid the \fImain\fR package. Note that since the compilation
  555. Xenvironment is set-up to \fImailhook\fR, not specifying package names in your
  556. Xvariables and subroutine is fine (in fact, it's meant to work that way).
  557. X.PP
  558. XYour script is free to do whatever it wants to the mail. Most of the time
  559. Xhowever, you end up using the \fImailagent\fR primitives to save the mail
  560. Xor forward it (but you are free to redesign your own and call them instead,
  561. Xof course). The interface is simple: each function takes but one argument,
  562. Xa string, which is the arguments to the command, if any. For instance, in
  563. Xa perl escape script, you would express:
  564. X.Ex
  565. X{ SAVE list; FORWARD "users"; FEED ~/bin/newmail -tty; REJECT }
  566. X.Ef
  567. Xwith:
  568. X.Ex
  569. X&save('list');
  570. X&forward('"users"');
  571. X&feed('~/bin/newmail -tty');
  572. X&reject;
  573. X.Ef
  574. XThe rule is simple: each command is replaced by a function call, with the
  575. Xremaining parameters enclosed in a string, if any. Alternatively, you may
  576. Xspecify parameters as a list: all the arguments you provide are joined
  577. Xinto a big happy string, using a space character as separator. The macro
  578. Xsubstitution mechanism is then ran on this resulting argument string.
  579. X.PP
  580. XEach function returns a boolean
  581. Xsuccess status of the command (i.e. 1 means success). For those functions which
  582. Xusually do not modify the filter's last execution status variable, a success is
  583. Xalways returned. This makes it possible to (intuitively) write:
  584. X.Ex
  585. X&exit(0) if &save('uucp');
  586. X&bounce('root') || &save('emergency');
  587. X.Ef
  588. Xand get the expected result. The mail will be saved in the emergency folder
  589. Xonly when saving in uucp folder failed and the mail could not be bounced to
  590. Xroot.
  591. X.PP
  592. XIt is important to understand that these commands have \fIexactly\fR the
  593. Xsame effect on the filtering process when they are run from a perl escape
  594. Xscript or from within the rule file as regular actions.
  595. XA \fI&reject\fR call will simply abandon the execution of the current perl
  596. Xscript and the filter automaton will regain control and attempt a new match.
  597. XBut \fIperl\fR brings you much more power, in particular system calls,
  598. Xcontrol structures like \fBif\fR and \fBfor\fR, raw regular expressions, etc...
  599. X.PP
  600. XThe special \fIperl\fR @INC array (which controls the search path for
  601. X\fIrequire\fR) is slightly modified by prepending the mailagent's own private
  602. Xlibrary path. This leaves the door open for future mailagent library perl
  603. Xscripts which may be required by the perl script. Furthermore,
  604. Xthe following special variables are set-up by perl before invoking your
  605. Xscript:
  606. X.sp
  607. X.PD 0
  608. X.TP 15
  609. X.I @ARGV
  610. XThe arguments of the script, which were given by the PERL command. This array
  611. Xis set up the exact same way you would expect it to be set up if you invoked
  612. Xthe command directly from the shell.
  613. X.TP
  614. X.I \$address
  615. XThe address part of the From: line.
  616. X.TP
  617. X.I \$cc
  618. XThe raw content of the Cc: line.
  619. X.TP
  620. X.I @cc
  621. XThe list of addresses on the Cc: line, with comments suppressed.
  622. X.TP
  623. X.I \$envelope
  624. XThe mail envelope, as computed using the first From line of the message.
  625. X.TP
  626. X.I \$friendly
  627. XThe comment part of the From: line, if any.
  628. X.TP
  629. X.I \$from
  630. XThe content of the From: line, with address and comment part.
  631. X.TP
  632. X.I %header
  633. XThis table, indexed by field name, returns the raw content on the
  634. Xcorresponding header line. See below.
  635. X.TP
  636. X.I \$login
  637. XThe login name of the address on the From: line.
  638. X.TP
  639. X.I \$precedence
  640. XThe content of the Precedence: line, if any at all.
  641. X.TP
  642. X.I \$reply_to
  643. XThe e-mail address where a reply should be sent to, with comment suppressed.
  644. X.TP
  645. X.I \$sender
  646. XThe sender of the message (may have a comment), derived in the same way the
  647. XSender: line is computed by the mailagent.
  648. X.TP
  649. X.I \$subject
  650. XThe subject of the message.
  651. X.TP
  652. X.I \$to
  653. XThe raw content of the To: line.
  654. X.TP
  655. X.I @to
  656. XThe list of addresses on the To: line, with comments suppressed.
  657. X.PD
  658. X.PP
  659. XThe associative array \fI%header\fR gives you access to all the fields in
  660. Xthe header of the message. For instance, \fI\$to\fR is really the value of
  661. X\fI\$header{'To'}\fR. The key is specified using a normalized case, i.e.
  662. Xthe first letter of each word is uppercased, the remaining being lowercased.
  663. XThis is independent of the actual physical representation in the message
  664. Xitself.
  665. X.PP
  666. XThe pseudo keys \fIHead\fR, \fIBody\fR and \fIAll\fR respectively gives you
  667. Xaccess to the raw header of the message, the body and the whole message.
  668. XThe \fI%header\fR array is really a reference to the \fImailagent\fR's internal
  669. Xdata structure, so modifying the values will influence the filtering process.
  670. XFor instance, the SAVE command writes the \fIHead\fR, the \fIX-Filter:\fR line,
  671. Xthe end of header (a single newline) and then the \fIBody\fR (this is an
  672. Xexample only, not a documented feature :-).
  673. X.PP
  674. XAs a final note, resist the temptation of reading the internals of the
  675. Xmailagent and directly calling the routines you need. If it is not documented
  676. Xin the manual page, it may be changed without notice by any further patch.
  677. X(And this does not say that documented features may not change also... It's
  678. Xjust more unlikely, and patches would clearly state that, of course.)
  679. X'''
  680. X.SS "Program Environment"
  681. X.PP
  682. XAll the programs started by the mailagent via RUN and friends inherit the
  683. Xfollowing environment variables: HOME, USER and NAME, respectively set from
  684. Xthe configuration parameters \fIhome\fR, \fIuser\fR and \fIname\fR. If the
  685. Xmailagent is invoked by the \fIfilter\fR, then the PATH is also set according
  686. Xto the configuration file (if you are using the C filter) or to whatever you
  687. Xset PATH (if you are using the shell filter).
  688. X.PP
  689. XAll the programs are executed from within the \fIhome\fR directory. This
  690. Xincludes scripts started via the PERL command and mail hooks. The latter will
  691. Xbe described in detail further down.
  692. X'''
  693. X.SS "File inclusion"
  694. X.PP
  695. XSome commands like FORWARD or KEEP allow you to specify a file name between
  696. Xdouble quotes to actually load parameters from this file. Unless a full path
  697. Xis given, the following method is used to locate the file: first in the location
  698. Xpointed to by the \fImailfilter\fR variable if set, otherwise in \fImaildir\fR
  699. Xand finally in the home directory. Note that this is not a search path in the
  700. Xsense that if \fImailfilter\fR is defined and the file is not there, an error
  701. Xwill be reported.
  702. X.PP
  703. XThe file should list each parameter (be it an address, a header or a pattern)
  704. Xon a line by itself. Shell-style comments (#) are allowed within that file and
  705. Xleading white spaces are trimmed (but not trailing spaces).
  706. X'''
  707. X.SS "Macros Substitutions"
  708. X.PP
  709. XAll the commands go through a macro substitution mechanism before being
  710. Xexecuted. The following macros are available:
  711. X.sp
  712. X.PD 0
  713. X.TP 10
  714. X%%
  715. XA real percent sign
  716. X.TP
  717. X%A
  718. XThe internet address extracted out of the \fIFrom:\fR field (\fIa.b.c\fR
  719. Xin \fIu@a.b.c\fR), converted to lower-case.
  720. X.TP
  721. X%C
  722. XCPU name on which the mailagent runs. That is a fully qualified hostname
  723. Xwith the domain name, e.g. \fIlyon.eiffel.com\fR.
  724. X.TP
  725. X%D
  726. XDay of the week (0-6)
  727. X.TP
  728. X%H
  729. XHost name (name of the machine on which the \fImailagent\fR runs), without
  730. Xany domain name. Always in lower-case, regardless of the machine name.
  731. X.TP
  732. X%I
  733. XThe internet domain name extracted out of the \fIFrom:\fR field (\fIb.c\fR
  734. Xin \fIu@a.b.c\fR), converted to lower-case.
  735. X.TP
  736. X%L
  737. XLength of the body part, in bytes
  738. X.TP
  739. X%N
  740. XFull name of the sender (login name if none)
  741. X.TP
  742. X%O
  743. XThe organization name extracted out of the \fIFrom:\fR field (\fIb\fR in
  744. X\fIu@a.b.c\fR), converted to lower-case.
  745. X.TP
  746. X%R
  747. XSubject of the original message with leading Re: suppressed
  748. X.TP
  749. X%S
  750. XRe: subject of original message
  751. X.TP
  752. X%T
  753. XTime of the last modification on mailed file (commands MESSAGE and NOTIFY)
  754. X.TP
  755. X%U
  756. XFull name of the user
  757. X.TP
  758. X%_
  759. XA white space (useful to put white spaces in single patterns)
  760. X.TP
  761. X%&
  762. XList of selectors which incurred match (among those specified via a regular
  763. Xexpression such as 'X-*: /foo/i'. If we find the \fIfoo\fR substring in the
  764. XX-Mailer: header line, then %& will be set to this value). Values in the list
  765. Xare comma separated.
  766. X.TP
  767. X%~
  768. XA null character, wiped out from the resulting string.
  769. X.TP
  770. X%\fIdigit\fR
  771. XValue of the corresponding back reference from the last match.
  772. X.TP
  773. X%#\fIvar\fR
  774. XValue of user-defined variable \fIvar\fR
  775. X.TP
  776. X%=\fIvar\fR
  777. XValue of the mailagent configuration variable \fIvar\fR as specified in the
  778. X\fI~/.mailagent\fR file.
  779. X.TP
  780. X%d
  781. XDay of the month (01-31)
  782. X.TP
  783. X%f
  784. XContents of the "From:" line, something like %N <%r> or %r (%N) depending
  785. Xon how the mailer is configured.
  786. X.TP
  787. X%h
  788. XHour of the day (00-23)
  789. X.TP
  790. X%i
  791. XMessage ID, if available (otherwise, this is a null string)
  792. X.TP
  793. X%l
  794. XNumber of lines in the message
  795. X.TP
  796. X%m
  797. XMonth of the year (01-12)
  798. X.TP
  799. X%n
  800. XLower-case login name of sender
  801. X.TP
  802. X%o
  803. XOrganization (where \fImailagent\fR runs)
  804. X.TP
  805. X%r
  806. XReturn address of message
  807. X.TP
  808. X%s
  809. XSubject of original message
  810. X.TP
  811. X%t
  812. XCurrent hour and minute (in HH:MM format)
  813. X.TP
  814. X%u
  815. XLogin name of the user
  816. X.TP
  817. X%y
  818. XYear (last two digits)
  819. X.TP
  820. X%[To]
  821. XValue of the header field (here To:)
  822. X.PD
  823. X'''
  824. X.SS "User-defined Macros"
  825. X.PP
  826. XThe mailagent lets you define your own macros in two ways: at the filter
  827. Xlevel via the MACRO command, or at the perl level in your own commands or
  828. Xperl actions.
  829. X.PP
  830. XOnce defined, a user macro (say \fIfoo\fR) can be substituted by using
  831. X\fI%-(foo)\fR. In the case of a single-letter macro, that can be optimized
  832. Xinto \fI%-f\fR for instance, i.e. the parenthesis can be omitted.
  833. X.PP
  834. XThere are six types of macros:
  835. X.sp
  836. X.TP 10
  837. XSCALAR
  838. XA scalar value is given, e.g: \fIred\fR. The macro's value is the literal
  839. Xscalar value, no further interpretation is performed on the data.
  840. X.TP
  841. XEXPR
  842. XA perl expression will be \fIeval\fRed to get the value, e.g: \fI\$red\fR.
  843. XNote that the evaluation will be performed within the \fIusrmac\fR package,
  844. Xso if you are referring to a variable in another package, it would be wise
  845. Xto specify it, as in \fI\$foo'bar\fR.
  846. X.TP
  847. XCONST
  848. XIt's really the same as EXPR, but the value is known to be a constant. So the
  849. Xfirst time a substitution is made, the expression will be evaluated, and then
  850. Xits result is cached.
  851. X.TP
  852. XFN
  853. XA perl function name (without the leading &), such as \fImain'do_this\fR.
  854. XThe function will be called with a single parameter: the name of the
  855. Xmacro itself. That leaves the door open for further user-defined conventions
  856. Xby forcing evaluation through one single perl function.
  857. X.TP
  858. XPROG
  859. XA program to run to get the actual value. Only trailing newline is chopped,
  860. Xothers are preserved. The program is forked each time. In the argument list
  861. Xgiven to the program, %n is expanded as the macro name we are trying to
  862. Xevaluate. If you specify that in the filtering rules, don't forget to
  863. Xescape the first %.
  864. X.TP
  865. XPROGC
  866. XSame as PROG really, but the program is forked only once and the value
  867. Xis cached for later perusal.
  868. X.PD
  869. X.PP
  870. XAt the perl level, four functions let you manipulate and define your
  871. Xmacros (all part of the \fIusrmac\fR package):
  872. X.sp
  873. X.TP 10
  874. X.I new(name, value, type)
  875. XReplace or create a %-(name) macro. For instance:
  876. X.Ex
  877. Xnew('foo', "$mailhook'header{'X-Foo'}", 'EXPR');
  878. X.Ef
  879. Xwould create a new macro \fIfoo\fR that would expand into the value of
  880. Xan hypothetical \fIX-Foo\fR header.
  881. X.TP
  882. X.I delete(name)
  883. XDelete all values recorded for the macro.
  884. X.TP
  885. X.I push(name, value, type)
  886. XStack a new macro, creating it if necessary.
  887. X.TP
  888. X.I pop(name)
  889. XRemove last macro definition on the stack.
  890. X.PD
  891. X.PP
  892. XOne macro stack is allocated for each macro, so that some kind of crude
  893. Xdynamic scoping may be implemented. Creating a macro via \fIpush\fR is
  894. Xlike taking a local variable in perl, while creating one by \fInew\fR is
  895. Xsimply assigning to a variable. Likely, \fIpop\fR is like exiting a
  896. Xblock with a local variable definition and \fIdelete\fR frees \fIall\fR
  897. Xthe macro bearing that name, i.e. it deletes the whole stack.
  898. X.PP
  899. XAt the filter level, the MACRO command has three options. By default,
  900. Xthe command defines a new macro by using \fIpush\fR, and the other
  901. Xoptions each let you access one of the other interface functions.
  902. XNote that macro definitions persist across APPLY commands.
  903. X'''
  904. X.SS "User-defined Logging"
  905. X.PP
  906. XMost of the time when writing a new mailagent filtering command or an
  907. Xperl hook, you will have a need for specific logging, either to report
  908. Xa problem or to keep track of what you are performing.
  909. X.PP
  910. XNormally, logs are appended into the \fIagentlog\fR file by calling
  911. X\fI&main'add_log(string)\fR (see subsection \fBGeneral Purpose Routines\fR).
  912. XFor plain mailagent actions, this is fine.
  913. X.PP
  914. XBut mailagent lets you define alternate logging files, referred to by name.
  915. XThis generic logging interface is defined in the \fIusrlog\fR package:
  916. X.sp
  917. X.TP 10
  918. X.I new(name, file, flag)
  919. XRecords a new log file known as \fIname\fR and done in \fIfile\fR. If the
  920. Xpathname given for this file is not absolute, it is rooted under the
  921. X\fIlogdir\fR directory. If \fIflag\fR is set to true, any logging done to
  922. Xthis file will also be copied to the default system-wide logfile. Nothing is
  923. Xdone if a logfile with the same name has already been defined.
  924. X.TP
  925. X.I delete(name)
  926. XDeletes the logfile known as \fIname\fR. Further logging done to that file
  927. Xis redirected to the default logfile.
  928. X.TP
  929. X.I main'usr_log(name, string)
  930. XAdds an entry to the logfile \fIname\fR. The default logfile is known as
  931. X\fIdefault\fR and cannot be redefined nor deleted. Note that this function
  932. Xis available from the \fImain\fR package. Calling it with \fIname\fR set to
  933. Xthe string \fI'default'\fR is mostly equivalent to calling directly
  934. X\fImain'add_log\fR with the notable exception that the \fB\-i\fR mailagent
  935. Xoption will not be honored in that case. This may or may not be useful to you.
  936. X.PP
  937. XIf you call \fI&main'usr_log\fR with a non-existent logfile name, logging
  938. Xis redirected to the default system-wide logfile defined in your
  939. X\fI~/.mailagent\fR.
  940. X'''
  941. X.SS "Dynamically Loading New Code"
  942. X.PP
  943. XIn you perl routines (user-defined commands, perl hooks, etc...), you may
  944. Xfeel the need to dynamically load some new code into mailagent. You have
  945. Xdirect access to the internal routine used by mailagent to implement the
  946. XREQUIRE command or load your new filtering commands for example.
  947. X.PP
  948. XUsing the so-called \fIdynload\fR interface buys you some extra features:
  949. X.IP \(bu 5
  950. XThe mailagent public library path is automatically prepended to the @INC
  951. Xarray, which lets you define your own system-wide or private perl library
  952. Xfiles (the private library path is defined by the \fIperlib\fR configuration
  953. Xvariable, the public library path was defined at installation time).
  954. X.IP \(bu
  955. XLike perl's \fIrequire\fR, mailagent keeps track of which files were loaded
  956. Xinto which packages and will not reload the same file in the same package
  957. Xtwice.
  958. X.IP \(bu
  959. XIt is possible to make sure that a specific function be defined in the
  960. Xloaded file, with an error reported if this is not the case.
  961. X.IP \(bu
  962. XYou benefit from the default logging done by \fIdynload\fR when some error
  963. Xoccurs.
  964. X.PP
  965. XIn order to do all this, you call:
  966. X.Ex
  967. X\fI&dynload'load(package, file, function)\fR
  968. X.Ef
  969. Xspecifying the package into which you wish to load the file, and optionally
  970. Xthe name of a function that must be defined once the file has been loaded
  971. X(leave this field to \fIundef\fR if you do not have such a constraint).
  972. XThe routine returns \fIundef\fR if the file cannot be loaded
  973. X(non-existent file, most probably), \fB0\fR if the file was loaded but
  974. Xcontained a syntax error or did not define the specified function, and \fB1\fR
  975. Xfor success.
  976. X'''
  977. X.SS "Using Once Commands"
  978. X.PP
  979. XThe ONCE constructs lets you specify a given command to be run once every
  980. Xperiod (day, week...). The command is identified by a \fIname\fR and a
  981. X\fItag\fR, the combination of the two being unique. Why not just a single
  982. Xidentifier? Well, that would be fine, but assume you want to send a message
  983. Xin reply to someone once every week. You could use the e-mail address of the
  984. Xperson as the command identifier. But what if you also want to send another
  985. Xmessage to the same address, this time once a month?
  986. X.PP
  987. XHere is a prototypical usage of a ONCE, which acts like the vacation program,
  988. Xexcepted that it sends a reply only once a day for a given address:
  989. X.Ex
  990. X{ ONCE (%r, message, 1d) MESSAGE ~/.message };
  991. X.Ef
  992. XThis relies on the macro substitution mechanism to send only once a day the
  993. Xmessage held in \fI~/.message\fR. Do not use the tag \fIvacation\fR, unless
  994. Xyou know what you are doing: this is the tag used internally by the mailagent
  995. Xin vacation mode. Recall that no selector nor pattern is understood as
  996. X"Subject: *", hence the rule is always executed because that pattern always
  997. Xmatches.
  998. X.PP
  999. XThe timestamps associated with each commands are kept in files under the Hash
  1000. Xdirectory. The name is used as a hashing key to compute the name of the file
  1001. X(the two first letters are used). Inside the file, timestamps are sorted by
  1002. Xname, then by tag. Of course, you could say (inverting tag and name):
  1003. X.Ex
  1004. X{ ONCE (message, %r, 1d) MESSAGE ~/.message };
  1005. X.Ef
  1006. Xbut that would be likely to be less efficient, as the first hashing would be
  1007. Xdone on a fixed word, hence all the timestamps would be located in the file
  1008. X\fIHash/m/e\fR (where \fIHash\fR is the name of your hashing directory, which
  1009. Xis the \fIhash\fR parameter in the configuration file).
  1010. X'''
  1011. X.SS "Specifying A Period"
  1012. X.PP
  1013. XThe period parameter of the ONCE commands or the \fIvacperiod\fR parameter
  1014. Xof your configuration file has the following format: a number followed by a
  1015. Xmodifier. The modifier is an atomic period like a day or a week, the number
  1016. Xis the number of atomic periods the final period should be equal to. The
  1017. Xavailable modifiers are:
  1018. X.sp
  1019. X.PD 0
  1020. X.TP 10
  1021. Xm
  1022. Xminute
  1023. X.TP
  1024. Xh
  1025. Xhour (60 minutes)
  1026. X.TP
  1027. Xd
  1028. Xday (24 hours)
  1029. X.TP
  1030. Xw
  1031. Xweek (7 days)
  1032. X.TP
  1033. XM
  1034. Xmonth (30 days)
  1035. X.TP
  1036. Xy
  1037. Xyear (365 days)
  1038. X.PD
  1039. X.PP
  1040. XAll the periods are converted internally in seconds, although you do not
  1041. Xreally care... Examples of valid periods range from "1m" to "136y" on a 32 bits
  1042. Xmachine (why ?).
  1043. X'''
  1044. X.SS "Timeouts"
  1045. X.PP
  1046. XIn order to avoid having a \fImailagent\fR waiting for a command forever, a
  1047. Xmaximum execution time of one hour is allowed. Past that amount of time, the
  1048. Xchild is sent a SIGTERM signal. If it does not die within the next 30 seconds,
  1049. Xa SIGKILL is sent. Output from the program, if any so far, is mailed back to
  1050. Xthe user.
  1051. X'''
  1052. X.SS "Avoiding Loops"
  1053. X.PP
  1054. XThe \fImailagent\fR leaves an "X-Filter:" header on each filtered message,
  1055. Xwhich in turn is used to detect loops. If a message already filtered is
  1056. Xto be processed, the \fImailagent\fR enters a special state _SEEN_. This
  1057. Xstate is special in the sense it is built-in, it is not matched by ALL, and
  1058. Xsome actions are not made available, namely: BACK, BOUNCE, FEED, FORWARD, GIVE,
  1059. XNOTIFY, PASS, PIPE, POST, PURIFY, QUEUE and RUN. Also note that although the
  1060. XONCE and SELECT constructs are enabled, they will not let you execute
  1061. Xdisallowed commands.
  1062. X.PP
  1063. XThe _SEEN_ mode makes it easy to deal with mails which loop because of an
  1064. Xalias loop you have no control on. If no action is found in the _SEEN_ mode,
  1065. Xthe mail is left in the mailbox, as usual. Moreover, if no saving is done,
  1066. Xa LEAVE is executed. This is the normal behavior.
  1067. X'''
  1068. X.SS "Message Files"
  1069. X.PP
  1070. XThe text of the message to be sent back (for MESSAGE or NOTIFY) is read from
  1071. Xa file and passed through the macro substitution mechanism. The special macro
  1072. X\fI%T\fR is set to the date of last modification made on that file. The format
  1073. Xis \fImonth/day\fR, and the year is added before the month only if it differs
  1074. Xfrom the current year.
  1075. X.PP
  1076. XAt the head of the message, you may put header lines. Those lines will
  1077. Xoverwrite the default supplied lines. That may be useful to change the default
  1078. Xsubject or add some additional fields like the name of your organization.
  1079. XThe end of your header is given by the first blank line encountered.
  1080. XIf the top of the message you wish to send looks like a mail header, you may
  1081. Xprotect it by adding a blank line at the very top of the file. This dummy line
  1082. Xwill be removed from the message and the whole file will be sent as a body
  1083. Xpart.
  1084. X.PP
  1085. XHere is an example of a vacation file. We add a carbon copy as well as the
  1086. Xname of our organization in the header:
  1087. X.Ex
  1088. XOrganization: %o
  1089. XCc: ram
  1090. X
  1091. X[Last revision made on %T]
  1092. X
  1093. XDear %N:
  1094. X
  1095. XI've received your mail regarding "%R".
  1096. XIt will be read as soon as I come back from vacation.
  1097. X
  1098. XSincerely,
  1099. X--
  1100. X%U <%u@%C>
  1101. X.Ef
  1102. X.SH "VACATION MODE"
  1103. X.PP
  1104. XWhen it's time to take some vacation, it is possible to set up the mailagent
  1105. Xin vacation mode. Every \fIvacperiod\fR, the message \fIvacfile\fR will be
  1106. Xsent back to the user (with macros substitutions) if the user is explicitly
  1107. Xlisted in the \fITo\fR or \fICc\fR field and if the sender is not a special
  1108. Xuser (\fIroot\fR, \fIuucp\fR, \fInews\fR, \fIdaemon\fR, \fIpostmaster\fR,
  1109. X\fInewsmaster\fR, \fIusenet\fR, \fIMailer-Daemon\fR, \fIMailer-Agent\fR or
  1110. X\fInobody\fR).
  1111. XMatches are done in a case insensitive manner, so \fIMAILER-DAEMON\fR will also
  1112. Xbe recognized as a special user.
  1113. XFurthermore, any message tagged with a \fIPrecedence:\fR field set to
  1114. X\fIbulk\fR, \fIlist\fR
  1115. Xor \fIjunk\fR will not trigger a vacation message. This built-in
  1116. Xbehavior can of course be overloaded by suitable rules (by testing and
  1117. Xissuing the vacation message yourself via MESSAGE).
  1118. X.PP
  1119. XInternally, the mailagent uses a ONCE
  1120. Xcommand tagged \fI(%r, vacation, \$vacperiod)\fR. This implies you must not
  1121. Xuse the \fIvacation\fR tag in your own ONCE commands, unless you know what
  1122. Xyou are doing.
  1123. X.PP
  1124. XBesides, the vacation message is sent only if no "VACATION off" commands were
  1125. Xissued, or if another "VACATION on" overwrote the previous one. Note that
  1126. Xwhether a rule matched or not is irrelevant to the algorithm. By default, of
  1127. Xcourse, the vacation message is allowed when the \fIvacation\fR configuration
  1128. Xparameter is set to \fIon\fR.
  1129. X.PP
  1130. XIf you are not pleased by the fact that a vacation message is sent to people
  1131. Xwho addressed you a carbon copy only, then you may write at the top of your
  1132. Xrule file:
  1133. X.Ex
  1134. XCc: ram  { VACATION off; REJECT };
  1135. X.Ef
  1136. XOf course, you have to substitute your own login name in place of \fIram\fR.
  1137. XYou cannot use the same scheme to allow vacation messages to special
  1138. Xusers like \fIroot\fR, because the test for "specialness" occurs after the
  1139. Xvacation mode flag. This is construed as a feature as it prevents stupid
  1140. Xmistakes, like using \fIr*\fR instead of \fIram\fR in the previous rule.
  1141. X.SH VARIABLES
  1142. XThe following variables are paid attention to: they may come from the
  1143. Xenvironment or be set in the rule file:
  1144. X.TP 10
  1145. X.I mailfilter
  1146. Xindicates where loaded patterns are to be looked for, if the name of the
  1147. Xfile is not fully qualified. If it is not set, \fImaildir\fR will be used
  1148. Xinstead. If \fImaildir\fR is not set either, the home directory is used.
  1149. X.TP
  1150. X.I maildir
  1151. Xis the location of your mail folders. Any relative path is understood as
  1152. Xstarting from \fImaildir\fR. If it is not set, \fI~/Mail\fR is used.
  1153. X.SH "AUTOMATIC ACKNOWLEDGMENTS"
  1154. XAnywhere in the mail, there can be an @RR left-justified line which will
  1155. Xsend back an acknowledgment to the sender of the mail. The @RR may optionally
  1156. Xbe followed by an address, in which case the acknowledgment will be sent
  1157. Xto that address instead.
  1158. XIn fact (but let's keep that a secret), this is a way for me to be able to
  1159. END_OF_FILE
  1160.   if test 49983 -ne `wc -c <'agent/man/mailagent.SH.02'`; then
  1161.     echo shar: \"'agent/man/mailagent.SH.02'\" unpacked with wrong size!
  1162.   fi
  1163.   # end of 'agent/man/mailagent.SH.02'
  1164. fi
  1165. if test -f 'agent/pl/unpack.pl' -a "${1}" != "-c" ; then 
  1166.   echo shar: Will not clobber existing file \"'agent/pl/unpack.pl'\"
  1167. else
  1168.   echo shar: Extracting \"'agent/pl/unpack.pl'\" \(2083 characters\)
  1169.   sed "s/^X//" >'agent/pl/unpack.pl' <<'END_OF_FILE'
  1170. X;# $Id: unpack.pl,v 3.0 1993/11/29 13:49:18 ram Exp ram $
  1171. X;#
  1172. X;#  Copyright (c) 1990-1993, Raphael Manfredi
  1173. X;#  
  1174. X;#  You may redistribute only under the terms of the Artistic License,
  1175. X;#  as specified in the README file that comes with the distribution.
  1176. X;#  You may reuse parts of this distribution only within the terms of
  1177. X;#  that same Artistic License; a copy of which may be found at the root
  1178. X;#  of the source tree for mailagent 3.0.
  1179. X;#
  1180. X;# $Log: unpack.pl,v $
  1181. X;# Revision 3.0  1993/11/29  13:49:18  ram
  1182. X;# Baseline for mailagent 3.0 netwide release.
  1183. X;#
  1184. X;#
  1185. X# Expands an archive's name
  1186. Xsub expand {
  1187. X    local($path) = shift;        # The archive
  1188. X    # Look for extension of base path (eg: .cpio.Z)
  1189. X    local(@fullpath) = <${path}.*>;
  1190. X    if (-1 == $#fullpath) {
  1191. X        &clean_tmp;
  1192. X        &fatal("no archive file");
  1193. X    }
  1194. X    $path = $fullpath[0];        # Name with archive extension
  1195. X}
  1196. X
  1197. X# Unpack(path,dir,flag) restores archive `path' into `dir'
  1198. X# and returns the location of the main directory.
  1199. Xsub unpack {
  1200. X    local($path) = shift;        # The archive
  1201. X    local($dir) = shift;        # Storage place
  1202. X    local($compflag) = shift;    # Flag for compression (useful for short names)
  1203. X    local($unpack) = "";        # Will hold the restore command
  1204. X    $path = &expand($path);        # Name with archive extension
  1205. X    &add_log("archive is $path") if $loglvl > 19;
  1206. X    # First determine wether it is compressed
  1207. X    if ($compflag) {
  1208. X        $unpack = "zcat | ";
  1209. X    }
  1210. X    # Cpio or tar ?
  1211. X    if ($path =~ /\.tar/) {
  1212. X        $unpack .= "tar xof -";
  1213. X    } else {
  1214. X        $unpack .= "cpio -icmd";
  1215. X    }
  1216. X    system "< $path (cd $dir; $unpack)";
  1217. X    $path =~ s|.*/(\w+)|$1|;    # Keep only basename
  1218. X    local ($stat) = $?;            # Return status
  1219. X    if ($stat) {
  1220. X        &clean_tmp;
  1221. X        &fatal("unable to unpack $path");
  1222. X    }
  1223. X    &add_log("unpacked $path with \"$unpack\"") if $loglvl > 12;
  1224. X
  1225. X    # The top level directory is the only file in $dir
  1226. X    local(@top) = <${dir}/*>;
  1227. X    if ($#top < 0) {
  1228. X        &clean_tmp;
  1229. X        &fatal("$prog_name: no top-level dir for $path");
  1230. X    }
  1231. X    if ($#top > 0) {
  1232. X        &add_log("WARNING more than one file in $dir") if $loglvl > 4;
  1233. X    }
  1234. X    &add_log("top-level dir for $path is $top[0]") if $loglvl > 19;
  1235. X    $top[0];        # Top-level directory
  1236. X}
  1237. X
  1238. END_OF_FILE
  1239.   if test 2083 -ne `wc -c <'agent/pl/unpack.pl'`; then
  1240.     echo shar: \"'agent/pl/unpack.pl'\" unpacked with wrong size!
  1241.   fi
  1242.   # end of 'agent/pl/unpack.pl'
  1243. fi
  1244. echo shar: End of archive 2 \(of 26\).
  1245. cp /dev/null ark2isdone
  1246. MISSING=""
  1247. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ; do
  1248.     if test ! -f ark${I}isdone ; then
  1249.     MISSING="${MISSING} ${I}"
  1250.     fi
  1251. done
  1252. if test "${MISSING}" = "" ; then
  1253.     echo You have unpacked all 26 archives.
  1254.     echo "Now run 'sh PACKNOTES', then read README and type Configure.'"
  1255.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1256. else
  1257.     echo You still must unpack the following archives:
  1258.     echo "        " ${MISSING}
  1259. fi
  1260. exit 0
  1261.  
  1262. exit 0 # Just in case...
  1263.