From:	SMTP%"ram@acri.fr" 28-JAN-1995 10:44:30.06
To:	USRC
CC:	
Subj:	v47i055: mailagent - Flexible mail filtering and processing package, v3.0, Patch27

Resent-Date: 26 Jan 1995 20:58:09 -0600
Path: decwrl!news.doit.wisc.edu!night.primate.wisc.edu!caen!hookup!swrinde!pipex!uunet!sparky!not-for-mail
From: ram@acri.fr (Raphael Manfredi)
Newsgroups: comp.sources.misc
Subject: v47i055: mailagent - Flexible mail filtering and processing package, v3.0, Patch27
Followup-To: comp.sources.d
Date: 26 Jan 1995 20:58:09 -0600
Organization: Advanced Computer Research Institute, Lyon, France
Lines: 1487
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-Id: <3g9ng1$42t@sparky.sterling.com>
Nntp-Posting-Host: sparky.sterling.com
X-Md4-Signature: 3f51692cf1510a60320616d5b1edb482
To: unix-sources@pa.dec.com
Resent-Message-Id: <"9pDfH1.0.H33.nmRAl"@ftp-gw-1.pa.dec.com>
Resent-From: unix-sources@pa.dec.com
X-Mailing-List: <unix-sources@pa.dec.com> archive/latest/474
X-Loop: unix-sources@pa.dec.com
Precedence: list
Resent-Sender: unix-sources-request@pa.dec.com

Submitted-by: ram@acri.fr (Raphael Manfredi)
Posting-number: Volume 47, Issue 55
Archive-name: mailagent/patch27
Environment: UNIX, Perl
Patch-To: mailagent: Volume 41, Issue 1-26

