File: //usr/share/sendmail/Parse_conf.pm
#!/usr/bin/perl -w
#------------------------------------------------------------------------
#
# $Sendmail: Parse_conf.pm,v 8.15.2 2021-03-16 16:04:16 cowboy Exp $
#
# Parse and update /etc/mail/sendmail.conf
#
# Copyright (c) 2001-2010 Richard Nelson. All Rights Reserved.
#
# Notes (to all):
#
# Notes (to self):
#
#------------------------------------------------------------------------
#
# Package/Module declaration
package Parse_conf;
require Exporter;
@ISA = qw(Exporter);
#@EXPORT = qw(read_conf write_conf);
@EXPORT_OK = qw(read_conf write_conf get_value);
$VERSION = '2.0000';
#
# Initialization of the perl environment
use strict; # be kosher
#use warnings; # Not needed here
use Cwd; # provide cwd()
use Env; # A few environmental references
use integer; # Peformance
use Sys::Hostname; # make sure we have a valid hostname
use Getopt::Long; # parameter handling
use FileHandle; # I/O
# Local libraries - for Debian Sendmail Perl helper functions
# BEGIN { $main::my_path = substr($0,$[,rindex($0,'/')) };
use lib ('.', substr($0,$[,rindex($0,'/')), "/usr/share/sendmail");
require Parse_mc;
# Version of this program
#($main::MYNAME = $main::0) =~ s|.*/||;
#$main::Author = "Richard Nelson";
#$main::AuthorMail = "cowboy\@debian.org";
#$main::Version = '$Revision: 1.00 $ ';
$Parse_conf::program_name = 'Parse_conf.pm';
$Parse_conf::program_version = '8.15.2';
$Parse_conf::program_date = '2021-03-16 16:04:16 cowboy';
$Parse_conf::debug = 0;
my $interp_pgm = "$^X";
my $interp_vrm = $];
$interp_vrm = ("$^V" | '000') if (defined $^V);
my $current_time = scalar localtime;
my $user = getlogin || (getpwuid($<))[0] || "Unknown!!";
my $hostname = hostname();
my $directory = getcwd();
$Parse_conf::Conffile = "/etc/mail/sendmail.conf";
my $debug;
#
#------------------------------------------------------------------------------
# Global variables
#------------------------------------------------------------------------------
my %parm_def = (
'DAEMON_NETMODE' => 'Static'
,'DAEMON_NETIF' => 'eth0'
,'DAEMON_MODE' => 'Daemon'
,'DAEMON_RUNASUSER' => 'No'
,'DAEMON_PARMS' => ''
,'DAEMON_HOSTSTATS' => 'No'
,'DAEMON_MAILSTATS' => 'No'
,'QUEUE_MODE' => '${DAEMON_MODE}'
,'QUEUE_INTERVAL' => '10m'
,'QUEUE_PARMS' => ''
,'MSP_MODE' => 'Cron'
,'MSP_INTERVAL' => '20m'
,'MSP_PARMS' => ''
,'MSP_MAILSTATS' => '${DAEMON_MAILSTATS}'
,'MISC_PARMS' => ''
,'CRON_MAILTO' => 'root'
,'CRON_PARMS' => ''
,'HANDS_OFF' => 'No'
,'LOG_CMDS' => 'No'
,'AGE_DATA' => ''
);
my %parameter = %parm_def;
my %parm_kw = (
'DAEMON_NETMODE' => ['static', 'dynamic']
,'DAEMON_MODE' => ['daemon', 'inetd','none']
,'QUEUE_MODE' => ['daemon', 'cron', 'none']
,'MSP_MODE' => ['daemon', 'cron', 'none']
);
my %parm_bool = (
'HANDS_OFF' => 1
,'DAEMON_RUNASUSER' => 1
,'DAEMON_HOSTSTATS' => 1
,'DAEMON_MAILSTATS' => 1
,'MSP_MAILSTATS' => 1
,'LOG_CMDS' => 1
);
my %parm_dependant = (
);
my %parm_deprecated = (
'DAEMON_STATS' => 'DAEMON_MAILSTATS'
,'MSP_STATS' => 'MSP_MAILSTATS'
);
my %parm_hidden = (
'DAEMON_RUNASUSER' => 1
,'prefix' => 1
,'exec_prefix' => 1
,'bindir' => 1
,'sbindir' => 1
,'libexecdir' => 1
,'datadir' => 1
,'sysconfdir' => 1
,'sharedstatedir' => 1
,'localstatedir' => 1
,'libdir' => 1
,'MTA_DAEMON' => 1
,'MTA_COMMAND' => 1
,'MTA_L' => 1
,'MTA_L_QUEUE' => 1
,'MTA_ROOT' => 1
,'MTA_PIDFILE' => 1
,'MSP_DAEMON' => 1
,'MSP_COMMAND' => 1
,'MSP_L' => 1
,'MSP_L_QUEUE' => 1
,'MSP_ROOT' => 1
,'MSP_PIDFILE' => 1
);
#
#------------------------------------------------------------------------------
# Finally, some code (almost)
#------------------------------------------------------------------------------
1; # return (true);
#
#------------------------------------------------------------------------------
# Read /etc/mail/sendmail.conf
#------------------------------------------------------------------------------
sub read_conf {
my ($input_file) = @_;
$input_file ||= $Parse_conf::Conffile;
$debug = $main::debug || $Parse_conf::debug;
# Update defaults according to current environment
&update_defaults;
# Read /etc/mail/sendmail.conf (if extant)
&read_config($input_file);
# Update old values to new format
&update_values;
# Make sure things are kosher
my $ok = &validate_config;
if (! $ok) {
die "Terminating due to configuration error.";
};
};
#
#------------------------------------------------------------------------------
# [Re]write /etc/mail/sendmail.conf
#------------------------------------------------------------------------------
sub write_conf {
my ($output_file) = @_;
$debug = $main::debug || $Parse_conf::debug;
&write_config($output_file);
};
#
#------------------------------------------------------------------------
# Update default settings according to current environment
#------------------------------------------------------------------------
sub update_defaults {
my ($class, $flags, $files, $options);
my ($ok, $stats);
my $file;
# Read the mc/m4 files
&Parse_mc::read_dbs('', '');
# Obtain entry for HOST_STATUS_DIRECTORY
($class, $flags, $files, $options) =
&Parse_mc::entry_dbs('confHOST_STATUS_DIRECTORY');
$file = @{$files}[0];
if ( $file ne '-' and -d $file ) {
$parameter{'DAEMON_HOSTSTATS'} = 'Yes';
}
else {
$parameter{'DAEMON_HOSTSTATS'} = 'No';
};
# Obtain entry for STATUS_FILE
($class, $flags, $files, $options) =
&Parse_mc::entry_dbs('STATUS_FILE');
$file = @{$files}[0];
if ( $file ne '-' and -e $file ) {
$parameter{'DAEMON_MAILSTATS'} = 'Yes';
}
else {
$parameter{'DAEMON_MAILSTATS'} = 'No';
};
# Obtain entry for MSP_STATUS_FILE
($class, $flags, $files, $options) =
&Parse_mc::entry_dbs('MSP_STATUS_FILE');
$file = @{$files}[0];
if ( $file ne '-' and -e $file ) {
$parameter{'MSP_MAILSTATS'} = 'Yes';
}
else {
$parameter{'MSP_MAILSTATS'} = 'No';
};
};
#
#------------------------------------------------------------------------
# Update old settings according to current format
#------------------------------------------------------------------------
sub update_values {
my ($ok, $var);
# Add m(inutes) to {queue,msp}_interval if needed
$parameter{'QUEUE_INTERVAL'} =~ s/^(p?\d+)$/$1m/;
$parameter{'MSP_INTERVAL'} =~ s/^(p?\d+)$/$1m/;
# Also update the queue aging data
($ok, $var) = &get_value('AGE_DATA');
my $tmpval = eval $var;
if ($@) {
warn $@;
}
else {
$var = $tmpval;
};
if (not defined $var) {
$tmpval = '""';
}
elsif (not ref $var) {
$tmpval = "$var";
}
elsif (@{$var} == 0) {
$tmpval = '""';
}
else {
$tmpval = '[';
foreach my $entry (@{$var}) {
foreach my $ndx ($[ .. $#{$entry}) {
@{$entry}[$ndx] =~ s/'/\\'/g;
};
@{$entry}[0] =~ s/^(\d+)$/$1m/;
$tmpval .= "['" . join("', '", @{$entry}) . "'],";
};
$tmpval .= ']';
$parameter{'AGE_DATA'} = $tmpval;
};
# Set any dependant fields here...
};
#
#------------------------------------------------------------------------
# Obtain parameter name
#------------------------------------------------------------------------
sub get_name {
my ($name, $quiet) = @_;
# Handle deprecated/renamed variables
if ( exists($parm_deprecated{$name}) ) {
print STDERR "$name is deprecated."
if ($debug and ! $quiet);
if ( $parm_deprecated{$name} ) {
print STDERR " Please use $parm_deprecated{$name} instead.\n"
if ($debug and ! $quiet);
$name = $parm_deprecated{$name};
}
else {
print STDERR " It will be ignored.\n"
if ($debug and ! $quiet);
};
};
return $name;
};
#
#------------------------------------------------------------------------
# Obtain value directly, or indirectly
#------------------------------------------------------------------------
sub get_value {
my ($name) = @_;
my $ok = 1;
my $value = '';
if ( ! exists($parameter{$name}) ) {
print STDERR "Variable $name not defined...\n";
return ($ok, $value);
};
$name = get_name($name, '');
$value = $parameter{$name};
my $tval = $value;
$tval =~ s/^\s*//;
my $default = 0;
# Dereference loop... keep original value if we get any errors...
Dereference:;
if ($tval =~ /^\$/) {
my @ref_stack = ($name);
my %ref_hash = ($name => 1);
while ($tval =~ /^\$/ and $ok) {
my $start = 1;
my $del = 1;
my $char = substr($tval, 1, 1);
if ( $char eq '{' or $char eq '(' ) {
$start += 1; $del += 2;
};
my $ref = get_name(substr($tval, $start,
length($tval)-$del), '');
push @ref_stack, $ref;
if (exists($ref_hash{$ref})) {
print STDERR "Go directly to jail; do not pass go, ",
"do not collect \$200\n";
print STDERR " Reference loop: ",
join('->', @ref_stack, '...'),"\n";
$ok = 0;
}
else {
$ref_hash{$ref} = 1;
if (lc $ref eq 'default') {
$tval = $parm_def{$name};
print STDERR
"Setting $name to default value: ",
"$parm_def{$name}.\n"
if ($debug);
}
elsif (exists($parameter{$ref})) {
$tval = $parameter{$ref};
print STDERR
"Setting $name to value of $ref: $tval.\n"
if ($debug);
}
else {
print STDERR
"Can not deference $ref, it doesn't exist.\n";
$ok = 0;
};
};
};
};
if ( $ok ) {
# Check keyword parms for valid values
if (exists $parm_kw{$name}) {
my @ltval = split(/\s/,$tval);
my $ltval = lc(@ltval[$[]);
my $found = "";
foreach my $value (@{$parm_kw{$name}}) {
if ($value eq $ltval) {
$found = 1; $tval = ucfirst($ltval); };
};
if ( ! $found ) {
$default += 1;
if ( $default > 1 ) {
print STDERR
"Can not resolve $name, value=$value.\n";
$ok = 0;
}
else {
print STDERR "Illegal value($tval) for $name.\n",
" Valid values are: ",
join(', ', @{$parm_kw{$name}}),
"\n",
" Set to default: $parm_def{$name}.\n";
$tval = $parm_def{$name};
goto Dereference;
};
};
}
# Check boolean parms for valid values
elsif (exists $parm_bool{$name}) {
my @ltval = split(/\s/,$tval);
my $ltval = lc(@ltval[$[]);
$ltval =~ s/^[ty1].*/1/;
$ltval =~ s/^[fn0].*/0/;
if ($ltval eq '0' or $ltval eq '1') {
$tval = ucfirst($ltval); }
else {
$default += 1;
if ( $default > 1 ) {
print STDERR
"Can not resolve $name, value=$value.\n";
$ok = 0;
}
else {
print STDERR "Illegal value($tval) for $name.\n",
" Valid values are: T[rue],Y[es],1,",
" F[alse],N[o],0\n",
" Set to default: $parm_def{$name}.\n";
$tval = $parm_def{$name};
goto Dereference;
};
};
};
};
$value = $tval if $ok;
print STDERR "get_value : $name => $value\n"
if ($debug);
return ($ok, $value);
};
#
#------------------------------------------------------------------------
# Read input configuration file (if no input, just use defaults)
#------------------------------------------------------------------------
sub read_config {
my ($input_file) = @_;
@ARGV = split(' ', $input_file);
return if (! -r $input_file);
my $savename = '';
my $parmname = '';
my $parmval = '';
my $parmref = '';
my $defname = '';
my $defval = '';
my $tmpval = '';
print STDOUT "Reading configuration from ", join(',',@ARGV), ".\n";
line: while (<ARGV>) {
next line if /^$/; # skip empty lines
chomp; # drop tailing \n
if (s/\\$//) {
$_ .= <>;
redo unless eof();
};
# check commented lines for default parameter values
# a bit of a kluge, but it works out nicely
if (/^#\s*([\w_]+)="([^"]*)"/) {
$defname = get_name($1, 1);
$defval = $2;
print STDERR "Default: $defname => $defval.\n"
if ($debug);
next line;
};
# Skip any comments
next line if /^#/; # skip comments
# Process assignment statements
if (/^\s*([\w_]+)="([^"]*)"/) {
$savename = $1;
$parmname = get_name($savename, '');
$parmval = $2;
print STDERR "Value : $savename => $parmval.\n"
if ($debug);
# Do we know about this parameter?
# NOTE: keep, even if we don't know about it to prevent
# problems with up/down grades (not loose anything)
if ( ! exists($parm_def{$parmname}) and
! exists($parm_hidden{$parmname}) ) {
print STDERR "$parmname is a user defined parameter.\n"
if ($debug);
};
# Note if value is default, if so, we'll change it to
# the current default - maybe counterintuitive, oh well
# it does help with migration
if ($parmname eq $defname and $parmval eq $defval) {
print STDERR "$parmname is the default value: $defval.\n"
if ($debug);
$parmval = $parm_def{$parmname};
};
# Finally, assign value
if (exists $parm_kw{$savename} or
exists $parm_bool{$savename}) {
$parmval = ucfirst($parmval);
};
if ($savename eq $parmname) {
$parameter{$parmname} = $parmval;
}
else {
$parameter{$savename} = $parmval;
};
};
};
};
#
#------------------------------------------------------------------------
# Validate current configuration
#------------------------------------------------------------------------
sub validate_config {
my $valid = 1;
print STDOUT "Validating configuration.\n";
# Really, we only care about the some of the variables - those
# that have defaults... the rest, well, so what !
foreach my $val (sort keys %parm_def) {
my ($ok, $value) = &get_value($val, 1);
if (! $ok) { $valid = 0; };
};
if (! $valid ) {
print STDERR "\nOne or more errors were encountered!\n\n";
};
return ($valid);
};
#
#------------------------------------------------------------------------
# Write updated configuration file
#------------------------------------------------------------------------
sub write_config {
my ($database_file) = @_;
my $ofh = new FileHandle;
# Make sure things are kosher
my $result = &validate_config;
if (! $result) {
die "Terminating due to configuration error.";
};
$database_file = $database_file || $Parse_conf::Conffile;
my $caller = "$main::program_name" if ($main::program_name);
$caller .= " $main::program_version" if ($main::program_version);
$caller .= " $main::program_date" if ($main::program_date);
print STDOUT "Writing configuration to $database_file.\n";
$database_file = '&STDOUT' if ($database_file eq '-');
unless ( open($ofh, ">$database_file") ) {
warn("Could not open $database_file($!), using STDOUT\n");
open($ofh, ">&STDOUT");
};
$database_file = '-' if ($database_file eq '&STDOUT');
# print $ofh <<"EOT";
####################################################################
##### This file is automagically generated -- edit at your own risk
#####
##### file: ${database_file}
##### generated via: (${interp_pgm} ${interp_vrm})
##### ${caller}
##### ${Parse_conf::program_name} ${Parse_conf::program_version} ${Parse_conf::program_date}
##### by: ${user}\@${hostname}
##### on: ${current_time}
##### in: ${directory}
##### input files:
#EOT
# foreach my $file ( split(' ', $input_file) ) {
# print $ofh <<"EOT";
##### ${file}
#EOT
# };
# print $ofh <<"EOT";
#####
####################################################################
print $ofh <<"EOT";
#------------------------------------------------------------------------------
#
# $database_file
#
# Copyright (c) 2001-2010 Richard Nelson. All Rights Reserved.
# Version: ${main::program_version}
# Time-stamp: <${main::program_date}>
#
# Parameter file for sendmail (sourced by /usr/share/sendmail/sendmail)
# Make all changes herein, instead of altering /etc/init.d/sendmail.
#
# After making changes here, you'll need to run /usr/sbin/sendmailconfig
# or ${main::program_name} to have the changes take effect -
# If you change DAEMON_MODE, QUEUE_MODE, or QUEUE_INTERVAL, you'll also
# need to run /etc/init.d/sendmail restart.
#
# Changes made herein will be kept across upgrades - except for comments!
# Some comment lines have special significance ...
#
# **** **** **** **** DO NOT EDIT THE COMMENTS **** **** **** ****
#
# Supported parameters (and defaults) are listed herein.
#
# Notes:
# * This setup allows sendmail to run in several modes:
# - listener and queue runner..DAEMON_MODE="daemon".QUEUE_MODE="daemon"
# - listener only..............DAEMON_MODE="daemon".QUEUE_MODE="none"
# - queue runner only..........DAEMON_MODE="none"...QUEUE_MODE="daemon"
# - *NOTHING* ?!?..............DAEMON_MODE="none"...QUEUE_MODE="none"
#
# * You can also run the listener from inetd:
# - listener and queue runner..DAEMON_MODE="inetd"..QUEUE_MODE="daemon"
# - listener only..............DAEMON_MODE="inetd"..QUEUE_MODE="none"
#
# * You can also run the queue runner from cron:
# - listener and queue runner..DAEMON_MODE="....."..QUEUE_MODE="cron"
# - queue runner only..........DAEMON_MODE="none"...QUEUE_MODE="cron"
#
# * _PARMS entries herein are shown in precedence order, any later _PARMS
# field will, if applicable, override any previous _PARMS fields.
#
# * Values *MUST* be surrounded with double quotes ("), single quotes
# will *NOT* work !
#
#------------------------------------------------------------------------------
# SMTP Listener Configuration
#
# DAEMON_NETMODE="$parm_def{'DAEMON_NETMODE'}"; Keyword SMTP network mode
# static: Do not monitor any network interfaces for changes
# dynamic: Monitor one or more interfaces for changes
#
DAEMON_NETMODE="$parameter{'DAEMON_NETMODE'}";
#
# DAEMON_NETIF="$parm_def{'DAEMON_NETIF'}"; string SMTP interface(s)
# This parameter defines the network interface(s) that the daemon
# will monitor for status changes (via ppp, dhcp, ifup/down hooks).
#
# NOTES:
# 1) Only list more than one interfaces if they only used for fallback,
# otherwise the daemon will wind up ping-ponging between interfaces.
# 2) Do not use 'lo' unless your daemon only listens on the localhost.
#
DAEMON_NETIF="$parameter{'DAEMON_NETIF'}";
#
# DAEMON_MODE="$parm_def{'DAEMON_MODE'}"; Keyword SMTP listener
# daemon: Run as standalone daemon
# inetd: Run from inet supervisor (forks for each mail)
# none: No listener (ie, nullclient/smarthost)
#
# NOTE: If you choose "none", mail will build up in the MSP queues
# and you will not receive any mail from external sites.
#
DAEMON_MODE="$parameter{'DAEMON_MODE'}";
#
# DAEMON_PARMS="$parm_def{'DAEMON_PARMS'}"; String Listener parms
# Any parameters here will be ignored when run from cron.
# Note that {QUEUE,MISC,CRON}_PARMS, if applicable, will override
# anything declared herein.
#
DAEMON_PARMS="$parameter{'DAEMON_PARMS'}";
#
# DAEMON_HOSTSTATS="$parm_def{'DAEMON_HOSTSTATS'}"; Boolean Listener stats
# This parameter determines whether or not host stats are collected
# and available for the \`hoststat\` command to display. There will
# be a (minor) performance hit, as files will be created/updated for each
# sendmail delivery attempt. The files are fixed in size, and small,
# but there can be many of them.
#
DAEMON_HOSTSTATS="$parameter{'DAEMON_HOSTSTATS'}";
#
# DAEMON_MAILSTATS="$parm_def{'DAEMON_MAILSTATS'}"; Boolean Listener stats
# This parameter determines whether or not mailer stats are collected
# and available for the \`mailstats\` command to display. There will
# be a (minor) performance hit, as this file will be updated for each
# item coming into, or out of, sendmail. The file is fixed in size,
# and small, so there's no need to rotate it.
#
DAEMON_MAILSTATS="$parameter{'DAEMON_MAILSTATS'}";
#
#------------------------------------------------------------------------------
# SMTP MTA Queue Runner Configuration
#
# QUEUE_MODE="$parm_def{'QUEUE_MODE'}"; Keyword SMTP queue runner
# daemon: Run as standalone daemon
# cron: Run from crontab
# none: No queue runner (ie, nullclient/smarthost)
#
QUEUE_MODE="$parameter{'QUEUE_MODE'}";
#
# QUEUE_INTERVAL="$parm_def{'QUEUE_INTERVAL'}"; Timespec (p?digits+w|d|h|m|s)
# Interval at which to run the MTA queues. What interval should you use?
# The amount of time that is acceptable before retrying delivery on
# mail that couldn't be delivered in one run, or how long an item can
# set in the queue before having the first delivery attempt done.
#
# NOTE: To use persistent queue-runners use this form: p120m
#
# NOTE: If you leave this field blank, You get *NO* queue runners !!!
#
QUEUE_INTERVAL="$parameter{'QUEUE_INTERVAL'}";
#
# QUEUE_PARMS="$parm_def{'QUEUE_PARMS'}"; String queue parameters
# Any parameters here are also used when run from cron.
# Note that MISC_PARMS and CRON_PARMS, if applicable, will override
# anything declared herein.
#
QUEUE_PARMS="$parameter{'QUEUE_PARMS'}";
#
#------------------------------------------------------------------------------
# SMTP - MSP Queue Runner Configuration
#
# MSP_MODE="$parm_def{'MSP_MODE'}"; Keyword MSP queue runner mode
# daemon: Run as standalone daemon
# cron: Run from crontab
# none: No queue runner (ie, nullclient/smarthost)
#
# NOTE: If QUEUE_MODE="cron" & MSP_MODE="none", the MSP queue will
# be run as part of the MTA queue running process.
#
MSP_MODE="$parameter{'MSP_MODE'}";
#
# MSP_INTERVAL="$parm_def{'MSP_INTERVAL'}"; Timespec (digits+w|d|h|m|s)
# Interval at which to run the MSP queues. What interval should you use?
# The amount of time that is acceptable before retrying delivery on
# mail that couldn't be accepted by the MTA, and was therefore left
# in the message submission queue. The MTA shouldn't be down that often
# so this can be larger than QUEUE_INTERVAL.
#
# NOTE: If you leave this field blank, The MSP queue will *NOT* be run !!!
#
MSP_INTERVAL="$parameter{'MSP_INTERVAL'}";
#
# MSP_PARMS="$parm_def{'MSP_PARMS'}"; String queue parameters
# Any parameters here are also used when run from cron.
# Note that MISC_PARMS and CRON_PARMS, if applicable, will override
# anything declared herein.
#
MSP_PARMS="$parameter{'MSP_PARMS'}";
#
# MSP_MAILSTATS="$parm_def{'MSP_MAILSTATS'}"; Boolean Listener stats
# This parameter determines whether or not mailer stats are collected
# and available for the \`mailstats\` command to display. There will
# be a (minor) performance hit, as this file will be updated for each
# item coming into, or out of, sendmail. The file is fixed in size,
# and small, so there's no need to rotate it.
#
MSP_MAILSTATS="$parameter{'MSP_MAILSTATS'}";
#
#------------------------------------------------------------------------------
# Miscellaneous Confguration
#
# MISC_PARMS="$parm_def{'MISC_PARMS'}"; String miscellaneous parameters
# Miscellaneous parameters - applied to any sendmail invocation.
# Any parameters here are also used when run from cron.
# Applied after {DAEMON,QUEUE}_PARMS, and can therefore override them
# if need be (in which case why did use them?)
# Note that CRON_PARMS, if applicable, will override anything
# declared herein.
#
# Here is where'd you setup and debugging or special parms that you
# want shared betwixt the possibly separate listener/queue-runner
# processes.
#
MISC_PARMS="$parameter{'MISC_PARMS'}";
#
#------------------------------------------------------------------------------
# Cron Job Configuration
#
# CRON_MAILTO="$parm_def{'CRON_MAILTO'}"; String cronjob output
# Recipient of *rare* cronjob output. Some cronjobs will be running
# under user `mail`, so any problems encountered would probably be missed
# so define a user who actually (hopefully) checks email now and again.
#
CRON_MAILTO="$parameter{'CRON_MAILTO'}";
#
# CRON_PARMS="$parm_def{'CRON_PARMS'}"; String cron specific parmeters
# Cron parameters - applied *only* when sendmail queue running is done
# via a cronjob. Applied after QUEUE_PARMS and MISC_PARMS, and can
# therefore override them if need be.
#
CRON_PARMS="$parameter{'CRON_PARMS'}";
#
#------------------------------------------------------------------------------
# Other stuff
# LOG_CMDS="$parm_def{'LOG_CMDS'}"; Binary command logging flag
# Will cause syslog entries for many of the sendmail related commands
# like runq, mailq, etc - you'll also see cron jobs (if enabled).
#
LOG_CMDS="$parameter{'LOG_CMDS'}";
#
# HANDS_OFF="$parm_def{'HANDS_OFF'}"; Binary Do *NOT* touch the configuration
# Set this *ONLY* if you are going to be fully responsible for the entire
# setup of sendmail - the directories, permissions, databases, etc. With
# this variable set to "Yes", nothing will be done for you during updates.
#
# In other words, "The blood be upon your hands" if you set this...
# My ability to help with problems will be greatly reduced !
#
# "Well, a pet peeve of mine is people who directly edit the
# .cf file instead of using the m4 configuration files.
# Don't do it! [laughs] I treat the .cf file as a binary
# file - you should too."
# -- Eric Allman 1999/10/18
# http://www.dotcomeon.com/allman_sendmail_qa.html
#
HANDS_OFF="$parameter{'HANDS_OFF'}";
#
#------------------------------------------------------------------------------
# Queue Aging Configuration
#
# Why would you want to age your queues? On every queue-run interval,
# sendmail will try *every* file in the queue... If a site is down
# for a while, considerable time can be wasted each interval in retrying
# it. The scheme supported allows aging by time, and can move the older
# files to another (less frequently run queue), thereby reducing overal
# system impact - and providing better mail throughput.
#
# Note that this support is completely separate from QUEUE_MODE=cron,
# you can age queues even if you're running QUEUE_MODE=daemon.
#
# There are four parts to the queue aging support, and these parts
# may be repeated, to operate on multiple queues.
#
# 1. Interval at which to age the queues (in minutes).
# What interval should you use? Roughly twice the normal queue
# interval, so that messages are tried twice in each successively
# slower queue.
#
# NOTE: some values just wont work, due to crontab pecularities
# a value of 90 minutes will actually be run at every x:30 !
# Please check /etc/cron.d/sendmail to make sure it is doing what
# you thought it should !
#
# 2. Criteria (optional and defaults to interval). This is the
# specification of which files to move. It defaults moving
# files whose age in the queues exceeds the interval.
# This field, if specified can be very complex - supporting
# aging by just about anything! see qtool(8) for details.
#
# 3. To queue. This is the queue to which files will be moved.
# It may be fully qualified, or relative to /var/spool/mqueue.
#
# 4. From queue. This is the queue from which files will be moved.
# It may be fully qualified, or relative to /var/spool/mqueue.
#
# Samples:
# AGE_DATA="[['25m', '', 'hourly', 'main']]";
# Every 25 minutes, move any file older than 25 minutes from
# /var/spool/mqueue/main to /var/spool/mqueue/hourly
#
# AGE_DATA="[['25m', '', 'hourly', 'main'],\\
# ['120m', '', 'daily', 'hourly']]";
# Same as the above, but also move files from the hourly queue
# to the daily queue after 120 minutes in the hourly queue.
#
# AGE_DATA="[['25m',\\
# '-e \\'\$msg{message}[0] == /Deferred: 452 4.2.2 Over quota/\\'',\\
# 'overquota', 'main']]";
# Every 25 minutes, move all files deferred because of quota
# violations from /var/spool/mqueue/main to
# /var/spool/mqueue/overquota where they can be processed on
# a different interval, or by some other means.
#
# If the above samples suggest Perl arrays, well, they are...
#
# AGE_DATA="$parm_def{'AGE_DATA'}"; Perl array Queue aging data
#
EOT
my ($ok, $var) = &get_value('AGE_DATA');
my $tmpval = eval $var;
if ($@) {
warn $@;
}
else {
$var = $tmpval;
};
if (not defined $var) {
print $ofh 'AGE_DATA="";',"\n";
}
elsif (not ref $var) {
print $ofh 'AGE_DATA="',$var,'";',"\n";
}
elsif (@{$var} == 0) {
print $ofh 'AGE_DATA="";',"\n";
}
else {
print $ofh 'AGE_DATA="[\\',"\n";
foreach my $entry (@{$var}) {
foreach my $ndx ($[ .. $#{$entry}) {
@{$entry}[$ndx] =~ s/'/\\'/g;
};
print $ofh "['",join("', '",@{$entry}),"'],\\\n";
};
print $ofh ']";',"\n";
};
print $ofh <<"EOT";
#
#------------------------------------------------------------------------------
# Dependant variables (set according to other variables)
#
EOT
foreach my $key (sort keys %parm_dependant) {
my ($ok, $value);
# Don't evaluate value, just stuff it...
next if ( ! $parameter{$key} );
($ok, $value) = (1, $parameter{$key});
print $ofh "$key=",'"',$value,'";',"\n";
};
print $ofh <<"EOT";
#
#------------------------------------------------------------------------------
# Hidden variables (the blood be upon your hands)
#
EOT
foreach my $key (sort keys %parm_hidden) {
my ($ok, $value);
# Don't evaluate value, just stuff it...
next if ( ! $parameter{$key} );
($ok, $value) = (1, $parameter{$key});
print $ofh "$key=",'"',$value,'";',"\n";
};
print $ofh <<"EOT";
#
#------------------------------------------------------------------------------
# Deprecated variables (kept for reference)
#
EOT
foreach my $key (sort keys %parm_deprecated) {
my ($ok, $value);
# Don't evaluate value, just stuff it...
if ( $parm_deprecated{$key} ) {
($ok, $value) = (1, join('','${', $parm_deprecated{$key}, '}'));
}
elsif ( $parameter{$key} ) {
($ok, $value) = (1, $parameter{$key});
};
print $ofh "$key=",'"',$value,'";',"\n";
};
print $ofh <<"EOT";
#
#------------------------------------------------------------------------------
# Unknown variables (kept for reference)
#
EOT
foreach my $key (sort keys %parameter) {
if (! exists($parm_def{$key}) and
! exists($parm_deprecated{$key})) {
# Don't evaluate value, just stuff it...
my ($ok, $value) = (1, $parameter{$key});
print $ofh "$key=",'"',$value,'";',"\n";
};
};
print $ofh <<"EOT";
#------------------------------------------------------------------------------
#
EOT
close($ofh);
if ( $database_file eq $Parse_conf::Conffile ) {
chown '0', '0', "$database_file";
chmod 0644, "$database_file";
};
};
__END__