home *** CD-ROM | disk | FTP | other *** search
- From: Raphael Manfredi <ram@acri.fr>
- Newsgroups: comp.sources.misc
- Subject: v44i088: mailagent - Flexible mail filtering and processing package, v3.0, Patch14
- Date: 22 Sep 1994 12:13:09 -0500
- Organization: Advanced Computer Research Institute, Lyon, France
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <35sdv5$r5c@sparky.sterling.com>
- X-Md4-Signature: e92b7f719734101e1dc4f203bab5ae54
-
- Submitted-by: Raphael Manfredi <ram@acri.fr>
- Posting-number: Volume 44, Issue 88
- Archive-name: mailagent/patch14
- Environment: UNIX, Perl
- Patch-To: mailagent: Volume 41, Issue 1-26
-
- [The latest patch for mailagent version 3.0 is #16.]
-
- System: mailagent version 3.0
- Patch #: 14
- Priority: MEDIUM
- Subject: patch #12, continued
- Date: Thu Sep 22 17:04:34 MET DST 1994
- From: Raphael Manfredi <ram@acri.fr>
-
- Description:
- See patch #12.
-
-
- 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 #16 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: 13
- 4c4
- < #define PATCHLEVEL 13
- ---
- > #define PATCHLEVEL 14
-
- Index: agent/pl/eval.pl
- Prereq: 3.0
- *** agent/pl/eval.pl.old Thu Sep 22 16:43:09 1994
- --- agent/pl/eval.pl Thu Sep 22 16:43:09 1994
- ***************
- *** 1,4 ****
- ! ;# $Id: eval.pl,v 3.0 1993/11/29 13:48:42 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- --- 1,4 ----
- ! ;# $Id: eval.pl,v 3.0.1.1 1994/09/22 14:18:11 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- ***************
- *** 9,14 ****
- --- 9,17 ----
- ;# of the source tree for mailagent 3.0.
- ;#
- ;# $Log: eval.pl,v $
- + ;# Revision 3.0.1.1 1994/09/22 14:18:11 ram
- + ;# patch12: replaced all deprecated 'do sub' calls with '&sub'
- + ;#
- ;# Revision 3.0 1993/11/29 13:48:42 ram
- ;# Baseline for mailagent 3.0 netwide release.
- ;#
- ***************
- *** 19,26 ****
-
- # Initialize the interpreter
- sub init_interpreter {
- ! do set_priorities(); # Fill in %Priority
- ! do set_functions(); # Fill in %Function
- $macro_T = "the Epoch"; # Default value for %T macro substitution
- }
-
- --- 22,29 ----
-
- # Initialize the interpreter
- sub init_interpreter {
- ! &set_priorities; # Fill in %Priority
- ! &set_functions; # Fill in %Function
- $macro_T = "the Epoch"; # Default value for %T macro substitution
- }
-
- ***************
- *** 57,63 ****
-
- # Print error messages -- asssumes $unit and $. correctly set.
- sub error {
- ! do add_log("ERROR @_") if $loglvl > 1;
- }
-
- # Add a value on the stack, modified by all the monadic operators.
- --- 60,66 ----
-
- # Print error messages -- asssumes $unit and $. correctly set.
- sub error {
- ! &add_log("ERROR @_") if $loglvl > 1;
- }
-
- # Add a value on the stack, modified by all the monadic operators.
- ***************
- *** 81,89 ****
- local($val2) = pop(@val); # Right value in algebraic notation
- local($val1) = pop(@val); # Left value in algebraic notation
- local($func) = $Function{$op}; # Function to be called
- ! do macros_subst(*val1); # Expand macros
- ! do macros_subst(*val2);
- ! push(@val, eval("do $func($val1, $val2)") ? 1: 0);
- }
-
- # Given an operator, either we add it in the stack @op, because its
- --- 84,92 ----
- local($val2) = pop(@val); # Right value in algebraic notation
- local($val1) = pop(@val); # Left value in algebraic notation
- local($func) = $Function{$op}; # Function to be called
- ! ¯os_subst(*val1); # Expand macros
- ! ¯os_subst(*val2);
- ! push(@val, eval("&$func($val1, $val2)") ? 1: 0);
- }
-
- # Given an operator, either we add it in the stack @op, because its
- ***************
- *** 94,104 ****
- sub update_stack {
- local($op) = shift(@_); # Operator
- if (!$Priority{$op}) {
- ! do error("illegal operator $op");
- return;
- } else {
- if ($#val < 0) {
- ! do error("missing first operand for '$op' (diadic operator)");
- return;
- }
- # Because of a bug in perl 4.0 PL19, I'm using a loop construct
- --- 97,107 ----
- sub update_stack {
- local($op) = shift(@_); # Operator
- if (!$Priority{$op}) {
- ! &error("illegal operator $op");
- return;
- } else {
- if ($#val < 0) {
- ! &error("missing first operand for '$op' (diadic operator)");
- return;
- }
- # Because of a bug in perl 4.0 PL19, I'm using a loop construct
- ***************
- *** 107,113 ****
- $Priority{$op[$#op]} > $Priority{$op} # Higher priority op
- && $#val > 0 # At least 2 values
- ) {
- ! do execute(); # Execute an higer priority stacked operation
- }
- push(@op, $op); # Everything at higher priority has been executed
- }
- --- 110,116 ----
- $Priority{$op[$#op]} > $Priority{$op} # Higher priority op
- && $#val > 0 # At least 2 values
- ) {
- ! &execute; # Execute an higer priority stacked operation
- }
- push(@op, $op); # Everything at higher priority has been executed
- }
- ***************
- *** 127,169 ****
- # A perl statement <<command>>
- if (s/^<<//) {
- if (s/^(.*)>>//) {
- ! do push_val((system
- ('perl','-e', "if ($1) {exit 0;} else {exit 1;}"
- ))? 0 : 1);
- } else {
- ! do error("incomplete perl statement");
- }
- }
- # A shell statement <command>
- elsif (s/^<//) {
- if (s/^(.*)>//) {
- ! do push_val((system
- ("if $1 >/dev/null 2>&1; then exit 0; else exit 1; fi"
- ))? 0 : 1);
- } else {
- ! do error("incomplete shell statement");
- }
- }
- # The '(' construct
- elsif (s/^\(//) {
- ! do push_val(do eval_expr(*_));
- # A final '\' indicates an end of line
- ! do error("missing final parenthesis") if !s/^\\//;
- }
- # Found a ')' or end of line
- elsif (/^\)/ || /^$/) {
- s/^\)/\\/; # Signals: left parenthesis found
- $expr = $_; # Remove interpreted stuff
- ! do execute() while $#val > 0; # Executed stacked operations
- while ($#op >= 0) {
- $_ = pop(@op);
- ! do error("missing second operand for '$_' (diadic operator)");
- }
- return $val[0];
- }
- # Diadic operators
- elsif (s/^(\|\||&&|>=|<=|>|<|==|!=|=|\/=)//) {
- ! do update_stack($1);
- }
- # Unary operator '!'
- elsif (s/^!//) {
- --- 130,172 ----
- # A perl statement <<command>>
- if (s/^<<//) {
- if (s/^(.*)>>//) {
- ! &push_val((system
- ('perl','-e', "if ($1) {exit 0;} else {exit 1;}"
- ))? 0 : 1);
- } else {
- ! &error("incomplete perl statement");
- }
- }
- # A shell statement <command>
- elsif (s/^<//) {
- if (s/^(.*)>//) {
- ! &push_val((system
- ("if $1 >/dev/null 2>&1; then exit 0; else exit 1; fi"
- ))? 0 : 1);
- } else {
- ! &error("incomplete shell statement");
- }
- }
- # The '(' construct
- elsif (s/^\(//) {
- ! &push_val(&eval_expr(*_));
- # A final '\' indicates an end of line
- ! &error("missing final parenthesis") if !s/^\\//;
- }
- # Found a ')' or end of line
- elsif (/^\)/ || /^$/) {
- s/^\)/\\/; # Signals: left parenthesis found
- $expr = $_; # Remove interpreted stuff
- ! &execute while $#val > 0; # Executed stacked operations
- while ($#op >= 0) {
- $_ = pop(@op);
- ! &error("missing second operand for '$_' (diadic operator)");
- }
- return $val[0];
- }
- # Diadic operators
- elsif (s/^(\|\||&&|>=|<=|>|<|==|!=|=|\/=)//) {
- ! &update_stack($1);
- }
- # Unary operator '!'
- elsif (s/^!//) {
- ***************
- *** 171,177 ****
- }
- # Everything else is a value which stands for itself (atom)
- elsif (s/^([\w'"%]+)//) {
- ! do push_val($1);
- }
- # Syntax error
- else {
- --- 174,180 ----
- }
- # Everything else is a value which stands for itself (atom)
- elsif (s/^([\w'"%]+)//) {
- ! &push_val($1);
- }
- # Syntax error
- else {
- ***************
- *** 186,192 ****
- local($val); # Value returned
- local(*expr) = shift(@_); # Expression to be parsed
- while ($expr) {
- ! $val = do eval_expr(*expr); # Expression will be modified
- print "extra closing parenthesis ignored.\n" if $expr =~ s/^\\\)*//;
- $expr = $val . $expr if $expr ne '';
- }
- --- 189,195 ----
- local($val); # Value returned
- local(*expr) = shift(@_); # Expression to be parsed
- while ($expr) {
- ! $val = &eval_expr(*expr); # Expression will be modified
- print "extra closing parenthesis ignored.\n" if $expr =~ s/^\\\)*//;
- $expr = $val . $expr if $expr ne '';
- }
-
- Index: agent/edusers.SH
- *** agent/edusers.SH.old Thu Sep 22 16:42:47 1994
- --- agent/edusers.SH Thu Sep 22 16:42:47 1994
- ***************
- *** 0 ****
- --- 1,104 ----
- + case $CONFIG in
- + '')
- + if test -f config.sh; then TOP=.;
- + elif test -f ../config.sh; then TOP=..;
- + elif test -f ../../config.sh; then TOP=../..;
- + elif test -f ../../../config.sh; then TOP=../../..;
- + elif test -f ../../../../config.sh; then TOP=../../../..;
- + else
- + echo "Can't find config.sh."; exit 1
- + fi
- + . $TOP/config.sh
- + ;;
- + esac
- + case "$0" in
- + */*) cd `expr X$0 : 'X\(.*\)/'` ;;
- + esac
- + echo "Extracting agent/edusers (with variable substitutions)"
- + $spitshell >edusers <<!GROK!THIS!
- + $startperl
- + eval "exec perl -S \$0 \$*"
- + if \$running_under_some_shell;
- +
- + # $Id: edusers.SH,v 3.0.1.1 1994/09/22 13:39:28 ram Exp $
- + #
- + # Copyright (c) 1990-1993, Raphael Manfredi
- + #
- + # You may redistribute only under the terms of the Artistic License,
- + # as specified in the README file that comes with the distribution.
- + # You may reuse parts of this distribution only within the terms of
- + # that same Artistic License; a copy of which may be found at the root
- + # of the source tree for mailagent 3.0.
- + #
- + # $Log: edusers.SH,v $
- + # Revision 3.0.1.1 1994/09/22 13:39:28 ram
- + # patch12: created
- + #
- +
- + \$mversion = '$VERSION';
- + \$patchlevel = '$PATCHLEVEL';
- + \$defeditor = '$defeditor';
- + !GROK!THIS!
- + $spitshell >>edusers <<'!NO!SUBS!'
- +
- + $userlist = "users";
- + $prog_name = $0; # Who I am
- + $prog_name =~ s|^.*/(.*)|$1|; # Keep only base name
- + $lockext = '.lock'; # Locking extension
- + *add_log = *stderr_log; # Ensure logs will go to stderr also
- +
- + $EDITOR = $ENV{'EDITOR'} || $ENV{'VISUAL'} || $defeditor;
- +
- + &read_config; # First, read configuration file (in ~/.mailagent)
- + &read_dist; # Read distributions
- + &catch_signals;
- +
- + $system = shift; # Which system do we want
- + $version = shift; # Which version it is
- +
- + # If no system is specified, try locating a '.package', then source it
- + # to get information...
- + if ($system eq '') {
- + die "$prog_name: you must specify a system name\n" unless &read_package;
- + $system = $pkg'package;
- + $version = $pkg'baserev;
- + }
- +
- + # A single '-' or a missing version means "highest available" version.
- + $version = $Version{$system} if $version eq '-' || $version eq '';
- +
- + # Full name of system for H table access
- + $pname = $system . "|" . $version;
- +
- + die "$prog_name: no program called $system\n" unless $System{$system};
- + die "$prog_name: no package $system version $version\n"
- + unless $Program{$pname};
- +
- + # Go to the system directory.
- + chdir "$Location{$pname}" ||
- + die "$prog_name: cannot go to $Location{$pname}\n";
- +
- + -f $userlist || die "$prog_name: no $userlist file yet for $system $version.\n";
- +
- + # Lock users file. That file should only be edited with the edusers script.
- + die "$prog_name: cannot lock $userlist.\n" if 0 != &acs_rqst($userlist);
- +
- + system "$EDITOR $userlist";
- + warn "$prog_name: WARNING: edition failed...\n" if $?;
- + &free_file($userlist);
- +
- + exit $?;
- +
- + !NO!SUBS!
- + $grep -v '^;#' pl/fatal.pl >>edusers
- + $grep -v '^;#' pl/add_log.pl >>edusers
- + $grep -v '^;#' pl/read_conf.pl >>edusers
- + $grep -v '^;#' pl/distribs.pl >>edusers
- + $grep -v '^;#' pl/secure.pl >>edusers
- + $grep -v '^;#' pl/acs_rqst.pl >>edusers
- + $grep -v '^;#' pl/free_file.pl >>edusers
- + $grep -v '^;#' pl/checklock.pl >>edusers
- + $grep -v '^;#' pl/signals.pl >>edusers
- + $grep -v '^;#' pl/package.pl >>edusers
- + chmod 755 edusers
- + $eunicefix edusers
-
- Index: agent/man/edusers.SH
- *** agent/man/edusers.SH.old Thu Sep 22 16:42:56 1994
- --- agent/man/edusers.SH Thu Sep 22 16:42:56 1994
- ***************
- *** 0 ****
- --- 1,106 ----
- + case $CONFIG in
- + '')
- + if test -f config.sh; then TOP=.;
- + elif test -f ../config.sh; then TOP=..;
- + elif test -f ../../config.sh; then TOP=../..;
- + elif test -f ../../../config.sh; then TOP=../../..;
- + elif test -f ../../../../config.sh; then TOP=../../../..;
- + else
- + echo "Can't find config.sh."; exit 1
- + fi
- + . $TOP/config.sh
- + ;;
- + esac
- + case "$0" in
- + */*) cd `expr X$0 : 'X\(.*\)/'` ;;
- + esac
- + echo "Extracting agent/man/edusers.$manext (with variable substitutions)"
- + $rm -f edusers.$manext
- + $spitshell >edusers.$manext <<!GROK!THIS!
- + .TH PACKAGE $manext
- + ''' @(#) Manual page for mailagent's edusers command
- + '''
- + ''' $Id: edusers.SH,v 3.0.1.1 1994/09/22 13:53:06 ram Exp $
- + '''
- + ''' Copyright (c) 1990-1993, Raphael Manfredi
- + '''
- + ''' You may redistribute only under the terms of the Artistic License,
- + ''' as specified in the README file that comes with the distribution.
- + ''' You may reuse parts of this distribution only within the terms of
- + ''' that same Artistic License; a copy of which may be found at the root
- + ''' of the source tree for mailagent 3.0.
- + '''
- + ''' $Log: edusers.SH,v $
- + ''' Revision 3.0.1.1 1994/09/22 13:53:06 ram
- + ''' patch12: created
- + '''
- + '''
- + .de Ex \" Start of Example
- + .sp
- + .in +5
- + .nf
- + ..
- + .de Ef \" End of Example
- + .sp
- + .in -5
- + .fi
- + ..
- + .SH NAME
- + edusers \- edit users list created by package
- + .SH SYNOPSIS
- + \fBedusers\fR [\fIsystem\fR [\fIversion\fR]]
- + .SH DESCRIPTION
- + This command lets you safely edit the \fIusers\fR list created by the
- + .I package
- + command. It locks the file before launching the editor, hence protecting
- + against any concurrent update by some \fIpackage\fR command that could
- + arrive at the same time (by e-mail). The level of protection this locking
- + buys you depends on the locking policy you have configured in
- + your \fI~/.mailagent\fR.
- + .PP
- + If you are within a package source tree, all you need to say is
- + .Ex
- + edusers
- + .Ef
- + to edit the \fIusers\fR file for that package. In order for that particular
- + feature to work properly, the package must have been placed under dist control,
- + or at least the \fIpackinit\fR command from the dist package must have been
- + run.
- + .PP
- + Otherwise, you may specify
- + a system name, and optionally a version number if that is not enough to
- + disambiguate. Using '-' will get you the lattest version available.
- + .PP
- + In any case, there must be a proper setting of the \fIdistribs\fR file
- + to use this command. If that file is not accurate, the \fIpackage\fR
- + command will not be able to produce a \fIusers\fR file anyway.
- + .SH ENVIRONMENT
- + The editor is taken out of the EDITOR variable if defined, then from
- + the VISUAL variable, defaulting to
- + .I $defeditor
- + if none of the variables is set.
- + .SH FILES
- + .PD 0
- + .TP 20
- + ~/.mailagent
- + configuration file for mailagent.
- + .TP
- + Spool/distribs
- + distribution list, same file as the one used for mailpatch.
- + .TP
- + System/.package
- + file created by dist's packinit command to indicate
- + the root of the source tree for that package.
- + .TP
- + System/users
- + list of users of that system.
- + .TP
- + Log/agentlog
- + mailagent's log file.
- + .PD
- + .SH AUTHOR
- + Raphael Manfredi <ram@acri.fr>
- + .SH "SEE ALSO"
- + mailagent($manext), metaconfig($manext), package($manext), packinit($manext).
- + !GROK!THIS!
- + chmod 444 edusers.$manext
-
- Index: agent/magent.SH
- Prereq: 3.0.1.2
- *** agent/magent.SH.old Thu Sep 22 16:42:54 1994
- --- agent/magent.SH Thu Sep 22 16:42:54 1994
- ***************
- *** 24,30 ****
- # via the filter. Mine looks like this:
- # "|exec /users/ram/mail/filter >>/users/ram/.bak 2>&1"
-
- ! # $Id: magent.SH,v 3.0.1.2 1994/07/01 14:54:29 ram Exp $
- #
- # Copyright (c) 1990-1993, Raphael Manfredi
- #
- --- 24,30 ----
- # via the filter. Mine looks like this:
- # "|exec /users/ram/mail/filter >>/users/ram/.bak 2>&1"
-
- ! # $Id: magent.SH,v 3.0.1.3 1994/09/22 13:52:34 ram Exp $
- #
- # Copyright (c) 1990-1993, Raphael Manfredi
- #
- ***************
- *** 35,40 ****
- --- 35,48 ----
- # of the source tree for mailagent 3.0.
- #
- # $Log: magent.SH,v $
- + # Revision 3.0.1.3 1994/09/22 13:52:34 ram
- + # patch12: now performs &init_constants as soon as possible
- + # patch12: changed interface for &queue_mail to include first 2 letters
- + # patch12: context is loaded earlier to initialize callout queue
- + # patch12: added definition for $MAX_LINKS, $S_IWOTH, $S_IWGRP and &abs
- + # patch12: changed &email_addr to cache its result and not rely on $cf'user
- + # patch12: moved &init_signals to pl/signals.pl as &catch_signals
- + #
- # Revision 3.0.1.2 1994/07/01 14:54:29 ram
- # patch8: fixed leading From date format (spacing problem)
- #
- ***************
- *** 193,198 ****
- --- 201,207 ----
-
- $file_name = shift; # File name to be processed (null if stdin)
- $ENV{'IFS'}='' if $ENV{'IFS'}; # Shell separation field
- + &init_constants; # Constants definitions
- &get_configuration; # Get a suitable configuration package (cf)
- select(STDOUT); # Because the -t option writes on STDOUT,
- $| = 1; # make sure it is flushed before we fork()
- ***************
- *** 237,249 ****
-
- if (!$locked && !$nolock) {
- # Another mailagent is running somewhere
- ! &queue_mail($file_name);
- exit 0;
- }
-
- # Initialize mail filtering and compile filter rule if necessary
- &init_all;
- &compile_rules unless $norule;
-
- # If rules are to be dumped, this is the only action
- if ($dump_rule) {
- --- 246,259 ----
-
- if (!$locked && !$nolock) {
- # Another mailagent is running somewhere
- ! &queue_mail($file_name, 'fm');
- exit 0;
- }
-
- # Initialize mail filtering and compile filter rule if necessary
- &init_all;
- &compile_rules unless $norule;
- + &context'init; # Load context, initialize callout queue
-
- # If rules are to be dumped, this is the only action
- if ($dump_rule) {
- ***************
- *** 286,292 ****
- if (0 != &analyze_mail($file_name)) { # Analyze the mail
- &add_log("ERROR while processing main message--queing it")
- if ($loglvl > 0);
- ! &queue_mail($file_name);
- unlink $lockfile;
- exit 0; # Do not continue
- } else {
- --- 296,302 ----
- if (0 != &analyze_mail($file_name)) { # Analyze the mail
- &add_log("ERROR while processing main message--queing it")
- if ($loglvl > 0);
- ! &queue_mail($file_name, 'fm');
- unlink $lockfile;
- exit 0; # Do not continue
- } else {
- ***************
- *** 364,371 ****
-
- # Start-up initializations
- sub init_all {
- ! &init_signals; # Trap common signals
- ! &init_constants; # Constants definitions
- &init_interpreter; # Initialize tables %Priority, %Function, ...
- &init_env; # Initialize the %XENV array
- &init_matcher; # Initialize special matching functions
- --- 374,380 ----
-
- # Start-up initializations
- sub init_all {
- ! &catch_signals; # Trap common signals
- &init_interpreter; # Initialize tables %Priority, %Function, ...
- &init_env; # Initialize the %XENV array
- &init_matcher; # Initialize special matching functions
- ***************
- *** 375,394 ****
- &init_special; # Initialize special user table %Special
- }
-
- - # Protect ourselves (trap common signals)
- - sub init_signals {
- - $SIG{'HUP'} = 'emergency';
- - $SIG{'INT'} = 'emergency';
- - $SIG{'QUIT'} = 'emergency';
- - $SIG{'PIPE'} = 'emergency';
- - $SIG{'IO'} = 'emergency';
- - $SIG{'BUS'} = 'emergency';
- - $SIG{'ILL'} = 'emergency';
- - $SIG{'SEGV'} = 'emergency';
- - $SIG{'ALRM'} = 'emergency';
- - $SIG{'TERM'} = 'emergency';
- - }
- -
- # Constants definitions
- sub init_constants {
- require 'ctime.pl';
- --- 384,389 ----
- ***************
- *** 398,403 ****
- --- 393,402 ----
- $LOCK_NB = 4; # Make a non-blocking lock request
- $LOCK_UN = 8; # Unlock the file
-
- + # Stat constants for file rights
- + $S_IWOTH = 02; # Writable by world (no .ph files here)
- + $S_IWGRP = 020; # Writable by group
- +
- # Status used by filter
- $FT_RESTART = 0; # Abort current action, restart from scratch
- $FT_CONT = 1; # Continue execution
- ***************
- *** 432,437 ****
- --- 431,439 ----
- $now =~ s/\s(\d:\d\d:\d\d)\b/0$1/; # Add leading 0 if hour < 10
- chop($now);
- $FAKE_FROM = "From mailagent " . $now;
- +
- + # Miscellaneous constants
- + $MAX_LINKS = 100; # Maximum number of symbolic link levels
- }
-
- # Initializes environment. All the variables are initialized in XENV array
- ***************
- *** 493,500 ****
- }
-
- # Computes the e-mail address of the user
- sub email_addr {
- ! $cf'user . '@' . &domain_addr; # E-mail address in internet format
- }
-
- # Domain name address for current host
- --- 495,510 ----
- }
-
- # Computes the e-mail address of the user
- + # Can't rely on the value of $cf'user since config file may not have
- + # been parsed when this routine is first called.
- sub email_addr {
- ! return $email_addr_cached if defined $email_addr_cached;
- ! local($user);
- ! ($user) = getpwuid($>);
- ! ($user) = getpwuid($<) unless $user;
- ! $user = 'nobody' unless $user;
- ! $email_addr_cached = $user . '@' . &domain_addr;
- ! return $email_addr_cached; # E-mail address in internet format
- }
-
- # Domain name address for current host
- ***************
- *** 517,522 ****
- --- 527,535 ----
- $path; # Return possibly stripped path
- }
-
- + # Compute absolute value -- on one line to avoid dataloading
- + sub abs { $_[0] > 0 ? $_[0] : -$_[0]; }
- +
- # Compute the system mailbox file name
- sub mailbox_name {
- # If ~/.mailagent provides us with a mail directory, use it and possibly
- ***************
- *** 638,642 ****
- --- 651,657 ----
- $grep -v '^;#' pl/tilde.pl >>magent
- $grep -v '^;#' pl/mh.pl >>magent
- $grep -v '^;#' pl/umask.pl >>magent
- + $grep -v '^;#' pl/signals.pl >>magent
- + $grep -v '^;#' pl/callout.pl >>magent
- chmod 755 magent
- $eunicefix magent
-
- Index: agent/pl/secure.pl
- Prereq: 3.0
- *** agent/pl/secure.pl.old Thu Sep 22 16:43:23 1994
- --- agent/pl/secure.pl Thu Sep 22 16:43:23 1994
- ***************
- *** 1,4 ****
- ! ;# $Id: secure.pl,v 3.0 1993/11/29 13:49:16 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- --- 1,4 ----
- ! ;# $Id: secure.pl,v 3.0.1.1 1994/09/22 14:38:04 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- ***************
- *** 9,14 ****
- --- 9,17 ----
- ;# of the source tree for mailagent 3.0.
- ;#
- ;# $Log: secure.pl,v $
- + ;# Revision 3.0.1.1 1994/09/22 14:38:04 ram
- + ;# patch12: symbolic directories are now specially handled
- + ;#
- ;# Revision 3.0 1993/11/29 13:49:16 ram
- ;# Baseline for mailagent 3.0 netwide release.
- ;#
- ***************
- *** 28,34 ****
- return 0; # Unsecure file
- }
- local($ST_MODE) = 2 + $[; # Field st_mode from inode structure
- - local($S_IWOTH) = 02; # Writable by world (no .ph files here)
- unless (-O _) { # Reuse stat info from -e
- &add_log("WARNING you do not own $type file $file") if $loglvl > 5;
- return 0; # Unsecure file
- --- 31,36 ----
- ***************
- *** 38,49 ****
- &add_log("WARNING $type file is world writable!") if $loglvl > 5;
- return 0; # Unsecure file
- }
- return 1 unless $cf'secure =~ /on/i || $< == 0;
-
- # Extra checks for secure mode (or if root user). We make sure the
- # file is not writable by group and then we conduct the same secure tests
- # on the directory itself
- - local($S_IWGRP) = 020; # Writable by group
- if ($st_mode & $S_IWGRP) {
- &add_log("WARNING $type file is group writable!") if $loglvl > 5;
- return 0; # Unsecure file
- --- 40,51 ----
- &add_log("WARNING $type file is world writable!") if $loglvl > 5;
- return 0; # Unsecure file
- }
- +
- return 1 unless $cf'secure =~ /on/i || $< == 0;
-
- # Extra checks for secure mode (or if root user). We make sure the
- # file is not writable by group and then we conduct the same secure tests
- # on the directory itself
- if ($st_mode & $S_IWGRP) {
- &add_log("WARNING $type file is group writable!") if $loglvl > 5;
- return 0; # Unsecure file
- ***************
- *** 56,77 ****
- return 0; # Unsecure directory, therefore unsecure file
- }
- $st_mode = (stat(_))[$ST_MODE];
- ! if ($st_mode & $S_IWOTH) {
- ! &add_log("WARNING directory of $type file is world writable!")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- ! if ($st_mode & $S_IWGRP) {
- ! &add_log("WARNING directory of $type file is group writable!")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- ! if (-l $dir) {
- ! &add_log("WARNING directory of $type file $file is a symbolic link")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- !
- ! 1; # At last! File is secure...
- }
-
- --- 58,145 ----
- return 0; # Unsecure directory, therefore unsecure file
- }
- $st_mode = (stat(_))[$ST_MODE];
- ! return 0 unless &check_st_mode($dir, 1);
- !
- ! # If linkdirs is OFF, we do not check further when faced with a symbolic
- ! # link to a directory.
- ! if (-l $dir && $cf'linkdirs !~ /^off/i && !&symdir_secure($dir, $type)) {
- ! &add_log("WARNING directory of $type file $file is an unsecure symlink")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- !
- ! 1; # At last! File is secure...
- ! }
- !
- ! # Is a symbolic link to a directory secure?
- ! sub symdir_secure {
- ! local($dir, $type) = @_;
- ! if (&symdir_check($dir, 0)) {
- ! &add_log("symbolic directory $dir for $type file is secure")
- ! if $loglvl > 11;
- ! return 1;
- ! }
- ! 0; # Not secure
- ! }
- !
- ! # A symbolic directory (that is a symlink pointing to a directory) is secure
- ! # if and only if:
- ! # - its target is a symlink that recursively proves to be secure.
- ! # - the target lies in a non world-writable directory
- ! # - the final directory at the end of the symlink chain is not world-writable
- ! # - less than $MAX_LINKS levels of indirection are needed to reach a real dir
- ! # Unfortunately, we cannot check for group writability here for the parent
- ! # target directory since the target might lie in a system directory which may
- ! # have a legitimate need to be read/write for root and wheel, for instance.
- ! # The routine returns 1 if the file is secure, 0 otherwise.
- ! sub symdir_check {
- ! local($dir, $level) = @_; # Directory, indirection level
- ! return 0 if $level++ > $MAX_LINKS;
- ! $dir = readlink($dir);
- ! unless (defined $dir) {
- ! &add_log("SYSERR readlink: $!") if $loglvl;
- ! return 0;
- ! }
- ! local($still_link) = -l _;
- ! unless (-d $dir || $still_link) {
- ! &add_log("ERROR inconsistency: $dir is a plain file?") if $loglvl;
- ! return 0; # Reached a plain file while following links to a dir!
- ! }
- ! unless (-d "$dir/..") {
- ! &add_log("ERROR inconsistency: $dir/.. is not a directory?") if $loglvl;
- ! return 0; # Reached a file hooked nowhere in the file system!
- ! }
- ! # Check parent directory
- ! local($ST_MODE) = 2 + $[; # Field st_mode from inode structure
- ! $st_mode = (stat(_))[$ST_MODE];
- ! return 0 unless &check_st_mode("$dir/..", 0);
- ! # Recurse if still a symbolic link
- ! if ($still_link) {
- ! return 0 unless &symdir_check($dir, $level);
- ! } else {
- ! $st_mode = (stat($dir))[$ST_MODE];
- ! return 0 unless &check_st_mode($dir, 1);
- ! }
- ! 1; # Ok, link is secure
- ! }
- !
- ! # Returns true if mode in $st_mode does not include world or group writable
- ! # bits, false otherwise. This helps factorizing code used in both &file_secure
- ! # and &symdir_check. Set $both to true if both world/group checks are desirable,
- ! # false to get only world checks.
- ! sub check_st_mode {
- ! local($dir, $both) = @_;
- ! if ($st_mode & $S_IWOTH) {
- ! &add_log("WARNING directory of $type file $dir is world writable!")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- ! return 1 unless $both;
- ! if ($st_mode & $S_IWGRP) {
- ! &add_log("WARNING directory of $type file $dir is group writable!")
- if $loglvl > 5;
- return 0; # Unsecure directory
- }
- ! 1;
- }
-
-
- Index: agent/pl/listqueue.pl
- Prereq: 3.0.1.1
- *** agent/pl/listqueue.pl.old Thu Sep 22 16:43:14 1994
- --- agent/pl/listqueue.pl Thu Sep 22 16:43:15 1994
- ***************
- *** 1,4 ****
- ! ;# $Id: listqueue.pl,v 3.0.1.1 1994/07/01 15:01:45 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- --- 1,4 ----
- ! ;# $Id: listqueue.pl,v 3.0.1.2 1994/09/22 14:26:00 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- ***************
- *** 9,14 ****
- --- 9,18 ----
- ;# of the source tree for mailagent 3.0.
- ;#
- ;# $Log: listqueue.pl,v $
- + ;# Revision 3.0.1.2 1994/09/22 14:26:00 ram
- + ;# patch12: localized variables used by stat() and localtime()
- + ;# patch12: now knows about callout queue messages
- + ;#
- ;# Revision 3.0.1.1 1994/07/01 15:01:45 ram
- ;# patch8: now honours new queuehold and queuelost config variables
- ;#
- ***************
- *** 26,32 ****
- }
- local(@dir) = readdir DIR; # Slurp the whole directory
- closedir DIR;
- ! local(@files) = grep(s!^(q|f)m!$cf'queue/${1}m!, @dir);
- undef @dir;
- if (-f "$cf'queue/$agent_wait") {
- if (open(WAITING, "$cf'queue/$agent_wait")) {
- --- 30,36 ----
- }
- local(@dir) = readdir DIR; # Slurp the whole directory
- closedir DIR;
- ! local(@files) = grep(s!^(q|f|c)m!$cf'queue/${1}m!, @dir);
- undef @dir;
- if (-f "$cf'queue/$agent_wait") {
- if (open(WAITING, "$cf'queue/$agent_wait")) {
- ***************
- *** 78,83 ****
- --- 82,92 ----
- .
- local($n) = $#files + 1;
- local($s) = $n > 1 ? 's' : '';
- + local($_);
- + local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- + $atime,$mtime,$ctime,$blksize,$blocks);
- + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);
- +
- print STDOUT " Mailagent Queue ($n request$s)\n";
- foreach (@files) {
- ($directory, $file) = m|^(.*)/(.*)|;
- ***************
- *** 110,121 ****
- ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- $atime,$mtime,$ctime,$blksize,$blocks) = stat(_);
- $status = '';
- # If file has 'mbox.' as part of its name, then it is an emergency
- # saving done by the mailagent. If it starts with 'logname', then it
- # is an emergency saving done by the filter.
- $file =~ s/^mbox\.// && ($status = 'Backup');
- $file =~ s/^$cf'user\.// && ($status = 'Backup');
- ! if ($file =~ /^qm/ && (time - $mtime) < $cf'queuehold) {
- # Queue mails starting with 'qm' have been queued by the filter
- # program. To avoid race conditions, those mails are skipped for
- # some time (cf to pqueue subroutine).
- --- 119,144 ----
- ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- $atime,$mtime,$ctime,$blksize,$blocks) = stat(_);
- $status = '';
- +
- # If file has 'mbox.' as part of its name, then it is an emergency
- # saving done by the mailagent. If it starts with 'logname', then it
- # is an emergency saving done by the filter.
- +
- $file =~ s/^mbox\.// && ($status = 'Backup');
- $file =~ s/^$cf'user\.// && ($status = 'Backup');
- !
- ! # Check for callout queue file. If it is a 'cm' file, or it is not in
- ! # the queue and is recorded in the callout queue, then it is marked
- ! # as a callout file and the queue time printed will be the trigger
- ! # time.
- !
- ! if (
- ! $file =~ /^cm/ ||
- ! ($directory ne $cf'queue && &callout'trigger($_))
- ! ) {
- ! $mtime = &callout'trigger($_); # May be called twice, that's ok.
- ! $status = 'Callout';
- ! } elsif ($file =~ /^qm/ && (time - $mtime) < $cf'queuehold) {
- # Queue mails starting with 'qm' have been queued by the filter
- # program. To avoid race conditions, those mails are skipped for
- # some time (cf to pqueue subroutine).
- ***************
- *** 124,136 ****
- # Processing of mail allowed (mailagent -q would flush it)
- $status = 'Deferred' unless $status;
- }
- ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime($mtime);
- $queued = sprintf("%.2d/%.2d-%.2d:%.2d", ++$mon,$mday,$hour,$min);
- ! $queued = 'Now' if (time - $mtime) < 60;
- $star = '';
- $star = '*' if $directory ne $cf'queue; # Spot out-of-queue mails
- ! if ((time - $mtime) > $cf'queuelost) { # Also spot old mails
- $star = '#';
- $star = '@' if $directory ne $cf'queue;
- }
- --- 147,165 ----
- # Processing of mail allowed (mailagent -q would flush it)
- $status = 'Deferred' unless $status;
- }
- +
- ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime($mtime);
- $queued = sprintf("%.2d/%.2d-%.2d:%.2d", ++$mon,$mday,$hour,$min);
- ! $queued = 'Now' if &'abs(time - $mtime) < 60;
- $star = '';
- $star = '*' if $directory ne $cf'queue; # Spot out-of-queue mails
- ! if ($status ne 'Callout') {
- ! if ((time - $mtime) > $cf'queuelost) { # Also spot old mails
- ! $star = '#';
- ! $star = '@' if $directory ne $cf'queue;
- ! }
- ! } elsif (time > $mtime) { # Spot callouts that should have triggered
- $star = '#';
- $star = '@' if $directory ne $cf'queue;
- }
-
- Index: agent/pl/context.pl
- Prereq: 3.0
- *** agent/pl/context.pl.old Thu Sep 22 16:43:07 1994
- --- agent/pl/context.pl Thu Sep 22 16:43:08 1994
- ***************
- *** 1,4 ****
- ! ;# $Id: context.pl,v 3.0 1993/11/29 13:48:38 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- --- 1,4 ----
- ! ;# $Id: context.pl,v 3.0.1.1 1994/09/22 14:16:30 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- ***************
- *** 9,14 ****
- --- 9,19 ----
- ;# of the source tree for mailagent 3.0.
- ;#
- ;# $Log: context.pl,v $
- + ;# Revision 3.0.1.1 1994/09/22 14:16:30 ram
- + ;# patch12: added access routines to detect context changes
- + ;# patch12: context is now written back to disk only when changed
- + ;# patch12: added callout queue knowledge
- + ;#
- ;# Revision 3.0 1993/11/29 13:48:38 ram
- ;# Baseline for mailagent 3.0 netwide release.
- ;#
- ***************
- *** 25,32 ****
- # Initialize context from context file
- sub init {
- &default; # Load a default context
- ! return unless -f $cf'context; # Finished if no saved context
- ! &load; # Load context, overwriting default context
- &clean; # Remove uneeded entries from context
- }
-
- --- 30,37 ----
- # Initialize context from context file
- sub init {
- &default; # Load a default context
- ! &load if -f $cf'context; # Load context, overwriting default context
- ! &callout'init; # Initialize callout queue
- &clean; # Remove uneeded entries from context
- }
-
- ***************
- *** 59,74 ****
-
- # Clean context, removing useless entries
- sub clean {
- ! delete $Context{'last-clean'} unless $cf'autoclean =~ /^on/i;
- }
-
- ! # Save a new context file
- sub save {
- require 'ctime.pl';
- local($existed) = -f $cf'context;
- &'acs_rqst($cf'context) if $existed; # Lock existing file
- unless (open(CONTEXT, ">$cf'context")) {
- &'add_log("ERROR cannot overwrite context file: $!") if $'loglvl > 1;
- return;
- }
- &'add_log("saving context file $cf'context") if $'loglvl > 17;
- --- 64,81 ----
-
- # Clean context, removing useless entries
- sub clean {
- ! &delete('last-clean') if $cf'autoclean !~ /^on/i && &get('last-clean');
- }
-
- ! # Save a new context file, if it has changed since we read it.
- sub save {
- + return unless $context_changed; # Do not save if no change
- require 'ctime.pl';
- local($existed) = -f $cf'context;
- &'acs_rqst($cf'context) if $existed; # Lock existing file
- unless (open(CONTEXT, ">$cf'context")) {
- &'add_log("ERROR cannot overwrite context file: $!") if $'loglvl > 1;
- + &'free_file($cf'context) if $existed;
- return;
- }
- &'add_log("saving context file $cf'context") if $'loglvl > 17;
- ***************
- *** 86,91 ****
- --- 93,127 ----
- }
-
- #
- + # Access features
- + #
- +
- + # Add or set an entry in the context
- + sub set {
- + local($entry, $value) = @_;
- + $Context{$entry} = $value;
- + $context_changed++;
- + }
- +
- + # Get a context entry value
- + sub get {
- + local($entry) = @_;
- + defined $Context{$entry} ? $Context{$entry} : undef;
- + }
- +
- + # Delete an entry from context
- + sub delete {
- + local($entry) = @_;
- + unless (defined $Context{$entry}) {
- + &'add_log("WARNING attempting to delete inexistant $entry context")
- + if $'loglvl > 5;
- + return;
- + }
- + delete $Context{$entry};
- + $context_changed++;
- + }
- +
- + #
- # Context-dependant actions
- #
-
- ***************
- *** 96,107 ****
- sub autoclean {
- return unless $cf'autoclean =~ /^on/i;
- local($period) = &'seconds_in_period($cf'cleanlaps);
- ! return if ($Context{'last-clean'} + $period) > time;
- # Retry time reached -- start auto cleaning
- &'add_log("autocleaning of dbr files") if $'loglvl > 8;
- $period = &'seconds_in_period($cf'agemax);
- &dbr'clean($period);
- ! $Context{'last-clean'} = time; # Update last cleaning time
- }
-
- #
- --- 132,143 ----
- sub autoclean {
- return unless $cf'autoclean =~ /^on/i;
- local($period) = &'seconds_in_period($cf'cleanlaps);
- ! return if (&get('last-clean') + $period) > time;
- # Retry time reached -- start auto cleaning
- &'add_log("autocleaning of dbr files") if $'loglvl > 8;
- $period = &'seconds_in_period($cf'agemax);
- &dbr'clean($period);
- ! &set('last-clean', time); # Update last cleaning time
- }
-
- #
- ***************
- *** 112,119 ****
- # the retry time was not reached. This routine is the main entry point in
- # the package, and is the only one called from the outside world.
- sub main'contextual_operations {
- - &init; # Initialize context
- &autoclean; # Clean dbr hash files
- &save; # Save new context
- }
-
- --- 148,155 ----
- # the retry time was not reached. This routine is the main entry point in
- # the package, and is the only one called from the outside world.
- sub main'contextual_operations {
- &autoclean; # Clean dbr hash files
- + &callout'flush; # Flush the callout queue
- &save; # Save new context
- }
-
-
- Index: agent/filter/parser.c
- Prereq: 3.0.1.2
- *** agent/filter/parser.c.old Thu Sep 22 16:42:53 1994
- --- agent/filter/parser.c Thu Sep 22 16:42:53 1994
- ***************
- *** 11,17 ****
- */
-
- /*
- ! * $Id: parser.c,v 3.0.1.2 1994/07/01 14:53:57 ram Exp $
- *
- * Copyright (c) 1990-1993, Raphael Manfredi
- *
- --- 11,17 ----
- */
-
- /*
- ! * $Id: parser.c,v 3.0.1.3 1994/09/22 13:47:21 ram Exp $
- *
- * Copyright (c) 1990-1993, Raphael Manfredi
- *
- ***************
- *** 22,27 ****
- --- 22,30 ----
- * of the source tree for mailagent 3.0.
- *
- * $Log: parser.c,v $
- + * Revision 3.0.1.3 1994/09/22 13:47:21 ram
- + * patch12: extended security checks to mimic those done by mailagent
- + *
- * Revision 3.0.1.2 1994/07/01 14:53:57 ram
- * patch8: new routine get_confval to get integer config variables
- *
- ***************
- *** 52,57 ****
- --- 55,67 ----
- #include <strings.h>
- #endif
-
- + #ifdef I_SYS_PARAM
- + #include <sys/param.h>
- + #endif
- + #ifndef MAX_PATHLEN
- + #define MAX_PATHLEN 2048 /* Maximum path length allowed by kernel */
- + #endif
- +
- #ifndef HAS_GETHOSTNAME
- #ifdef HAS_UNAME
- #include <sys/utsname.h>
- ***************
- *** 180,186 ****
- * Returning from this routine implies that the security checks succeeded.
- */
-
- ! struct stat buf; /* Statistics buffer */
-
- if (-1 == stat(file, &buf)) {
- add_log(1, "SYSERR stat: %m (%e)");
- --- 190,196 ----
- * Returning from this routine implies that the security checks succeeded.
- */
-
- ! struct stat buf; /* Statistics buffer */
-
- if (-1 == stat(file, &buf)) {
- add_log(1, "SYSERR stat: %m (%e)");
- ***************
- *** 195,204 ****
- {
- /* Check basic permissions on the specified file. It cannot be world
- * writable and must be owned by the user. If the file specified does not
- ! * exist, no error is reported however.
- */
-
- ! struct stat buf; /* Statistics buffer */
-
- if (-1 == stat(file, &buf))
- return;
- --- 205,220 ----
- {
- /* Check basic permissions on the specified file. It cannot be world
- * writable and must be owned by the user. If the file specified does not
- ! * exist, no error is reported however. If the 'secure' option is set
- ! * to ON, or if we are running with superuser credentials, further checks
- ! * are performed on the directory containing the file.
- */
-
- ! struct stat buf; /* Statistics buffer */
- ! char parent[MAX_PATHLEN+1]; /* For parent directory */
- ! char *cfsecure; /* Config value for the 'secure' parameter */
- ! char *c; /* Last slash position in file name */
- ! int wants_secure = 0; /* Set to true for extra security checks */
-
- if (-1 == stat(file, &buf))
- return;
- ***************
- *** 212,217 ****
- --- 228,290 ----
-
- if (buf.st_uid != geteuid())
- fatal("file %s not owned by user!", file);
- +
- + cfsecure = ht_value(&symtab, "secure"); /* Do we need extra security? */
- + if (
- + (cfsecure != (char *) 0 && /* Ok, secure is defined */
- + 0 == strcasecmp(cfsecure, "ON")) || /* And extra checks wanted */
- + geteuid() == ROOTID /* Running as superuser */
- + )
- + wants_secure = 1; /* Activate checks */
- +
- + if (!wants_secure) {
- + add_log(12, "basic checks ok for file %s", file);
- + return;
- + }
- +
- + /*
- + * Extra security checks for group writability and parent directory.
- + */
- +
- + add_log(17, "performing additional checks on %s", file);
- +
- + #ifndef S_IWGRP
- + #define S_IWGRP 00020 /* Write permissions for group */
- + #endif
- +
- + if (buf.st_mode & S_IWGRP)
- + fatal("file %s is group writable!", file);
- +
- + /*
- + * Ok, go on and check the parent directory...
- + */
- +
- + if (*file != '/') { /* Path is not abosule, assume from home */
- + strcpy(parent, home); /* Prefill with home */
- + strcat(parent, "/");
- + } else
- + *parent = '\0'; /* Null string */
- + strcat(parent, file); /* Append file to get an absolute path */
- + if (c = rindex(parent, '/'))
- + *c = '\0'; /* Strip down last path component */
- +
- + add_log(17, "checking directory %s", parent);
- +
- + if (-1 == stat(parent, &buf)) {
- + add_log(1, "SYSERR stat: %m (%e)");
- + fatal("cannot stat directory %s", parent);
- + }
- +
- + if (buf.st_mode & S_IWOTH)
- + fatal("directory %s is world writable!", parent);
- +
- + if (buf.st_mode & S_IWGRP)
- + fatal("directory %s is group writable!", parent);
- +
- + if (buf.st_uid != geteuid())
- + fatal("directory %s not owned by user!", parent);
- +
- + add_log(12, "file %s seems to be secure", file);
- }
-
- public char *homedir()
-
- Index: agent/pl/builtins.pl
- Prereq: 3.0
- *** agent/pl/builtins.pl.old Thu Sep 22 16:43:06 1994
- --- agent/pl/builtins.pl Thu Sep 22 16:43:06 1994
- ***************
- *** 1,4 ****
- ! ;# $Id: builtins.pl,v 3.0 1993/11/29 13:48:35 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- --- 1,4 ----
- ! ;# $Id: builtins.pl,v 3.0.1.1 1994/09/22 14:10:40 ram Exp $
- ;#
- ;# Copyright (c) 1990-1993, Raphael Manfredi
- ;#
- ***************
- *** 9,14 ****
- --- 9,18 ----
- ;# of the source tree for mailagent 3.0.
- ;#
- ;# $Log: builtins.pl,v $
- + ;# Revision 3.0.1.1 1994/09/22 14:10:40 ram
- + ;# patch12: added escapes in strings for perl5 support
- + ;# patch12: builtins are now looked for in &run_builtins
- + ;#
- ;# Revision 3.0 1993/11/29 13:48:35 ram
- ;# Baseline for mailagent 3.0 netwide release.
- ;#
- ***************
- *** 92,103 ****
- # The @RR command asks for a receipt
- sub builtin_rr {
- local($_) = @_;
- ! &add_log("found an @RR request to $_") if $loglvl > 18;
- # @RR request honored only if not from special user and directed to us
- unless (&special_user) {
- push(@Builtcode, "&send_receipt('$_')");
- } else {
- ! &add_log("ignoring @RR request to $_") if $loglvl > 4;
- }
- }
-
- --- 96,107 ----
- # The @RR command asks for a receipt
- sub builtin_rr {
- local($_) = @_;
- ! &add_log("found an \@RR request to $_") if $loglvl > 18;
- # @RR request honored only if not from special user and directed to us
- unless (&special_user) {
- push(@Builtcode, "&send_receipt('$_')");
- } else {
- ! &add_log("ignoring \@RR request to $_") if $loglvl > 4;
- }
- }
-
- ***************
- *** 106,120 ****
- local($_) = @_;
- return if /[=\$^&*([{}`\\|;><?]/; # Invalid character found
- $Userpath = $_;
- ! &add_log("found an @PATH request to $_") if $loglvl > 18;
- }
-
- # Execute stacked builtins
- sub run_builtins {
- return if $#Builtcode < 0; # No recorded builtins
- foreach (@Builtcode) {
- eval($_); # Execute stacked builtin
- }
- ! @Builtcode = (); # Reset builtcode array
- }
-
- --- 110,136 ----
- local($_) = @_;
- return if /[=\$^&*([{}`\\|;><?]/; # Invalid character found
- $Userpath = $_;
- ! &add_log("found an \@PATH request to $_") if $loglvl > 18;
- }
-
- # Execute stacked builtins
- sub run_builtins {
- + undef @Builtcode;
- + # Lookup for builtins. Code moved out of &parse_mail.
- + foreach $line (split(/\n/, $Header{'Body'})) {
- + if ($line =~ s/^@(\w+)\s*//) { # A builtin command ?
- + local($subroutine) = $Builtin{$1};
- + &$subroutine($line) if $subroutine; # Record it if known
- + }
- + }
- + # End of original &parse_mail exerpt, beginning of original &run_builtins
- + # NOTE: since builtins are now looked for here and run from there directly,
- + # going through the burden of @Builtcode is not necessary. Will get fixed
- + # one day, possibly.
- return if $#Builtcode < 0; # No recorded builtins
- foreach (@Builtcode) {
- eval($_); # Execute stacked builtin
- }
- ! undef @Builtcode; # Reset builtcode array
- }
-
-
- *** End of Patch 14 ***
-
- exit 0 # Just in case...
-