[The latest patch for mailagent version 3.0 is #29.]

System: mailagent version 3.0
Patch #: 27
Priority: MEDIUM
Subject: regenerated Configure with metaconfig 3.0 PL48
Subject: regenerated Makefile.SH with jmake 3.0 PL48
Subject: extended copyright notice to include year 1995
Subject: mailagent now works with perl 5.0
Subject: new option letter 't' for mailagent -s
Subject: new commands BEEP and PROTECT
Subject: new macro %a for biff messages
Subject: added support for NFS bug on remote read-only folders
Subject: destination address for PROCESS is now parsed correctly
Subject: added support for folder mode change, as defined by PROTECT
Subject: new macro %a for variable bells, under the control of BEEP
Subject: fixed a typo in &yyerror and various code clean-up
Subject: ported to perl 5.0 PL0
Subject: added automatic @ escape in patterns for perl 5.0
Subject: avoid problems on slow machines in test mode for queue timestamps
Subject: added support for the Msg-Protect MH profile component
Subject: allows new PROTECT command to override default Msg-Protect
Subject: UNSEEN mark in log has the home directory stripped via &tilda
Subject: new routine &chmod for folder permission settting
Subject: escape all @ in config file for perl 5.0
Subject: new routines &unset and &undef
Subject: added default values for PROTECT and BEEP
Subject: added logs in case of eval errors for perl 5.0
Subject: new commands PROTECT and BEEP
Subject: put signal handler names into double quotes for perl 5.0
Subject: now supports 't' to track only top-most rule file stats
Subject: added eval error tracking for perl 5.0
Subject: extended rules for the PROTECT command tests
Subject: now sets a default umask in the configuration
Subject: added checks for Msg-Protect and PROTECT
Subject: two new files
Date: Wed Jan 25 16:45:06 MET 1995
From: Raphael Manfredi <ram@acri.fr>

Description:
	Regenerated Configure with metaconfig 3.0 PL48 for install
	binary lookup.

	Regenerated most Makefile.SH files with jmake 3.0 PL48 to
	benefit from the install lookup.

	Extended copyright notice to include year 1995.

	Mailagent now works with perl 5.0. It has been fully tested on
	my DEC OSF/1 3.0 machine and passes all its regression tests.
	However, this perl 5.0 is a version patched with early
	patches from the perl5-porters list. See the README file for
	instructions about how to get those patches.

	New option letter 't' for mailagent -s. The 'mailagent -surat'
	command will only deliver statistics for the top-level rule file.
	Indeed, each time your rule file changes, mailagent normally
	starts a new set of statistics on top of older ones.

	New commands BEEP and PROTECT. The BEEP command controls the new
	%a macro for biffing message, which is expanded into the matching
	amount of ^G characters. The PROTECT commands lets you define
	file protections for newly created folders.

	I also added support for the Msg-Protect MH profile component
	when saving into an MH folder, at Eric M. Carroll's request.
	However, the new PROTECT command can override the default Msg-Protect
	specification from your ~/.mh_profile.

	Added support for NFS bug on remote read-only folders. Indeed, SUN's
	NFS running on SUN 4.1.2 was allowing a remote write to a read-only
	folder lying on my DEC OSF/1 3.0 machine...

	Destination address for PROCESS is now parsed correctly, by using
	the RFC822 parser instead of a local hacked parsing.

	Ported many files to perl 5.0 PL0. This included workarounds for
	perl 5.0 bugs, and lots of @ escaping in strings and patterns,
	mainly in the regression test suite.

	Avoid problems on slow machines in test mode for queue timestamps.
	Some slow machines were reported to fail some tests in option/l.
	I made sure those will not occur any more by twiddling with the
	queue output string in test mode.

	UNSEEN mark in log has the home directory stripped via &tilda.

	Two new files.

Repeat-By: 

Fix:	From rn, say "| patch -p -N -d DIR", where DIR is your mailagent source
	directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
	If you don't have the patch program, apply the following by hand,
	or get patch (version 2.0, latest patchlevel).

	After patching:
		*** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #29 FIRST ***

	If patch indicates that patchlevel is the wrong version, you may need
	to apply one or more previous patches, or the patch may already
	have been applied.  See the patchlevel.h file to find out what has or
	has not been applied.  In any event, don't continue with the patch.

	If you are missing previous patches they can be obtained from me:

		Raphael Manfredi <ram@acri.fr>

	If you send a mail message of the following form it will greatly speed
	processing:

		Subject: Command
		@SH mailpatch PATH mailagent 3.0 LIST
			   ^ note the c

	where PATH is a return path FROM ME TO YOU either in Internet notation,
	or in bang notation from some well-known host, and LIST is the number
	of one or more patches you need, separated by spaces, commas, and/or
	hyphens.  Saying 35- says everything from 35 to the end.

	To get some more detailed instructions, send me the following mail:

		Subject: Command
		@SH mailhelp PATH


Index: patchlevel.h
Prereq: 26
4c4
< #define PATCHLEVEL 26
---
> #define PATCHLEVEL 27

Index: Configure
Prereq: 3.0.1.7
*** Configure.old	Wed Jan 25 16:34:21 1995
--- Configure	Wed Jan 25 16:34:23 1995
***************
*** 18,26 ****
  # archive site. Check with Archie if you don't know where that can be.)
  #
  
! # $Id: Configure,v 3.0.1.7 1995/01/03 17:53:24 ram Exp $
  #
! # Generated on Tue Jan 03 18:36:52 MET 1995 [metaconfig 3.0 PL44]
  
  cat >/tmp/c1$$ <<EOF
  ARGGGHHHH!!!!!
--- 18,26 ----
  # archive site. Check with Archie if you don't know where that can be.)
  #
  
! # $Id: Configure,v 3.0.1.8 1995/01/25 15:13:16 ram Exp $
  #
! # Generated on Wed Jan 11 17:24:28 MET 1995 [metaconfig 3.0 PL48]
  
  cat >/tmp/c1$$ <<EOF
  ARGGGHHHH!!!!!
***************
*** 118,123 ****
--- 118,124 ----
  chgrp=''
  chmod=''
  chown=''
+ comm=''
  compress=''
  cp=''
  cpio=''
***************
*** 263,268 ****
--- 264,271 ----
  i_systimek=''
  i_time=''
  timeincl=''
+ install=''
+ installdir=''
  intsize=''
  libc=''
  glibpth=''
***************
*** 368,417 ****
  	eunicefix=/etc/unixtovms.exe
  fi
  
! : list of known cpp symbols
! al="AMIX BIT_MSF BSD BSD4_3 BSD_NET2 CRAY DGUX DOLPHIN DPX2"
! al="$al GO32 HP700 I386 I80960 I960 Lynx M68000 M68K MACH"
! al="$al MIPSEB MIPSEL MSDOS MTXINU MVS"
  al="$al M_COFF M_I186 M_I286 M_I386 M_I8086 M_I86 M_I86SM"
  al="$al M_SYS3 M_SYS5 M_SYSIII M_SYSV M_UNIX M_XENIX"
  al="$al NeXT OCS88 OSF1 PARISC PC532 PORTAR POSIX"
! al="$al PWB R3000 SVR3 SVR4"
! al="$al SYSTYPE_BSD SYSTYPE_SVR4 SYSTYPE_SYSV"
! al="$al UTEK UTS UTek UnicomPBB UnicomPBD Utek VMS"
! al="$al _AIX _AIX32 _AM29000 _COFF _CRAY _EPI _IBMR2"
  al="$al _MIPSEB _MIPSEL _M_COFF _M_I86 _M_I86SM _M_SYS3"
! al="$al _M_SYS5 _M_SYSIII _M_SYSV _M_UNIX _M_XENIX _R3000"
  al="$al _SYSTYPE_BSD _SYSTYPE_BSD43 _SYSTYPE_SVR4"
! al="$al _SYSTYPE_SYSV _SYSV3 _UNICOS"
  al="$al __386BSD__ __BIG_ENDIAN __BIG_ENDIAN__ __BSD_4_4__"
  al="$al __DGUX__ __DPX2__ __H3050R __H3050RX"
  al="$al __LITTLE_ENDIAN __LITTLE_ENDIAN__ __MACH__"
  al="$al __MIPSEB __MIPSEB__ __MIPSEL __MIPSEL__"
! al="$al __Next__ __OSF1__ __PARAGON__ __PWB __STDC__"
  al="$al ____386BSD____ __alpha __alpha__ __amiga"
  al="$al __bsd4_2 __bsd4_2__ __bsdi__ __convex__"
  al="$al __host_mips__"
  al="$al __hp9000s200 __hp9000s300 __hp9000s400 __hp9000s500"
  al="$al __hp9000s500 __hp9000s700 __hp9000s800"
! al="$al __hppa __hpux __i286 __i286__ __i386 __i386__"
! al="$al __i486 __i486__ __i860 __i860__"
  al="$al __m68k __m68k__ __m88100__ __m88k __m88k__"
  al="$al __mc68000 __mc68000__ __mc68020 __mc68020__"
  al="$al __mc68030 __mc68030__ __mc68040 __mc68040__"
  al="$al __mc88100 __mc88100__ __mips __mips__"
  al="$al __motorola__ __osf__ __pa_risc __sparc__ __stdc__"
  al="$al __sun __sun__ __svr3__ __svr4__ __ultrix __ultrix__"
! al="$al __unix __unix__ __vax __vax__"
  al="$al _host_mips _mips _unix"
! al="$al a29k aegis alliant am29000 amiga ansi ardent"
! al="$al bsd bsd43 bsd4_2 bsd4_3 bsd4_4 bull"
! al="$al convex cray ctix encore gcos gimpel"
! al="$al hcx host_mips hp200 hp300 hp700 hp800"
  al="$al hp9000 hp9000s300 hp9000s400 hp9000s500"
! al="$al hp9000s700 hp9000s800 hp9k8 hpux"
  al="$al i186 i286 i386 i486 i8086"
! al="$al i80960 i860 iAPX286 ibm interdata is68k"
! al="$al linux luna luna88k m68k m88100 m88k"
  al="$al mc300 mc500 mc68000 mc68010 mc68020 mc68030"
  al="$al mc68040 mc68060 mc68k mc68k32 mc700"
  al="$al mc88000 mc88100 merlin mert mips mvs n16"
--- 371,425 ----
  	eunicefix=/etc/unixtovms.exe
  fi
  
! : list of known cpp symbols, sorted alphabetically
! al="AMIX BIT_MSF BSD BSD4_3 BSD_NET2 CMU CRAY DGUX DOLPHIN DPX2"
! al="$al GO32 GOULD_PN HP700 I386 I80960 I960 Lynx M68000 M68K MACH"
! al="$al MIPSEB MIPSEL MSDOS MTXINU MULTIMAX MVS"
  al="$al M_COFF M_I186 M_I286 M_I386 M_I8086 M_I86 M_I86SM"
  al="$al M_SYS3 M_SYS5 M_SYSIII M_SYSV M_UNIX M_XENIX"
  al="$al NeXT OCS88 OSF1 PARISC PC532 PORTAR POSIX"
! al="$al PWB R3000 RES RISC6000 RT Sun386i SVR3 SVR4"
! al="$al SYSTYPE_BSD SYSTYPE_SVR4 SYSTYPE_SYSV Tek4132 Tek4300"
! al="$al UMAXV USGr4 USGr4_2 UTEK UTS UTek UnicomPBB UnicomPBD Utek"
! al="$al VMS Xenix286"
! al="$al _AIX _AIX32 _AIX370 _AM29000 _COFF _CRAY _CX_UX _EPI"
! al="$al _IBMESA _IBMR2 _M88K _M88KBCS_TARGET"
  al="$al _MIPSEB _MIPSEL _M_COFF _M_I86 _M_I86SM _M_SYS3"
! al="$al _M_SYS5 _M_SYSIII _M_SYSV _M_UNIX _M_XENIX _NLS _PGC_ _R3000"
  al="$al _SYSTYPE_BSD _SYSTYPE_BSD43 _SYSTYPE_SVR4"
! al="$al _SYSTYPE_SYSV _SYSV3 _U370 _UNICOS"
  al="$al __386BSD__ __BIG_ENDIAN __BIG_ENDIAN__ __BSD_4_4__"
  al="$al __DGUX__ __DPX2__ __H3050R __H3050RX"
  al="$al __LITTLE_ENDIAN __LITTLE_ENDIAN__ __MACH__"
  al="$al __MIPSEB __MIPSEB__ __MIPSEL __MIPSEL__"
! al="$al __Next__ __OSF1__ __PARAGON__ __PGC__ __PWB __STDC__"
! al="$al __SVR4_2__ __UMAXV__"
  al="$al ____386BSD____ __alpha __alpha__ __amiga"
  al="$al __bsd4_2 __bsd4_2__ __bsdi__ __convex__"
  al="$al __host_mips__"
  al="$al __hp9000s200 __hp9000s300 __hp9000s400 __hp9000s500"
  al="$al __hp9000s500 __hp9000s700 __hp9000s800"
! al="$al __hppa __hpux __hp_osf __i286 __i286__ __i386 __i386__"
! al="$al __i486 __i486__ __i860 __i860__ __ibmesa __ksr1__ __linux__"
  al="$al __m68k __m68k__ __m88100__ __m88k __m88k__"
  al="$al __mc68000 __mc68000__ __mc68020 __mc68020__"
  al="$al __mc68030 __mc68030__ __mc68040 __mc68040__"
  al="$al __mc88100 __mc88100__ __mips __mips__"
  al="$al __motorola__ __osf__ __pa_risc __sparc__ __stdc__"
  al="$al __sun __sun__ __svr3__ __svr4__ __ultrix __ultrix__"
! al="$al __unix __unix__ __uxpm__ __uxps__ __vax __vax__"
  al="$al _host_mips _mips _unix"
! al="$al a29k aegis aix aixpc alliant alpha am29000 amiga ansi ardent"
! al="$al apollo ardent att386 att3b"
! al="$al bsd bsd43 bsd4_2 bsd4_3 bsd4_4 bsdi bull"
! al="$al cadmus clipper concurrent convex cray ctix"
! al="$al dmert encore gcos gcx gimpel gould"
! al="$al hbullx20 hcx host_mips hp200 hp300 hp700 hp800"
  al="$al hp9000 hp9000s300 hp9000s400 hp9000s500"
! al="$al hp9000s700 hp9000s800 hp9k8 hppa hpux"
  al="$al i186 i286 i386 i486 i8086"
! al="$al i80960 i860 iAPX286 ibm ibm032 ibmrt interdata is68k"
! al="$al ksr1 linux luna luna88k m68k m88100 m88k"
  al="$al mc300 mc500 mc68000 mc68010 mc68020 mc68030"
  al="$al mc68040 mc68060 mc68k mc68k32 mc700"
  al="$al mc88000 mc88100 merlin mert mips mvs n16"
***************
*** 420,431 ****
  al="$al news700 news800 news900 ns16000 ns32000"
  al="$al ns32016 ns32332 ns32k nsc32000 os osf"
  al="$al parisc pc532 pdp11 plexus posix pyr"
! al="$al riscix riscos sequent sgi sinix sony sony_news"
! al="$al sonyrisc sparc sparclite spectrum stratos"
  al="$al sun sun3 sun386 svr4 sysV68 sysV88"
  al="$al titan tower tower32 tower32_200 tower32_600 tower32_700"
! al="$al tower32_800 tower32_850 tss u3b u3b2 u3b20 u3b200"
! al="$al u3b5 ultrix unix unixpc unos vax venix vms"
  al="$al xenix z8000"
  
  gccversion=''
--- 428,439 ----
  al="$al news700 news800 news900 ns16000 ns32000"
  al="$al ns32016 ns32332 ns32k nsc32000 os osf"
  al="$al parisc pc532 pdp11 plexus posix pyr"
! al="$al riscix riscos scs sequent sgi sinix sony sony_news"
! al="$al sonyrisc sparc sparclite spectrum stardent stratos"
  al="$al sun sun3 sun386 svr4 sysV68 sysV88"
  al="$al titan tower tower32 tower32_200 tower32_600 tower32_700"
! al="$al tower32_800 tower32_850 tss u370 u3b u3b2 u3b20 u3b200"
! al="$al u3b20d u3b5 ultrix unix unixpc unos vax venix vms"
  al="$al xenix z8000"
  
  gccversion=''
***************
*** 494,500 ****
  : produce awk script to parse command line options
  cat >options.awk <<'EOF'
  BEGIN {
! 	optstr = "deEf:hrsSD:U:V";	# getopt-style specification
  
  	len = length(optstr);
  	for (i = 1; i <= len; i++) {
--- 502,508 ----
  : produce awk script to parse command line options
  cat >options.awk <<'EOF'
  BEGIN {
! 	optstr = "dD:eEf:hOrsSU:V";	# getopt-style specification
  
  	len = length(optstr);
  	for (i = 1; i <= len; i++) {
***************
*** 551,556 ****
--- 559,565 ----
  error=''
  silent=''
  extractsh=''
+ override=''
  optdef='optdef.sh'
  rm -f $optdef
  
***************
*** 574,579 ****
--- 583,589 ----
  	-r) shift; reuseval=true;;
  	-s) shift; silent=true;;
  	-E) shift; alldone=exit;;
+ 	-O) shift; override=true;;
  	-S) shift; extractsh=true;;
  	-D)
  		shift
