home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-03 | 54.6 KB | 1,645 lines |
- Newsgroups: comp.sources.misc
- From: Raphael Manfredi <ram@acri.fr>
- Subject: v41i017: mailagent - Flexible mail filtering and processing package, v3.0, Part17/26
- Message-ID: <1993Dec3.213310.22471@sparky.sterling.com>
- X-Md4-Signature: a52515bcb2908f86200f38505242c4da
- Sender: kent@sparky.sterling.com (Kent Landfield)
- Organization: Advanced Computer Research Institute, Lyon, France.
- Date: Fri, 3 Dec 1993 21:33:10 GMT
- Approved: kent@sparky.sterling.com
-
- Submitted-by: Raphael Manfredi <ram@acri.fr>
- Posting-number: Volume 41, Issue 17
- Archive-name: mailagent/part17
- Environment: UNIX, Perl
- Supersedes: mailagent: Volume 33, Issue 93-109
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: Credits agent/files/agenthelp agent/filter/environ.c
- # agent/pl/header.pl agent/pl/lexical.pl agent/pl/newcmd.pl
- # agent/test/Makefile.SH agent/test/actions
- # Wrapped by ram@soft208 on Mon Nov 29 16:49:57 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 17 (of 26)."'
- if test -f 'Credits' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Credits'\"
- else
- echo shar: Extracting \"'Credits'\" \(6672 characters\)
- sed "s/^X//" >'Credits' <<'END_OF_FILE'
- XINTRO
- X
- XThis version of mailagent has been written by Raphael Manfredi based on
- Xprevious work from Larry Wall, published in dist-2.0.
- X
- XHISTORY
- X
- XThe mailagent history is somewhat linked to the dist package history. When
- XI discovered dist-2.0 in August 1990 and began extending metaconfig and the
- Xpat tools, I also began extending Larry Wall's mailagent, which was included
- Xin dist-2.0 along with the mailpatch command.
- X
- XI started adding mailhelp, maildist and maillist because I needed them, and
- Xthen left France in March 1991 to go write an Eiffel compiler until March 1993.
- XSince I was getting a lot of mail at ISE, I felt the need for a real mail
- Xfilter and not just an @SH command processor. Moreover, I was getting tired of
- Xhaving "Command mails" showing in my mailbox. The only mail filter I knew at
- Xthat time was ELM's, and it was not meeting my requirements.
- X
- XTherefore, I started extending mailagent late 1991 up to the point where it
- Xbecame a real and flexible mail filter (according to my standards anyway)
- Xand since I thought others would like to play with it too, I released it
- Xas a beta 3.0 (known as version 2.9) on comp.sources.misc in July 1992 after
- X7 months of hard work.
- X
- XI got a lot of positive feedback on this program, and therefore I continued
- Xto extend it. I also began to see some limitations in the 2.9 version and
- Xstarted adding new features (like perl escapes, user-defined commands,
- Xetc...). I originally intended to make version 3.0 part of dist-3.0, but
- Xmailagent was starting to get a life of its own and not really a part of dist.
- XHowever, @SH commands like ``package'' are meant to be used in conjunction
- Xwith metaconfig, one of dist's components.
- X
- XIn March 1993, I left ISE and returned to France to join A.C.R.I.. Although
- Xmailagent-3.0 was virtually finished by that time, I needed to release dist-3.0
- Xfirst due to some intensive user-pressure ;-). It's only late October 1993 that
- XI found the time to finalize the manual page and add all the small features
- Xstacked in my TODO list...
- X
- XCREDITS
- X
- XMy first thanks will go to Larry Wall <lwall@netlabs.com> who wrote perl
- Xin the first place. I would never have dreamed of implementing mailagent
- Xfrom scratch if perl had not been invented.
- X
- XThen I'd like to thank all the early mailagent users for their useful input,
- Xsuggestions, encouragement, contributions, constructive criticism or bug
- Xreports, and especially (by alphabetical order on the first name):
- X
- X Akihiro Hashimoto <cik1a03@dominic.ipc.chiba-u.ac.jp>
- X Andrew Hardie <ash@cellar.demon.co.uk>
- X Andy Glew <glew@ichips.intel.com>
- X Arthur Siffert <siffert@spot.Colorado.EDU>
- X Bertrand Meyer <bertrand@eiffel.com>
- X Bill Campbell <billc@sierra.com>
- X Bill Wohler <wohler@hw1175.sap-ag.de>
- X Bjoern Stabell <bjoerns@stud.cs.uit.no>
- X Brent Chapman <brent@GreatCircle.COM>
- X CJ Canon <Clement.J.Canon@arp.anu.edu.au>
- X Charles A. Lind <lind@eng.umd.edu>
- X Chris Lewis <clewis@ferret.ocunix.on.ca>
- X Christian Bertin <bertin@acri.fr>
- X Christoph von Stuckrad <stucki@math.fu-berlin.de>
- X Christopher Davis <ckd@eff.org>
- X Dan O'Neill <dano@Cadence.COM>
- X Dan Pierson <pierson@kukri.enet.dec.com>
- X Darrell Schiebel <dschieb@muse.cv.nrao.edu>
- X David Giddy <d.giddy@trl.oz.au>
- X David Vincenzetti <vince@dsi.unimi.it>
- X David W. Tamkin <dattier@ddsw1.mcs.com>
- X Edward Feustel <efeustel@ida.org>
- X Eric M. Carroll <eric@enfm.utcc.utoronto.ca>
- X Erland Unruh <Erland.Unruh@malmo.trab.se>
- X Forrest Aldrich <visgraph!forrie>
- X Geoffrey Hart <ghart@ems.cdc.com>
- X George Entenman <ge@mcnc.org>
- X George Smith <gbs@stratus.swdc.stratus.com>
- X George W. Wood <wood@ibmoto.com>
- X Graham Stoney <greyham@research.canon.oz.au>
- X Henry Kautz <kautz@research.att.com>
- X J. Mark Noworolski <jmn@crown.Berkeley.EDU>
- X JJ Lay <csjjlay@knuth.mtsu.edu>
- X James Ault <aultj@rpi.edu>
- X Jan Polcher <polcher@lmd.ens.fr>
- X Jan-Piet Mens <jpm@Logix.DE>
- X Janna Wemekamp <jw@cxcbr.cx.oz.au>
- X Jean-Marc Calvez <calvez@acri.fr>
- X Jean-Marc Eurin <eurin@acri.fr>
- X Jim McCoy <mccoy@ccwf.cc.utexas.edu>
- X John Plate <plate@infotek.dk>
- X Jost Krieger <x920031@rubb.rz.ruhr-uni-bochum.de>
- X Keith Pyle <keith@ibmoto.com>
- X Keith Rose <rose@ultryx.com>
- X Kent Landfield <kent@imd.sterling.com>
- X Kresten Krab Thorup <krab@iesd.auc.dk>
- X Larry W. Virden <lvirden@cas.org>
- X Mark Allman <mallman@oucsace.cs.ohiou.edu>
- X Mark Kristie <clueless@camelot.bradley.edu>
- X Mats Lidell <Mats.Lidell@eua.ericsson.se>
- X Matthew Simmons <zarthac@camelot.bradley.edu>
- X Michael Elkins <michael@jarthur.Claremont.EDU>
- X Michael Peppler <mpeppler@itf0.itf.ch>
- X NW Thomson <nige@kauri.vuw.ac.nz>
- X Nigel Metheringham <nigelm@ohm.york.ac.uk>
- X Ofer Inbar <cos@chaos.cs.brandeis.edu>
- X Pascal Poissonnier <ppoisson@acri.fr>
- X Patrick Labbaye <labbaye@acri.fr >
- X Paul Raines <raines@bohr.physics.upenn.edu>
- X Peter J Diaz de Leon <peter@miller.cs.uwm.edu>
- X Peter N. Wan <peter@cc.gatech.edu>
- X Ralf E. Stranzenbach <ralf@reswi.en.open.de>
- X Richard Schneider <rschneid@erc.epson.com>
- X Robert Brown <robertb@Barra.COM>
- X Scott A. McIntyre <scott@shrug.dur.ac.uk>
- X Scott Blachowicz <scott@statsci.com>
- X Scott Robinson <shr@ichips.intel.com>
- X Scott Schwartz <schwartz@groucho.cs.psu.edu>
- X Sean Casey <sean@ms.uky.edu>
- X Shigeya Suzuki <shigeya@foretune.co.jp>
- X Soumendra Daas <dos@remus.ee.byu.edu>
- X Sterling IMD <root@imd.sterling.com>
- X Steve Hill <steveh@okam.corp.sgi.com>
- X Syd Weinstein <syd@dsinc.dsi.com>
- X Terry Hull <terry@eece.ksu.edu>
- X Thomas Richter <richter@chemie.fu-berlin.de>
- X Thunder-Thumbs <siffert@rintintin.Colorado.EDU>
- X Tom Christiansen <tchrist@wraeththu.cs.colorado.edu>
- X Tom Limoncelli <tom_limoncelli@Warren.MENTORG.COM>
- X Tom Zheng <tzheng@cs.purdue.edu>
- X Valery Alexeev <alexeev@math.utah.edu>
- X Wes Price <ww2@bullwinkle.ssc.gov>
- X Wolfram Schmidt <wschmidt@iao.fhg.de>
- X Yeung Chee Wai <cheewai@uxmail.ust.hk>
- X alexeev@math.utah.edu
- X drw@bourbaki.mit.edu
- X jim@morse.ilo.dec.com
- X rschneid@callisto.erc.epson.com
- X rsmith@proteus.arc.nasa.gov
- X s090@brems.ii.uib.no
- X sondeen@ISI.EDU
- X wschmidt@iao.fhg.de
- X
- XIf I forgot your name, please let me know, and accept my apologies -- not
- Xnecessarily in that order ;-).
- X
- XDeepest thanks go to:
- X
- X Christian Bertin <bertin@acri.fr>
- X Eric M. Carroll <eric@enfm.utcc.utoronto.ca>
- X Graham Stoney <greyham@research.canon.oz.au>
- X Jean-Marc Eurin <eurin@acri.fr>
- X
- Xfor their active contributions, with a special mention to Jean-Marc Eurin
- Xfor carefully reviewing the release, installing it and proofreading the (long)
- Xmanual page before my official posting to comp.sources.misc.
- X
- XFinally, thank you Shigeya Suzuki <shigeya@foretune.co.jp> for hosting the
- Xagent-users mailing list. Send mail to majordomo@foretune.co.jp to subscribe.
- X
- X Raphael Manfredi <ram@acri.fr>
- X Lyon, France, December 1993
- END_OF_FILE
- if test 6672 -ne `wc -c <'Credits'`; then
- echo shar: \"'Credits'\" unpacked with wrong size!
- fi
- # end of 'Credits'
- fi
- if test -f 'agent/files/agenthelp' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/files/agenthelp'\"
- else
- echo shar: Extracting \"'agent/files/agenthelp'\" \(6402 characters\)
- sed "s/^X//" >'agent/files/agenthelp' <<'END_OF_FILE'
- XThe purpose of the mail agent is to enable me answer some of your
- Xrequests, even if it's early in the morning and I've just gone to bed ! :-)
- X
- XFor instance, you need Larry Wall's patch program or Rich Salz's cshar.
- XI have them and I use them in my own kits. So you may ask me to send them
- Xto you. Of course, you could send me a mail saying "Please, could you
- Xsend me the cshar distribution kit ?", but I certainly won't be able to do
- Xit at once , either because I am not there when the mail arrives, or
- Xbecause someone else asked before you...
- X
- XWith the mail agent, there are no problems. You simply (!) send me a mail
- Xof the following form:
- X
- X Subject: Command
- X @SH maildist =DEST= cshar 3.0
- X
- Xand you will get version 3.0 of cshar.
- X
- X
- XHere are the possible commands:
- X
- X - mailhelp PATH
- X # sends some help
- X
- X - maillist PATH
- X # sends a list of what is available
- X
- X - mailpatch PATH SYSTEM VERSION LIST
- X # sends patches for a system
- X
- X - maildist PATH SYSTEM VERSION
- X # sends a whole distribution kit (latest patchlevel)
- X
- Xwhere PATH is a return path FROM ME TO YOU either in Internet notation
- Xor in bang notation from some well-known host. As far as you are
- Xconcerned, it appears to be =DEST=.
- X
- XPATH may be omitted for mailhelp and maillist, in which case the return
- Xaddress found in the mail header will be used.
- X
- XSYSTEM is the system's name and VERSION is the version number. For
- Xsystems that are not maintained, the version number has no sense and
- Xthus may be omitted (for maildist). A '-' stands for the latest version.
- X
- XThe LIST for mailpatch is the number of one or more patches you need,
- Xseparated by spaces, commas, and/or hyphens. For instance:
- X
- X 2,3 4-7,10-
- X
- Xasks for patches 2 and 3, then 4 to 7, and from 10 to the end, while
- X
- X -5 10 11
- X
- Xrequests patches up to 5, then 10 and 11.
- X
- X
- XCommands must be preceded by the token "@SH" at the beginning of a line.
- XDo not put spaces/tabs in front of "@SH". In the mail examples I give,
- XI do put one, but it is only for clarity purpose.
- X
- XIn the same way, the line "Subject: Command" must be left-justified.
- XNote that the subject of the mail does not need to be "Command", as long
- Xas you put the "Subject: Command" line in the body of your message,
- Xbefore your commands. You may use either "Command" or "command".
- X
- XOnce the "Subject: Command" line appears in your mail, either in the
- Xheader or in the body, you may put as many commands as necessary.
- XFor example:
- X
- X Subject: Command
- X
- X @SH maillist =DEST=
- X @SH maildist =DEST= cshar 3.0
- X
- X
- XIf you are in doubt of what is the return path, you may put "PATH" or a
- Xsingle '-' instead of your address, and the mail agent will replace it
- Xwith the return path it finds in the mail header. In case you do not
- Xtrust your mail headers, you may force the return path with the "@PATH"
- Xcommand. The mail agent reads the whole message before actually
- Xprocessing it, so the location of this command does not really matters.
- XHere is an example:
- X
- X Subject: Command
- X
- X @SH mailhelp
- X @SH mailpatch - kit 2.0 4,5
- X @PATH =DEST=
- X
- X
- XWhen you ask for files to be sent, the mail agent makes shell archives or
- Xkit archives, depending on the amount of bytes that are to be returned.
- XIf it exceeds an arbitrary-fixed limit of =MAXSIZE= bytes, files are sent
- Xas kit archives. Otherwise, they will be sent as shell archives provided
- Xthat no file is greater than the maximum allowed for a single shell
- Xarchive. This is called the "auto" packing mode.
- X
- XThe "@PACK" command forces the distribution mode, which is "auto" by
- Xdefault. The specified packing mode is used, until another "@PACK"
- Xcommand is found. Valid parameters are "auto", "kit" and "shar".
- XNote that forcing mode to "shar" may well result in a failure if one
- Xof the files to be sent is bigger than the maximum size allowed for a
- Xshell-archive (around 50000 bytes). However, the mail agent does its
- Xbest: it will split large files and uuencode non-ASCII ones.
- X
- XWhen you use maildist, please do not request for "shar" mode, as "kit" will
- Xbe more efficient and safer. Note that when the packing mode is "auto" and
- Xthe mailagent has to kit the files, a minikit is included. Hence you may
- Xunkit the distribution even if you do not have kit. But it will always be
- Xsimpler with kit anyway.
- X
- X"Kit" is a binary tar-mailer that you must own in order to unkit
- Xthe kit archives which do not include a 'minikit'. If you do not have it,
- Xsend me the following mail:
- X
- X Subject: Command
- X @SH maildist =DEST= kit -
- X
- Xand you will get the latest release of "kit".
- X
- XHere is another example that uses the "@PACK" request (the following
- Xpackage names, revision numbers and patchlevels are here for the purpose
- Xof demonstration only. Reality may -- and often will -- be completely
- Xdifferent):
- X
- X Subject: Command
- X
- X -- Set the return path, so that we can use '-' without fear.
- X @PATH =DEST=
- X -- Request patches for kit 2.0, sent in "auto" packing mode.
- X -- Note that the '-' actually stands for the return path.
- X -- We could also have said:
- X -- @SH mailpatch =DEST= kit 2.0 3-
- X -- but as long as we have more than one command in the file,
- X -- it would be cumbersome to repeat the address each time.
- X @SH mailpatch - kit 2.0 3-
- X -- Force packing mode to "shar", as we don't want to kit 'kit'.
- X -- We don't know what the latest version is, so we put a '-'.
- X -- Maildist will send the version at its highest patchlevel.
- X @PACK shar
- X @SH maildist - kit -
- X -- Kit is more reliable and will greatly reduce the amount of
- X -- transmitted data (typical gain is 50% for sources).
- X @PACK kit
- X -- We want version 2.0 for dist and nothing else.
- X @SH maildist - dist 2.0
- X -- Request all patches for the latest version of matrix
- X @SH mailpatch - matrix - 1-
- X
- X
- XA nice thing with the mail agent is that you can ask for a receipt, in
- Xorder to be sure that I received your mail. You may do so by placing
- Xthe "@RR" command at the beginning of any line in the body of your
- Xmessage. A receipt will then be sent to the return path extracted from
- Xthe header. You may force the receipt to be sent to a given address by
- Xgiving it after the @RR token. Saying "@RR PATH" or "@RR -" is possible
- Xbut not very different from a single "@RR" !!
- X
- XHere are valid requests:
- X
- X @RR
- X @RR =DEST=
- X @RR login@cpu.domain.top
- X
- XNote that no "Subject: Command" line is necessary for that, so you may
- Xask for receipts in every mail.
- X
- X
- XIf this help file is not clear enough, or if you have suggestions/questions,
- Xfeel free to ask me.
- END_OF_FILE
- if test 6402 -ne `wc -c <'agent/files/agenthelp'`; then
- echo shar: \"'agent/files/agenthelp'\" unpacked with wrong size!
- fi
- # end of 'agent/files/agenthelp'
- fi
- if test -f 'agent/filter/environ.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/filter/environ.c'\"
- else
- echo shar: Extracting \"'agent/filter/environ.c'\" \(6445 characters\)
- sed "s/^X//" >'agent/filter/environ.c' <<'END_OF_FILE'
- X/*
- X
- X ###### # # # # # ##### #### # # ####
- X # ## # # # # # # # # ## # # #
- X ##### # # # # # # # # # # # # # #
- X # # # # # # # ##### # # # # # ### #
- X # # ## # # # # # # # # ## ### # #
- X ###### # # ## # # # #### # # ### ####
- X
- X Environment setting.
- X*/
- X
- X/*
- X * $Id: environ.c,v 3.0 1993/11/29 13:48:07 ram Exp ram $
- X *
- X * Copyright (c) 1990-1993, Raphael Manfredi
- X *
- X * You may redistribute only under the terms of the Artistic License,
- X * as specified in the README file that comes with the distribution.
- X * You may reuse parts of this distribution only within the terms of
- X * that same Artistic License; a copy of which may be found at the root
- X * of the source tree for mailagent 3.0.
- X *
- X * $Log: environ.c,v $
- X * Revision 3.0 1993/11/29 13:48:07 ram
- X * Baseline for mailagent 3.0 netwide release.
- X *
- X */
- X
- X#include "config.h"
- X#include "portable.h"
- X#include "hash.h"
- X#include <stdio.h>
- X
- X#ifdef I_STRING
- X#include <string.h>
- X#else
- X#include <strings.h>
- X#endif
- X#include "confmagic.h"
- X
- X#define ENV_VARS 200 /* An average number of environment vars */
- X#define MAX_STRING 4096 /* Maximum size for an environment value */
- X
- X/* The environment is stored as an associative array: the key is the variable's
- X * name, and we store the value as the associated value, of course. This is
- X * not suitable for direct passing to a child, but it eases the environment
- X * modifications.
- X */
- Xprivate struct htable henv; /* The associative array for env */
- X
- Xextern char *malloc(); /* Memory allocation */
- Xextern char *strsave(); /* String saving */
- X
- Xpublic void print_env(fd, envp)
- XFILE *fd;
- Xchar **envp;
- X{
- X /* Print the environment held in 'envp' on file 'fd'. This is mainly
- X * intended for debug purposes.
- X */
- X
- X while (*envp)
- X fprintf(fd, "%s\n", *envp++);
- X}
- X
- Xpublic int init_env(envp)
- Xchar **envp;
- X{
- X /* Initializes the associative array with the current environment. Returns
- X * 0 if ok, -1 if failed due to a lack of memory.
- X */
- X
- X char env_line[MAX_STRING + 1]; /* The environment line */
- X char *ptr; /* Pointer inside env_line */
- X char *env; /* The current environment line */
- X
- X if (-1 == ht_create(&henv, ENV_VARS))
- X return -1; /* Cannot create H table */
- X
- X while (env = *envp++) {
- X strncpy(env_line, env, MAX_STRING);
- X ptr = index(env_line, '=');
- X if (ptr == (char *) 0) {
- X add_log(6, "WARNING bad environment line");
- X continue;
- X }
- X *ptr = '\0'; /* Before '=' lies the key */
- X if ((char *) 0 == ht_put(&henv, env_line, ptr + 1)) {
- X add_log(4, "ERROR cannot record environment any more");
- X return -1;
- X }
- X }
- X
- X return 0; /* Ok */
- X}
- X
- Xpublic int append_env(key, value)
- Xchar *key;
- Xchar *value;
- X{
- X /* Appends 'value' at the end of the environment variable 'key', if it
- X * already exits, otherwise create it with that value.
- X * Returns 0 for success, -1 for failure.
- X */
- X
- X char env_line[MAX_STRING + 1]; /* Then environment line */
- X char *cval; /* Current value */
- X
- X cval = ht_value(&henv, key);
- X if (cval == (char *) 0) {
- X if ((char *) 0 == ht_put(&henv, key, value)) {
- X add_log(1, "ERROR cannot insert environment variable '%s'", key);
- X return -1; /* Insertion failed */
- X }
- X return 0; /* Insertion ok */
- X }
- X
- X strncpy(env_line, cval, MAX_STRING);
- X if (strlen(env_line) + strlen(value) > MAX_STRING) {
- X add_log(1, "ERROR cannot append to environment variable '%s'", key);
- X return -1;
- X }
- X strcat(env_line, value);
- X if ((char *) 0 == ht_force(&henv, key, env_line)) {
- X add_log(1, "ERROR cannot update environment variable '%s'", key);
- X return -1;
- X }
- X
- X return 0; /* Ok */
- X}
- X
- Xpublic int prepend_env(key, value)
- Xchar *key;
- Xchar *value;
- X{
- X /* Prepends 'value' at the head of the environment variable 'key', if it
- X * already exits, otherwise create it with that value.
- X * Returns 0 for success, -1 for failure.
- X */
- X
- X char env_line[MAX_STRING + 1]; /* Then environment line */
- X char *cval; /* Current value */
- X
- X cval = ht_value(&henv, key);
- X if (cval == (char *) 0) {
- X if ((char *) 0 == ht_put(&henv, key, value)) {
- X add_log(1, "ERROR cannot insert environment variable '%s'", key);
- X return -1; /* Insertion failed */
- X }
- X return 0; /* Insertion ok */
- X }
- X
- X strncpy(env_line, value, MAX_STRING);
- X if (strlen(env_line) + strlen(cval) > MAX_STRING) {
- X add_log(1, "ERROR cannot prepend to environment variable '%s'", key);
- X return -1;
- X }
- X strcat(env_line, cval);
- X if ((char *) 0 == ht_force(&henv, key, env_line)) {
- X add_log(1, "ERROR cannot update environment variable '%s'", key);
- X return -1;
- X }
- X
- X return 0; /* Ok */
- X}
- X
- Xpublic int set_env(key, value)
- Xchar *key;
- Xchar *value;
- X{
- X /* Set environment value 'key' and return 0 for success, -1 for failure. */
- X
- X char env_line[MAX_STRING + 1]; /* Then environment line */
- X char *cval; /* Current value */
- X
- X cval = ht_value(&henv, key);
- X if (cval == (char *) 0) {
- X if ((char *) 0 == ht_put(&henv, key, value)) {
- X add_log(1, "ERROR cannot insert environment variable '%s'", key);
- X return -1; /* Insertion failed */
- X }
- X return 0; /* Insertion ok */
- X }
- X
- X if ((char *) 0 == ht_force(&henv, key, value)) {
- X add_log(1, "ERROR cannot update environment variable '%s'", key);
- X return -1;
- X }
- X
- X return 0; /* Ok */
- X}
- X
- Xpublic char **make_env()
- X{
- X /* Create the environment pointer suitable for the execle() system call.
- X * Return a null pointer if there is not enough memory to create the
- X * environment.
- X */
- X
- X char env_line[MAX_STRING + 1]; /* The environment line */
- X char **envp; /* The environment pointer returned */
- X char **ptr; /* Pointer in the environment */
- X int nb_line; /* Number of lines */
- X
- X nb_line = ht_count(&henv) + 1; /* Envp ends with a null pointer */
- X if (nb_line == 0) {
- X add_log(6, "NOTICE environment is empty");
- X return (char **) 0;
- X }
- X envp = (char **) malloc(nb_line * sizeof(char *));
- X if (envp == (char **) 0)
- X fatal("out of memory");
- X
- X if (-1 == ht_start(&henv))
- X fatal("environment H table botched");
- X
- X ptr = envp;
- X for (ptr = envp; --nb_line > 0; (void) ht_next(&henv), ptr++) {
- X sprintf(env_line, "%s=%s", ht_ckey(&henv), ht_cvalue(&henv));
- X *ptr = strsave(env_line);
- X if (*ptr == (char *) 0)
- X fatal("no more memory for environment");
- X }
- X
- X *ptr = (char *) 0; /* Environment is NULL terminated */
- X
- X return envp; /* Pointer to new environment */
- X}
- X
- END_OF_FILE
- if test 6445 -ne `wc -c <'agent/filter/environ.c'`; then
- echo shar: \"'agent/filter/environ.c'\" unpacked with wrong size!
- fi
- # end of 'agent/filter/environ.c'
- fi
- if test -f 'agent/pl/header.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/header.pl'\"
- else
- echo shar: Extracting \"'agent/pl/header.pl'\" \(6455 characters\)
- sed "s/^X//" >'agent/pl/header.pl' <<'END_OF_FILE'
- X;# $Id: header.pl,v 3.0 1993/11/29 13:48:49 ram Exp ram $
- X;#
- X;# Copyright (c) 1990-1993, Raphael Manfredi
- X;#
- X;# You may redistribute only under the terms of the Artistic License,
- X;# as specified in the README file that comes with the distribution.
- X;# You may reuse parts of this distribution only within the terms of
- X;# that same Artistic License; a copy of which may be found at the root
- X;# of the source tree for mailagent 3.0.
- X;#
- X;# $Log: header.pl,v $
- X;# Revision 3.0 1993/11/29 13:48:49 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- Xpackage header;
- X
- X# This package implements a header checker. To initialize it, call 'reset'.
- X# Then, call 'valid' with a header line and the function returns 0 if the
- X# line is not part of a header (which means all the lines seen since 'reset'
- X# are not part of a mail header). If the line may still be part of a header,
- X# returns 1. Finally, -1 is returned at the end of the header.
- X
- Xsub init {
- X # Main header fields which should be looked at when parsing a mail header
- X %Mailheader = (
- X 'From', 1,
- X 'To', 1,
- X 'Subject', 1,
- X 'Date', 1,
- X );
- X}
- X
- X# Reset header checking status
- Xsub reset {
- X &init unless $init_done++; # Initialize private data
- X $last_was_header = 0; # Previous line was not a header
- X $maybe = 0; # Do we have a valid part of header?
- X $line = 0; # Count number of lines in header
- X}
- X
- X# Is the current line still part of a valid header ?
- Xsub valid {
- X local($_) = @_;
- X return 1 if $last_was_header && /^\s/; # Continuation line
- X return -1 if /^$/; # End of header
- X $last_was_header = /^([\w\-]+):/ ? 1 : 0;
- X # Activate $maybe when essential parts of a valid mail header are found
- X # Any client can check 'maybe' to see if what has been parsed so far would
- X # be a valid RFC-822 header, even though syntactically correct.
- X $maybe |= $Mailheader{$1} if $last_was_header;
- X $last_was_header = /^From\s+\S+/
- X unless $last_was_header || $line; # First line may be special
- X ++$line; # One more line
- X $last_was_header; # Are we still inside header?
- X}
- X
- X# Produce a warning header field about a specific item
- Xsub warning {
- X local($field, $added) = @_;
- X local($warning);
- X local(@field) = split(' ', $field);
- X $warning = 'X-Filter-Note: ';
- X if ($added && @field == 1) {
- X $warning .= "Header $field added at ";
- X } elsif ($added && @field > 1) {
- X $field = join(', ', @field);
- X $field =~ s/^(.*), (.*)/$1 and $2/;
- X $warning .= "Headers $field added at ";
- X } else {
- X $warning .= "Parsing error in original previous line at ";
- X }
- X $warning .= &main'domain_addr;
- X $warning;
- X}
- X
- X# Make sure header contains vital fields. The header is held in an array, on
- X# a line basis with final new-line chopped. The array is modified in place,
- X# setting defaults from the %Header array (if defined, which is the case for
- X# digests mails) or using local defaults.
- Xsub clean {
- X local(*array) = @_; # Array holding the header
- X local($added) = ''; # Added fields
- X
- X $added .= &check(*array, 'From', $cf'user, 1);
- X $added .= &check(*array, 'To', $cf'user, 1);
- X $added .= &check(*array, 'Date', &fake_date, 0);
- X $added .= &check(*array, 'Subject', '<none>', 1);
- X
- X &push(*array, &warning($added, 1)) if $added ne '';
- X}
- X
- X# Check presence of specific field and use value of %Header as a default if
- X# available and if '$use_header' is set, otherwise use the provided value.
- X# Return added field or a null string if nothing is done.
- Xsub check {
- X local(*array, $field, $default, $use_header) = @_;
- X local($faked); # Faked value to be used
- X if ($use_header) {
- X $faked = (defined $'Header{$field}) ? $'Header{$field} : $default;
- X } else {
- X $faked = $default;
- X }
- X
- X # Try to locate field in header
- X local($_);
- X foreach (@array) {
- X return '' if /^$field:/;
- X }
- X
- X &push(*array, "$field: $faked");
- X $field . ' ';
- X}
- X
- X# Push header line at the end of the array, without assuming any final EOH line
- Xsub push {
- X local(*array, $line) = @_;
- X local($last) = pop(@array);
- X push(@array, $last) if $last ne ''; # There was no EOH
- X push(@array, $line); # Insert header line
- X push(@array, '') if $last eq ''; # Restore EOH
- X}
- X
- X# Compute a valid date field suitable for mail header
- Xsub fake_date {
- X require 'ctime.pl';
- X local($date) = &'ctime(time);
- X # Traditionally, MTAs add a ',' right after week day
- X $date =~ s/^(\w+)(\s)/$1,$2/;
- X chop($date); # Ctime adds final new-line
- X $date;
- X}
- X
- X# Normalizes header: every first letter is uppercase, the remaining of the
- X# word being lowercased, as in This-Is-A-Normalized-Header. Note that RFC-822
- X# does not impose such a formatting.
- Xsub normalize {
- X local($field_name) = @_; # Header to be normalized
- X $field_name =~ s/(\w+)/\u\L$1/g;
- X $field_name; # Return header name with proper case
- X}
- X
- X# Format header field to fit into 78 columns, each continuation line being
- X# indented by 8 chars. Returns the new formatted header string.
- Xsub format {
- X local($field) = @_; # Field to be formatted
- X local($tmp); # Buffer for temporary formatting
- X local($new) = ''; # Constructed formatted header
- X local($kept); # Length of current line
- X local($len) = 78; # Amount of characters kept
- X local($cont) = ' ' x 8; # Continuation lines starts with 8 spaces
- X # Format header field, separating lines on ',' or space.
- X while (length($field) > $len) {
- X $tmp = substr($field, 0, $len); # Keep first $len chars
- X $tmp =~ s/^(.*)([,\s]).*/$1$2/; # Cut at last space or ,
- X $kept = length($tmp); # Amount of chars we kept
- X $tmp =~ s/\s*$//; # Remove trailing spaces
- X $tmp =~ s/^\s*//; # Remove leading spaces
- X $new .= $cont if $new; # Continuation starts with 8 spaces
- X $len = 70; # Account continuation for next line
- X $new .= "$tmp\n";
- X $field = substr($field, $kept, 9999);
- X }
- X $new .= $cont if $new; # Add 8 chars if continuation
- X $new .= $field; # Remaining information on one line
- X}
- X
- X# Scan the head of a file and try to determine whether there is a mail
- X# header at the beginning or not. Return true if a header was found.
- Xsub main'header_found {
- X local($file) = @_;
- X local($correct) = 1; # Were all the lines from top correct ?
- X local($_);
- X open(FILE, $file) || return 0; # Don't care to report error
- X &reset; # Initialize header checker
- X while (<FILE>) { # While still in a possible header
- X last if /^$/; # Exit if end of header reached
- X $correct = &valid($_); # Check line validity
- X last unless $correct; # No, not a valid header
- X }
- X close FILE;
- X $correct;
- X}
- X
- Xpackage main;
- X
- END_OF_FILE
- if test 6455 -ne `wc -c <'agent/pl/header.pl'`; then
- echo shar: \"'agent/pl/header.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/header.pl'
- fi
- if test -f 'agent/pl/lexical.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/lexical.pl'\"
- else
- echo shar: Extracting \"'agent/pl/lexical.pl'\" \(6447 characters\)
- sed "s/^X//" >'agent/pl/lexical.pl' <<'END_OF_FILE'
- X;# $Id: lexical.pl,v 3.0 1993/11/29 13:48:55 ram Exp ram $
- X;#
- X;# Copyright (c) 1990-1993, Raphael Manfredi
- X;#
- X;# You may redistribute only under the terms of the Artistic License,
- X;# as specified in the README file that comes with the distribution.
- X;# You may reuse parts of this distribution only within the terms of
- X;# that same Artistic License; a copy of which may be found at the root
- X;# of the source tree for mailagent 3.0.
- X;#
- X;# $Log: lexical.pl,v $
- X;# Revision 3.0 1993/11/29 13:48:55 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- X#
- X# Lexical parsing of the rules
- X#
- X
- X# The following subroutine is called whenever a new rule input is needed.
- X# It returns that new line or a null string if end of file has been reached.
- Xsub read_filerule {
- X <RULES>; # Read a new line from file
- X}
- X
- X# The following subroutine is called in place of read_rule when rules are
- X# coming from the command line via @Linerules.
- Xsub read_linerule {
- X $.++; # One more line
- X shift(@Linerules); # Read a new line from array
- X}
- X
- X# Assemble a whole rule in one line and return it. The end of a line is
- X# marked by a ';' at the end of an input line.
- Xsub get_line {
- X local($result) = ""; # what will be returned
- X local($in_braces) = 0; # are we inside braces ?
- X for (;;) {
- X $_ = &read_rule; # new rule line (pseudo from compile_rules)
- X last if $_ eq ''; # end of file reached
- X s/\n$//; # don't use chop in case we read from array
- X next if /^\s*#/; # skip comments
- X next if /^\s*$/; # skip empty lines
- X s/\s\s+/ /; # reduce white spaces
- X $result .= $_;
- X # Very simple braces handling
- X /.*{/ && ($in_braces = 1);
- X if ($in_braces) {
- X /.*}/ && ($in_braces = 0);
- X }
- X last if !$in_braces && /;\s*$/;
- X }
- X $result;
- X}
- X
- X# Get optional mode (e.g. <TEST>) at the beginning of the line and return
- X# it, or ALL if none was present. A mode can be negated by pre-pending a '!'.
- Xsub get_mode {
- X local(*line) = shift(@_); # edited in place
- X local($_) = $line; # make a copy of original
- X local($mode) = "ALL"; # default mode
- X s/^\s*<([\s\w,!]+)>// && ($mode = $1);
- X $mode =~ s/\s//g; # no spaces in returned mode
- X $line = $_; # eventually updates the line
- X $mode;
- X}
- X
- X# A selector is either a script or a list of header fields ending with a ':'.
- Xsub get_selector {
- X local(*line) = shift(@_); # edited in place
- X local($_) = $line; # make a copy of original
- X local($selector) = "";
- X s/^\s*,//; # remove rule separator
- X if (/^\s*\[\[/) { # detected a script form
- X $selector = 'script:';
- X } else {
- X s/^\s*([^\/,{\n]*(<[\d\s,-]+>)?\s*:)// && ($selector = $1);
- X }
- X $line = $_; # eventually updates the line
- X $selector;
- X}
- X
- X# A pattern if either a single word (with no white space) or something
- X# starting with a / and ending with an un-escaped / followed by some optional
- X# modifiers.
- X# Patterns may be preceded by a single '!' to negate the matching value.
- Xsub get_pattern {
- X local(*line) = shift(@_); # edited in place
- X local($_) = $line; # make a copy of original
- X local($pattern) = ""; # the recognized pattern
- X local($buffer) = ""; # the buffer used for parsing
- X local($not) = ''; # shall boolean value be negated?
- X s|^\s*||; # remove leading spaces
- X s/^!// && ($not = '!'); # A leading '!' inverts matching status
- X if (s|^\[\[([^{]*)\]\]||) { # pattern is a script
- X $pattern = $1; # get the whole script
- X } elsif (s|^/||) { # pattern starts with a /
- X $pattern = "/"; # record the /
- X while (s|([^/]*/)||) { # while there is something before a /
- X $buffer = $1; # save what we've been reading
- X $pattern .= $1;
- X last unless $buffer =~ m|\\/$|; # finished unless / is escaped
- X }
- X s/^(\w+)// && ($pattern .= $1); # add optional modifiers
- X } else { # pattern does not start with a /
- X s/([^\s,;{]*)// && ($pattern = $1); # grab all until next delimiter
- X }
- X $line = $_; # eventually updates the line
- X $pattern =~ s/\s+$//; # remove trailing spaces
- X if ($not && !$pattern) {
- X &add_log("ERROR discarding '!' not followed by pattern") if $loglvl;
- X } else {
- X $pattern = $not . $pattern;
- X }
- X $pattern;
- X}
- X
- X# Extract the action part from the line (by editing it in place) and return
- X# the first action encountered. Nesting of {...} blocks may occur.
- Xsub get_action {
- X local(*line) = shift(@_); # edited in place
- X local($_) = $line; # make a copy of original
- X return '' unless s/^\s*\{/{/;
- X local($action) = &action_parse(*_, 0);
- X &add_log("ERROR no action, discarding '$_'") if $loglvl && $action eq '';
- X $line = $_; # eventually update the line
- X $action =~ s/^\{\s*//; # remove leading and trailing braces
- X $action =~ s/\s*\}$//;
- X $action; # return new action block
- X}
- X
- X# Recursively parse the action string and return the parsed portion of the text
- X# with proper nesting wherever necessary. The string given as parameter is
- X# edited in place and the remaining is the unparsed part.
- Xsub action_parse {
- X local(*_) = shift(@_); # edited in place
- X local($level) = shift(@_); # recursion level
- X local($parsed) = ''; # the part we parsed so far
- X local($block); # block recognized
- X local($follow); # recursion string returned
- X for (;;) {
- X # Go to first un-escaped '{', if possible and save leading string
- X # up-to first '{'. Note that any '}' immediately stops scanning.
- X s/^(([^\\{}]|\\.)*{)// && ($parsed .= $1);
- X # Go to first un-escaped '}', with any '{' stopping scan.
- X $block = '';
- X s/^(([^\\{}]|\\.)*\})// && ($block = $1);
- X $parsed .= $block; # block may be empty, or has trailing '}'
- X if ($parsed =~ s/\{$//) { # recursion if '{' found
- X $follow = &action_parse(*_, $level + 1);
- X # If a null string is returned, then no matching '}' was found
- X &add_log("WARNING no closing brace (added for you)")
- X if $follow eq '' && $loglvl > 5;
- X $parsed .= '{' . $follow . '}';
- X } elsif (s/^\}//) { # reached end of a block
- X &add_log("WARNING extra closing brace ignored")
- X if $level == 0 && $loglvl > 5;
- X return $parsed;
- X } else {
- X # Get the whole string until the next '}' and return. If a '{'
- X # interposes, the first match will return an empty string. In that
- X # case, we continue if we are not at level #0. Otherwise we got the
- X # whole action and may return now.
- X $block = '';
- X s/^(([^\\{}]|\\.)*\})// && ($block = $1);
- X if ($block eq '' && $level) { # Advance until '{'
- X s/^(([^\\}]|\\.)*\{)// && ($block = $1);
- X $parsed .= $block;
- X next;
- X }
- X $block =~ s/\}//;
- X return $parsed . $block;
- X }
- X }
- X}
- X
- END_OF_FILE
- if test 6447 -ne `wc -c <'agent/pl/lexical.pl'`; then
- echo shar: \"'agent/pl/lexical.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/lexical.pl'
- fi
- if test -f 'agent/pl/newcmd.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/newcmd.pl'\"
- else
- echo shar: Extracting \"'agent/pl/newcmd.pl'\" \(6409 characters\)
- sed "s/^X//" >'agent/pl/newcmd.pl' <<'END_OF_FILE'
- X;# $Id: newcmd.pl,v 3.0 1993/11/29 13:49:03 ram Exp ram $
- X;#
- X;# Copyright (c) 1990-1993, Raphael Manfredi
- X;#
- X;# You may redistribute only under the terms of the Artistic License,
- X;# as specified in the README file that comes with the distribution.
- X;# You may reuse parts of this distribution only within the terms of
- X;# that same Artistic License; a copy of which may be found at the root
- X;# of the source tree for mailagent 3.0.
- X;#
- X;# $Log: newcmd.pl,v $
- X;# Revision 3.0 1993/11/29 13:49:03 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- X;# This package handles the dynamic loading of a perl script in memory,
- X;# providing a dynamic way of enhancing the command set of the mailagent.
- X;#
- X;# New commands are specified in the newcmd file specified in the config file.
- X;# The syntax of this file is the following:
- X;#
- X;# <cmd_name> <path> <function> [<status_flag> [<seen_flag>]]
- X;#
- X;# cmd_name: this is the command name, eg. RETURN_SENDER
- X;# path: this is the path to the perl script implementing the command.
- X;# function: the perl function within the script which implements the command
- X;# status_flag: states whether the command modifies the execution status
- X;# seen_flag: states whether the command is allowed in _SEEN_ mode
- X;#
- X;# The last two booleans are optional, and may be specified as either 'yes'
- X;# and 'no' or 'true' and 'false'. Their default value is respectively true
- X;# and false.
- X;#
- X;# New commands are loaded as they are used and put in a special newcmd
- X;# package, so that the names of the routines do not conflict with the
- X;# mailagent's one. They are free to use whatever function the mailagent
- X;# implements by prefixing the routine name with its package: normally, the
- X;# execution of the command is done from within the newcmd package.
- X;#
- X;# Commands are given a single argument: the string forming the command name.
- X;# Therefore, the command may implement the syntax it wishes. However, for
- X;# the user convenience, the special array @newcmd'argv is preset with a
- X;# shell-style parsed version. The mailagent also initializes the same
- X;# special variables as the one set for PERL commands, only does it put them
- X;# in the newcmd package instead of mailhook.
- X;#
- X;# Several data structures are maintained by this package:
- X;# %Usercmd, maps a command name to a file
- X;# %Loaded, records whether a file has been loaded or not
- X;# %Run, maps a command name to a perl function
- X;#
- X
- Xpackage newcmd;
- X
- X#
- X# User-defined commands
- X#
- X
- X# Parse the newcmd file and record all new commands in the mailagent data
- X# structures.
- Xsub load {
- X return unless -s $cf'newcmd; # Empty or non-existent file
- X
- X # Security checks. We cannot extend the mailagent commands if the file
- X # describing those new commands is not owned by the user or ir world
- X # writable. Indeed, someone could redefine default commands like LEAVE
- X # and use that to break into the user account.
- X return unless &'file_secure($cf'newcmd, 'new command');
- X
- X unless (open(NEWCMD, $cf'newcmd)) {
- X &'add_log("ERROR cannot open $cf'newcmd: $!") if $'loglvl;
- X &'add_log("WARNING new commands not loaded") if $'loglvl > 5;
- X return;
- X }
- X
- X local($home) = $cf'home;
- X $home =~ s/(\W)/\\$1/g; # Escape possible meta-characters like '+'
- X
- X local($_);
- X local($cmd, $path, $function, $status, $seen);
- X while (<NEWCMD>) {
- X next if /^\s*#/; # Skip comments
- X next if /^\s*$/; # Skip blank lines
- X ($cmd, $path, $function, $status, $seen) = split(' ');
- X $cmd =~ tr/a-z/A-Z/; # Cannonicalize to upper-case
- X $path =~ s/~/$cf'home/; # Perform ~ substitution
- X unless (-e $path && -r _) {
- X $path =~ s/^$home/~/;
- X &'add_log("ERROR command '$cmd' bound to unreadable file $path")
- X if $'loglvl > 1;
- X next; # Skip invalid command
- X }
- X # Load command into data structures by setting internal tables
- X $'Filter{$cmd} = "newcmd'run"; # Main dispatcher for new commands
- X $Usercmd{$cmd} = $path; # Record command path
- X $Loaded{$path} = 0; # File not loaded yet
- X $Run{$cmd} = $function; # Perl function to call
- X $'Nostatus{$cmd} = 1 if $status =~ /^f|n/i;
- X $'Rfilter{$cmd} = 1 unless $seen =~ /^t|y/i;
- X &interface'add($cmd); # Add interface for perl hooks
- X
- X $path =~ s/^$home/~/;
- X &'add_log("new command $cmd in $path (&$function)")
- X if $'loglvl > 18;
- X }
- X close NEWCMD;
- X}
- X
- X# This is the main dispatcher for user-defined command.
- X# Our caller 'run_command' has set up some special variables, like $mfile
- X# and $cmd_name, which are used here. Someday, I'll have to encapsulate that
- X# in a better way--RAM.
- Xsub run {
- X # Make global variables visible in this package. Variables which should
- X # not be changed are marked 'read only'.
- X local($cmd) = $'cmd; # Full command line (read only)
- X local($cmd_name) = $'cmd_name; # Command name (read only)
- X local($mfile) = $'mfile; # File name (read only)
- X local(*ever_saved) = *'ever_saved; # Saving already occurred?
- X local(*cont) = *'cont; # Continuation status
- X local(*vacation) = *'vacation; # Vacation message allowed?
- X local(*lastcmd) = *'lastcmd; # Last failure status stored
- X local(*wmode) = *'wmode; # Filter mode
- X
- X &'add_log("user-defined command $cmd_name") if $'loglvl > 15;
- X
- X # Let's see if we already have loaded the perl script which is responsible
- X # for implementing this command.
- X local($path) = $Usercmd{$cmd_name};
- X unless ($path) {
- X &'add_log("ERROR unknown user-defined command $cmd_name") if $'loglvl;
- X return 1; # Command failed (should not happen)
- X }
- X local($function) = $Run{$cmd_name};
- X
- X unless (&dynload'load('newcmd', $path, $function)) {
- X &'add_log("ERROR cannot load code for user-defined $cmd_name")
- X if $'loglvl;
- X return 1; # Command failed
- X }
- X
- X # At this point, we know we have some code to call in order to run the
- X # user-defined command. Prepare the special array @ARGV and initialize
- X # the mailhook variable in the current package.
- X &hook'initvar('newcmd'); # Initialize convenience variables
- X local(@ARGV); # Argument vector for command
- X require 'shellwords.pl';
- X eval '@ARGV = &shellwords($cmd)';
- X
- X # We don't need to protect the following execution within an eval, since
- X # we are currently inside one, via run_command.
- X local($failed) = &$function($cmd); # Call user-defined function
- X
- X # Log our action
- X local($msg) = $failed ? "and failed" : "successfully";
- X &'add_log("ran $cmd_name [$mfile] $msg") if $'loglvl > 6;
- X
- X $failed; # Propagate failure status
- X}
- X
- Xpackage main;
- X
- END_OF_FILE
- if test 6409 -ne `wc -c <'agent/pl/newcmd.pl'`; then
- echo shar: \"'agent/pl/newcmd.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/newcmd.pl'
- fi
- if test -f 'agent/test/Makefile.SH' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/Makefile.SH'\"
- else
- echo shar: Extracting \"'agent/test/Makefile.SH'\" \(3702 characters\)
- sed "s/^X//" >'agent/test/Makefile.SH' <<'END_OF_FILE'
- X: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL14]
- X: $X-Id: Jmake.tmpl,v 3.0.1.1 1993/08/20 07:36:36 ram Exp ram $
- X
- Xcase $CONFIG in
- X'')
- X if test -f config.sh; then TOP=.;
- X elif test -f ../config.sh; then TOP=..;
- X elif test -f ../../config.sh; then TOP=../..;
- X elif test -f ../../../config.sh; then TOP=../../..;
- X elif test -f ../../../../config.sh; then TOP=../../../..;
- X else
- X echo "Can't find config.sh."; exit 1
- X fi
- X . $TOP/config.sh
- X ;;
- Xesac
- Xcase "$0" in
- X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
- Xesac
- XCURRENT=agent/test
- XDIR=`echo $CURRENT/ | sed -e 's/\.\///g'`
- Xecho "Extracting ${DIR}Makefile (with variable substitutions)"
- XDATE=`date`
- X$spitshell >Makefile <<!GROK!THIS!
- X########################################################################
- X# Makefile generated from Makefile.SH on $DATE
- X
- XSHELL = /bin/sh
- XJMAKE = jmake
- XTOP = ../..
- XCURRENT = $CURRENT
- XDIR = $DIR
- X
- X########################################################################
- X# Parameters set by Configure -- edit config.sh if changes are needed
- X
- XCTAGS = ctags
- XMAKE = make
- XMV = $mv
- XRM = $rm -f
- X
- X!GROK!THIS!
- X$spitshell >>Makefile <<'!NO!SUBS!'
- X########################################################################
- X# Jmake rules for building libraries, programs, scripts, and data files
- X# $X-Id: Jmake.rules,v 3.0 1993/08/18 12:04:14 ram Exp ram $
- X
- X########################################################################
- X# Start of Jmakefile
- X
- X# $X-Id: Jmakefile,v 2.9.1.1 92/08/02 16:14:36 ram Exp $
- X#
- X# Copyright (c) 1990-1993, Raphael Manfredi
- X#
- X# You may redistribute only under the terms of the Artistic License,
- X# as specified in the README file that comes with the distribution.
- X# You may reuse parts of this distribution only within the terms of
- X# that same Artistic License; a copy of which may be found at the root
- X# of the source tree for mailagent 3.0.
- X#
- X# $X-Log$
- X
- Xall::
- X @echo "The following may take a while..."
- X @echo "Don't panic if any of these tests fails and do not stop make."; \
- X ./TEST
- X @if test -f OK; then \
- X echo "Failure detected, retrying one more time, just in case..."; \
- X echo "Successful tests will not be rerun but flagged as 'done'."; \
- X sleep 2; \
- X ./TEST; \
- X if test -f OK; then \
- X echo "Hmm... Still failed... There might be a real problem."; \
- X echo "I shall be using the plain (non dataloaded) version."; \
- X sleep 2;\
- X ./TEST -n; \
- X fi \
- X fi
- X
- Xtest:
- X ./TEST -i
- X
- Xlocal_clean::
- X $(RM) -r out
- X $(RM) OK
- X
- X########################################################################
- X# Common rules for all Makefiles -- do not edit
- X
- Xemptyrule::
- X
- Xclean: local_clean
- Xrealclean: local_realclean
- Xclobber: local_clobber
- X
- Xlocal_clean::
- X $(RM) core *~ *.o
- X
- Xlocal_realclean:: local_clean
- X
- Xlocal_clobber:: local_realclean
- X $(RM) Makefile config.sh
- X
- XMakefile.SH: Jmakefile
- X -@if test -f $(TOP)/.package; then \
- X if test -f Makefile.SH; then \
- X echo " $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \
- X $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \
- X fi; \
- X echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \
- X $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \
- X else touch $@; exit 0; fi
- X
- XMakefile: Makefile.SH
- X /bin/sh Makefile.SH
- X
- Xtags::
- X $(CTAGS) -w *.[ch]
- X $(CTAGS) -xw *.[ch] > tags
- X
- Xlocal_clobber::
- X $(RM) tags
- X
- X########################################################################
- X# Empty rules for directories with no sub-directories -- do not edit
- X
- Xinstall::
- X @echo "install in $(CURRENT) done."
- X
- Xdeinstall::
- X @echo "deinstall in $(CURRENT) done."
- X
- Xinstall.man::
- X @echo "install.man in $(CURRENT) done."
- X
- Xdeinstall.man::
- X @echo "deinstall.man in $(CURRENT) done."
- X
- XMakefiles::
- X
- XMakefiles.SH::
- X
- X!NO!SUBS!
- Xchmod 644 Makefile
- X$eunicefix Makefile
- X
- END_OF_FILE
- if test 3702 -ne `wc -c <'agent/test/Makefile.SH'`; then
- echo shar: \"'agent/test/Makefile.SH'\" unpacked with wrong size!
- fi
- # end of 'agent/test/Makefile.SH'
- fi
- if test -f 'agent/test/actions' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/actions'\"
- else
- echo shar: Extracting \"'agent/test/actions'\" \(6572 characters\)
- sed "s/^X//" >'agent/test/actions' <<'END_OF_FILE'
- X#
- X# Mailagent rules for action regression tests
- X#
- X
- X# $Id: actions,v 3.0 1993/11/29 13:49:23 ram Exp ram $
- X#
- X# Copyright (c) 1990-1993, Raphael Manfredi
- X#
- X# You may redistribute only under the terms of the Artistic License,
- X# as specified in the README file that comes with the distribution.
- X# You may reuse parts of this distribution only within the terms of
- X# that same Artistic License; a copy of which may be found at the root
- X# of the source tree for mailagent 3.0.
- X#
- X# $Log: actions,v $
- X# Revision 3.0 1993/11/29 13:49:23 ram
- X# Baseline for mailagent 3.0 netwide release.
- X#
- X
- Xmaildir = ~;
- X
- XX-Tag: /abort/
- X{
- X ABORT -f;
- X SAVE always;
- X ABORT;
- X SAVE %u.1;
- X}
- X
- XX-Tag: /annotate/
- X{
- X ANNOTATE X-Anno-1: first;
- X ANNOTATE X-Anno-2 second;
- X ANNOTATE X-Anno-3;
- X ANNOTATE -d X-Anno-Error;
- X ANNOTATE -d X-Anno-4 fourth;
- X}
- X
- XX-Tag: /apply/ { APPLY apply.1; REJECT -t APPLY; SAVE never };
- X<IMPOSSIBLE> { SAVE never; REJECT APPLY };
- X<APPLY> { APPLY apply.2; REJECT -f; SAVE always };
- X<APPLY> { SAVE never };
- X
- XX-Tag: /assign #1/,
- XTo: /^(\w+)@/
- X{
- X ASSIGN ram %1;
- X ASSIGN other try;
- X ASSIGN final '%#other.2';
- X ASSIGN :ram 1 + 2;
- X RUN /bin/echo '%#ram,%#other,%#final' > output';
- X}
- X
- XX-Tag: /assign #2/
- X{
- X ASSIGN :ram %#:ram + 4;
- X ASSIGN other '1+2';
- X ASSIGN final %#other + 4;
- X RUN /bin/echo '%#:ram,%#other,%#final' > output';
- X}
- X
- XX-Tag: /back/
- X{
- X BACK RUN ~/pgm;
- X}
- X
- XX-Tag: /begin/
- X{
- X BEGIN ONE;
- X BEGIN TWO;
- X REJECT;
- X}
- X
- X<ONE> { SAVE one };
- X<ONE,TWO,THREE> { SAVE two; BEGIN THREE; REJECT };
- X<THREE> { SAVE three };
- X
- XX-Tag: /bounce 1/ { BOUNCE nobody };
- XX-Tag: /bounce 2/ { BOUNCE "list" };
- X
- XX-Tag: /delete/ { DELETE };
- X
- XX-Tag: /feed/
- X{
- X FEED grep -v To:;
- X SAVE ok;
- X REJECT;
- X}
- X
- XX-Tag: /feed/, To: ram { SAVE no_resync };
- X
- XX-Tag: /forward 1/ { FORWARD nobody };
- XX-Tag: /forward 2/ { FORWARD "list" };
- X
- XX-Tag: /give/ { GIVE wc > output };
- X
- XX-Tag: /keep/
- X{
- X KEEP From: To Subject X-None X-Long-* U*;
- X KEEP To Subject X-Long-* From X-None U*;
- X KEEP X-Long-*: Unu*-Head* X-None: To: Subject: From:;
- X KEEP "header-list" From;
- X SAVE ok;
- X REJECT;
- X}
- XX-Tag: /keep/, To: ram { SAVE no_resync };
- X
- XX-Tag: /message/ { MESSAGE msg; DELETE };
- X
- XX-Tag: /macro/
- X{
- X MACRO first It seems to;
- X MACRO first Another instance;
- X MACRO -p first;
- X MACRO second null;
- X MACRO -r second = ('work fine', EXPR);
- X MACRO third toto;
- X MACRO -d third;
- X RUN /bin/echo %-(first) %-(second)%-(third). > ok;
- X DELETE;
- X}
- X
- XX-Tag: /nop/ { NOP; DELETE };
- X
- XX-Tag: /notify 1/ { NOTIFY msg nobody; DELETE };
- XX-Tag: /notify 2/ { NOTIFY msg "list"; DELETE };
- X
- XX-Tag: /once/
- X{
- X ONCE (ram,tag,1w) SAVE one;
- X ONCE (ram,tag,1w) SAVE two;
- X ONCE (mars,tag,1w) SAVE three;
- X ONCE (other,tag,0m) SAVE four;
- X}
- X
- XX-Tag: /pass/
- X{
- X PASS grep -v and;
- X SAVE output;
- X}
- X
- XX-Tag: /perl/ { REJECT PERL };
- X<PERL> { PERL perl.1; SAVE never };
- X<PERL> { PERL perl.2 'arg 1' "arg 2"; SAVE never };
- X<PERL> { PERL perl.1; SAVE never };
- X<PERL> { PERL no_such_file; ABORT -f; SAVE never };
- X
- XX-Tag: /pipe/ { PIPE wc > output };
- X
- XX-Tag: /post 1/ { POST alt.test comp.others };
- XX-Tag: /post 2/ { POST -l "list" };
- X
- XX-Tag: /purify/
- X{
- X PURIFY grep -v Subject:;
- X SAVE output;
- X}
- X
- XX-Tag: /queue/ { QUEUE; QUEUE; QUEUE; QUEUE };
- X
- XX-Tag: /record #1/ { RECORD; SAVE %u.1 };
- XX-Tag: /record #1/ { SAVE %u.1 };
- X<_SEEN_> X-Tag: /record #1/ { SAVE %u.2 };
- X<RECORD> X-Tag: /record #2/ { SAVE %u.3 };
- XX-Tag: /record #2/ { RECORD -r RECORD; SAVE %u.1 };
- XX-Tag: /record #3/ { RECORD -a; SAVE %u.1 };
- XX-Tag: /record #4/ { RECORD -c; REJECT -f RECORD; SAVE %u.1 };
- X<RECORD> X-Tag: /record #4/ { SAVE %u.2 };
- X
- XX-Tag: /require/ { REJECT REQUIRE; };
- X<REQUIRE> { REQUIRE non_existent; REJECT -f; SAVE never };
- X<REQUIRE> { REQUIRE perl.1; REJECT -t; SAVE never };
- X<REQUIRE> { REQUIRE perl.1; REJECT -t; SAVE never };
- X<REQUIRE> { REQUIRE perl.2 test_pack; REJECT -t; SAVE never };
- X<REQUIRE>
- X{
- X MACRO perl_1 = (newcmd'perl_1, FN);
- X MACRO perl_2 = (&test_pack'perl_2, EXPR);
- X RUN /bin/echo We got %-(perl_1) and %-(perl_2) here > ok;
- X DELETE;
- X};
- X
- XX-Tag: /reject/ { REJECT REJ; SAVE %u.1 };
- X<REJ> X-Tag: /reject/ { SAVE always; REJECT -t REJ; SAVE never };
- X
- X<INITIAL> X-Tag: /restart/ { RESTART -t RES; SAVE %u.1; REJECT };
- X<RES> X-Tag: /restart/ { RESTART no_such_mode; SAVE never };
- X
- XX-Tag: /resync/,
- XTo: ram
- X{
- X PURIFY grep -v To:;
- X RESYNC;
- X REJECT;
- X}
- X
- XX-Tag: /resync/, To: ram { SAVE %u.1 };
- XX-Tag: /resync/ { SAVE output };
- X
- XX-Tag: /run/ { RUN /bin/echo Works. > ok; DELETE };
- X
- XX-Tag: /save #1/ { SAVE mbox };
- XX-Tag: /save #2/ { SAVE path/another/third/mbox };
- X
- XX-Tag: /select/
- X{
- X SELECT (Jan 2 1970 .. Jan 1 2001) SAVE one;
- X SELECT (last month .. last minute) SAVE two;
- X SELECT (last minute .. next minute) SAVE three;
- X SELECT (now - 10 seconds .. now + 5 minutes) SAVE four;
- X SELECT (Jan 1 2001 .. Jan 2 1970) SAVE five;
- X}
- X
- XX-Tag: /unknown #1/ { unknown_command; DELETE };
- XX-Tag: /unknown #2/ { DELETE; unknown_command };
- X
- XX-Tag: /split #1/ { SPLIT here; SAVE here };
- XX-Tag: /split #2/ { SPLIT -ida here };
- XX-Tag: /split #3/ { SPLIT -iew here };
- XX-Tag: /split #4/ { SPLIT -iew };
- XX-Tag: /split #5/ { SPLIT -iew here };
- XX-Tag: /digest/ { SAVE here };
- X
- XX-Tag: /store #1/ { STORE mbox };
- XX-Tag: /store #2/ { STORE path/another/third/mbox };
- X
- XX-Tag: /strip/
- X{
- X STRIP X-N* Received:;
- X STRIP Received;
- X STRIP X-N* "header-list";
- X SAVE ok;
- X REJECT;
- X}
- XX-Tag: /strip/, To: ram { SAVE no_resync };
- X
- XX-Tag: /subst/,
- XTo: /(.*)/
- X{
- X SUBST 1 /com/fr/g;
- X ASSIGN subject %[Subject];
- X ASSIGN :persistent '%#subject';
- X SUBST #subject /^Re:\s+//;
- X SUBST #:persistent /^Re:\s+//;
- X RUN /bin/echo '%1,%#subject,%#:persistent' >output;
- X DELETE;
- X}
- X
- XX-Tag: /tr/,
- XTo: /(.*)/
- X{
- X TR 1 /a-z/A-Z/;
- X ASSIGN subject %[Subject];
- X ASSIGN :persistent '%#subject';
- X TR #subject /ice/ICE/;
- X TR #:persistent /ice/ICE/;
- X RUN /bin/echo '%1,%#subject,%#:persistent' >output;
- X DELETE;
- X}
- X
- XX-Tag: /unique #1/ { UNIQUE; SAVE %u.1 };
- X<_SEEN_> X-Tag: /unique #1/ { SAVE %u.1 };
- XX-Tag: /unique #1/ { SAVE %u.2 };
- X<UNIQUE> X-Tag: /unique #2/ { SAVE %u.3 };
- XX-Tag: /unique #2/ { UNIQUE -r UNIQUE; SAVE %u.1 };
- XX-Tag: /unique #3/ { UNIQUE -a; SAVE %u.1 };
- XX-Tag: /unique #4/ { UNIQUE -c; REJECT -f UNIQUE; SAVE %u.1 };
- X<UNIQUE> X-Tag: /unique #4/ { SAVE %u.2 };
- X
- XX-Tag: /write #1/ { WRITE mbox };
- XX-Tag: /write #2/ { WRITE path/another/third/mbox };
- X
- XX-Tag: /compress/ { LEAVE; SAVE always; SAVE another };
- XX-Tag: /mmdf/ { LEAVE; SAVE always; SAVE always };
- XX-Tag: /newcmd/ { FIRST_CMD arg1 arg2; SECOND_CMD; DELETE };
- XX-Tag: /usrmac/ { PERL script; ABORT -f; DELETE };
- XX-Tag: /mh/ { SAVE +tmp; SAVE +new; SAVE dir; SAVE simple };
- END_OF_FILE
- if test 6572 -ne `wc -c <'agent/test/actions'`; then
- echo shar: \"'agent/test/actions'\" unpacked with wrong size!
- fi
- # end of 'agent/test/actions'
- fi
- echo shar: End of archive 17 \(of 26\).
- cp /dev/null ark17isdone
- MISSING=""
- 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
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 26 archives.
- echo "Now run 'sh PACKNOTES', then read README and type Configure.'"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
-
- exit 0 # Just in case...
-