home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-03 | 55.0 KB | 1,859 lines |
- Newsgroups: comp.sources.misc
- From: Raphael Manfredi <ram@acri.fr>
- Subject: v41i019: mailagent - Flexible mail filtering and processing package, v3.0, Part19/26
- Message-ID: <1993Dec3.213411.22706@sparky.sterling.com>
- X-Md4-Signature: 0fcb416ae11bbd7464c06ca92a7fdd14
- Sender: kent@sparky.sterling.com (Kent Landfield)
- Organization: Advanced Computer Research Institute, Lyon, France.
- Date: Fri, 3 Dec 1993 21:34:11 GMT
- Approved: kent@sparky.sterling.com
-
- Submitted-by: Raphael Manfredi <ram@acri.fr>
- Posting-number: Volume 41, Issue 19
- Archive-name: mailagent/part19
- 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: agent/files/help/Makefile.SH agent/files/mailagent.cf
- # agent/filter/main.c agent/man/Makefile.SH agent/pl/builtins.pl
- # agent/pl/mmdf.pl agent/pl/read_conf.pl agent/pl/rfc822.pl
- # agent/test/TEST agent/test/level agent/test/rules install.SH
- # 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 19 (of 26)."'
- if test -f 'agent/files/help/Makefile.SH' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/files/help/Makefile.SH'\"
- else
- echo shar: Extracting \"'agent/files/help/Makefile.SH'\" \(4413 characters\)
- sed "s/^X//" >'agent/files/help/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/files/help
- 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
- XINSTALL = ../../../install
- X
- X########################################################################
- X# Parameters set by Configure -- edit config.sh if changes are needed
- X
- XCTAGS = ctags
- XMAKE = make
- XMV = $mv
- XPRIVLIB = $installprivlib
- 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 92/07/14 16:47:32 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
- XFILES = addauth approve delpower end getauth help newpower \
- X passwd password power release remauth set setauth user
- X
- Xall::
- X
- Xall:: $(FILES)
- X
- Xlocal_realclean::
- X $(RM) $(FILES)
- X
- Xaddauth: addauth.SH
- X /bin/sh addauth.SH
- X
- Xapprove: approve.SH
- X /bin/sh approve.SH
- X
- Xdelpower: delpower.SH
- X /bin/sh delpower.SH
- X
- Xend: end.SH
- X /bin/sh end.SH
- X
- Xgetauth: getauth.SH
- X /bin/sh getauth.SH
- X
- Xhelp: help.SH
- X /bin/sh help.SH
- X
- Xnewpower: newpower.SH
- X /bin/sh newpower.SH
- X
- Xpasswd: passwd.SH
- X /bin/sh passwd.SH
- X
- Xpassword: password.SH
- X /bin/sh password.SH
- X
- Xpower: power.SH
- X /bin/sh power.SH
- X
- Xrelease: release.SH
- X /bin/sh release.SH
- X
- Xremauth: remauth.SH
- X /bin/sh remauth.SH
- X
- Xset: set.SH
- X /bin/sh set.SH
- X
- Xsetauth: setauth.SH
- X /bin/sh setauth.SH
- X
- Xuser: user.SH
- X /bin/sh user.SH
- X
- X
- Xinstall::
- X @for dir in $(PRIVLIB) $(PRIVLIB)/help; do \
- X case '${MFLAGS}' in *[i]*) set +e;; esac; \
- X (set -x; $(INSTALL) -d $$dir); \
- X done
- X
- Xdeinstall::
- X $(RM) -r $(PRIVLIB) $(PRIVLIB)/help
- X
- Xinstall:: $(FILES)
- X @case '${MFLAGS}' in *[i]*) set +e;; esac; \
- X for i in $(FILES); do \
- X (set -x; $(INSTALL) -c -m 444 $$i $(PRIVLIB)/help); \
- X done
- X
- Xdeinstall::
- X @case '${MFLAGS}' in *[i]*) set +e;; esac; \
- X for i in $(FILES); do \
- X (set -x; $(RM) $(PRIVLIB)/help/$$i); \
- X done
- 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 4413 -ne `wc -c <'agent/files/help/Makefile.SH'`; then
- echo shar: \"'agent/files/help/Makefile.SH'\" unpacked with wrong size!
- fi
- # end of 'agent/files/help/Makefile.SH'
- fi
- if test -f 'agent/files/mailagent.cf' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/files/mailagent.cf'\"
- else
- echo shar: Extracting \"'agent/files/mailagent.cf'\" \(4439 characters\)
- sed "s/^X//" >'agent/files/mailagent.cf' <<'END_OF_FILE'
- X#
- X# Configuration file for mailagent
- X#
- X
- X# $Id: mailagent.cf,v 3.0 1993/11/29 13:48:02 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: mailagent.cf,v $
- X# Revision 3.0 1993/11/29 13:48:02 ram
- X# Baseline for mailagent 3.0 netwide release.
- X#
- X
- X#
- X# Configuration section
- X#
- X
- X# Paramters likely to change
- Xhome : /lyon/ram # Home directory (must be correctly set)
- Xlevel : 9 # Logging level
- Xtmpdir : /tmp # Temporary directory to be used
- Xemergdir : ~/tmp/lost+mail # Emergency directory (for dumps)
- Xtrack : OFF # Track matches on stdout (on/off)
- X
- X# Minimum path to ensure and path depending on the machine
- Xpath : /bin:/usr/bin:/usr/ucb
- Xp_york : ~/bin:~/bin/rs2030
- Xp_lyon : ~/bin:~/bin/rs2030
- Xp_rome : ~/bin:~/bin/sun4:/base/common/GENERAL/sun4/bin
- X
- X# User who runs mailagent
- Xuser : ram
- Xname : Raphael
- X
- X# Vacation mode (on/off), vacation file and period
- Xvacation : OFF # Vacation mode on/off
- Xvacfile : ~/.vacation # File to be sent back
- Xvacperiod: 1d # Period between two vacation messages
- X
- X# Mail and news transport agents
- X# By default, values for sendmail and sendnews are determined at configuration
- X# time. The default mailopt is -odq when sendmail is used. The -h option is
- X# always added to the sendnews program to indicate headers are already present.
- Xsendmail : /usr/lib/sendmail
- Xsendnews : /usr/lib/news/inews
- Xmailopt : -odq
- Xnewsopt :
- X
- X
- X#
- X# Parameters which should not change very often
- X#
- X
- X# Define main configuration parameters
- Xspool : ~/var/mailagent # Spool directory
- Xqueue : $spool/queue # Queue directory (must exist)
- Xlogdir : ~/var/log # Where logfile is stored
- Xcontext : $spool/context # Mailagent's context file
- Xlog : agentlog # Log file is in $logdir
- Xseq : .seq # Seq file is in $spool
- Xtimezone : PST8PDT # Time zone location
- Xstatfile : $spool/mailagent.st # Statistics file
- Xrules : ~/.rules # Filter's rules location (optional)
- Xrulecache: $spool/rulecache # Cache for compiled rules (optional)
- Xnfslock : OFF # NFS-secure locking (optional)
- Xsecure : ON # Make extended checks on sensitive files
- X
- X# Mailbox parameters
- Xmaildrop : /usr/mail # System mail drop directory (optional)
- Xmailbox : $user # Mailbox file name (optional)
- Xmmdf : OFF # Allow MMDF-style mailbox delivery
- Xmmdfbox : OFF # Force new folders to MMDF format
- X
- X# MH-style folders
- Xmhprofile: ~/.mh_profile # Name of the MH profile file (optional)
- Xmsgprefix: .msg_prefix # File containing message name prefix
- X
- X# Optional parameters (for experts...)
- X#compress : ~/.compress # Folder compression list
- X#newcmd : $spool/newcmd # Definition of new filtering commands
- X#perlib : pl # Extended perl library search path
- X
- X# Database hashing directory (in $spool) and other controls
- Xhash : dbr # Hashing directory
- Xcleanlaps: 1M # Laps between cleanings
- Xautoclean: ON # Turn periodic cleaning on/off
- Xagemax : 1y # Maximum lifetime for entries
- X
- X#
- X# Parameters for SERVER
- X#
- X
- Xcomserver: $spool/server # Valid server commands
- Xservdir : $spool/cmds # Default path for perl server commands
- Xmaxerrors: 10 # Allow at most ten errors before flushing
- Xmaxcmds : 10 # Allow maximum of ten commands in one request
- Xscriptcc : ON # Send copy of sesssion transcripts to user?
- Xbqueue : $spool/batch # Batch queue (not implemented yet)
- Xpowers : $spool/powers # Directory for power administration
- Xpowerlog : $logdir/powerlog # Log requests for new powers
- Xpowerlist: $powers/aliases # Mapping of powers to filename in powerdir
- Xpowerdir : $powers/clearance # Directory listing user clearances for powers
- Xpasswd : $powers/passwd # Power passwords
- Xhelpdir : $spool/help # Help directory for server commands
- X
- X#
- X# Parameters for PROCESS
- X#
- X
- Xcomfile : $spool/commands # Valid commands
- Xdistlist : $spool/distribs # Distribution list
- Xproglist : $spool/proglist # Program description list
- Xmaxsize : 150000 # Maximum size before kiting
- Xplsave : $spool/plsave # Where patchlevels are saved
- Xauthfile : $spool/auth # Remote sending authorizations (not yet)
- END_OF_FILE
- if test 4439 -ne `wc -c <'agent/files/mailagent.cf'`; then
- echo shar: \"'agent/files/mailagent.cf'\" unpacked with wrong size!
- fi
- # end of 'agent/files/mailagent.cf'
- fi
- if test -f 'agent/filter/main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/filter/main.c'\"
- else
- echo shar: Extracting \"'agent/filter/main.c'\" \(4488 characters\)
- sed "s/^X//" >'agent/filter/main.c' <<'END_OF_FILE'
- X/*
- X
- X # # ## # # # ####
- X ## ## # # # ## # # #
- X # ## # # # # # # # #
- X # # ###### # # # # ### #
- X # # # # # # ## ### # #
- X # # # # # # # ### ####
- X
- X The main entry point.
- X*/
- X
- X/*
- X * $Id: main.c,v 3.0 1993/11/29 13:48:15 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: main.c,v $
- X * Revision 3.0 1993/11/29 13:48:15 ram
- X * Baseline for mailagent 3.0 netwide release.
- X *
- X */
- X
- X#include "config.h"
- X#include "portable.h"
- X
- X#ifdef I_STRING
- X#include <string.h>
- X#else
- X#include <strings.h>
- X#endif
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include "logfile.h"
- X#include "io.h"
- X#include "hash.h"
- X#include "msg.h"
- X#include "parser.h"
- X#include "sysexits.h"
- X#include "lock.h"
- X#include "confmagic.h"
- X
- X#define MAX_STRING 2048 /* Maximum string length */
- X
- Xprivate Signal_t handler(); /* Signal handler */
- Xprivate void set_signal(); /* Set up the signal handler */
- X
- Xextern void env_home(); /* Only for tests */
- X
- Xpublic void main(argc, argv, envp)
- Xint argc;
- Xchar **argv;
- Xchar **envp;
- X{
- X /* This is the main entry point for the mail filter */
- X
- X char *value; /* Symbol value */
- X int euid, uid; /* Current effective and real uid */
- X int egid, gid; /* Effective and real gid */
- X
- X /* Compute program name, removing any leading path to keep only the name
- X * of the executable file.
- X */
- X progname = rindex(argv[0], '/'); /* Only last name if '/' found */
- X if (progname++ == (char *) 0) /* There were no '/' */
- X progname = argv[0]; /* This must be the filename then */
- X progpid = getpid(); /* Program's PID */
- X
- X /* Security precautions. Look who we are and who we pretend to be */
- X uid = getuid();
- X gid = getgid();
- X euid = geteuid();
- X egid = getegid();
- X
- X /* The '-t' option means we are in test mode: set the home directory by
- X * using the environment HOME variable, so that we may provide our own
- X * configuration file elsewhere. Of course, this cannot be used if the
- X * filter is setuid and invoked by an uid different than the owner of the
- X * filter program.
- X */
- X if (argc > 1 && 0 == strcmp(argv[1], "-t")) {
- X if (uid != euid || gid != egid) {
- X fprintf(stderr, "filter: no option allowed when set%s\n",
- X uid != euid ? "uid" : "gid");
- X exit(EX_USAGE);
- X }
- X env_home(); /* Get HOME form environment */
- X }
- X
- X set_signal(); /* Set up signal handler */
- X read_conf(".mailagent"); /* Read configuration file */
- X
- X add_log(19, "starting processing");
- X
- X /* We'll be invoking a perl script with the -S switch, and perl will not
- X * allow us to do that if it detects "setuidness". Some sendmail programs
- X * are broken and do not reset the uid/gid correctly when they process
- X * their queue. This is why it is important to set the setuid and setgid
- X * bits on the filter program.
- X */
- X
- X /* Make sure our gid matches the effective gid */
- X if (egid != gid && -1 == setgid(egid)) {
- X add_log(1, "SYSERR setgid: %m (%e)");
- X add_log(4, "WARNING cannot set GID to %d, continuing as %d", egid, gid);
- X } else if (egid != gid)
- X add_log(6, "NOTICE reset GID from %d to %d", gid, egid);
- X
- X /* Make sure our uid matches the effective uid */
- X if (euid != uid && -1 == setuid(euid)) {
- X add_log(1, "SYSERR setuid: %m (%e)");
- X add_log(4, "WARNING cannot set UID to %d, continuing as %d", euid, uid);
- X } else if (euid != uid)
- X add_log(6, "NOTICE reset UID from %d to %d", uid, euid);
- X
- X value = ht_value(&symtab, "queue"); /* Fetch queue location */
- X if (value == (char *) 0)
- X fatal("queue directory not defined");
- X
- X set_env_vars(envp); /* Set environment variables */
- X process(); /* Process mail */
- X
- X exit(EX_OK); /* We did it */
- X}
- X
- Xprivate void set_signal()
- X{
- X /* Set up the signal handler */
- X
- X#ifdef SIGHUP
- X signal(SIGHUP, handler);
- X#endif
- X#ifdef SIGINT
- X signal(SIGINT, handler);
- X#endif
- X#ifdef SIGQUIT
- X signal(SIGQUIT, handler);
- X#endif
- X#ifdef SIGTERM
- X signal(SIGTERM, handler);
- X#endif
- X}
- X
- Xprivate Signal_t handler(sig)
- Xint sig;
- X{
- X /* A signal was caught */
- X
- X release_lock(); /* Release lock file if necessary */
- X fatal("caught signal #%d", sig);
- X}
- X
- END_OF_FILE
- if test 4488 -ne `wc -c <'agent/filter/main.c'`; then
- echo shar: \"'agent/filter/main.c'\" unpacked with wrong size!
- fi
- # end of 'agent/filter/main.c'
- fi
- if test -f 'agent/man/Makefile.SH' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/man/Makefile.SH'\"
- else
- echo shar: Extracting \"'agent/man/Makefile.SH'\" \(4062 characters\)
- sed "s/^X//" >'agent/man/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/man
- 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
- XINSTALL = ../../install
- X
- X########################################################################
- X# Parameters set by Configure -- edit config.sh if changes are needed
- X
- XCTAGS = ctags
- XL = $manext
- XMANSRC = $installmansrc
- XMAKE = make
- XMV = $mv
- XRM = $rm -f
- X
- X########################################################################
- X# Automatically generated parameters -- do not edit
- X
- XMANPAGE = \$(MPAGES)
- X
- X########################################################################
- X# New suffixes and associated building rules -- edit with care
- X
- X.SUFFIXES: .SH .$manext
- X
- X.SH.$manext:
- X /bin/sh \$<
- 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 92/07/14 16:49:04 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
- XMPAGES = mailagent.$(L) maildist.$(L) maillist.$(L) mailhelp.$(L) \
- X mailpatch.$(L) package.$(L)
- X
- Xall:: $(MPAGES)
- X
- Xlocal_realclean::
- X $(RM) $(MPAGES)
- X
- Xinstall.man::
- X @if test "$(MANSRC)"; then \
- X case '${MFLAGS}' in *[i]*) set +e;; esac; \
- X for file in $(MPAGES); do \
- X (set -x; $(INSTALL) -c -m 444 $$file $(MANSRC)); \
- X done; \
- X else exit 0; fi
- X
- Xdeinstall.man::
- X @if test "$(MANSRC)"; then \
- X case '${MFLAGS}' in *[i]*) set +e;; esac; \
- X for file in $(MPAGES); do \
- X (set -x; $(RM) $(MANSRC)/$$file); \
- X done; \
- X else exit 0; fi
- 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 4062 -ne `wc -c <'agent/man/Makefile.SH'`; then
- echo shar: \"'agent/man/Makefile.SH'\" unpacked with wrong size!
- fi
- chmod +x 'agent/man/Makefile.SH'
- # end of 'agent/man/Makefile.SH'
- fi
- if test -f 'agent/pl/builtins.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/builtins.pl'\"
- else
- echo shar: Extracting \"'agent/pl/builtins.pl'\" \(3583 characters\)
- sed "s/^X//" >'agent/pl/builtins.pl' <<'END_OF_FILE'
- X;# $Id: builtins.pl,v 3.0 1993/11/29 13:48:35 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: builtins.pl,v $
- X;# Revision 3.0 1993/11/29 13:48:35 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- X#
- X# Executing builtin commands
- X#
- X
- X# Send a receipt
- Xsub send_receipt {
- X local($subj) = $Header{'Subject'};
- X local($msg_id) = $Header{'Message-Id'};
- X local($from) = $Header{'From'};
- X local($sender) = $Header{'Reply-To'};
- X local($to) = $Header{'To'};
- X local($ack_dest) = @_; # Were to send receipt
- X local($dest); # Return path to be used (derived from mail)
- X
- X # If no @PATH directive was found, use $sender as a return path
- X $dest = $Userpath; # Set by an @PATH
- X $dest = $sender unless $dest;
- X # Remove the <> if any (e.g. path derived from Return-Path)
- X $dest =~ /<(.*)>/ && ($dest = $1);
- X
- X # Derive a correct return path for receipt
- X $ack_dest = 'PATH' if $ack_dest eq '-';
- X $ack_dest = "" if $ack_dest =~ /[=\$^&*([{}`\\|;><?]/;
- X $ack_dest = $dest if ($ack_dest eq '' || $ack_dest =~ /PATH/);
- X
- X # Compute host name (fully qualified, i.e. with domain name)
- X chop($hostname = `$phostname`);
- X $hostname .= $mydomain if $hostname =~ /^\w+$/;
- X
- X chop($date = `date`);
- X open(MAILER,"|$cf'sendmail $cf'mailopt $ack_dest");
- X print MAILER <<EOM;
- XTo: $ack_dest
- XSubject: Re: $subj (receipt)
- X$MAILER
- XEOM
- X if ($msg_id ne '') {
- X print MAILER "\nYour message $msg_id,\n";
- X } else {
- X print MAILER "\nYour message ";
- X }
- X print MAILER "addressed to $to,\n" if $to ne '';
- X print MAILER "whose subject was \"$subj\",\n" if $subj ne '';
- X print MAILER <<EOM;
- Xhas been received by $hostname on $date
- X
- X-- mailagent speaking for $cf'user
- XEOM
- X close MAILER;
- X if ($?) {
- X &add_log("ERROR couldn't send receipt to $ack_dest") if $loglvl > 0;
- X } else {
- X &add_log("SENT receipt to $ack_dest") if $loglvl > 2;
- X }
- X}
- X
- X#
- X# Deal with builtins
- X#
- X
- X# Built-in commands are listed herein. Those commands being built-in are always
- X# dealt with during mail parsing and are taken care of at the beginning of the
- X# rules analysis. The code to be executed for each builtin is stored in the
- X# Builtcode array by those routines.
- Xsub init_builtins {
- X %Builtin = (
- X 'RR', 'builtin_rr',
- X 'PATH', 'builtin_path'
- X );
- X undef @Builtcode;
- X}
- X
- X# Whenever a builtin command is recognized (on the fly) while parsing the mail
- X# body, the corresponding builtin function is called with the remaining of the
- X# line given as argument (leading spaces removed).
- X
- X# The @RR command asks for a receipt
- Xsub builtin_rr {
- X local($_) = @_;
- X &add_log("found an @RR request to $_") if $loglvl > 18;
- X # @RR request honored only if not from special user and directed to us
- X unless (&special_user) {
- X push(@Builtcode, "&send_receipt('$_')");
- X } else {
- X &add_log("ignoring @RR request to $_") if $loglvl > 4;
- X }
- X}
- X
- X# The @PATH command sets a valid return path (recorded in $Userpath)
- Xsub builtin_path {
- X local($_) = @_;
- X return if /[=\$^&*([{}`\\|;><?]/; # Invalid character found
- X $Userpath = $_;
- X &add_log("found an @PATH request to $_") if $loglvl > 18;
- X}
- X
- X# Execute stacked builtins
- Xsub run_builtins {
- X return if $#Builtcode < 0; # No recorded builtins
- X foreach (@Builtcode) {
- X eval($_); # Execute stacked builtin
- X }
- X @Builtcode = (); # Reset builtcode array
- X}
- X
- END_OF_FILE
- if test 3583 -ne `wc -c <'agent/pl/builtins.pl'`; then
- echo shar: \"'agent/pl/builtins.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/builtins.pl'
- fi
- if test -f 'agent/pl/mmdf.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/mmdf.pl'\"
- else
- echo shar: Extracting \"'agent/pl/mmdf.pl'\" \(4318 characters\)
- sed "s/^X//" >'agent/pl/mmdf.pl' <<'END_OF_FILE'
- X;# $Id: mmdf.pl,v 3.0 1993/11/29 13:49:02 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: mmdf.pl,v $
- X;# Revision 3.0 1993/11/29 13:49:02 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- X;# This set of routine handles MMDF-style mailboxes, which differ from the
- X;# traditional Unix-style boxes by encapsulating each message between 2 lines
- X;# of 4 ^A, one at the begining and one at the end. The leading From_ line is
- X;# consequently not needed and is removed.
- X;#
- X;# Note: this MMDF-style mailbox is also used by MH packed folders.
- X;#
- X#
- X# MMDF-style saving routines
- X#
- X
- Xpackage mmdf;
- X
- X# Attempt to save in a possible MMDF mailbox. The routine opens the mailbox
- X# and tries to determine what kind of mailbox it is, then selects the
- X# appropriate saving routine.
- Xsub save {
- X local(*FD, $mailbox) = @_; # File descriptor and mailbox name
- X if (&is_mmdf($mailbox)) { # Folder looks like an MMDF mailbox
- X &save_mmdf(*FD, 'MDF'); # Use MMDF format then
- X } else {
- X &save_unix(*FD); # Be conservative and use standard format
- X }
- X}
- X
- X# Save to a MMDF-style mailbox and return failure status with message length
- X# Can also be used to save MH messages if parameter $mmdf set to 'MH' (in which
- X# case the two ^A delimiter lines are ommitted).
- Xsub save_mmdf {
- X local(*FD, $mmdf) = @_; # File descriptor, MH/MDF format
- X local($amount) = 0; # Amount of bytes saved
- X local($failed);
- X local($from);
- X local(@head) = split(/\n/, $'Header{'Head'});
- X $from = shift(@head); # The first From_ line has to be skipped
- X unless ($from =~ /^From\s/) {
- X &'add_log("WARNING leading From line absent") if $'loglvl > 5;
- X unshift(@head, $from); # Put it back if not a From_ line
- X }
- X unless ($mmdf eq 'MH') {
- X (print FD "\01\01\01\01\n") || ($failed = 1);
- X $amount += 5;
- X }
- X foreach $line (@head) {
- X (print FD $line, "\n") || ($failed = 1);
- X $amount += length($line) + 1;
- X }
- X (print FD $'FILTER, "\n\n") || ($failed = 1);
- X (print FD $'Header{'Body'}) || ($failed = 1);
- X &force_flushing(*FD);
- X unless ($mmdf eq 'MH') {
- X (print FD "\01\01\01\01\n") || ($failed = 1);
- X $amount += 5;
- X }
- X $amount +=
- X length($'Header{'Body'}) + # Message body
- X length($'FILTER) + 2; # X-Filter line plus two newlines
- X ($failed, $amount);
- X}
- X
- X# Save to a Unix-style mailbox and return failure status with message length
- Xsub save_unix {
- X local(*FD) = @_; # File descriptor
- X local($amount) = 0; # Amount of bytes saved
- X local($failed);
- X # First print the Header, then add the X-Filter: line, followed by body.
- X (print FD $'Header{'Head'}) || ($failed = 1);
- X (print FD $'FILTER, "\n\n") || ($failed = 1);
- X (print FD $'Header{'Body'}) || ($failed = 1);
- X &force_flushing(*FD);
- X (print FD "\n") || ($failed = 1); # Allow parsing by other tools
- X $amount +=
- X length($'Header{'Head'}) + # Message header
- X length($'Header{'Body'}) + # Message body
- X length($'FILTER) + 2 + # X-Filter line plus two newlines
- X 1; # Trailing new-line
- X ($failed, $amount);
- X}
- X
- X# Force flushing on file descriptor, so that after next print, we may rest
- X# assured everything as been written on disk. That way, we may stat the file
- X# without closing it (since that would release any flock-style lock).
- Xsub force_flushing {
- X local(*FD) = @_; # File descriptor we want to flush
- X select((select(FD), $| = 1)[0]);
- X}
- X
- X# Guess whether the folder we are writing to is MMDF-style or not.
- Xsub is_mmdf {
- X local($folder) = @_; # The folder to be scanned
- X open(FOLDER, "$folder") || return 0; # Can't open -> not MMDF, say.
- X local($_); # First line from folder
- X $_ = <FOLDER>; # Can be empty
- X close FOLDER;
- X return 0 if /^From\s/; # Looks like an Unix-style mailbox
- X return 1 if /^\01\01\01\01\n/; # This must be an MMDF-style mailbox
- X # If we can't decide (most probably because $_ is empty), then choose
- X # according to the 'mmdfbox' parameter.
- X &'add_log("WARNING folder $folder may be corrupted")
- X if $_ ne '' && $'loglvl > 5;
- X $cf'mmdfbox =~ /on/i ? 1 : 0; # Force MMDF if mmdfbox is ON
- X}
- X
- Xpackage main;
- X
- END_OF_FILE
- if test 4318 -ne `wc -c <'agent/pl/mmdf.pl'`; then
- echo shar: \"'agent/pl/mmdf.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/mmdf.pl'
- fi
- if test -f 'agent/pl/read_conf.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/read_conf.pl'\"
- else
- echo shar: Extracting \"'agent/pl/read_conf.pl'\" \(4166 characters\)
- sed "s/^X//" >'agent/pl/read_conf.pl' <<'END_OF_FILE'
- X;# $Id: read_conf.pl,v 3.0 1993/11/29 13:49:12 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: read_conf.pl,v $
- X;# Revision 3.0 1993/11/29 13:49:12 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- Xpackage cf;
- X
- X# This package is responsible for keeping track of the configuration variables.
- X
- X# Read configuration file (usually in ~/.mailagent)
- Xsub main'read_config {
- X local($file) = @_; # where config file is located
- X local($_);
- X $file = '~/.mailagent' unless $file;
- X local($myhome) = $ENV{'HOME'}; # must be correctly set by filter
- X $file =~ s/~/$myhome/; # ~ substitution
- X local($main'config) = $file; # Save it: could be modified by config
- X open(CONFIG, "$file") ||
- X &'fatal("can't open config file $file");
- X local($config) = ' ' x 2000; # pre-extend to avoid realloc()
- X $config = '';
- X while (<CONFIG>) {
- X next if /^[ \t]*#/; # skip comments
- X next if /^[ \t]*\n/; # skip empy lines
- X $config .= $_;
- X }
- X &parse($config) || &'fatal('bad configuration');
- X close CONFIG;
- X
- X # Security checks, pending of those performed by the C filter. They are
- X # somewhat necessary, even though the mailagent does not run setuid
- X # (because anybody may activate the mailagent for any user by sending him
- X # a mail, and world writable configuration files makes the task too easy
- X # for a potential hacker). The tests are performed once the configuration
- X # file has been parsed, so logging of fatal errors may occur.
- X
- X local($unsecure) = 0;
- X
- X $unsecure++ unless &'file_secure($'config, 'config');
- X $unsecure++ unless &'file_secure($rules, 'rule');
- X &'fatal("unsecure configuration!") if $unsecure;
- X
- X return unless -f "$rules"; # No rule file
- X}
- X
- X# Parse config file held in variable and return 1 if ok, 0 for errors
- Xsub parse {
- X local($config) = @_;
- X local($eval) = ' ' x 1000; # Pre-extend
- X local($myhome) = $ENV{'HOME'}; # must be correctly set by filter
- X local($var, $value);
- X local($_);
- X $eval = '';
- X foreach (split(/\n/, $config)) {
- X if (/^[ \t]*([^ \t\n:\/]*)[ \t]*:[ \t]*([^#\n]*)/) {
- X $var = $1;
- X $value = $2;
- X $value =~ s/\s*$//; # remove trailing spaces
- X $eval .= "\$$var = \"$value\";\n";
- X $eval .= "\$$var =~ s|~|$myhome|g;\n"; # ~ substitution
- X }
- X }
- X eval $eval; # evaluate configuration parameters within package
- X
- X if ($@ ne '') { # Parsing error detected
- X local($error) = $@; # Logged error
- X local($*) = 1;
- X $error = (split(/\n/, $error))[0]; # Keep only first line
- X # Dump error message on stderr, as well as faulty configuration file.
- X # The original is restored out of the perl form to avoid surprise.
- X $eval =~ s/^\$.* =~ s\|~\|.*\n//g; # Remove added ~ substitutions
- X $eval =~ s/^\$//g; # Remove leading '$'
- X $eval =~ s/ = "(.*)";/: $1/g; # Keep only variable value
- X chop($eval);
- X print STDERR <<EOM;
- X**** Syntax error in configuration:
- X$error
- X
- X---- Begin of Faulty Configuration
- X$eval
- X---- End of Faulty Configuration
- X
- XEOM
- X &'add_log("syntax error in configuration: $error") if $'loglvl > 1;
- X return 0;
- X }
- X
- X # Define the mailagent parameters from those in config file
- X $logfile = $logdir . "/$log";
- X $seqfile = $spool . "/$seq";
- X $hashdir = $spool . "/$hash";
- X $main'loglvl = int($level); # This one is visible in the main package
- X $main'track_all = 1 if $track =~ /on/i; # Option -t set by config
- X $sendmail = $'mailer if $sendmail eq ''; # No sendmail program specified
- X $sendnews = $'inews if $sendnews eq ''; # No news posting program
- X $mailopt = '-odq' if $mailopt eq '' && $sendmail =~ /sendmail/;
- X
- X # Update @INC perlib search path with the perlib variable. Paths not
- X # starting by a '/' are supposed to be under the mailagent private lib
- X # directory.
- X
- X if (defined $perlib) {
- X foreach (split(':', $perlib)) {
- X s/^~/$home/;
- X $_ = $'privlib . '/' . $_ unless m|^/|;
- X push(@INC, $_);
- X }
- X }
- X
- X 1; # Ok
- X}
- X
- Xpackage main;
- X
- END_OF_FILE
- if test 4166 -ne `wc -c <'agent/pl/read_conf.pl'`; then
- echo shar: \"'agent/pl/read_conf.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/read_conf.pl'
- fi
- if test -f 'agent/pl/rfc822.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/rfc822.pl'\"
- else
- echo shar: Extracting \"'agent/pl/rfc822.pl'\" \(4527 characters\)
- sed "s/^X//" >'agent/pl/rfc822.pl' <<'END_OF_FILE'
- X;# $Id: rfc822.pl,v 3.0 1993/11/29 13:49:13 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: rfc822.pl,v $
- X;# Revision 3.0 1993/11/29 13:49:13 ram
- X;# Baseline for mailagent 3.0 netwide release.
- X;#
- X;#
- X;# The following routines do some parsing on RFC822 headers (such as the
- X;# ones provided by sendmail).
- X;#
- X
- X# Parse an address and returns (internet, comment)
- X# Examples:
- X# ram@eiffel.com (Raphael Manfredi) -> (ram@eiffel.com, Raphael Manfredi)
- X# Raphael Manfredi <ram@eiffel.com> -> (ram@eiffel.com, Raphael Manfredi)
- X# Note that we try to parse malformed RFC822 addresses to the best we can, by
- X# giving priority to anything between <> for correct e-mail address detection.
- X# Common errors include having a '<>' construct as part of the comment attached
- X# to the address as "name <surname> lastname", but this can only be followed
- X# by a <> address and the regexp is built so that it will skip the first <>
- X# and match only the last one on the line.
- Xsub parse_address {
- X local($_) = shift(@_); # The address to be parsed
- X local($comment);
- X local($internet);
- X if (/^\s*(.*)\s+<(\S+)>[^()]*$/) { # comment <address>
- X $comment = $1;
- X $internet = $2;
- X $comment =~ s/^"(.*)"/$1/; # "comment" -> comment
- X ($internet, $comment);
- X } elsif (/^\s*([^()]+)\s+\((.*)\)/) { # address (comment)
- X $comment = $2;
- X $internet = $1;
- X # Construct '<address> (comment)' is invalid but... priority to <>
- X # This will also take care of "comment" <address> (other-comment)
- X $internet =~ /<(\S+)>/ && ($internet = $1);
- X ($internet, $comment);
- X } elsif (/^\s*<(\S+)>\s*(.*)/) { # <address> ...garbage...
- X ($1, $2);
- X } elsif (/^\s*\((.*)\)\s+<?(.*)>?/) { # (comment) [address or <address>]
- X ($2, $1);
- X } else { # plain address, grab first word
- X /^\s*(\S+)\s*(.*)/;
- X ($1, $2);
- X }
- X}
- X
- X# Parses an internet address and returns the login name of the sender. When
- X# facing an RFC 822 group addressing (like To: group:;), it returns the group
- X# name.
- Xsub login_name {
- X local($_) = shift(@_); # The internet address
- X if (/^(\S+):;/) { # rfc-822-group:;
- X &last_name($1);
- X } elsif (s/^"(\S+)"@\S+/$1/) { # "user@domain"@other
- X &login_name($_); # parse user@domain
- X } elsif (s/^(\S+)@\S+/$1/) { # user@domain.name
- X &login_name($_); # parse user
- X } elsif (s/^(\S+)%\S+/$1/) { # user%domain.name
- X &login_name($_); # parse user
- X } elsif (s/^\S+!(\S+)/$1/) { # ...!backbone!user
- X &last_name($_); # user can only be a simple name
- X } else { # everything else must be a single name
- X &last_name($_); # keep only last name
- X }
- X}
- X
- X# Extract last name from a login name like First_name.Last_name and put it
- X# in lowercase. Hence, Raphael.Manfredi will become manfredi. Since '_' or '.'
- X# characters could be legitimely used in a login name (or distribution list),
- X# we remove it only when followed by an upper-cased letter.
- Xsub last_name {
- X local($_) = shift(@_); # The sender's login name
- X s/.*\.([A-Z]\w*)/$1/; # Keep only the last name (. separation)
- X s/.*_([A-Z]\w*)/$1/; # Same as above (_ separation)
- X tr/A-Z/a-z/; # And lowercase it
- X $_;
- X}
- X
- X# Parse an e-mail address and return a three element array:
- X# ($host, $domain, $country)
- Xsub internet_info {
- X local($_) = shift(@_); # The internet address
- X local($login) = &login_name($_); # Get the address login name
- X local($internet); # The internet part of the address
- X # Try with uucp form first, to detect things like eiffel!ram@inria.fr
- X # We use the login name to anchor the last '!' or the first '@' or '%'
- X ($internet) = /([^!]*)!$login/i;
- X ($internet) = /$login[@%]([\w.-]*)/i unless $internet;
- X $internet =~ tr/A-Z/a-z/; # Always lower-cased
- X local(@parts) = split(/\./, $internet); # Break on dots
- X if (@parts == 1) { # Only a host name
- X # Maybe this is a local address, maybe this is a uucp name. Assume that
- X # it is local if there is an '@' sign, as in 'ram@lyon'. Otherwise, it
- X # is a uucp name, as in 'eiffel!ram'.
- X push(@parts, 'uucp') if /!$login/; # UUCP name
- X push(@parts, split(/\./, $mydomain)) if @parts == 1;
- X }
- X unshift(@parts, '') if @parts == 2; # No host name
- X @parts[($#parts - 2) .. $#parts]; # ($host, $domain, $country)
- X}
- X
- END_OF_FILE
- if test 4527 -ne `wc -c <'agent/pl/rfc822.pl'`; then
- echo shar: \"'agent/pl/rfc822.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/rfc822.pl'
- fi
- if test -f 'agent/test/TEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/TEST'\"
- else
- echo shar: Extracting \"'agent/test/TEST'\" \(4682 characters\)
- sed "s/^X//" >'agent/test/TEST' <<'END_OF_FILE'
- X: # feed this into perl
- X eval 'exec perl -S $0 "$@"'
- X if $running_under_some_shell;
- X
- X# $Id: TEST,v 3.0 1993/11/29 13:49:22 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: TEST,v $
- X# Revision 3.0 1993/11/29 13:49:22 ram
- X# Baseline for mailagent 3.0 netwide release.
- X#
- X
- Xchop($pwd = `pwd`);
- X$ENV{'HOME'} = "$pwd/out";
- Xchop($host = `(hostname 2>/dev/null || uname -n) 2>/dev/null`);
- X$host =~ s/^([^.]*)\..*/$1/; # Trim domain name
- X$ENV{'HOST'} = $host;
- X$ENV{'USER'} = 'nobody'; # In case we get mails back from RUN and friends
- X$ENV{'PWD'} = $pwd;
- X$ENV{'LEVEL'} = 0; # Default loglvl for filter and cmd tests
- X
- X@tests = ('basic', 'option', 'filter', 'cmd', 'misc');
- X$failed = 0;
- X$how_many = 0;
- X
- Xrequire 'getopt.pl';
- X&Getopt;
- X
- X$mailagent = 'mailagent'; # Default program (dataloaded version)
- X$mailagent = 'magent' if $opt_n; # Use non-dataloaded version
- X$ENV{'MAILAGENT'} = $mailagent;
- X$ENV{'PATH'} = "$pwd/..:" . $ENV{'PATH'};
- X
- X-f "../$mailagent" && -x _ || die "No $mailagent.\n";
- X-f '../filter/filter' && -x _ || die "No filter.\n";
- X$> || die "Cannot run tests as super-user.\n";
- X
- X&load_ok; # Don't rerun successful tests if up to date
- X
- X# A level file indicates default loglvl
- Xif (-f 'level') {
- X chop($level = `cat level`);
- X $ENV{'LEVEL'} = int($level);
- X}
- X
- Xunless (-f 'OK') {
- X %Ok = ();
- X `rm -rf out` if -d 'out';
- X}
- X
- Xumask 022; # Ensure none of the files are world writable
- X
- X`mkdir out` unless -d 'out';
- X
- Xselect(STDOUT);
- X$| = 1;
- Xopen(OK, ">>OK");
- Xselect(OK);
- X$| = 1; # We may safely interrupt
- Xselect(STDOUT);
- X
- Xforeach $dir (@tests) {
- X next unless -d $dir;
- X &run($dir);
- X}
- X
- X# Summarize what happened
- X
- Xclose OK;
- X
- Xif ($failed == 0) {
- X print "All tests successful.\n";
- X} else {
- X print "Failed $how_many test", $how_many == 1 ? '' : 's';
- X print " from $failed file", $failed == 1 ? '' : 's', ".\n";
- X}
- X
- X&clean_up;
- Xexit 0; # End of tests
- X
- X#
- X# Subroutines
- X#
- X
- Xsub clean_up {
- X return if $failed || $opt_i; # -i asks for incrementality
- X unlink 'OK';
- X `rm -rf out` if -d 'out';
- X}
- X
- Xsub print {
- X local($dir, $file) = @_;
- X $file =~ s/\.t$//;
- X local($len) = 1 + length($dir) + length($file);
- X print "$dir/$file", '.' x (17 - $len);
- X}
- X
- Xsub num { $a <=> $b; }
- X
- Xsub result {
- X local($test, $output) = @_;
- X local($now) = time;
- X local(@res) = split(/\n/, $output); # Failed test numbers
- X if ($res[0] eq '') {
- X print "FAILED (no test run)\n";
- X ++$failed;
- X } elsif ($res[$#res] == 0 && $#res > 0 && $res[$#res -1] == $#res) {
- X print "FAILED (all tests)\n";
- X ++$failed;
- X $how_many += $#res;
- X } elsif ($res[0] == 0) {
- X print "ok\n";
- X print OK "$test $now\n";
- X } elsif ($res[0] == -1) {
- X print "untested\n";
- X } else {
- X # Program outputs the number of each test failed, and last must be 0
- X local($last) = pop(@res);
- X push(@res, $last) unless $last == 0;
- X local($n) = @res + 0;
- X local($s) = $n == 1 ? '' : 's';
- X print "FAILED ($n test$s:";
- X @res = sort num @res;
- X print ' ', join(',', @res);
- X print " and aborted" unless $last == 0;
- X print ")\n";
- X ++$failed;
- X $how_many += $n;
- X }
- X if ($failed && $opt_s) { # Stop at first error if -s
- X print "Aborted tests.\n";
- X exit 0;
- X }
- X}
- X
- Xsub run {
- X local($dir) = @_;
- X chdir $dir || die "Cannot chdir to $dir: $!\n";
- X local(@files) = <*.t>;
- X local($test);
- X local($output);
- X foreach $file (@files) {
- X &print($dir, $file);
- X $test = "$dir/$file";
- X if ($Ok{$test} >= ((stat($file))[9])) { # Check time stamp
- X print "done\n";
- X next;
- X }
- X $output = `perl $file`;
- X &result($test, $output);
- X &basic_failed if $dir eq 'basic' && $failed;
- X }
- X chdir '..' || die "Cannot chdir back to ..: $!\n";
- X}
- X
- Xsub basic_failed {
- X print "Failed a basic test, cannot continue.\n";
- X unlink 'OK';
- X exit 0;
- X}
- X
- Xsub load_ok {
- X return unless -f 'OK';
- X
- X # Make sure the OK file is up to date, unless -o (outdated)
- X unless ($opt_o) {
- X local($ok_mtime) = (stat('OK'))[9];
- X local($ma_mtime) = (stat("../$mailagent"))[9];
- X local($fi_mtime) = (stat('../filter/filter'))[9];
- X local($restart) = 0;
- X if ($ma_mtime > $ok_mtime) {
- X warn "Mailagent has changed, restarting tests...\n";
- X ++$restart;
- X } elsif ($fi_mtime > $ok_mtime) {
- X warn "Filter has changed, restarting tests...\n";
- X ++$restart;
- X }
- X unlink 'OK' if $restart;
- X }
- X
- X return unless -f 'OK';
- X local($file, $when);
- X open(OK, 'OK') || return;
- X while (<OK>) {
- X chop;
- X ($file, $when) = /^(\S+)\s+(\d+)/;
- X $Ok{$file} = $when if $when;
- X }
- X close OK;
- X
- X}
- X
- END_OF_FILE
- if test 4682 -ne `wc -c <'agent/test/TEST'`; then
- echo shar: \"'agent/test/TEST'\" unpacked with wrong size!
- fi
- chmod +x 'agent/test/TEST'
- # end of 'agent/test/TEST'
- fi
- if test -f 'agent/test/level' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/level'\"
- else
- echo shar: Extracting \"'agent/test/level'\" \(2 characters\)
- sed "s/^X//" >'agent/test/level' <<'END_OF_FILE'
- X0
- END_OF_FILE
- if test 2 -ne `wc -c <'agent/test/level'`; then
- echo shar: \"'agent/test/level'\" unpacked with wrong size!
- fi
- # end of 'agent/test/level'
- fi
- if test -f 'agent/test/rules' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/rules'\"
- else
- echo shar: Extracting \"'agent/test/rules'\" \(4703 characters\)
- sed "s/^X//" >'agent/test/rules' <<'END_OF_FILE'
- X#
- X# Mailagent rules for filter regression tests
- X#
- X
- X# $Id: rules,v 3.0 1993/11/29 13:50:27 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: rules,v $
- X# Revision 3.0 1993/11/29 13:50:27 ram
- X# Baseline for mailagent 3.0 netwide release.
- X#
- X
- Xmaildir = ~;
- Xmailfilter = ~;
- X
- XSubject: /test/ { DELETE };
- X
- X# filter/default
- XX-Tag: /default #1/ { DELETE };
- XX-Tag: /default #2/ { NOP };
- XX-Tag: /unknown/ { UNKNOWN };
- X
- X# filter/loop
- XX-Tag: /loop #1/ { BEGIN LOOP; RESTART };
- XX-Tag: /loop #2/ { DELETE };
- X
- X# filter/multiple
- XX-None Subject To X-Tag: /multiple #1/ { SAVE %u.1 };
- XX-None X-Tag: /multiple #2/, X-Other: /another/,
- XTo Cc: root, Cc To: ram { SAVE %u.3; REJECT MULTIPLE };
- X<MULTIPLE> X-Non-Existent: * { SAVE %u.2 };
- XX-Tag: /multiple #2/, X-Other: /multiple #2/ { SAVE %u.2 };
- X
- X# filter/list
- XX-Tag: /list/ { BEGIN LIST; REJECT };
- X<LIST> To: ram { SAVE %u.1 };
- X<LIST> To: max { SAVE %u.2 };
- X<LIST> To: /^root@eiffel.com$/ { SAVE %u.3 };
- X<LIST> To: /^riot@eiffel.co$/ { DELETE };
- X<LIST> To: /^riot@eiffel.com$/ { SAVE %u.4 };
- X<LIST> To: /^riot/ { SAVE %u.5 };
- X<LIST> To: /riot/ { SAVE %u.6 };
- X<LIST> Newsgroups: news.lists { SAVE %u.7 };
- X<LIST> To: !ram { SAVE %u.8 };
- X
- X# filter/pattern
- XX-T.*: "pattern-list" { BEGIN PAT; REJECT };
- X<PAT> .*Re[^\-]*$: *, ^Sub*: * { RUN /bin/echo '%&' > macro; DELETE };
- X
- X# filter/backref
- XX-Tag: /^back(.*) #1/,
- XSubject: /Re:\s+(\w+)\s+ice\s+(\w+)/,
- XFrom: /(.*)compilers/,
- XFrom: /com(.*)rs/,
- XTo: /^(\w+)@(\S+)/ { RUN /bin/echo '%1,%4,%5@%6,%2 %3' > output; DELETE };
- X
- XX-Tag: /^back.* #2/,
- XNewsgroups:
- X /(comp.lang.perl)/,
- X /(comp.unix.wizards)/,
- X /(comp.mail.mh)/ { SAVE %1 };
- X
- X# filter/escape
- XX-Tag: /escape/ { RUN /bin/echo '\;,\\\;,\\,\w' > output; DELETE };
- X
- X# filter/mode
- XX-Tag: /mode/ { REJECT MODE };
- X<MODE, !INITIAL> { SAVE always; REJECT };
- X<MODE> { SAVE always.2; REJECT };
- X<!NOSUCH,!BADMODE> X-Tag: /mode/ { SAVE always.3; REJECT };
- X<!MODE> X-Tag: /mode/ { SAVE never; REJECT };
- X<MODE> { DELETE };
- X
- X# filter/not
- XX-Tag: /not #1/ { BEGIN NOT; REJECT };
- X<NOT> To: !ram { SAVE never };
- X<NOT> To: !/ram@eiffel/ { SAVE never };
- X<NOT> To: !/^ram/i { SAVE never };
- X<NOT> To: /^ram/i { SAVE always; REJECT };
- X<NOT> To: !/^root/i { SAVE always.2; REJECT };
- X<NOT> X-Tag: !"pattern-list" { SAVE always.3 };
- X
- XX-Tag: /not #2/,
- X!To: !ram,
- XTo: !compilers,
- X!From: root { SAVE always };
- X
- X# filter/group
- XX-Tag: /group/ { BEGIN GROUP; REJECT };
- X<GROUP> !To !From: ram { SAVE never };
- X<GROUP> To !From: !ram { SAVE never };
- X<GROUP> !To !From: ram,
- X !Subject !From: ram { SAVE never };
- X<GROUP> !To: root, ram { SAVE never };
- X<GROUP> !F.*: /compiler/ { SAVE never };
- X<GROUP> !From: ram, !To: ram { SAVE always; REJECT };
- X<GROUP> From: ram, To: ram { SAVE never };
- X<GROUP> From: /compiler/,
- X !From: ram, !From: !/compiler/ { SAVE always.2; REJECT };
- X<GROUP> From !Cc !To: /compiler/,
- X From !Cc !To: ram,
- X !From To Cc: /eiffel/,
- X !From To Cc: !/ice/ { SAVE always.3 };
- X
- X# filter/case
- XX-Tag: case, Cc: root { STRIP Cc; SAVE always };
- X
- X# filter/status
- XX-Tag: /status/ { REJECT -t STATUS };
- X<STATUS> { RUN ../no/such/file; REJECT -t; SAVE always; REJECT -t; SAVE never };
- X<STATUS> { RUN ../this/does/not/exist; REJECT -f; SAVE never };
- X<STATUS> { RUN ../nor/does/this; REJECT -t; REJECT -t; REJECT -f; SAVE never };
- X<STATUS> { SAVE always.2; REJECT -f; BEGIN INITIAL; REJECT -t };
- X<INITIAL> X-Tag: /status/ { SAVE always.3 };
- X
- X# filter/hook
- XX-Tag: /hook #(\d)/ { SAVE hook.%1; ABORT -t; SAVE never };
- X
- X# filter/range
- XX-Tag: /range/ { BEGIN RANGE; REJECT };
- X<RANGE> From <2, 4>: /compiler/ { SAVE always; REJECT };
- X<RANGE> To Cc: made { SAVE always.2; REJECT };
- X<RANGE> To Cc <1, 1>: made { SAVE never; REJECT };
- X<RANGE> To Cc <1, 2>: must { SAVE always.3; REJECT };
- X<RANGE> To Cc <3, 1>: ram { SAVE never.2; REJECT };
- X<RANGE> Body <-, 3>: /SIGPLAN/ { SAVE never.3; REJECT };
- X<RANGE> Body <-, ->: /SIGPLAN/ { SAVE always.4; REJECT };
- X<RANGE> Body <9, 9>: /SIGPLAN/ { SAVE always.5; REJECT };
- X<RANGE> Body <9, 9>: /CD-ROM/ { SAVE never.4; REJECT };
- X<RANGE> Body <13, 14>: /something/ { SAVE always.6; REJECT };
- X<RANGE> Body <-3, ->: /Regards/ { SAVE always.7; REJECT };
- X<RANGE> Cc <-1, ->: made { SAVE always.8; REJECT };
- X<RANGE> Body <-3, ->: /request/ { SAVE never.5; REJECT };
- X<RANGE> Cc <-1, ->: must { SAVE never.6 };
- X<RANGE> { DELETE };
- X
- END_OF_FILE
- if test 4703 -ne `wc -c <'agent/test/rules'`; then
- echo shar: \"'agent/test/rules'\" unpacked with wrong size!
- fi
- # end of 'agent/test/rules'
- fi
- if test -f 'install.SH' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'install.SH'\"
- else
- echo shar: Extracting \"'install.SH'\" \(3974 characters\)
- sed "s/^X//" >'install.SH' <<'END_OF_FILE'
- 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
- Xecho "Extracting install (with variable substitutions)"
- X$spitshell >install <<!GROK!THIS!
- X$startsh
- X# @(#) Installing script accepting bsd-style arguments
- X
- X# $Id: install.SH,v 3.0 1993/11/29 13:50:29 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: install.SH,v $
- X# Revision 3.0 1993/11/29 13:50:29 ram
- X# Baseline for mailagent 3.0 netwide release.
- X#
- X
- Xchown='$chown'
- Xchmod='$chmod'
- Xchgrp='$chgrp'
- Xrm='$rm'
- Xmv='$mv'
- Xtest='$test'
- Xsed='$sed'
- X!GROK!THIS!
- X$spitshell >>install <<'!NO!SUBS!'
- X
- Xmode=""
- Xdst=""
- Xsrc=""
- Xdostrip=""
- Xnewdir=""
- Xuid=""
- Xgid=""
- X
- X# simulates mkdir -p
- Xmkdir_p='
- Xname=$1;
- Xcreate="";
- Xwhile $test $name; do
- X if $test ! -d "$name"; then
- X create="$name $create";
- X name=`echo $name | $sed -e "s|^[^/]*$||"`;
- X name=`echo $name | $sed -e "s|\(.*\)/.*|\1|"`;
- X else
- X name="";
- X fi;
- Xdone;
- Xfor file in $create; do
- X mkdir $file && $test $verbose &&
- X echo "install: created directory $file" >&2;
- Xdone
- X'
- X
- Xverbose=''
- X
- Xwhile $test x$1 != x
- Xdo
- X case $1 in
- X -c) shift
- X continue
- X ;;
- X -m) mode="$2 "
- X shift
- X shift
- X continue
- X ;;
- X -o) uid="$2 "
- X shift
- X shift
- X continue
- X ;;
- X -g) gid="$2 "
- X shift
- X shift
- X continue
- X ;;
- X -s) dostrip="strip"
- X shift
- X continue
- X ;;
- X -d) newdir="$newdir$2 "
- X shift
- X shift
- X continue
- X ;;
- X -v) verbose='true'
- X shift
- X ;;
- X *) if $test x$src = x
- X then
- X src=$1
- X else
- X dst=$1
- X fi
- X shift
- X continue
- X ;;
- X esac
- Xdone
- X
- X# if -d option is used, we have to create the path given
- Xif $test ! x$newdir = x
- Xthen
- X for i in $newdir
- X do
- X set x $i
- X shift
- X eval $mkdir_p
- X done
- X exit 0 # -d is the only action
- Xfi
- X
- Xif $test x$src = x
- Xthen
- X echo "install: no input file specified" >&2
- X exit 1
- Xfi
- X
- Xif $test x$dst = x
- Xthen
- X echo "install: no destination specified" >&2
- X exit 1
- Xfi
- X
- Xsrcbase=`basename $src`
- Xdstbase=`basename $dst`
- X
- X# If the destination is a directory, the target name is srcbase...
- Xif $test -d $dst; then
- X dstbase=$srcbase
- Xelse
- X dst="`echo $dst | sed 's,^\(.*\)/.*$,\1,'`"
- X if $test ! -d $dst; then
- X dstbase=$dst
- X dst="."
- X fi
- Xfi
- X
- X# If the src has a directory, extract the dir name...
- Xif $test "$src" != "$srcbase" -a "$src" != "./$srcbase"; then
- X src="`echo $src | sed 's,^\(.*\)/.*$,\1,'`"
- Xelse
- X src="."
- Xfi
- X
- X# dst is the destination directory and dstbase the base name.
- X# srcbase is the base name of source and src the source dir.
- X
- Xsrcpth=`(cd $src; pwd)`/$srcbase
- Xdestpth=`(cd $dst; pwd)`/$dstbase
- Xif $test x$srcpth = x$destpth; then
- X $test $verbose && \
- X echo "install: destination and source are identical"
- X exit 0
- Xfi
- X
- X# Do the install
- X(
- X cd $src
- X
- X if $test -f $dst/$dstbase; then
- X $rm -f $dst/$dstbase && $test $verbose &&
- X echo "install: $dst/$dstbase removed"
- X fi
- X if $test -f $dst/$dstbase; then
- X $mv $dst/$dstbase $dst/OLD$dstbase && $test $verbose &&
- X echo "install: $dst/$dstbase renamed as OLD$dstbase"
- X fi
- X
- X cp $srcbase $dst/$dstbase && $test $verbose &&
- X echo "install: $srcbase installed as $dst/$dstbase"
- X
- X if $test ! x$dostrip = x; then
- X strip $dst/$dstbase 2>/dev/null && $test $verbose &&
- X echo "install: stripped $dst/$dstbase"
- X fi
- X
- X if $test ! x$uid = x; then
- X $chown $uid $dst/$dstbase
- X fi
- X if $test ! x$gid = x; then
- X $chgrp $gid $dst/$dstbase
- X fi
- X if $test ! x$mode = x
- X then
- X $chmod $mode $dst/$dstbase
- X fi
- X)
- X
- Xexit 0
- X!NO!SUBS!
- Xchmod 755 install
- X$eunicefix install
- END_OF_FILE
- if test 3974 -ne `wc -c <'install.SH'`; then
- echo shar: \"'install.SH'\" unpacked with wrong size!
- fi
- chmod +x 'install.SH'
- # end of 'install.SH'
- fi
- echo shar: End of archive 19 \(of 26\).
- cp /dev/null ark19isdone
- 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...
-