***************
*** 600,606 ****
  		esac
  		shift
  		;;
! 	-V) echo "$me generated by metaconfig 3.0 PL44." >&2
  		exit 0;;
  	--) break;;
  	-*) echo "$me: unknown option $1" >&2; shift; error=true;;
--- 610,616 ----
  		esac
  		shift
  		;;
! 	-V) echo "$me generated by metaconfig 3.0 PL48." >&2
  		exit 0;;
  	--) break;;
  	-*) echo "$me: unknown option $1" >&2; shift; error=true;;
***************
*** 611,617 ****
  case "$error" in
  true)
  	cat >&2 <<EOM
! Usage: $me [-dehrESV] [-f config.sh] [-D symbol] [-D symbol=value]
                   [-U symbol] [-U symbol=]
    -d : use defaults for all answers.
    -e : go on without questioning past the production of config.sh.
--- 621,627 ----
  case "$error" in
  true)
  	cat >&2 <<EOM
! Usage: $me [-dehrEOSV] [-f config.sh] [-D symbol] [-D symbol=value]
                   [-U symbol] [-U symbol=]
    -d : use defaults for all answers.
    -e : go on without questioning past the production of config.sh.
***************
*** 623,628 ****
--- 633,639 ----
           -D symbol         symbol gets the value 'define'
           -D symbol=value   symbol gets the value 'value'
    -E : stop at the end of questions, after having produced config.sh.
+   -O : let -D and -U override definitions from loaded configuration file.
    -S : perform variable substitutions on all .SH files (can mix with -f)
    -U : undefine symbol:
           -U symbol    symbol gets the value 'undef'
***************
*** 638,647 ****
  true) exec 1>/dev/null;;
  esac
  
! : run the defines and the undefines, if any
  touch $optdef
  . ./$optdef
- rm -f $optdef
  
  case "$extractsh" in
  true)
--- 649,657 ----
  true) exec 1>/dev/null;;
  esac
  
! : run the defines and the undefines, if any, but leave the file out there...
  touch $optdef
  . ./$optdef
  
  case "$extractsh" in
  true)
***************
*** 654,659 ****
--- 664,670 ----
  	echo "Fetching answers from $config_sh..."
  	cd ..
  	. $config
+ 	test "$override" && . ./$optdef
  	echo " "
  	. ./UU/extract
  	rm -rf UU
***************
*** 802,807 ****
--- 813,833 ----
  	case  "\$answ" in
  	"\$ans")
  		case "\$ans" in
+ 		\\&*)
+ 			set x \`expr "X\$ans" : "X&\(.*\)\$"\`
+ 			shift
+ 			case "\$1" in
+ 			-d)
+ 				fastread=yes
+ 				echo "(OK, I'll run with -d after this question.)"
+ 				;;
+ 			-*)
+ 				echo "*** Sorry, \$1 not supported yet."
+ 				;;
+ 			esac
+ 			$myecho
+ 			ans=!
+ 			;;
  		"!")
  			sh 1>&4
  			echo " "
***************
*** 901,906 ****
--- 927,934 ----
  If you are in a hurry, you may run 'Configure -d'.  This will bypass nearly all
  the questions and use the computed defaults (or the previous answers if there
  was already a config.sh file). Type 'Configure -h' for a list of options.
+ You may also start interactively and then answer '& -d' at any prompt to turn
+ on the non-interactive behaviour for the remaining of the execution.
  
  EOH
  	. ./myread
***************
*** 934,947 ****
  : see if sh knows # comments
  echo " "
  echo "Checking your sh to see if it knows about # comments..." >&4
! if sh -c '#' >/dev/null 2>&1 ; then
  	echo "Your sh handles # comments correctly."
  	shsharp=true
  	spitshell=cat
  	echo " "
  	echo "Okay, let's see if #! works on this system..."
  	xcat=/bin/cat
! 	test -r $xcat || xcat=/usr/bin/cat
  	echo "#!$xcat" >try
  	$eunicefix try
  	chmod +x try
--- 962,975 ----
  : see if sh knows # comments
  echo " "
  echo "Checking your sh to see if it knows about # comments..." >&4
! if `sh -c '#' >/dev/null 2>&1`; then
  	echo "Your sh handles # comments correctly."
  	shsharp=true
  	spitshell=cat
  	echo " "
  	echo "Okay, let's see if #! works on this system..."
  	xcat=/bin/cat
! 	test -f $xcat || xcat=/usr/bin/cat
  	echo "#!$xcat" >try
  	$eunicefix try
  	chmod +x try
***************
*** 1024,1030 ****
  		: just loop through to pick last item
  	done
  	if test -f \$thisthing; then
! 		echo \$dir/\$thing
  		exit 0
  	elif test -f \$dir/\$thing.exe; then
  		: on Eunice apparently
--- 1052,1058 ----
  		: just loop through to pick last item
  	done
  	if test -f \$thisthing; then
! 		echo \$thisthing
  		exit 0
  	elif test -f \$dir/\$thing.exe; then
  		: on Eunice apparently
***************
*** 1045,1054 ****
--- 1073,1084 ----
  chgrp
  chmod
  chown
+ comm
  echo
  expr
  grep
  ln
+ mkdir
  mv
  rm
  sed
***************
*** 1118,1124 ****
  	echo "Hopefully test is built into your sh."
  	;;
  *)
! 	if sh -c "PATH= test true" >/dev/null 2>&1; then
  		echo "Using the test built into your sh."
  		test=test
  		_test=test
--- 1148,1154 ----
  	echo "Hopefully test is built into your sh."
  	;;
  *)
! 	if `sh -c "PATH= test true" >/dev/null 2>&1`; then
  		echo "Using the test built into your sh."
  		test=test
  		_test=test
***************
*** 1226,1231 ****
--- 1256,1262 ----
  		tmp_n="$n"
  		tmp_c="$c"
  		. ../config.sh
+ 		test "$override" && . ./$optdef
  		cp ../config.sh .
  		n="$tmp_n"
  		c="$tmp_c"
***************
*** 1243,1248 ****
--- 1274,1280 ----
  	cp $config_sh config.sh 2>/dev/null
  	. ./config.sh
  	cd UU
+ 	test "$override" && . ./$optdef
  	cp ../config.sh .
  	n="$tmp_n"
  	c="$tmp_c"
***************
*** 1285,1293 ****
  . ./myread
  case "$ans" in
  	y*) d_portable="$define"
- 	for file in $loclist $trylist; do
- 		eval $file="\$file"
- 	done
  	;;
  	*)  d_portable="$undef" ;;
  esac
--- 1317,1322 ----
***************
*** 1345,1350 ****
--- 1374,1386 ----
  orig_dflt="$dflt"
  
  case "$fn" in
+ *\(*)
+ 	expr $fn : '.*(\(.*\)).*' | tr ',' '\012' >getfile.ok
+ 	fn=`echo $fn | sed 's/(.*)//'`
+ 	;;
+ esac
+ 
+ case "$fn" in
  *:*)
  	loc_file=`expr $fn : '.*:\(.*\)'`
  	fn=`expr $fn : '\(.*\):.*'`
***************
*** 1399,1404 ****
--- 1435,1447 ----
  	true) rp="$rp (~name ok)";;
  	esac
  	. UU/myread
+ 	if test -f UU/getfile.ok && \
+ 		$contains "^$ans\$" UU/getfile.ok >/dev/null 2>&1
+ 	then
+ 		value="$ans"
+ 		ansexp="$ans"
+ 		break
+ 	fi
  	case "$ans" in
  	none)
  		value=''
***************
*** 1416,1422 ****
  			case $? in
  			0)
  				if test "$ans" != "$value"; then
! 					echo "(That is $value on this particular system.)"
  				fi
  				;;
  			*) value="$ans";;
--- 1459,1465 ----
  			case $? in
  			0)
  				if test "$ans" != "$value"; then
! 					echo "(That expands to $value on this system.)"
  				fi
  				;;
  			*) value="$ans";;
***************
*** 1518,1523 ****
--- 1561,1567 ----
  ans="$value"
  rp="$orig_rp"
  dflt="$orig_dflt"
+ rm -f getfile.ok
  EOSC
  
  : determine where manual pages are on this system
***************
*** 1804,1810 ****
  	cc="$ans"
  fi
  echo " "
! echo "Checking if you are using GNU cc ..." >&4
  $cat >gccvers.c <<EOM
  #include <stdio.h>
  int main() {
--- 1848,1854 ----
  	cc="$ans"
  fi
  echo " "
! echo "Checking for GNU cc in disguise and/or its version number..." >&4
  $cat >gccvers.c <<EOM
  #include <stdio.h>
  int main() {
***************
*** 1872,1878 ****
  
  : Set private lib path
  case "$plibpth" in
! '') if mips; then
  		plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
  	fi;;
  esac
--- 1916,1922 ----
  
  : Set private lib path
  case "$plibpth" in
! '') if ./mips; then
  		plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
  	fi;;
  esac
***************
*** 3419,3424 ****
--- 3463,3469 ----
  
  : get C preprocessor symbols handy
  echo " "
+ $echo $n "Hmm... $c"
  echo $al | $tr ' ' '\012' >Cppsym.know
  $cat <<EOSS >Cppsym
  $startsh
***************
*** 3465,3473 ****
  EOSS
  chmod +x Cppsym
  $eunicefix Cppsym
! echo "Your C preprocessor defines the following symbols:"
! Cppsym -l $al >Cppsym.true
! $cat Cppsym.true
  
  : see if this is a termio system
  val="$undef"
--- 3510,3571 ----
  EOSS
  chmod +x Cppsym
  $eunicefix Cppsym
! ./Cppsym -l $al | $sort | $grep -v '^$' >Cppsym.true
! 
! : now check the C compiler for additional symbols
! $cat >ccsym <<EOS
! $startsh
! $cat >tmp.c <<EOF
! extern int foo;
! EOF
! for i in \`$cc -v -c tmp.c 2>&1\`
! do
! 	case "\$i" in
! 	-D*) echo "\$i" | $sed 's/^-D//';;
! 	-A*) $test "$gccversion" && echo "\$i" | $sed 's/^-A\(.*\)(\(.*\))/\1=\2/';;
! 	esac
! done
! $rm -f try.c
! EOS
! chmod +x ccsym
! $eunicefix ccsym
! ./ccsym | $sort | $uniq >ccsym.raw
! $awk '/\=/ { print $0; next } { print $0"=1" }' ccsym.raw >ccsym.list
! $awk '{ print $0"=1" }' Cppsym.true >ccsym.true
! $comm -13 ccsym.true ccsym.list >ccsym.own
! $comm -12 ccsym.true ccsym.list >ccsym.com
! $comm -23 ccsym.true ccsym.list >ccsym.cpp
! also=''
! symbols='symbols'
! if $test -z ccsym.raw; then
! 	echo "Your C compiler doesn't seem to define any symbol!" >&4
! 	echo " "
! 	echo "However, your C preprocessor defines the following ones:"
! 	$cat Cppsym.true
! else
! 	if $test -s ccsym.com; then
! 		echo "Your C compiler and pre-processor define these symbols:"
! 		$sed -e 's/\(.*\)=.*/\1/' ccsym.com
! 		also='also '
! 		symbols='ones'
! 		$test "$silent" || sleep 1
! 	fi
! 	if $test -s ccsym.cpp; then
! 		$test "$also" && echo " "
! 		echo "Your C pre-processor ${also}defines the following $symbols:"
! 		$sed -e 's/\(.*\)=.*/\1/' ccsym.cpp
! 		also='further '
! 		$test "$silent" || sleep 1
! 	fi
! 	if $test -s ccsym.own; then
! 		$test "$also" && echo " "
! 		echo "Your C compiler ${also}defines the following cpp variables:"
! 		$sed -e 's/\(.*\)=1/\1/' ccsym.own
! 		$sed -e 's/\(.*\)=.*/\1/' ccsym.own | $uniq >>Cppsym.true
! 		$test "$silent" || sleep 1
! 	fi
! fi
! $rm -f ccsym*
  
  : see if this is a termio system
  val="$undef"
***************
*** 3614,3621 ****
  echo " "
  case "$defeditor" in
  '')
! 	case "$_vi" in
! 	*/*) dflt="$_vi";;
  	*) dflt=/usr/ucb/vi;;
  	esac
  	;;
--- 3712,3719 ----
  echo " "
  case "$defeditor" in
  '')
! 	case "$vi" in
! 	*/*) dflt="$vi";;
  	*) dflt=/usr/ucb/vi;;
  	esac
  	;;
***************
*** 3720,3725 ****
--- 3818,3948 ----
  	;;
  esac
  
+ : locate a BSD compatible install program
+ echo " "
+ echo "Looking for a BSD-compatible install program..." >&4
+ creatdir=''
+ case "$install" in
+ '')
+ 	tryit=''
+ 	for file in ginstall installbsd scoinst install; do
+ 		for dir in $pth; do
+ 			if $test -f $dir/$file; then
+ 				tryit="$tryit $dir/$file"
+ 				break
+ 			fi
+ 		done
+ 	done
+ 	$cat >try.c <<EOC
+ main()
+ {
+ 	printf("OK\n");
+ 	exit(0);
+ }
+ EOC
+ 	if $cc try.c -o try >/dev/null 2>&1; then
+ 		cp try try.ns
+ 		strip try >/dev/null 2>&1
+ 	else
+ 		echo "(I can't seem to compile a trivial C program -- bypassing.)"
+ 		echo "try" >try
+ 		cp try try.ns
+ 	fi
+ 	$cat >tryinst <<EOS
+ $startsh
+ $rm -rf foo d
+ \$1 -d foo/bar
+ $mkdir d
+ \$1 -c -m 764 try.ns d
+ \$1 -c -s -m 642 try.ns d/try
+ EOS
+ 	chmod +x tryinst
+ 	$eunicefix tryinst
+ 	dflt=''
+ 	either=''
+ 	for prog in $tryit; do
+ 		$echo $n "Checking $prog... $c"
+ 		./tryinst $prog >/dev/null 2>&1
+ 		if $test -d foo/bar; then
+ 			creatdir="$prog -d"
+ 		fi
+ 		(ls -l d/try >try.ls; ls -l d/try.ns >tryno.ls) 2>/dev/null
+ 		if (cmp -s d/try try && cmp -s d/try.ns try.ns && \
+ 			$contains 'rwxrw-r--' tryno.ls && \
+ 			$contains 'rw-r---w-' try.ls) >/dev/null 2>&1
+ 		then
+ 			dflt="$prog"
+ 			echo "ok, that will do."
+ 			break
+ 		fi
+ 		echo "not good$either."
+ 		either=' either'
+ 		$rm -f try*.ls
+ 	done
+ 	$rm -rf foo d tryinst try try*.ls try.*
+ 	case "$dflt" in
+ 	'')
+ 		echo "Hopefully, $package comes with its own install script!"
+ 		dflt='./install'
+ 		;;
+ 	esac
+ 	;;
+ *) dflt="$install";;
+ esac
+ $cat <<EOM
+ 
+ I will be requiring a BSD-compatible install program (one that allows
+ options like -s to strip executables or -m to specify a file mode) to
+ install $package.
+ 
+ If the question below contains a fully qualified default path, then it
+ is probably ok. If it is an unqualified name such as 'install', then it
+ means I was unable to find out a good install program I could use. If
+ you know of one, please tell me about it. If the default is './install',
+ then I shall be using the install script supplied with $package.
+ 
+ EOM
+ fn='/fe~(install,./install)'
+ rp='Which install program shall I use?'
+ . ./getfile
+ install="$ans"
+ 
+ : how can we create nested directories?
+ echo " "
+ echo "Ok, let's see how we can create nested directories..." >&4
+ case "$installdir" in
+ '')
+ 	case "$creatdir" in
+ 	'')
+ 		$mkdir -p foo/bar >/dev/null 2>&1
+ 		if $test -d foo/bar; then
+ 			echo "Great, we can build them using 'mkdir -p'."
+ 			creatdir='mkdir -p'
+ 		elif eval "$install -d foo/bar"; $test -d foo/bar; then
+ 			creatdir="install -d"
+ 			echo "It looks like '$creatdir' will do it for us."
+ 		fi
+ 		;;
+ 	*)
+ 		eval "$creatdir foo/bar" >/dev/null 2>&1
+ 		if $test -d foo/bar; then
+ 			echo "Ah! We can use '$creatdir' to do just that."
+ 		fi
+ 		;;
+ 	esac
+ 	$rm -rf foo
+ 	case "$creatdir" in
+ 	'')
+ 		echo "Heck! Another ancient system lacking the comfort of modern ones!"
+ 		echo "You can thank $package for bringing you its own install script!"
+ 		installdir='./install -d'
+ 		;;
+ 	*) installdir="$creatdir";;
+ 	esac
+ 	;;
+ *) echo "As you already told me, '$installdir' should work.";;
+ esac
+ 
  : is AFS running?
  echo " "
  if test -d /afs; then
***************
*** 3796,3802 ****
  
  $package has manual pages available in source form.
  EOM
! case "$_nroff" in
  nroff)
  	echo "However, you don't have nroff, so they're probably useless to you."
  	case "$mansrc" in
--- 4019,4025 ----
  
  $package has manual pages available in source form.
  EOM
! case "$nroff" in
  nroff)
  	echo "However, you don't have nroff, so they're probably useless to you."
  	case "$mansrc" in
***************
*** 3988,3999 ****
  : determine the name of a reasonable mailer
  case "$mailer" in
  '')
! 	if $test -f "$_sendmail"; then
! 		dflt="$_sendmail"
! 	elif $test -f "$_smail"; then
! 		dflt="$_smail"
! 	elif $test -f "$_rmail"; then
! 		dflt="$_rmail"
  	elif $test -f /bin/mail; then
  		dflt=/bin/mail
  	else
--- 4211,4222 ----
  : determine the name of a reasonable mailer
  case "$mailer" in
  '')
! 	if $test -f "$sendmail"; then
! 		dflt="$sendmail"
! 	elif $test -f "$smail"; then
! 		dflt="$smail"
! 	elif $test -f "$rmail"; then
! 		dflt="$rmail"
  	elif $test -f /bin/mail; then
  		dflt=/bin/mail
  	else
***************
*** 4291,4298 ****
  	if test -f /usr/bin/perl; then
  		dflt=/usr/bin/perl
  	else
! 		case "$_perl" in
! 		*/*) dflt="$_perl";;
  		*) dflt=/usr/bin/perl;;
  		esac
  	fi
--- 4514,4521 ----
  	if test -f /usr/bin/perl; then
  		dflt=/usr/bin/perl
  	else
! 		case "$perl" in
! 		*/*) dflt="$perl";;
  		*) dflt=/usr/bin/perl;;
  		esac
  	fi
***************
*** 4520,4535 ****
  
  : check for void type
  echo " "
  $cat >&4 <<EOM
- Checking to see how well your C compiler groks the void type...
- 
    Support flag bits are:
      1: basic void declarations.
      2: arrays of pointers to functions returning void.
      4: operations between pointers to and addresses of void functions.
      8: generic void pointers.
- 
  EOM
  case "$voidflags" in
  '')
  	$cat >try.c <<'EOCP'
--- 4743,4758 ----
  
  : check for void type
  echo " "
+ echo "Checking to see how well your C compiler groks the void type..." >&4
+ echo " "
  $cat >&4 <<EOM
    Support flag bits are:
      1: basic void declarations.
      2: arrays of pointers to functions returning void.
      4: operations between pointers to and addresses of void functions.
      8: generic void pointers.
  EOM
+ echo " "
  case "$voidflags" in
  '')
  	$cat >try.c <<'EOCP'
***************
*** 5091,5096 ****
--- 5314,5330 ----
  	esac
  fi
  
+ : in case they want portability, strip down executable paths
+ case "$d_portable" in
+ "$define")
+ 	echo " "
+ 	echo "Stripping down executable paths..." >&4
+ 	for file in $loclist $trylist; do
+ 		eval $file="\$file"
+ 	done
+ 	;;
+ esac
+ 
  : create config.sh file
  echo " "
  echo "Creating config.sh..." >&4
***************
*** 5120,5125 ****
--- 5354,5360 ----
  chgrp='$chgrp'
  chmod='$chmod'
  chown='$chown'
+ comm='$comm'
  compress='$compress'
  cp='$cp'
  cpio='$cpio'
***************
*** 5265,5270 ****
--- 5500,5507 ----
  i_systimek='$i_systimek'
  i_time='$i_time'
  timeincl='$timeincl'
+ install='$install'
+ installdir='$installdir'
  intsize='$intsize'
  libc='$libc'
  glibpth='$glibpth'

Index: agent/man/mailagent.SH
Prereq: 3.0.1.9
*** agent/man/mailagent.SH.old	Wed Jan 25 16:34:30 1995
--- agent/man/mailagent.SH	Wed Jan 25 16:34:31 1995
***************
*** 20,26 ****
  .TH MAILAGENT $manext "Version $VERSION PL$PATCHLEVEL"
  ''' @(#) Manual page for mailagent's filter -- (c) ram February 1991
  '''
! ''' $Id: mailagent.SH,v 3.0.1.9 1995/01/03 18:01:53 ram Exp $
  '''
  '''  Copyright (c) 1990-1993, Raphael Manfredi
  '''  
--- 20,26 ----
  .TH MAILAGENT $manext "Version $VERSION PL$PATCHLEVEL"
  ''' @(#) Manual page for mailagent's filter -- (c) ram February 1991
  '''
! ''' $Id: mailagent.SH,v 3.0.1.10 1995/01/25 15:17:42 ram Exp $
  '''
  '''  Copyright (c) 1990-1993, Raphael Manfredi
  '''  
***************
*** 31,36 ****
--- 31,41 ----
  '''  of the source tree for mailagent 3.0.
  '''
  ''' $Log: mailagent.SH,v $
+ ''' Revision 3.0.1.10  1995/01/25  15:17:42  ram
+ ''' patch27: new option letter 't' for mailagent -s
+ ''' patch27: new commands BEEP and PROTECT
+ ''' patch27: new macro %a for biff messages
+ '''
  ''' Revision 3.0.1.9  1995/01/03  18:01:53  ram
  ''' patch24: new -u option for ANNOTATE documented
  ''' patch24: fixed example on the shell server command (power checking)
***************
*** 91,97 ****
  .SH NAME
  mailagent \- an automatic mail-processing tool
  .SH SYNOPSIS
! \fBmailagent\fR [ \fB\-dhilqtFV\fR ] [ \fB\-s{umary}\fR ] [ \fB\-f\fI file\fR ]
  [ \fB\-e\fI rule\fR ] [ \fB\-c\fI config\fR ] [ \fB\-L\fI loglevel\fR ]
  [ \fB\-r\fI rulefile\fR ] [ \fB\-o\fI override\fR ] [ \fImailfile\fR ]
  .SH DESCRIPTION
--- 96,102 ----
  .SH NAME
  mailagent \- an automatic mail-processing tool
  .SH SYNOPSIS
! \fBmailagent\fR [ \fB\-dhilqtFV\fR ] [ \fB\-s{umaryt}\fR ] [ \fB\-f\fI file\fR ]
  [ \fB\-e\fI rule\fR ] [ \fB\-c\fI config\fR ] [ \fB\-L\fI loglevel\fR ]
  [ \fB\-r\fI rulefile\fR ] [ \fB\-o\fI override\fR ] [ \fImailfile\fR ]
  .SH DESCRIPTION
***************
*** 832,840 ****
  .B \-r\fI file\fR
  Specify an alternate rule file.
  .TP
! .B \-s {umary}
  Build a summary of all the statistics gathered so far. The output can be
! controlled by appending one or more letters from the set {umary}. Using
  \fB\-summary\fR is a convenient way to get the whole history of the filter
  actions. The \fBu\fR modifier will print only used rules. The \fBm\fR will
  merge all the statistics at the end while \fBa\fR reports the mode the
--- 837,845 ----
  .B \-r\fI file\fR
  Specify an alternate rule file.
  .TP
! .B \-s {umaryt}
  Build a summary of all the statistics gathered so far. The output can be
! controlled by appending one or more letters from the set {umaryt}. Using
  \fB\-summary\fR is a convenient way to get the whole history of the filter
  actions. The \fBu\fR modifier will print only used rules. The \fBm\fR will
  merge all the statistics at the end while \fBa\fR reports the mode the
***************
*** 842,848 ****
  statistics and the \fBy\fR is pretty useless and is here only to get a nice
  mnemonic option. Note that specifying an option more than once has no effect
  whatsoever on the option itself (i.e. you may put three \fBUu\fR and only
! one \fBm\fR, but you'll still get the summary!).
  .TP
  .B \-t
  Put the mailagent in a special tracking mode where all the rule matches and
--- 847,858 ----
  statistics and the \fBy\fR is pretty useless and is here only to get a nice
  mnemonic option. Note that specifying an option more than once has no effect
  whatsoever on the option itself (i.e. you may put three \fBUu\fR and only
! one \fBm\fR, but you'll still get the summary!). The \fBt\fR letter may be
! followed by digits specifying how many rule file versions relative to the
! topmost (most recent) rule file we should extract from the statistics, that
! amount defaulting to 1: using \fB-surat\fR will print a complete statistics
! report for the last version of your rules, while \fB-surt12a\fR would do the
! same for the last twelve versions of those same rules.
  .TP
  .B \-t
  Put the mailagent in a special tracking mode where all the rule matches and
***************
*** 1534,1545 ****
  for instance, is changed: we do not take a body back but commands.
  (The execution status is that of the \fIcommand\fR)
  .TP
  BEGIN \fIstate\fR
  Enter a new state. An explicit REJECT or RESTART is necessary to abort the
  processing of the current rule. The processing begins in state INITIAL.
  (Does not modify existing status)
  .TP
! BOUNCE \fIaddress(es)
  Bounce the message to the specified address(es) and acts as if a save had
  been done. The only difference with FORWARD is that no Resent-like lines are
  added to the header. If an address is specified in double quotes, it is taken
--- 1544,1573 ----
  for instance, is changed: we do not take a body back but commands.
  (The execution status is that of the \fIcommand\fR)
  .TP
+ BEEP [-l] \fIcount\fR
+ This command may be used to tune the amount of beeps emitted when biffing on
+ the terminal, for each \fI%a\fR expansion. By default, that amount is set to 1.
+ Using the \fB\-l\fR option alters the beep count locally for the rule.
+ Otherwise, the default amount is changed.
+ .sp
+ Note that this simply expands %a into the suitable amount of Ctrl-G characters.
+ Your terminal must be allowed to issue consecutive bells for this to work.
+ Very often, terminals are configured so that the first bell received disables
+ further beeps for some period, to avoid cascades of bells.
+ If you use \fIxterm\fR for instance, you should use:
+ .Ex
+ xterm -xrm "XTerm*BellSuppressTime: 0"
+ .Ef
+ to enable consecutive bells. Otherwise, \fIxterm\fR will swallow them during
+ 200 ms, hence making the BEEP command ineffective, apparently.
+ (Does not modify existing status)
+ .TP
  BEGIN \fIstate\fR
  Enter a new state. An explicit REJECT or RESTART is necessary to abort the
  processing of the current rule. The processing begins in state INITIAL.
  (Does not modify existing status)
  .TP
! BOUNCE \fIaddress(es)\fR
  Bounce the message to the specified address(es) and acts as if a save had
  been done. The only difference with FORWARD is that no Resent-like lines are
  added to the header. If an address is specified in double quotes, it is taken
***************
*** 1676,1681 ****
--- 1704,1726 ----
  subject is PROCESS.
  (Always returns success)
  .TP
+ PROTECT [-lu] \fImode\fR
+ Sets the default protection mode that should be set on created folders
+ (or created files when saving into an MH folder or a directory). By default,
+ permissions are governed by the UMASK command, but this lets you override
+ the default. The specified \fImode\fR should be preceded by a \fB0\fR as
+ in \fI0644\fR to give the familiar octal permissions. Otherwise, it is
+ interpreted as a decimal number, so beware!
+ .sp
+ The \fB\-l\fR option may be used to specify a mode locally for one rule.
+ Otherwise, the protection mode is set globally. The \fB\-u\fR option unsets
+ the global (or local when combined with \fB-l\fR) mode, reverting to the
+ default behaviour where only the umask is taken into account by the system.
+ .sp
+ Note that when saving into an MH folder, the PROTECT command takes precedence
+ over the \fIMsg-Protect\fR field from your ~/.mh_profile file.
+ (Does not alter execution status)
+ .TP
  PURIFY \fIprogram\fR
  Feed the header into a program and get new header back. No RESYNC is done.
  This may be used to indeed purify the header by removing all the verbose
***************
*** 2847,2854 ****
  The folder path. It has the correct semantics for MH and directory folders,
  i.e. it points to the folder directory itself. Otherwise, the same as %p.
  .TP
  %b
! A beeping character (^G)
  .TP
  %d
  Full path where folders such as the one being saved into are stored if not
--- 2892,2905 ----
  The folder path. It has the correct semantics for MH and directory folders,
  i.e. it points to the folder directory itself. Otherwise, the same as %p.
  .TP
+ %a
+ Alarm characters (^G).
+ May expand to more than one under the control
+ of the BEEP filtering command. Use %b if you only want a single bell.
+ .TP
  %b
! A beeping character (^G).
! As opposed to %a, this only expands to give \fBone\fR bell.
  .TP
  %d
  Full path where folders such as the one being saved into are stored if not

Index: ChangeLog
*** ChangeLog.old	Wed Jan 25 16:45:03 1995
--- ChangeLog	Wed Jan 25 16:45:03 1995
***************
*** 1,3 ****
--- 1,117 ----
+ Wed Jan 25 16:44:40 MET 1995   Raphael Manfredi <ram@acri.fr>
+ 
+ . Description:
+ 
+ 	Regenerated Configure with metaconfig 3.0 PL48 for install
+ 	binary lookup.
+ 
+ 	Regenerated most Makefile.SH files with jmake 3.0 PL48 to
+ 	benefit from the install lookup.
+ 
+ 	Extended copyright notice to include year 1995.
+ 
+ 	Mailagent now works with perl 5.0. It has been fully tested on
+ 	my DEC OSF/1 3.0 machine and passes all its regression tests.
+ 	However, this perl 5.0 is a version patched with early
+ 	patches from the perl5-porters list. See the README file for
+ 	instructions about how to get those patches.
+ 
+ 	New option letter 't' for mailagent -s. The 'mailagent -surat'
+ 	command will only deliver statistics for the top-level rule file.
+ 	Indeed, each time your rule file changes, mailagent normally
+ 	starts a new set of statistics on top of older ones.
+ 
+ 	New commands BEEP and PROTECT. The BEEP command controls the new
+ 	%a macro for biffing message, which is expanded into the matching
+ 	amount of ^G characters. The PROTECT commands lets you define
+ 	file protections for newly created folders.
+ 
+ 	I also added support for the Msg-Protect MH profile component
+ 	when saving into an MH folder, at Eric M. Carroll's request.
+ 	However, the new PROTECT command can override the default Msg-Protect
+ 	specification from your ~/.mh_profile.
+ 
+ 	Added support for NFS bug on remote read-only folders. Indeed, SUN's
+ 	NFS running on SUN 4.1.2 was allowing a remote write to a read-only
+ 	folder lying on my DEC OSF/1 3.0 machine...
+ 
+ 	Destination address for PROCESS is now parsed correctly, by using
+ 	the RFC822 parser instead of a local hacked parsing.
+ 
+ 	Ported many files to perl 5.0 PL0. This included workarounds for
+ 	perl 5.0 bugs, and lots of @ escaping in strings and patterns,
+ 	mainly in the regression test suite.
+ 
+ 	Avoid problems on slow machines in test mode for queue timestamps.
+ 	Some slow machines were reported to fail some tests in option/l.
+ 	I made sure those will not occur any more by twiddling with the
+ 	queue output string in test mode.
+ 
+ 	UNSEEN mark in log has the home directory stripped via &tilda.
+ 
+ 	Two new files.
+ 
+ . Files changed:
+ 
+ 	* agent/man/mailagent.SH: New option letter 't' for mailagent -s. 
+ 	New commands BEEP and PROTECT.  New macro %a for biff messages.
+ 
+ 	* agent/pl/actions.pl: Added support for NFS bug on remote read-only
+ 	folders.  Destination address for PROCESS is now parsed correctly. 
+ 	Added support for folder mode change, as defined by PROTECT.
+ 
+ 	* agent/pl/biff.pl: New macro %a for variable bells, under the
+ 	control of BEEP.
+ 
+ 	* agent/pl/filter.pl: New commands BEEP and PROTECT.
+ 
+ 	* agent/pl/getdate.pl: Fixed a typo in &yyerror and various code
+ 	clean-up.  Ported to perl 5.0 PL0.
+ 
+ 	* agent/pl/lexical.pl: Added automatic @ escape in patterns for perl
+ 	5.0.
+ 
+ 	* agent/pl/listqueue.pl: Avoid problems on slow machines in test mode
+ 	for queue timestamps.
+ 
+ 	* agent/test/cmd/vacation.t, agent/test/cmd/notify.t,
+ 	agent/pl/parse.pl, agent/pl/queue_mail.pl, agent/test/misc/compress.t,
+ 	, agent/test/cmd/message.t, agent/pl/macros.pl: Ported to perl 5.0
+ 	PL0.
+ 
+ 	* agent/pl/mh.pl: Added support for the Msg-Protect MH profile
+ 	component.  Allows new PROTECT command to override default
+ 	Msg-Protect.  UNSEEN mark in log has the home directory stripped via
+ 	&tilda.
+ 
+ 	* agent/pl/mmdf.pl: New routine &chmod for folder permission settting.
+ 
+ 	* agent/pl/read_conf.pl: Escape all @ in config file for perl 5.0.
+ 
+ 	* agent/pl/rulenv.pl: New routines &unset and &undef.  Added default
+ 	values for PROTECT and BEEP.  Added logs in case of eval errors for
+ 	perl 5.0.
+ 
+ 	* agent/pl/runcmd.pl: New commands PROTECT and BEEP.
+ 
+ 	* agent/pl/signals.pl: Put signal handler names into double quotes
+ 	for perl 5.0.
+ 
+ 	* agent/pl/stats.pl: Now supports 't' to track only top-most rule
+ 	file stats.
+ 
+ 	* agent/pl/usrmac.pl: Ported to perl 5.0 PL0.  Added eval error
+ 	tracking for perl 5.0.
+ 
+ 	* agent/test/actions: Extended rules for the PROTECT command tests.
+ 
+ 	* agent/test/basic/config.t: Now sets a default umask in the
+ 	configuration.
+ 
+ 	* agent/test/cmd/protect.t, agent/test/cmd/beep.t: Created.
+ 
+ 	* agent/test/misc/mh.t: Added checks for Msg-Protect and PROTECT.
+ 
  Tue Jan 03 19:36:49 MET 1995   Raphael Manfredi <ram@acri.fr>
  
  . Description:

Index: agent/pl/mh.pl
Prereq: 3.0.1.2
*** agent/pl/mh.pl.old	Wed Jan 25 16:34:38 1995
--- agent/pl/mh.pl	Wed Jan 25 16:34:38 1995
***************
*** 1,4 ****
! ;# $Id: mh.pl,v 3.0.1.2 1994/09/22 14:27:16 ram Exp $
  ;#
  ;#  Copyright (c) 1990-1993, Raphael Manfredi
  ;#  
--- 1,4 ----
! ;# $Id: mh.pl,v 3.0.1.3 1995/01/25 15:26:22 ram Exp $
  ;#
  ;#  Copyright (c) 1990-1993, Raphael Manfredi
  ;#  
***************
*** 9,14 ****
--- 9,19 ----
  ;#  of the source tree for mailagent 3.0.
  ;#
  ;# $Log: mh.pl,v $
+ ;# Revision 3.0.1.3  1995/01/25  15:26:22  ram
+ ;# patch27: added support for the Msg-Protect MH profile component
+ ;# patch27: allows new PROTECT command to override default Msg-Protect
+ ;# patch27: UNSEEN mark in log has the home directory stripped via &tilda
+ ;#
  ;# Revision 3.0.1.2  1994/09/22  14:27:16  ram
  ;# patch12: now updates folder_saved variable with file pathname
  ;#
***************
*** 32,56 ****
  package mh;
  
  # Attempt to save in a MH directory folder. Note that the profile entry
! # Msg-Protect is not honored (always 0600, mailagent's default).
  sub save {
  	local($folder) = @_;		# MH folder name (without leading '+')
  	&profile;					# Get MH profile, once and for all
  	$folder = "$cf'home/$Profile{'Path'}/$folder";
  	local($mode) = oct("0$Profile{'Folder-Protect'}" || '0700');
  	&'makedir($folder, $mode);	# Create folder dir with right permissions
! 	&save_msg($folder, 'MH');	# Propagate failure status
  }
  	
  # Save in a directory, not really an MH folder.
  sub savedir {
  	local($folder) = @_;		# Directory folder name
! 	&save_msg($folder, 'DIR');	# Propagate failure status
  }
  
  # Common subroutine to &save and &savedir
  sub save_msg {
! 	local($folder, $mh) = @_;
  	unless (-d $folder) {
  		&'add_log("ERROR $mh folder $folder is not a directory")
  			if $'loglvl > 1;
--- 37,67 ----
  package mh;
  
  # Attempt to save in a MH directory folder. Note that the profile entry
! # Msg-Protect is honored, unless overridden by a PROTECT command.
  sub save {
  	local($folder) = @_;		# MH folder name (without leading '+')
  	&profile;					# Get MH profile, once and for all
+ 	local($fmode);				# File protection mode
  	$folder = "$cf'home/$Profile{'Path'}/$folder";
  	local($mode) = oct("0$Profile{'Folder-Protect'}" || '0700');
+ 	$fmode = oct("0$Profile{'Msg-Protect'}") if defined $Profile{'Msg-Protect'};
+ 	$fmode = $env'protect if defined $env'protect;
  	&'makedir($folder, $mode);	# Create folder dir with right permissions
! 	&save_msg($folder, $fmode, 'MH');	# Propagate failure status
  }
  	
  # Save in a directory, not really an MH folder.
+ # Message protection is adjusted if a PROTECT was issued.
  sub savedir {
  	local($folder) = @_;		# Directory folder name
! 	local($fmode);				# File protection mode
! 	$fmode = $env'protect if defined $env'protect;
! 	&save_msg($folder, $fmode, 'DIR');	# Propagate failure status
  }
  
  # Common subroutine to &save and &savedir
  sub save_msg {
! 	local($folder, $fmode, $mh) = @_;
  	unless (-d $folder) {
  		&'add_log("ERROR $mh folder $folder is not a directory")
  			if $'loglvl > 1;
***************
*** 84,89 ****
--- 95,101 ----
  		if $size != $amount && $'loglvl;
  
  	$failed = 1 if $size != $amount;
+ 	&mmdf'chmod($fmode, $name) if defined $fmode;	# Ignore chmod errors
  
  	# Update the unseen sequence, if needed and saving succeeded. An entry
  	# is also made in the logfile for easy grep'ing and locating of messages
***************
*** 92,98 ****
  	&unseen($name)
  		if $mh eq 'MH' && $Profile{'Unseen-Sequence'} ne '' && !$failed;
  
! 	&'add_log("UNSEEN $name") if $'loglvl > 6;	# Mark clearly in log
  	$'folder_saved = $name;		# Keep track of last folder we save into
  	return $failed;				# Return failure status
  }
--- 104,112 ----
  	&unseen($name)
  		if $mh eq 'MH' && $Profile{'Unseen-Sequence'} ne '' && !$failed;
  
! 	# Mark as unseen in log when saved within a directory
! 	&'add_log("UNSEEN " . &'tilda($name)) if $'loglvl > 6;
! 
  	$'folder_saved = $name;		# Keep track of last folder we save into
  	return $failed;				# Return failure status
  }

*** End of Patch 27 ***

exit 0 # Just in case...

