Import sendmail-8.8.3 - this contains the official fix to replace the

previous workaround patch that I used.

Obtained from: Eric Allman <eric@sendmail.org>
This commit is contained in:
Peter Wemm 1996-11-18 02:26:51 +00:00
parent 606a993469
commit fcf445de96
33 changed files with 1733 additions and 602 deletions

View File

@ -1,12 +1,125 @@
SENDMAIL RELEASE NOTES
@(#)RELEASE_NOTES 8.8.2.1 (Berkeley) 10/18/96
@(#)RELEASE_NOTES 8.8.3.2 (Berkeley) 11/16/96
This listing shows the version of the sendmail binary, the version
of the sendmail configuration files, the date of release, and a
summary of the changes in that release.
8.8.2/8.8.2 96/11/18
8.8.3/8.8.3 96/11/17
SECURITY: it was possible to get a root shell by lying to sendmail
about argv[0] and then sending it a signal. Problem noted
by Leshka Zakharoff <leshka@leshka.chuvashia.su> on the
best-of-security list.
Log sendmail binary version number in "Warning: .cf version level
(%d) exceeds program functionality (%d) message" -- this
should make it clearer to people that they are running
the wrong binary.
Fix a problem that occurs when you open an SMTP connection and then
do one or more ETRN commands followed by a MAIL command; at
the end of the DATA phase sendmail would incorrectly report
"451 SMTP-MAIL: lost child: No child processes". Problem
noted by Eric Bishop of Virginia Tech.
When doing text-based host canonification (typically /etc/hosts
lookup), a null host name would match any /etc/hosts entry
with space at the end of the line. Problem noted by Steve
Hubert of the University of Washington, Seattle.
7 to 8 bit BASE64 MIME conversions could duplicate bits of text.
Problem reported by Tom Smith of Digital Equipment Corp.
Increase the size of the DNS answer buffer -- the standard UDP packet
size PACKETSZ (512) is not sufficient for some nameserver
answers containing very many resource records. The resolver
may also switch to TCP and retry if it detects UDP packet
overflow. Also, allow for the fact that the resolver
routines res_query and res_search return the size of the
*un*truncated answer in case the supplied answer buffer it
not big enough to accommodate the entire answer. Patch from
Eric Wassenaar.
Improvements to MaxDaemonChildren code. If you think you have too
many children, probe the ones you have to verify that they
are still around. Suggested by Jared Mauch of CICnet, Inc.
Also, do this probe before growing the vector of children
pids; this previously caused the vector to grow indefinitely
due to a race condition. Problem reported by Kyle Jones of
UUNET.
On some architectures, <db.h> (from the Berkeley DB library) defines
O_EXLOCK to zero; this fools the map compilation code into
thinking that it can avoid race conditions by locking on open.
Change it to check for O_EXLOCK non-zero. Problem noted by
Leif Erlingsson of Data Lege.
Always call res_init() on startup (if compiled in, of course) to
allow the sendmail.cf file to tweak resolver flags; without
it, flag tweaks in ResolverOptions are ignored. Patch from
Andrew Sun of Merrill Lynch.
Improvements to host status printing code. Suggested by Steve Hubert
of the University of Washington, Seattle.
Change MinQueueAge option processing to do the check for the job age
when reading the queue file, rather than at the end; this
avoids parsing the addresses, which can do DNS lookups.
Problem noted by John Beck of InReference, Inc.
When MIME was being 7->8 bit decoded, "From " lines weren't being
properly escaped. Problem noted by Peter Nilsson of the
University of Linkoping.
In some cases, sendmail would retain root permissions during queue
runs even if RunAsUser was set. Problem noted by Mark
Thomas of Mark G. Thomas Consulting.
If the F=l flag was set on an SMTP mailer to indicate that it is
actually local delivery, and NOTIFY=SUCCESS is specified in
the envelope, and the receiving SMTP server speaks DSN, then
the DSN would be both generated locally and propogated to the
other end.
The U= mailer field didn't correctly extract the group id if the
user id was numeric. Problem noted by Kenneth Herron of
MCI Telecommunications Communications.
If a message exceeded the fixed maximum size on input, the body of
the message was included in the bounce. Note that this did
not occur if it exceeded the maximum _output_ size. Problem
reported by Kyle Jones of UUNET.
PORTABILITY FIXES:
AIX4: 4.1 does't have a working setreuid(2); change the
AIX4 defines to use seteuid(2) instead, which
works on 4.1 as well as 4.2. Problem noted by
Håkan Lindholm of interAF, Sweden.
AIX4: use tzname[] vector to determine time zone name.
Patch from NAKAMURA Motonori of Kyoto University.
MkLinux: add Makefile.Linux.ppc and OSTYPE(mklinux) support.
Contributed by Paul DeBois <dubois@primate.wisc.edu>.
Solaris: kstat(3k) support for retrieving the load average.
This adds the LA_KSTAT definition for LA_TYPE.
The outline of the implementation was contributed
by Michael Tokarev of Telecom Service, JSC, Moscow.
HP-UX 10.0 gripes about the (perfectly legal!) forward
declaration of struct rusage at the top of conf.h;
change it to only be included if you are using gcc,
which is apparently the only compiler that requires
it in the first place. Problem noted by Jeff
Earickson of Colby College.
IRIX: don't default to using gcc. IRIX is a civilized
operating system that comes with a decent compiler
by default. Problem noted by Barry Bouwsma and
Kari Hurtta.
CONFIG: specify F=9 as default in FEATURE(local_procmail) for
consistency with other local mailers. Inconsistency
pointed out by Teddy Hogeborn <teddy@fukt.hk-r.se>.
CONFIG: if the "limited best mx" feature is used (to reduce DNS
overhead) as part of the bestmx_is_local feature, the
domain part was dropped from the name. Patch from Steve
Hubert of the University of Washington, Seattle.
CONFIG: catch addresses of the form "user@.dom.ain"; these could
end up being translated to the null host name, which would
return any entry in /etc/hosts that had a space at the end
of the line. Problem noted by Steve Hubert of the
University of Washington, Seattle.
CONFIG: add OSTYPE(aix4). From Michael Sofka of Rensselaer
Polytechnic Institute.
MAKEMAP: tweak hash and btree parameters for better performance.
Patch from Matt Dillon of Best Internet Communications.
NEW FILES:
src/Makefiles/Makefile.Linux.ppc
cf/ostype/aix4.m4
cf/ostype/mklinux.m4
8.8.2/8.8.2 96/10/18
SECURITY: fix a botch in the 7-bit MIME patch; the previous patch
changed the code but didn't fix the problem.
PORTABILITY FIXES:
@ -1089,7 +1202,7 @@ summary of the changes in that release.
Syntax errors such as unbalanced parentheses in the configuration
file could be omitted if you had "Oem" prior to the
syntax error in the config file. Change to always print
the error message. It was especially wierd because it
the error message. It was especially weird because it
would cause a "warning" message to be sent to the Postmaster
for every message sent (but with no transcript). Problem
noted by Gregory Paris of Motorola.
@ -1823,7 +1936,7 @@ summary of the changes in that release.
only works on adjacent preferences, so an MX list that
had A=5, B=10, A=15 would leave both As, but one that had
A=5, A=10, B=15 would reduce to A, B. This is intentional,
just in case there is something wierd I haven't thought of.
just in case there is something weird I haven't thought of.
Suggested by Barry Shein of Software Tool & Die.
SECURITY: .forward files cannot be symbolic links. If they are,
a bad guy can read your private files.
@ -2420,7 +2533,7 @@ summary of the changes in that release.
fixed by Michael Corrigan and Christophe Wolfhugel.
8.6.7/8.6.6 94/03/14
SECURITY: it was possible to get root access by using wierd
SECURITY: it was possible to get root access by using weird
values to the -d flag. Thanks to Alain Durand of
INRIA for forwarding me the notice from the bugtraq
list.
@ -2558,7 +2671,7 @@ summary of the changes in that release.
CNAME loops caused an error message to be generated, but also
re-queued the message. Changed to just re-queue the
message (it's really hard to just bounce it because
of the wierd way the name server works in the presence
of the weird way the name server works in the presence
of CNAME loops). Problem noted by James M.R.Matheson
of Cambridge University.
Avoid giving ``warning: foo owned process doing -bs'' messages
@ -2823,7 +2936,7 @@ summary of the changes in that release.
Make sure that route-addrs always have <angle brackets> around
them in non-SMTP envelopes (SMTP envelopes already do
this properly).
Avoid wierd headers on unbalanced punctuation of the form:
Avoid weird headers on unbalanced punctuation of the form:
``Joe User <user)'' -- this caused reference to the
null macro. Fix from Rick McCarty of IO.COM.
Fix a problem that caused an alias "user: user@local.host" to
@ -3488,7 +3601,7 @@ summary of the changes in that release.
the "to" address). Problem noted by John Myers.
Fix dfopen to return NULL if the open failed; I was depending
on fdopen(-1) returning NULL, which isn't the case. This
isn't serious, but does result in wierd error diagnoses.
isn't serious, but does result in weird error diagnoses.
From Michael Corrigan.
CONFIG: add UUCP_MAX_SIZE M4 macro to set the maximum size of
messages sent through UUCP-family mailers. Suggested
@ -3524,7 +3637,7 @@ summary of the changes in that release.
Changes from Eric Wassenaar.
Open /dev/null for the transcript if the create of the xf file
failed; this avoids at least one possible null pointer
reference in very wierd cases. From Eric Wassenaar.
reference in very weird cases. From Eric Wassenaar.
Clean up statistics gathering; it was over-reporting because of
forks. From Eric Wassenaar.
Fix problem that causes old Return-Path: line to override new
@ -3775,7 +3888,7 @@ summary of the changes in that release.
PRALIASES: support for printing NEWDB databases. From
Michael J. Corrigan of U.C. San Diego.
CONFIG: don't pass pseudo-domains to $[ ... $] (if you have
a wildcard MX it can have wierd results). From
a wildcard MX it can have weird results). From
Christophe Wolfhugel.
CONFIG: dot terminate relay hostnames in S0. From Christophe
Wolfhugel.
@ -3888,7 +4001,7 @@ summary of the changes in that release.
Don't try to flock non-regular files when mailing to a file.
In particular, this was a problem if you tried to
send to /dev/null.
Fix a wierd bug that can cause senders to be queued as
Fix a weird bug that can cause senders to be queued as
recipients if the name server is down when the mail
is initially sent. This hack just ignores sender
deletion (essentially, it sets the MeToo flag) if there
@ -4222,7 +4335,7 @@ summary of the changes in that release.
file to have an F line, and the format of the T option
to accept take the format "return/warn" (both intervals).
Don't force all local names to lower case -- this was left over
from the wierd handling of case mapping on aliases. It
from the weird handling of case mapping on aliases. It
is now driven (as expected) by the "u" mailer flag.
Problem noted by P{r Emanuelsson.
Fix problem that caused headers on returned email to be trashed;
@ -4325,7 +4438,7 @@ summary of the changes in that release.
mailer.
Additional debug printing in getcanonname (show query type).
Don't add the e_fromdomain on sender addresses -- this interacts
wierdly with the owner- code.
weirdly with the owner- code.
Improve delivery logging to not log obvious or meaningless stuff.
Include numeric IP address in Received: lines per RFC 1123 section
5.2.8.
@ -4407,7 +4520,7 @@ summary of the changes in that release.
Config extensions for Sam Leffler's FlexFAX software.
6.31/6.10 93/02/28
Fix some more bugs in alias owner code -- there were some wierd
Fix some more bugs in alias owner code -- there were some weird
cases where an error in a non-aliased name would override
the return info in an aliased name with an owner.
Changes from WIDE Project, forwarded to me by Motonori Nakamura:

View File

@ -4,7 +4,7 @@
Eric Allman <eric@CS.Berkeley.EDU>
@(#)README 8.106 (Berkeley) 10/12/96
@(#)README 8.108 (Berkeley) 11/16/96
This document describes the sendmail configuration files being used
@ -128,7 +128,7 @@ Let's examine a typical .mc file:
divert(0)
The divert(-1) will delete the crud in the resulting output file.
The copyright notice can be replace by whatever your lawyers require;
The copyright notice can be replaced by whatever your lawyers require;
our lawyers require the one that I've included in my files. A copyleft
is a copyright by another name. The divert(0) restores regular output.
@ -587,8 +587,10 @@ uucpdomain Similar feature for UUCP hosts. The default map definition
always_add_domain
Include the local host domain even on locally delivered
mail. Normally it is not added unless it is already
present.
mail. Normally it is not added on unqualified names.
However, if you use a shared message store but do not use
the same user name space everywhere, you may need the host
name on local names.
allmasquerade If masquerading is enabled (using MASQUERADE_AS), this
feature will cause recipient addresses to also masquerade
@ -940,8 +942,8 @@ You can have your host masquerade as another using
MASQUERADE_AS(host.domain)
This causes mail being sent to be labeled as coming from the
indicated domain, rather than $j. One normally masquerades as one
of one's own subdomains (for example, it's unlikely that I would
indicated host.domain, rather than $j. One normally masquerades as
one of one's own subdomains (for example, it's unlikely that I would
choose to masquerade as an MIT site). This behaviour is modified by
a plethora of FEATUREs; in particular, see masquerade_envelope,
allmasquerade, limited_masquerade, and masquerade_entire_domain.
@ -1217,6 +1219,11 @@ Plussed users
If that is not found, the alias "root+*" will be tried,
then "root".
LDAP
For notes on use LDAP in sendmail, see
http://www-leland.stanford.edu/~bbense/Inst.html
+----------------+
| SECURITY NOTES |

View File

@ -0,0 +1,108 @@
#
# Makefile for configuration files.
#
# @(#)Makefile.dist 8.9 (Berkeley) 9/12/95
#
#
# Configuration files are created using "m4 file.mc > file.cf";
# this may be easier than tweaking the Makefile. You do need to
# have a fairly modern M4 available (GNU m4 works). On SunOS, use
# /usr/5bin/m4.
#
M4= m4
#M4= /usr/src/usr.bin/m4/obj/m4
CFDIR= ..
CHMOD= chmod
ROMODE= 444
RM= rm -f
.SUFFIXES: .mc .cf
.mc.cf:
$(RM) $@
$(M4) ${CFDIR}/m4/cf.m4 $*.mc > $@
$(CHMOD) $(ROMODE) $@
ALL= generic-bsd4.4.cf generic-hpux9.cf generic-hpux10.cf \
generic-osf1.cf generic-solaris2.cf \
cs-hpux9.cf cs-osf1.cf cs-solaris2.cf \
cs-sunos4.1.cf cs-ultrix4.cf \
s2k-osf1.cf s2k-ultrix4.cf \
chez.cs.cf huginn.cs.cf mail.cs.cf mail.eecs.cf mailspool.cs.cf \
python.cs.cf ucbarpa.cf ucbvax.cf vangogh.cs.cf
all: $(ALL)
clean cleandir:
$(RM) $(ALL) core
depend install:
# this is overkill, but....
M4FILES=\
${CFDIR}/domain/Berkeley.EDU.m4 \
${CFDIR}/domain/CS.Berkeley.EDU.m4 \
${CFDIR}/domain/EECS.Berkeley.EDU.m4 \
${CFDIR}/domain/S2K.Berkeley.EDU.m4 \
${CFDIR}/feature/allmasquerade.m4 \
${CFDIR}/feature/always_add_domain.m4 \
${CFDIR}/feature/bestmx_is_local.m4 \
${CFDIR}/feature/bitdomain.m4 \
${CFDIR}/feature/domaintable.m4 \
${CFDIR}/feature/local_procmail.m4 \
${CFDIR}/feature/mailertable.m4 \
${CFDIR}/feature/nocanonify.m4 \
${CFDIR}/feature/nodns.m4 \
${CFDIR}/feature/notsticky.m4 \
${CFDIR}/feature/nouucp.m4 \
${CFDIR}/feature/nullclient.m4 \
${CFDIR}/feature/redirect.m4 \
${CFDIR}/feature/smrsh.m4 \
${CFDIR}/feature/stickyhost.m4 \
${CFDIR}/feature/use_cw_file.m4 \
${CFDIR}/feature/uucpdomain.m4 \
${CFDIR}/hack/cssubdomain.m4 \
${CFDIR}/m4/cf.m4 \
${CFDIR}/m4/nullrelay.m4 \
${CFDIR}/m4/proto.m4 \
${CFDIR}/m4/version.m4 \
${CFDIR}/mailer/cyrus.m4 \
${CFDIR}/mailer/fax.m4 \
${CFDIR}/mailer/local.m4 \
${CFDIR}/mailer/mail11.m4 \
${CFDIR}/mailer/pop.m4 \
${CFDIR}/mailer/procmail.m4 \
${CFDIR}/mailer/smtp.m4 \
${CFDIR}/mailer/usenet.m4 \
${CFDIR}/mailer/uucp.m4 \
${CFDIR}/ostype/aix3.m4 \
${CFDIR}/ostype/amdahl-uts.m4 \
${CFDIR}/ostype/aux.m4 \
${CFDIR}/ostype/bsd4.3.m4 \
${CFDIR}/ostype/bsd4.4.m4 \
${CFDIR}/ostype/bsdi1.0.m4 \
${CFDIR}/ostype/dgux.m4 \
${CFDIR}/ostype/domainos.m4 \
${CFDIR}/ostype/dynix3.2.m4 \
${CFDIR}/ostype/hpux9.m4 \
${CFDIR}/ostype/irix4.m4 \
${CFDIR}/ostype/irix5.m4 \
${CFDIR}/ostype/linux.m4 \
${CFDIR}/ostype/nextstep.m4 \
${CFDIR}/ostype/osf1.m4 \
${CFDIR}/ostype/ptx2.m4 \
${CFDIR}/ostype/riscos4.5.m4 \
${CFDIR}/ostype/sco3.2.m4 \
${CFDIR}/ostype/solaris2.m4 \
${CFDIR}/ostype/sunos3.5.m4 \
${CFDIR}/ostype/sunos4.1.m4 \
${CFDIR}/ostype/svr4.m4 \
${CFDIR}/ostype/ultrix4.m4 \
${CFDIR}/siteconfig/uucp.cogsci.m4 \
${CFDIR}/siteconfig/uucp.old.arpa.m4 \
${CFDIR}/siteconfig/uucp.ucbarpa.m4 \
${CFDIR}/siteconfig/uucp.ucbvax.m4 \
$(ALL): $(M4FILES)

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)bestmx_is_local.m4 8.3 (Berkeley) 5/11/96')
VERSIONID(`@(#)bestmx_is_local.m4 8.4 (Berkeley) 10/23/96')
divert(-1)
LOCAL_CONFIG
@ -60,7 +60,7 @@ LOCAL_NET_CONFIG
ifelse(_ARG_, `', `', `#')dnl unlimited bestmx
R$* < @ $* > $* $: $1 < @ $2 @@ $(bestmx $2 $) > $3
ifelse(_ARG_, `', `#', `')dnl limit bestmx to $=B
R$* < @ $* $=B > $* $: $1 < @ $2 @@ $(bestmx $2 $3 $) > $4
R$* < @ $* $=B > $* $: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4
R$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3
R$* < @ $* @@ $=w . > $* $#local $: $1
R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)local_procmail.m4 8.5 (Berkeley) 2/12/96')
VERSIONID(`@(#)local_procmail.m4 8.6 (Berkeley) 10/20/96')
divert(-1)
define(`LOCAL_MAILER_PATH',
@ -43,5 +43,5 @@ define(`LOCAL_MAILER_PATH',
PROCMAIL_MAILER_PATH,
`/usr/local/bin/procmail'),
_ARG_))
define(`LOCAL_MAILER_FLAGS', `SPfhn')
define(`LOCAL_MAILER_FLAGS', `SPfhn9')
define(`LOCAL_MAILER_ARGS', `procmail -Y -a $h -d $u')

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)proto.m4 8.134 (Berkeley) 10/13/96')
VERSIONID(`@(#)proto.m4 8.135 (Berkeley) 10/26/96')
MAILER(local)dnl
@ -662,7 +662,7 @@ R$* $: <> $1
R<> $* < @ [ $+ ] > $* $1 < @ [ $2 ] > $3
R<> $* <$* : $* > $* $#error $@ 5.1.1 $: "colon illegal in host name part"
R<> $* $1
R$* < @ . > $* $#error $@ 5.1.2 $: "invalid host name"
R$* < @ . $* > $* $#error $@ 5.1.2 $: "invalid host name"
ifdef(`_MAILER_smtp_',
`# handle numeric address spec

View File

@ -32,8 +32,8 @@ divert(-1)
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
VERSIONID(`@(#)version.m4 8.8.2.1 (Berkeley) 10/18/96')
VERSIONID(`@(#)version.m4 8.8.3.1 (Berkeley) 11/16/96')
#
divert(0)
# Configuration version number
DZ8.8.2`'ifdef(`confCF_VERSION', `/confCF_VERSION')
DZ8.8.3`'ifdef(`confCF_VERSION', `/confCF_VERSION')

View File

@ -0,0 +1,41 @@
divert(-1)
#
# Copyright (c) 1996 Eric P. Allman
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
divert(0)
VERSIONID(`@(#)aix4.m4 8.1 (Berkeley) 11/13/96')
ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/bellmail)')dnl
ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', mail -F $g $u)')dnl
ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `mn9')')dnl
define(`confTIME_ZONE', `USE_TZ')dnl

View File

@ -0,0 +1,44 @@
divert(-1)
#
# Copyright (c) 1983 Eric P. Allman
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# MkLinux support contributed by Paul DeBois <dubois@primate.wisc.edu>
#
divert(0)
VERSIONID(`@(#)mklinux.m4 8.1 (Berkeley) 10/30/96')
ifdef(`STATUS_FILE',,
`define(`STATUS_FILE', /var/log/sendmail.st)')
ifdef(`PROCMAIL_MAILER_PATH',,
define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail'))
FEATURE(local_procmail)

View File

@ -1,280 +1,540 @@
Message-Id: <199412081919.NAA23234@austin.BSDI.COM>
To: Eric Allman <eric@cs.berkeley.edu>
Subject: Re: sorting mailings lists with fastest delivery users first
In-reply-to: Your message of Thu, 08 Dec 1994 06:08:33 PST.
References: <199412081408.GAA06210@mastodon.CS.Berkeley.EDU>
From: Tony Sanders <sanders@bsdi.com>
Received: from austin.bsdi.com (root{9l9gVDC7v8t3dlv0OtXTlby6X1zBWd56}@austin.BSDI.COM [205.230.224.49]) by knecht.Sendmail.ORG (8.8.2/8.8.2) with ESMTP id JAA05023 for <eric@sendmail.org>; Thu, 31 Oct 1996 09:29:47 -0800 (PST)
Received: from austin.bsdi.com (localhost [127.0.0.1]) by austin.bsdi.com (8.7.4/8.7.3) with ESMTP id KAA19250; Thu, 31 Oct 1996 10:28:18 -0700 (MST)
Message-Id: <199610311728.KAA19250@austin.bsdi.com>
To: Eric Allman <eric@sendmail.org>
cc: marc@xfree86.org
Subject: Updated mailprio_0_93.shar
From: Tony Sanders <sanders@earth.com>
Organization: Berkeley Software Design, Inc.
Date: Thu, 08 Dec 1994 13:19:39 -0600
Sender: sanders@austin.BSDI.COM
Date: Thu, 31 Oct 1996 10:28:14 -0700
Sender: sanders@austin.bsdi.com
Eric Allman writes:
> Nope, that's a new one, so far as I know. Any interest in
> contributing it? For small lists it seems overkill, but for
> large lists it could be a major win.
Eric, please update contrib/mailprio in the sendmail distribution
to this version at your convenience. Thanks.
Sure, I will contribute it; after I sent you mail last night I went ahead
and finished up what I thought needed to be done. I would like to get
some feedback from you on a few items, if you have time.
I've also made this available in:
ftp://ftp.earth.com/pub/postmaster/
There are two programs, mailprio_mkdb and mailprio (source below).
mailprio_0_93.shar follows...
mailprio_mkdb reads maillog files and creates a DB file of address vs.
delay. I'm not too happy with how it does the averages right now but this
is just a quick hack. However, it should at least order sites that take
days vs. those that deliver on the first pass through. One thing that
would make this information a lot more accurate is if sendmail could log
a "transaction delay" (on failures also), as well as total delivery delay.
Perhaps, as an option, it could maintain the DB file itself?
mailprio then simply reads a list of addresses from stdin (the mailing
list), and tries to prioritize them according to the info the database.
It collects comment lines and other junk at the top of the file; all
mailprio does is reorder lines, the actual text of the file should
be unchanged to the extent that you can verify it with:
sort sorted_list > checkit; sort mailing-list | diff - checkit
Users with no delay information are put next. The prioritized list is last.
Of course, this function could also be built-into sendmail (eventually).
Putting "new account" info at the top with the current averaging function
probably adversly affects the prioritized list (at least in the short
term), but putting it at the bottom would not really give the new accounts
a fair chance. I suspect this isn't that big of a problem. I'm running
this here on a list with 461 accounts and about 10 messages per day so
I'll see how it goes. I'll keep some stats on delay times and see what
happens.
Another thing that would help this situation, is if sendmail had the queue
ordered by site (but you already know this). If you ever get to do per
site queuing you should consider "blocking" a queue for some short period
of time if a connection fails to that site [sendmail does this inside a
single process on a per account basis now right?]; this would allow multiple
sendmails to quickly skip over those sites for people like me that run:
for i in 1 2 3 4 5 6 7 8 ; do daemon sendmail -q; done
to flush a queue that has gotten behind. You could also do this inside
sendmail with a parallelism option (when it is time to run the queue, how
many processes to start).
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: mailprio mailprio_mkdb
# Wrapped by sanders@austin.BSDI.COM on Fri Dec 9 18:07:02 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'mailprio' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mailprio'\"
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1996-10-31 10:07 MST by <sanders@earth.com>.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 8260 -rwxr-xr-x mailprio
# 3402 -rw-r--r-- mailprio.README
# 4182 -rwxr-xr-x mailprio_mkdb
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
echo shar: Extracting \"'mailprio'\" \(3093 characters\)
sed "s/^X//" >'mailprio' <<'END_OF_FILE'
X#!/usr/bin/perl
X#
X# mailprio -- setup mail priorities for a mailing list
X#
X# Sort mailing list by mailprio database:
X# mailprio < mailing-list > sorted_list
X# Double check against orig:
X# sort sorted_list > checkit; sort mailing-list | diff - checkit
X# If it checks out, install it.
X#
X# TODO:
X# option to process mqueue files so we can reorder files in the queue!
X$usage = "Usage: mailprio [-p priodb]\n";
X$home = "/home/sanders/lists";
X$priodb = "$home/mailprio";
shar_touch=:
echo
echo 'WARNING: not restoring timestamps. Consider getting and'
echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
# ============= mailprio ==============
if test -f 'mailprio' && test X"$1" != X"-c"; then
echo 'x - skipping mailprio (file already exists)'
else
echo 'x - extracting mailprio (text)'
sed 's/^X//' << 'SHAR_EOF' > 'mailprio' &&
#!/usr/bin/perl
#
# mailprio,v 1.4 1996/10/31 17:03:52 sanders Exp
# Version 0.93 -- Thu Oct 31 09:42:25 MST 1996
#
# mailprio -- setup mail priorities for a mailing list
#
# Copyright 1994, 1996, Tony Sanders <sanders@earth.com>
# Rights are hereby granted to download, use, modify, sell, copy, and
# redistribute this software so long as the original copyright notice
# and this list of conditions remain intact and modified versions are
# noted as such.
#
# I would also very much appreciate it if you could send me a copy of
# any changes you make so I can possibly integrate them into my version.
#
# Options:
# -p priority_database -- Specify database to use if not default
# -q -- Process sendmail V8.8.X queue format files
#
# Sort mailing lists or sendmail queue files by mailprio database.
# Files listed on the command line are locked and then sorted in place, in
# the absence of any file arguments it will read STDIN and write STDOUT.
#
# Examples:
# mailprio < mailing-list > sorted_list
# mailprio mailing-list1 mailing-list2 mailing-list3 ...
# mailprio -q /var/spool/mqueue/qf*
# To double check results:
# sort sorted_list > checkit; sort orig-mailing-list | diff - checkit
#
# To get the maximum value from a transaction delay based priority
# function you need to reorder the distribution list (and the mail
# queue files for that matter) fairly often; you could even have
# your mailing list software reorder the list before each outgoing
# message.
#
$usage = "Usage: mailprio [-p priodb] [-q] [mailinglists ...]\n";
$home = "/home/sanders/lists";
$priodb = "$home/mailprio";
$locking = "flock"; # "flock" or "fcntl"
X
Xif ($main'ARGV[0] =~ /^-/) {
X $args = shift;
X if ($args =~ m/\?/) { print $usage; exit 0; }
X if ($args =~ m/p/) {
X $priodb = shift || die $usage, "-p requires argument\n"; }
X}
# In shell, it would go more or less like this:
# old_mailprio > /tmp/a
# fgrep -f lists/inet-access /tmp/a | sed -e 's/^.......//' > /tmp/b
# ; /tmp/b contains list of known users, faster delivery first
# fgrep -v -f /tmp/b lists/inet-access > /tmp/c
# ; put all unknown stuff at the top of new list for now
# echo '# -----' >> /tmp/c
# cat /tmp/b >> /tmp/c
X
X# In shell script, it goes something like this:
X# old_mailprio > /tmp/a
X# fgrep -f lists/inet-access /tmp/a | sed -e 's/^.......//' > /tmp/b
X# ; /tmp/b contains list of known users, faster delivery first
X# fgrep -v -f /tmp/b lists/inet-access > /tmp/c
X# ; put all unknown stuff at the top of new list for now
X# echo '# -----' >> /tmp/c
X# cat /tmp/b >> /tmp/c
$qflag = 0;
while ($main'ARGV[0] =~ /^-/) {
X $args = shift;
X if ($args =~ m/\?/) { print $usage; exit 0; }
X if ($args =~ m/q/) { $qflag = 1; }
X if ($args =~ m/p/) {
X $priodb = shift || die $usage, "-p requires argument\n"; }
}
X
X# Setup %list and @list
Xlocal($addr, $canon);
Xwhile ($addr = <STDIN>) {
X chop $addr;
X next if $addr =~ /^# ----- /; # that's our line
X push(@list, $addr), next if $addr =~ /^\s*#/; # save comments
X $canon = &canonicalize((&simplify_address($addr))[0]);
X unless (defined $canon) {
X warn "no address found: $addr\n";
X push(@list, $addr); # save it anyway
X next;
push(@main'ARGV, '-') if ($#ARGV < 0);
while ($file = shift @ARGV) {
X if ($file eq "-") {
X $source = "main'STDIN";
X $sink = "main'STDOUT";
X } else {
X $sink = $source = "FH";
X open($source, "+< $file") || do { warn "$file: $!\n"; next; };
X if (!defined &seize($source, &LOCK_EX | &LOCK_NB)) {
X # couldn't get lock, just skip it
X close($source);
X next;
X }
X }
X if (defined $list{$canon}) {
X warn "duplicate: ``$addr -> $canon''\n";
X push(@list, $addr); # save it anyway
X next;
X
X local(*list);
X &process($source, *list);
X
X # setup to write output
X if ($file ne "-") {
X # zero the file (FH is hardcoded because truncate requires it, sigh)
X seek(FH, 0, 0) || die "$file: seek: $!\n";
X truncate(FH, 0) || die "$file: truncate: $!\n";
X }
X $list{$canon} = $addr;
X}
X
Xlocal(*prio);
Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n";
Xforeach $to (keys %list) {
X if (defined $prio{$to}) {
X # add to list of found users (%userprio) and remove from %list
X # so that we know what users were not yet prioritized
X $userprio{$to} = $prio{$to}; # priority
X $useracct{$to} = $list{$to}; # string
X delete $list{$to};
X # do the dirty work
X &output($sink, *list);
X
X close($sink) || warn "$file: $!\n"; # close clears the lock
X close($source);
}
X
sub process {
X # Setup %list and @list
X local($source, *list) = @_;
X local($addr, $canon);
X while ($addr = <$source>) {
X chop $addr;
X next if $addr =~ /^# ----- /; # that's our line
X push(@list, $addr), next if $addr =~ /^\s*#/; # save comments
X if ($qflag) {
X next if $addr =~ m/^\./;
X push(@list, $addr), next if !($addr =~ s/^(R[^:]*:)//);
X $Rflags = $1;
X }
X $canon = &canonicalize((&simplify_address($addr))[0]);
X unless (defined $canon) {
X warn "$file: no address found: $addr\n";
X push(@list, ($qflag?$Rflags:'') . $addr); # save it as is
X next;
X }
X if (defined $list{$canon}) {
X warn "$file: duplicate: ``$addr -> $canon''\n";
X push(@list, ($qflag?$Rflags:'') . $addr); # save it as is
X next;
X }
X $list{$canon} = $addr;
X }
X}
Xdbmclose(%prio);
}
X
X# Put all the junk we found at the very top
X# (this might not always be a feature)
Xprint join("\n", @list), "\n";
sub output {
X local($sink, *list) = @_;
X
X# unprioritized users go next, slow accounts will get moved down quickly
Xprint '# ----- unprioritized users', "\n";
Xforeach $to (keys %list) { print $list{$to}, "\n"; }
X local($to, *prio, *userprio, *useracct);
X dbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n";
X foreach $to (keys %list) {
X if (defined $prio{$to}) {
X # add to list of found users (%userprio) and remove from %list
X # so that we know what users were not yet prioritized
X $userprio{$to} = $prio{$to}; # priority
X $useracct{$to} = $list{$to}; # string
X delete $list{$to};
X }
X }
X dbmclose(%prio);
X
X# finally, our prioritized list of users
Xprint '# ----- prioritized users', "\n";
Xforeach $to (sort { $userprio{$a} <=> $userprio{$b}; } keys %userprio) {
X die "Opps! Something is seriously wrong with useracct: $to\n"
X unless defined $useracct{$to};
X print $useracct{$to}, "\n";
X}
X # Put all the junk we found at the very top
X # (this might not always be a feature)
X print $sink join("\n", @list), "\n" if int(@list);
X
Xexit(0);
X # prioritized list of users
X if (int(keys %userprio)) {
X print $sink '# ----- prioritized users', "\n" unless $qflag;
X foreach $to (sort by_userprio keys %userprio) {
X die "Opps! Something is seriously wrong with useracct: $to\n"
X unless defined $useracct{$to};
X print $sink 'RFD:' if $qflag;
X print $sink $useracct{$to}, "\n";
X }
X }
X
X# REPL-LIB ---------------------------------------------------------------
X # unprioritized users go last, fast accounts will get moved up eventually
X # XXX: should go before the "really slow" prioritized users?
X if (int(keys %list)) {
X print $sink '# ----- unprioritized users', "\n" unless $qflag;
X foreach $to (keys %list) {
X print $sink 'RFD:' if $qflag;
X print $sink $list{$to}, "\n";
X }
X }
X
Xsub canonicalize {
X print $sink ".\n" if $qflag;
}
X
sub by_userprio {
X # sort first by priority, then by key.
X $userprio{$a} <=> $userprio{$b} || $a cmp $b;
}
X
# REPL-LIB ---------------------------------------------------------------
X
sub canonicalize {
X local($addr) = @_;
X # lowercase, strip leading/trailing whitespace
X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr;
X}
}
X
X# @addrs = simplify_address($addr);
Xsub simplify_address {
# @addrs = simplify_address($addr);
sub simplify_address {
X local($_) = shift;
X 1 while s/\([^\(\)]*\)//g; # strip comments
X 1 while s/"[^"]*"//g; # strip comments
X split(/,/); # split into parts
X 1 while s/\([^\(\)]*\)//g; # strip comments
X 1 while s/"[^"]*"//g; # strip comments
X split(/,/); # split into parts
X foreach (@_) {
X 1 while s/.*<(.*)>.*/\1/;
X s/^\s+//;
X s/\s+$//;
X 1 while s/.*<(.*)>.*/\1/;
X s/^\s+//;
X s/\s+$//;
X }
X @_;
X}
END_OF_FILE
if test 3093 -ne `wc -c <'mailprio'`; then
echo shar: \"'mailprio'\" unpacked with wrong size!
fi
chmod +x 'mailprio'
# end of 'mailprio'
fi
if test -f 'mailprio_mkdb' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mailprio_mkdb'\"
else
echo shar: Extracting \"'mailprio_mkdb'\" \(3504 characters\)
sed "s/^X//" >'mailprio_mkdb' <<'END_OF_FILE'
X#!/usr/bin/perl
X#
X# mailprio_mkdb -- make mail priority database based on delay times
X#
X$usage = "Usage: mailprio_mkdb [-l maillog] [-p priodb]\n";
X$home = "/home/sanders/lists";
X$maillog = "/var/log/maillog";
X$priodb = "$home/mailprio";
}
X
Xif ($main'ARGV[0] =~ /^-/) {
### ---- ###
#
# Error codes
#
do 'errno.ph';
eval 'sub ENOENT {2;}' unless defined &ENOENT;
eval 'sub EINTR {4;}' unless defined &EINTR;
eval 'sub EINVAL {22;}' unless defined &EINVAL;
X
#
# File locking
#
do 'sys/unistd.ph';
eval 'sub SEEK_SET {0;}' unless defined &SEEK_SET;
X
do 'sys/file.ph';
eval 'sub LOCK_SH {0x01;}' unless defined &LOCK_SH;
eval 'sub LOCK_EX {0x02;}' unless defined &LOCK_EX;
eval 'sub LOCK_NB {0x04;}' unless defined &LOCK_NB;
eval 'sub LOCK_UN {0x08;}' unless defined &LOCK_UN;
X
do 'fcntl.ph';
eval 'sub F_GETFD {1;}' unless defined &F_GETFD;
eval 'sub F_SETFD {2;}' unless defined &F_SETFD;
eval 'sub F_GETFL {3;}' unless defined &F_GETFL;
eval 'sub F_SETFL {4;}' unless defined &F_SETFL;
eval 'sub O_NONBLOCK {0x0004;}' unless defined &O_NONBLOCK;
eval 'sub F_SETLK {8;}' unless defined &F_SETLK; # nonblocking
eval 'sub F_SETLKW {9;}' unless defined &F_SETLKW; # lockwait
eval 'sub F_RDLCK {1;}' unless defined &F_RDLCK;
eval 'sub F_UNLCK {2;}' unless defined &F_UNLCK;
eval 'sub F_WRLCK {3;}' unless defined &F_WRLCK;
$s_flock = "sslll"; # struct flock {type, whence, start, len, pid}
X
# return undef on failure
sub seize {
X local ($FH, $lock) = @_;
X local ($ret);
X if ($locking eq "flock") {
X $ret = flock($FH, $lock);
X return ($ret == 0 ? undef : 1);
X } else {
X local ($flock, $type) = 0;
X if ($lock & &LOCK_SH) { $type = &F_RDLCK; }
X elsif ($lock & &LOCK_EX) { $type = &F_WRLCK; }
X elsif ($lock & &LOCK_UN) { $type = &F_UNLCK; }
X else { $! = &EINVAL; return undef; }
X $flock = pack($s_flock, $type, &SEEK_SET, 0, 0, 0);
X $ret = fcntl($FH, ($lock & &LOCK_NB) ? &F_SETLK : &F_SETLKW, $flock);
X return ($ret == -1 ? undef : 1);
X }
}
SHAR_EOF
$shar_touch -am 1031100396 'mailprio' &&
chmod 0755 'mailprio' ||
echo 'restore of mailprio failed'
shar_count="`wc -c < 'mailprio'`"
test 8260 -eq "$shar_count" ||
echo "mailprio: original size 8260, current size $shar_count"
fi
# ============= mailprio.README ==============
if test -f 'mailprio.README' && test X"$1" != X"-c"; then
echo 'x - skipping mailprio.README (file already exists)'
else
echo 'x - extracting mailprio.README (text)'
sed 's/^X//' << 'SHAR_EOF' > 'mailprio.README' &&
mailprio README
X
mailprio.README,v 1.2 1996/10/31 17:03:54 sanders Exp
Version 0.93 -- Thu Oct 31 09:42:25 MST 1996
X
Copyright 1994, 1996, Tony Sanders <sanders@earth.com>
Rights are hereby granted to download, use, modify, sell, copy, and
redistribute this software so long as the original copyright notice
and this list of conditions remain intact and modified versions are
noted as such.
X
I would also very much appreciate it if you could send me a copy of
any changes you make so I can possibly integrate them into my version.
X
The current version of this and other related mail tools are available in:
X ftp://ftp.earth.com/pub/postmaster/
X
Even with the new persistent host status in sendmail V8.8.X this
function can still reduce the lag time distributing mail to a large
group of people. It also makes it a little more likely that everyone
will get mailing list mail in the order sent which can help reduce
duplicate postings. Basically, the goal is to put slow hosts at
the bottom of the list so that as many fast hosts are delivered
as quickly as possible.
X
CONTENTS
========
X
X mailprio.README -- simple docs
X mailprio -- the address sorter
X mailprio_mkdb -- builds the database for the sorter
X
X
CHANGES
=======
X Version 0.92
X Initial public release.
X
X Version 0.93
X Updated to make use of the (somewhat) new xdelay statistic.
X Changed -q flag to support new sendmail queue file format (RFD:<addr>).
X Fixed argument parsing bug.
X Fixed bug with database getting "garbage" in it.
X
X
CONFIGURATION
=============
X
X You need to edit each script and ensure proper configuration.
X
X In mailprio check: #!perl path, $home, $priodb, $locking
X
X In mailprio_mkdb check: #!perl path, $home, $priodb, $maillog
X
X
USAGE: mailprio
===============
X
X Usage: mailprio [-p priodb] [-q] [mailinglists ...]
X -p priority_database -- Specify database to use if not default
X -q -- Process sendmail queue format files
X [USE WITH CAUTION]
X
X Sort mailing lists or sendmail V8 queue files by mailprio database.
X Files listed on the command line are locked and then sorted in place, in
X the absence of any file arguments it will read STDIN and write STDOUT.
X
X Examples:
X mailprio < mailing-list > sorted_list
X mailprio mailing-list1 mailing-list2 mailing-list3 ...
X mailprio -q /var/spool/mqueue/qf* [not recommended]
X To double check results:
X sort sorted_list > checkit; sort orig-mailing-list | diff - checkit
X
X NOTE:
X To get the maximum value from a transaction delay based priority
X function you need to reorder the distribution list (and the mail
X queue files for that matter) fairly often; you could even have
X your mailing list software reorder the list before each outgoing
X message.
X
X
USAGE: mailprio_mkdb
====================
X
X Usage: mailprio_mkdb [-l maillog] [-p priodb]
X -l maillog -- Specify maillog to process if not default
X -p priority_database -- Specify database to use if not default
X
X Builds the mail priority database using information from the maillog.
X
X Run at least nightly before you rotate the maillog. If you are
X going to run mailprio more often than that then you will need to
X load the current maillog information before that will do any good
X (and to keep from reloading the same information you will need
X some kind of incremental maillog information to load from).
SHAR_EOF
$shar_touch -am 1031100396 'mailprio.README' &&
chmod 0644 'mailprio.README' ||
echo 'restore of mailprio.README failed'
shar_count="`wc -c < 'mailprio.README'`"
test 3402 -eq "$shar_count" ||
echo "mailprio.README: original size 3402, current size $shar_count"
fi
# ============= mailprio_mkdb ==============
if test -f 'mailprio_mkdb' && test X"$1" != X"-c"; then
echo 'x - skipping mailprio_mkdb (file already exists)'
else
echo 'x - extracting mailprio_mkdb (text)'
sed 's/^X//' << 'SHAR_EOF' > 'mailprio_mkdb' &&
#!/usr/bin/perl
#
# mailprio_mkdb,v 1.5 1996/10/31 17:03:53 sanders Exp
# Version 0.93 -- Thu Oct 31 09:42:25 MST 1996
#
# mailprio_mkdb -- make mail priority database based on delay times
#
# Copyright 1994, 1996, Tony Sanders <sanders@earth.com>
# Rights are hereby granted to download, use, modify, sell, copy, and
# redistribute this software so long as the original copyright notice
# and this list of conditions remain intact and modified versions are
# noted as such.
#
# I would also very much appreciate it if you could send me a copy of
# any changes you make so I can possibly integrate them into my version.
#
# The average function moves the value around quite rapidly (half-steps)
# which may or may not be a feature. This version uses the new xdelay
# statistic (new as of sendmail V8) which is per transaction. We also
# weight the result based on the overall delay.
#
# Something that might be worth doing for systems that don't support
# xdelay would be to compute an approximation of the transaction delay
# by sorting by messages-id and delay then computing the difference
# between adjacent delay values.
#
# To get the maximum value from a transaction delay based priority
# function you need to reorder the distribution list (and the mail
# queue files for that matter) fairly often; you could even have
# your mailing list software reorder the list before each outgoing
# message.
X
$usage = "Usage: mailprio_mkdb [-l maillog] [-p priodb]\n";
$home = "/home/sanders/lists";
$maillog = "/var/log/maillog";
$priodb = "$home/mailprio";
X
while ($ARGV[0] =~ /^-/) {
X $args = shift;
X if ($args =~ m/\?/) { print $usage; exit 0; }
X if ($args =~ m/l/) {
X $maillog = shift || die $usage, "-l requires argument\n"; }
X if ($args =~ m/p/) {
X $priodb = shift || die $usage, "-p requires argument\n"; }
X}
}
X
Xlocal(*prio);
X# We'll merge with existing information if it's already there.
Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n";
X&getlog_stats($maillog, *prio);
X# foreach $addr (sort { $prio{$a} <=> $prio{$b}; } keys %prio) {
X# printf("%06d %s\n", $prio{$addr}, $addr); }
Xdbmclose(%prio);
Xexit(0);
$SIG{'PIPE'} = 'handle_pipe';
X
Xsub getlog_stats {
# will merge with existing information
dbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n";
&getlog_stats($maillog, *prio);
dbmclose(%prio);
exit(0);
X
sub handle_pipe {
X dbmclose(%prio);
}
X
sub getlog_stats {
X local($maillog, *stats) = @_;
X local($to, $delay);
X local($h, $m, $s);
X open(MAILLOG, "< $maillog") || die "$maillog: $!\n";
X while (<MAILLOG>) {
X ($delay) = (m/, delay=([^,]*), /);
X $delay || next;
X ($h, $m, $s) = split(/:/, $delay);
X $delay = ($h * 60 * 60) + ($m * 60) + $s;
X next unless / to=/ && / stat=/;
X next if / stat=queued/;
X if (/ stat=sent/i) {
X # read delay and xdelay and convert to seconds
X ($delay) = (m/ delay=([^,]*),/);
X next unless $delay;
X ($h, $m, $s) = split(/:/, $delay);
X $delay = ($h * 60 * 60) + ($m * 60) + $s;
X
X # deleting everything after ", " seems safe enough, though
X # it is possible that it was inside "..."'s and that we will
X # miss some addresses because of it. However, I'm not willing
X # to do full parsing just for that case. If this bothers you
X # you could do something like: s/, (delay|ctladdr)=.*//;
X # but you have to make sure you catch all the possible names.
X $to = $_; $to =~ s/^.* to=//; $to =~ s/, .*//;
X ($xdelay) = (m/ xdelay=([^,]*),/);
X next unless $xdelay;
X ($h, $m, $s) = split(/:/, $xdelay);
X $xdelay = ($h * 60 * 60) + ($m * 60) + $s;
X
X # Now weight the delay factor by the transaction delay (xdelay).
X $xdelay /= 300; # [0 - 1(@5 min)]
X $xdelay += 0.5; # [0.5 - 1.5]
X $xdelay = 1.5 if $xdelay > 1.5; # clamp
X $delay *= $xdelay; # weight delay by xdelay
X }
X elsif (/, stat=/) {
X # delivery failure of some sort (i.e. bad)
X $delay = 432000; # force 5 days
X }
X $delay = 1000000 if $delay > 1000000;
X
X # filter the address(es); isn't perfect but is "good enough"
X $to = $_; $to =~ s/^.* to=//;
X 1 while $to =~ s/\([^\(\)]*\)//g; # strip comments
X 1 while $to =~ s/"[^"]*"//g; # strip comments
X $to =~ s/, .*//; # remove other stat info
X foreach $addr (&simplify_address($to)) {
X next unless $addr;
X $addr = &canonicalize($addr);
X # print $delay, " ", $addr, "\n";
X $stats{$addr} = $delay unless defined $stats{$addr}; # init
X
X # This average function moves the value around quite rapidly
X # which may or may not be a feature.
X #
X # This has at least one odd behavior because we currently only
X # use the delay information from maillog which is only logged
X # on actual delivery. This works backwards from what we really
X # want to happen when a fast host goes down for a while and then
X # comes back up.
X #
X # I spoke with Eric and he suggested adding an xdelay statistic
X # for a per transaction delay which would help that situation
X # a lot. What I believe you want in that cases something like:
X # delay fast, xdelay fast: smokin', these hosts go first
X # delay slow, xdelay fast: put host high on the list (back up?)
X # delay fast, xdelay slow: host is down/having problems/slow
X # delay slow, xdelay slow: poorly connected sites, very last
X # Of course, you have to reorder the distribution list fairly
X # often for that to help. Come to think of it, you should
X # also reorder /var/spool/mqueue files also (if they aren't
X # locked of course). Hmmm....
X # pseudo-average in the new delay (half-steps)
X # simple, moving average
X $stats{$addr} = int(($stats{$addr} + $delay) / 2);
X }
X }
X close(MAILLOG);
X}
}
X
X# REPL-LIB ---------------------------------------------------------------
# REPL-LIB ---------------------------------------------------------------
X
Xsub canonicalize {
sub canonicalize {
X local($addr) = @_;
X # lowercase, strip leading/trailing whitespace
X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr;
X}
}
X
X# @addrs = simplify_address($addr);
Xsub simplify_address {
# @addrs = simplify_address($addr);
sub simplify_address {
X local($_) = shift;
X 1 while s/\([^\(\)]*\)//g; # strip comments
X 1 while s/"[^"]*"//g; # strip comments
@ -285,13 +545,13 @@ X s/^\s+//;
X s/\s+$//;
X }
X @_;
X}
END_OF_FILE
if test 3504 -ne `wc -c <'mailprio_mkdb'`; then
echo shar: \"'mailprio_mkdb'\" unpacked with wrong size!
}
SHAR_EOF
$shar_touch -am 1031100396 'mailprio_mkdb' &&
chmod 0755 'mailprio_mkdb' ||
echo 'restore of mailprio_mkdb failed'
shar_count="`wc -c < 'mailprio_mkdb'`"
test 4182 -eq "$shar_count" ||
echo "mailprio_mkdb: original size 4182, current size $shar_count"
fi
chmod +x 'mailprio_mkdb'
# end of 'mailprio_mkdb'
fi
echo shar: End of shell archive.
exit 0

View File

@ -30,7 +30,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)op.me 8.97 (Berkeley) 10/17/96
.\" @(#)op.me 8.98 (Berkeley) 11/16/96
.\"
.\" eqn op.me | pic | troff -me
.eh 'SMM:08-%''Sendmail Installation and Operation Guide'
@ -68,7 +68,7 @@ Eric Allman
InReference, Inc.
eric@Sendmail.ORG
.sp
Version 8.97
Version 8.98
.sp
For Sendmail Version 8.8
.)l
@ -3561,6 +3561,25 @@ The full name of the sender.
The home directory of the recipient.
.ip $_
The validated sender address.
.ip ${bodytype}
The message body type
(7BIT or 8BITMIME),
as determined from the envelope.
.ip ${client_addr}
The IP address of the SMTP client.
Defined in the SMTP server only.
.ip ${client_name}
The host name of the SMTP client.
Defined in the SMTP server only.
.ip ${client_port}
The port number of the SMTP client.
Defined in the SMTP server only.
.ip ${envid}
The envelope id passed to sendmail as part of the envelope.
.ip ${opMode}
The current operation mode (from the
.b \-b
flag).
.pp
There are three types of dates that can be used.
The
@ -3758,10 +3777,12 @@ and the receiver has the IDENT protocol turned on,
it will include the user name on that host.
.pp
The
.b ${client_name}
.b ${client_name} ,
.b ${client_addr} ,
and
.b ${client_addr}
are set to the name and address of the SMTP client
.b ${client_port}
macros
are set to the name, address, and port number of the SMTP client
who is invoking
.i sendmail
as a server.
@ -8129,7 +8150,7 @@ A transcript of the current session.
.\"Eric Allman
.\"InReference, Inc.
.\".sp
.\"Version 8.97
.\"Version 8.98
.\".ce 0
.bp 2
.rs

View File

@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mail.local.c 8.30 (Berkeley) 10/9/96";
static char sccsid[] = "@(#)mail.local.c 8.33 (Berkeley) 11/13/96";
#endif /* not lint */
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)makemap.c 8.17 (Berkeley) 9/25/96";
static char sccsid[] = "@(#)makemap.c 8.18 (Berkeley) 11/13/96";
#endif /* not lint */
#include <stdio.h>
@ -97,6 +97,7 @@ main(argc, argv)
int st;
int mode;
int putflags;
long dbcachesize = 1024 * 1024;
enum type type;
int fd;
union
@ -112,6 +113,7 @@ main(argc, argv)
union dbent key, val;
#ifdef NEWDB
BTREEINFO bti;
HASHINFO hinfo;
#endif
char ibuf[BUFSIZE];
char fbuf[MAXNAME];
@ -122,7 +124,12 @@ main(argc, argv)
progname = argv[0];
while ((opt = getopt(argc, argv, "Ndforv")) != EOF)
#ifdef FFR_CFLAG
#define OPTIONS "Nc:dforv"
#else
#define OPTIONS "Ndforv"
#endif
while ((opt = getopt(argc, argv, OPTIONS)) != EOF)
{
switch (opt)
{
@ -130,6 +137,12 @@ main(argc, argv)
inclnull = TRUE;
break;
#ifdef FFR_CFLAG
case 'c':
dbcachesize = atol(optarg);
break;
#endif
case 'd':
allowdups = TRUE;
break;
@ -189,7 +202,11 @@ main(argc, argv)
switch (type)
{
case T_ERR:
#ifdef FFR_CFLAG
fprintf(stderr, "Usage: %s [-N] [-c cachesize] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname);
#else
fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname);
#endif
exit(EX_USAGE);
case T_UNKNOWN:
@ -294,7 +311,11 @@ main(argc, argv)
#ifdef NEWDB
case T_HASH:
dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL);
/* tweak some parameters for performance */
hinfo.nelem = 4096;
hinfo.cachesize = dbcachesize;
dbp.db = dbopen(mapname, mode, 0644, DB_HASH, &hinfo);
if (dbp.db != NULL)
{
# if OLD_NEWDB
@ -306,6 +327,9 @@ main(argc, argv)
break;
case T_BTREE:
/* tweak some parameters for performance */
bti.cachesize = dbcachesize;
dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti);
if (dbp.db != NULL)
{

View File

@ -30,7 +30,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)READ_ME 8.125 (Berkeley) 10/18/96
# @(#)READ_ME 8.130 (Berkeley) 11/10/96
#
This directory contains the source files for sendmail.
@ -168,7 +168,7 @@ LDAPMAP Lightweight Directory Lookup Protocol support. You will
this flag.
>>> NOTE WELL for NEWDB support: it is CRITICAL that you remove ndbm.o
>>> from libdb.a and ndbm.h from the appropriate include directories if
>>> from libdb.a before you install it and DO NOT install ndbm.h if
>>> you want to get ndbm support. If you don't delete these, there is
>>> absolutely no point to including -DNDBM, since it will just get you
>>> another (inferior) API to the same format database. These files
@ -355,11 +355,20 @@ LA_TYPE The type of load average your kernel supports. These
the dg_sys_info system call.
LA_HPUX (10) is an HP-UX specific version that uses the
pstat_getdynamic system call.
LA_IRIX6 (11) is an IRIX 6.x specific version that adapts
to 32 or 64 bit kernels; it is otherwise very similar
to LA_INT.
LA_KSTAT (12) uses the (Solaris-specific) kstat(3k)
implementation.
LA_DEVSHORT (13) reads a short from a system file (default:
/dev/table/avenrun) and scales it in the same manner
as LA_SHORT.
LA_INT, LA_SHORT, LA_FLOAT, and LA_READKSYM have several
other parameters that they try to divine: the name of your
kernel, the name of the variable in the kernel to examine,
the number of bits of precision in a fixed point load average,
and so forth.
and so forth. LA_DEVSHORT uses _PATH_AVENRUN to find the
device to be read to find the load average.
In desperation, use LA_ZERO. The actual code is in
conf.c -- it can be tweaked if you are brave.
FSHIFT For LA_INT, LA_SHORT, and LA_READKSYM, this is the number
@ -809,6 +818,26 @@ IRIX
the developers' option in order to get the necessary include
files.
If you compile with -lmalloc (the fast memory allocator), you may
get warning messages such as the following:
ld32: WARNING 85: definition of _calloc in /usr/lib32/libmalloc.so
preempts that definition in /usr/lib32/mips3/libc.so.
ld32: WARNING 85: definition of _malloc in /usr/lib32/libmalloc.so
preempts that definition in /usr/lib32/mips3/libc.so.
ld32: WARNING 85: definition of _realloc in /usr/lib32/libmalloc.so
preempts that definition in /usr/lib32/mips3/libc.so.
ld32: WARNING 85: definition of _free in /usr/lib32/libmalloc.so
preempts that definition in /usr/lib32/mips3/libc.so.
ld32: WARNING 85: definition of _cfree in /usr/lib32/libmalloc.so
preempts that definition in /usr/lib32/mips3/libc.so.
These are unavoidable and innocuous -- just ignore them.
According to Dave Sill <de5@ornl.gov>, there is a version of the
Berkeley db library patched to run on Irix 6.2 available from
http://reality.sgi.com/ariel/db-1.85-irix.tar.Z .
NeXT or NEXTSTEP
NEXTSTEP 3.3 and earlier ship with the old DBM library. You will
need to acquire the new Berkeley DB from ftp.cs.berkeley.edu.
@ -1348,4 +1377,4 @@ version.c The version number and information about this
Eric Allman
(Version 8.125, last update 10/18/96 07:32:40)
(Version 8.130, last update 11/10/96 11:15:30)

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96";
static char sccsid[] = "@(#)collect.c 8.60 (Berkeley) 11/15/96";
#endif /* not lint */
# include <errno.h>
@ -488,7 +488,7 @@ readerr:
** Examples are who is the from person & the date.
*/
eatheader(e, !requeueflag);
eatheader(e, TRUE);
if (GrabTo && e->e_sendqueue == NULL)
usrerr("No recipient addresses found in header");
@ -557,6 +557,7 @@ readerr:
/* check for message too large */
if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
{
e->e_flags |= EF_NO_BODY_RETN;
e->e_status = "5.2.3";
usrerr("552 Message exceeds maximum fixed size (%ld)",
MaxMessageSize);

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)conf.c 8.312 (Berkeley) 10/17/96";
static char sccsid[] = "@(#)conf.c 8.315 (Berkeley) 11/10/96";
#endif /* not lint */
# include "sendmail.h"
@ -1188,8 +1188,19 @@ init_md(argc, argv)
/* keep gethostby*() from stripping the local domain name */
set_domain_trim_off();
#endif
#if SECUREWARE
#if SECUREWARE || defined(_SCO_unix_)
set_auth_parameters(argc, argv);
# ifdef _SCO_unix_
/*
** This is required for highest security levels (the kernel
** won't let it call set*uid() or run setuid binaries without
** it). It may be necessary on other SECUREWARE systems.
*/
if (getluid() == -1)
setluid(0);
# endif
#endif
#ifdef VENDOR_DEFAULT
@ -1245,6 +1256,8 @@ init_vendor_macros(e)
#define LA_DGUX 9 /* special DGUX implementation */
#define LA_HPUX 10 /* special HPUX implementation */
#define LA_IRIX6 11 /* special IRIX 6.2 implementation */
#define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */
#define LA_DEVSHORT 13 /* read short from a device */
/* do guesses based on general OS type */
#ifndef LA_TYPE
@ -1780,8 +1793,100 @@ int getla(void)
}
#endif
#if LA_TYPE == LA_KSTAT
#include <kstat.h>
int
getla()
{
kstat_ctl_t *kc;
kstat_t *ksp;
kstat_named_t *ksn;
int la;
kc = kstat_open();
if (kc == NULL)
{
if (tTd(3, 1))
printf("getla: kstat_open(): %s\n",
errstring(errno));
return -1;
}
ksp = kstat_lookup(kc, "unix", 0, "system_misc"); /* NULL on error */
if (ksp == NULL)
{
if (tTd(3, 1))
printf("getla: kstat_lookup(): %s\n",
errstring(errno);
return -1;
}
if (kstat_read(kc, ksp, NULL) < 0)
{
if (tTd(3, 1))
printf("getla: kstat_read(): %s\n",
errstring(errno);
return -1;
}
ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
la = (ksn->value.ul + FSCALE/2) >> FSHIFT;
kstat_close(kc);
return la;
}
#endif /* LA_TYPE == LA_KSTAT */
#if LA_TYPE == LA_DEVSHORT
/*
** Read /dev/table/avenrun for the load average. This should contain
** three shorts for the 1, 5, and 15 minute loads. We only read the
** first, since that's all we care about.
**
** Intended for SCO OpenServer 5.
*/
# ifndef _PATH_AVENRUN
# define _PATH_AVENRUN "/dev/table/avenrun"
# endif
int
getla()
{
static int afd = -1;
short avenrun;
int loadav;
int r;
errno = EBADF;
if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
{
if (errno != EBADF)
return -1;
afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
if (afd < 0)
{
syslog(LOG_ERR, "can't open %s: %m", _PATH_AVENRUN);
return -1;
}
}
r = read(afd, &avenrun, sizeof avenrun);
if (tTd(3, 5))
printf("getla: avenrun = %d\n", avenrun);
loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
if (tTd(3, 1))
printf("getla: %d\n", loadav);
return loadav;
}
#endif /* LA_TYPE == LA_DEVSHORT */
#if LA_TYPE == LA_ZERO
int
getla()
{
if (tTd(3, 1))
@ -1941,8 +2046,10 @@ refuseconnections(port)
syslog(LOG_INFO, "rejecting connections on port %d: load average: %d",
port, CurrentLA);
#endif
return TRUE;
}
else if (!enoughdiskspace(MinBlocksFree + 1))
if (!enoughdiskspace(MinBlocksFree + 1))
{
setproctitle("rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
@ -1951,20 +2058,26 @@ refuseconnections(port)
syslog(LOG_INFO, "rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
#endif
return TRUE;
}
else if (MaxChildren > 0 && CurChildren >= MaxChildren)
if (MaxChildren > 0 && CurChildren >= MaxChildren)
{
setproctitle("rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
#ifdef LOG
if (LogLevel >= 14)
syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d",
proc_list_probe();
if (CurChildren >= MaxChildren)
{
setproctitle("rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
#ifdef LOG
if (LogLevel >= 14)
syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
#endif
return TRUE;
}
}
else
return FALSE;
return TRUE;
return FALSE;
}
/*
** SETPROCTITLE -- set process title for ps

View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)conf.h 8.267 (Berkeley) 10/17/96
* @(#)conf.h 8.272 (Berkeley) 11/16/96
*/
/*
@ -41,7 +41,9 @@
** included in the next release.
*/
#ifdef __GNUC__
struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#endif
# include <sys/param.h>
# include <sys/types.h>
@ -216,7 +218,11 @@ extern void hard_syslog(int, char *, ...);
#ifdef _AIX4
# define _AIX3 1 /* pull in AIX3 stuff */
# define HASSETREUID 1 /* setreuid(2) works */
# define USESETEUID 1 /* seteuid(2) works */
# define TZ_TYPE TZ_NAME /* use tzname[] vector */
# if _AIX4 >= 40200
# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */
# endif
#endif
@ -409,6 +415,9 @@ typedef int pid_t;
# define snprintf __snprintf /* but names it oddly in 2.5 */
# define vsnprintf __vsnprintf
# endif
# ifndef LA_TYPE
# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */
# endif
# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
@ -588,6 +597,7 @@ extern long dgux_inet_addr();
# define WAITUNION 1 /* use "union wait" as wait argument type */
# define UID_T int /* compiler gripes on uid_t */
# define GID_T int /* ditto for gid_t */
# define MODE_T int /* and mode_t */
# define sleep sleepX
# define setpgid setpgrp
# ifndef LA_TYPE
@ -791,31 +801,43 @@ extern int errno;
** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier.
*/
/* SCO OpenServer 5 */
#if _SCO_DS >= 1
# include <paths.h>
# define _SCO_unix_4_2
# define HASSNPRINTF 1 /* has snprintf() call */
# define HASFCHMOD 1 /* has fchmod() call */
# define HASSETRLIMIT 1 /* has setrlimit() call */
# define HASSNPRINTF 1 /* has snprintf(3) call */
# define HASFCHMOD 1 /* has fchmod(2) call */
# define HASSETRLIMIT 1 /* has setrlimit(2) call */
# define USESETEUID 1 /* has seteuid(2) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# define RLIMIT_NEEDS_SYS_TIME_H 1
# ifndef LA_TYPE
# define LA_TYPE LA_DEVSHORT
# endif
# define _PATH_AVENRUN "/dev/table/avenrun"
#endif
/* SCO UNIX 3.2v4.2/Open Desktop 3.0 */
#ifdef _SCO_unix_4_2
# define _SCO_unix_
# define HASSETREUID 1 /* has setreuid(2) call */
#endif
/* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */
#ifdef _SCO_unix_
# include <sys/stream.h> /* needed for IP_SRCROUTE */
# define SYSTEM5 1 /* include all the System V defines */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */
# define MAXPATHLEN PATHSIZE
# define LA_TYPE LA_SHORT
# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */
# define SFS_BAVAIL f_bfree /* alternate field name */
# define SPT_TYPE SPT_SCO /* write kernel u. area */
# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */
# define UID_T uid_t
# define GID_T gid_t
# define GIDSET_T gid_t
# define _PATH_UNIX "/unix"
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
@ -828,9 +850,10 @@ extern int errno;
# endif
# ifndef _SCO_DS
# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */
# define ftruncate chsize /* use chsize(2) to emulate ftruncate */
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
# define NETUNIX 0 /* no unix domain socket support */
# define LA_TYPE LA_SHORT
# endif
#endif
@ -1850,6 +1873,10 @@ extern int errno;
# define SIZE_T size_t
#endif
#ifndef MODE_T
# define MODE_T mode_t
#endif
#ifndef ARGV_T
# define ARGV_T char **
#endif

View File

@ -37,9 +37,9 @@
#ifndef lint
#ifdef DAEMON
static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)";
static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (with daemon mode)";
#else
static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)";
static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (without daemon mode)";
#endif
#endif /* not lint */
@ -193,7 +193,7 @@ getrequests(e)
for (;;)
{
register int pid;
register pid_t pid;
auto int lotherend;
extern bool refuseconnections();
extern int getla();
@ -244,6 +244,16 @@ getrequests(e)
/* wait for a connection */
setproctitle("accepting connections on port %d",
ntohs(DaemonAddr.sin.sin_port));
#if 0
/*
** Andrew Sun <asun@ieps-sun.ml.com> claims that this will
** fix the SVr4 problem. But it seems to have gone away,
** so is it worth doing this?
*/
if (SetNonBlocking(DaemonSocket, FALSE) < 0)
log an error here;
#endif
do
{
errno = 0;
@ -734,9 +744,8 @@ makeconnection(host, port, mci, e)
extern char MsgBuf[];
usrerr("553 Invalid numeric domain spec \"%s\"", host);
mci->mci_status = "5.1.2";
mci->mci_rstatus = newstr(MsgBuf);
return (EX_NOHOST);
mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf);
return EX_NOHOST;
}
#if NETINET
addr.sin.sin_family = AF_INET; /*XXX*/
@ -773,11 +782,11 @@ gothostent:
if (errno == ETIMEDOUT || h_errno == TRY_AGAIN ||
(errno == ECONNREFUSED && UseNameServer))
{
mci->mci_status = "4.4.3";
mci->mci_rstatus = NULL;
return (EX_TEMPFAIL);
mci_setstat(mci, EX_TEMPFAIL, "4.4.3", NULL);
return EX_TEMPFAIL;
}
#endif
mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
return (EX_NOHOST);
}
addr.sa.sa_family = hp->h_addrtype;
@ -839,6 +848,7 @@ gothostent:
default:
syserr("Can't connect to address family %d", addr.sa.sa_family);
mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
return (EX_NOHOST);
}
@ -876,7 +886,11 @@ gothostent:
{
sav_errno = errno;
syserr("makeconnection: cannot create socket");
goto failure;
#ifdef XLA
xla_host_end(host);
#endif
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
return EX_TEMPFAIL;
}
#ifdef SO_SNDBUF
@ -964,18 +978,12 @@ gothostent:
continue;
}
/* failure, decide if temporary or not */
failure:
/* couldn't open connection */
#ifdef XLA
xla_host_end(host);
#endif
if (transienterror(sav_errno))
return EX_TEMPFAIL;
else
{
message("%s", errstring(sav_errno));
return (EX_UNAVAILABLE);
}
mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL);
return EX_TEMPFAIL;
}
/* connection ok, put it into canonical form */
@ -984,9 +992,11 @@ gothostent:
(mci->mci_in = fdopen(s, "r")) == NULL)
{
syserr("cannot open SMTP client channel, fd=%d", s);
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
return EX_TEMPFAIL;
}
mci_setstat(mci, EX_OK, NULL, NULL);
return (EX_OK);
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96";
static char sccsid[] = "@(#)deliver.c 8.251 (Berkeley) 11/11/96";
#endif /* not lint */
#include "sendmail.h"
@ -78,7 +78,7 @@ sendall(e, mode)
ENVELOPE *splitenv = NULL;
bool oldverbose = Verbose;
bool somedeliveries = FALSE;
int pid;
pid_t pid;
extern void sendenvelope();
/*
@ -760,7 +760,7 @@ sendenvelope(e, mode)
int
dofork()
{
register int pid = -1;
register pid_t pid = -1;
DOFORK(fork);
return (pid);
@ -813,11 +813,12 @@ deliver(e, firstto)
ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */
int rcode; /* response code */
char *firstsig; /* signature of firstto */
int pid = -1;
pid_t pid = -1;
char *volatile curhost;
register volatile u_short port = 0;
time_t xstart;
bool suidwarn;
bool anyok; /* at least one address was OK */
int mpvect[2];
int rpvect[2];
char *pv[MAXPV+1];
@ -1314,7 +1315,7 @@ tryhost:
if (mci_lock_host(mci) != EX_OK)
{
mci->mci_exitstat = EX_TEMPFAIL;
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
continue;
}
@ -1840,6 +1841,7 @@ tryhost:
extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *));
extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *));
extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *));
/*
** Send the MAIL FROM: protocol
@ -1883,10 +1885,6 @@ tryhost:
e->e_to = tobuf + 1;
rcode = smtpdata(m, mci, e);
}
/* now close the connection */
if (!bitset(MCIF_CACHED, mci->mci_flags))
smtpquit(m, mci, e);
}
if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
{
@ -1917,11 +1915,17 @@ tryhost:
*/
give_up:
if (tobuf[0] != '\0')
giveresponse(rcode, m, mci, ctladdr, xstart, e);
if (rcode == EX_OK)
markstats(e, tochain);
mci_store_persistent(mci);
#ifdef SMTP
# if FFR_LMTP
if (bitnset(M_LMTP, m->m_flags))
{
tobuf[0] = '\0';
anyok = FALSE;
}
else
# endif
#endif
anyok = rcode == EX_OK;
for (to = tochain; to != NULL; to = to->q_tchain)
{
@ -1929,11 +1933,37 @@ tryhost:
if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
continue;
/* mark bad addresses */
if (rcode != EX_OK)
#ifdef SMTP
# if FFR_LMTP
/* if running LMTP, get the status for each address */
if (bitnset(M_LMTP, m->m_flags))
{
markfailure(e, to, mci, rcode);
continue;
rcode = smtpgetstat(m, mci, e);
if (rcode == EX_OK)
{
strcat(tobuf, ",");
strcat(tobuf, to->q_paddr);
anyok = TRUE;
}
else
{
e->e_to = to->q_paddr;
markfailure(e, to, mci, rcode);
giveresponse(rcode, m, mci, ctladdr, xstart, e);
e->e_to = tobuf + 1;
continue;
}
}
else
# endif
#endif
{
/* mark bad addresses */
if (rcode != EX_OK)
{
markfailure(e, to, mci, rcode);
continue;
}
}
/* successful delivery */
@ -1958,6 +1988,38 @@ tryhost:
}
}
#ifdef SMTP
# if FFR_LMTP
if (bitnset(M_LMTP, m->m_flags))
{
/*
** Global information applies to the last recipient only;
** clear it out to avoid bogus errors.
*/
rcode = EX_OK;
e->e_statmsg = NULL;
/* reset the mci state for the next transaction */
if (mci->mci_state == MCIS_ACTIVE)
mci->mci_state = MCIS_OPEN;
}
# endif
#endif
if (tobuf[0] != '\0')
giveresponse(rcode, m, mci, ctladdr, xstart, e);
if (anyok)
markstats(e, tochain);
mci_store_persistent(mci);
#ifdef SMTP
/* now close the connection */
if (clever && mci->mci_state != MCIS_CLOSED &&
!bitset(MCIF_CACHED, mci->mci_flags))
smtpquit(m, mci, e);
#endif
/*
** Restore state and return.
*/
@ -2142,7 +2204,7 @@ endmailer(mci, e, pv)
st = waitfor(mci->mci_pid);
if (st == -1)
{
syserr("endmailer %s: wait", pv[0]);
syserr("endmailer %s: wait", mci->mci_mailer->m_name);
return (EX_SOFTWARE);
}
@ -2951,7 +3013,7 @@ mailfile(filename, ctladdr, sfflags, e)
register ENVELOPE *e;
{
register FILE *f;
register int pid = -1;
register pid_t pid = -1;
int mode;
bool suidwarn = geteuid() == 0;
@ -3146,9 +3208,9 @@ mailfile(filename, ctladdr, sfflags, e)
/* reset ISUID & ISGID bits for paranoid systems */
#if HASFCHMOD
(void) fchmod(fileno(f), (int) stb.st_mode);
(void) fchmod(fileno(f), (MODE_T) stb.st_mode);
#else
(void) chmod(filename, (int) stb.st_mode);
(void) chmod(filename, (MODE_T) stb.st_mode);
#endif
(void) xfclose(f, "mailfile", filename);
(void) fflush(stdout);
@ -3259,10 +3321,10 @@ hostsignature(m, host, e)
/* update the connection info for this host */
mci = mci_get(hp, m);
mci->mci_lastuse = curtime();
mci->mci_exitstat = rcode;
mci->mci_errno = errno;
mci->mci_herrno = h_errno;
mci->mci_lastuse = curtime();
mci_setstat(mci, rcode, NULL, NULL);
/* use the original host name as signature */
nmx = 1;

View File

@ -36,9 +36,9 @@
#ifndef lint
#if NAMED_BIND
static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)";
static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)";
#else
static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)";
static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)";
#endif
#endif /* not lint */
@ -48,10 +48,23 @@ static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name serve
#include <resolv.h>
#include <arpa/inet.h>
/*
** The standard udp packet size PACKETSZ (512) is not sufficient for some
** nameserver answers containing very many resource records. The resolver
** may switch to tcp and retry if it detects udp packet overflow.
** Also note that the resolver routines res_query and res_search return
** the size of the *un*truncated answer in case the supplied answer buffer
** it not big enough to accommodate the entire answer.
*/
#ifndef MAXPACKET
# define MAXPACKET 8192 /* max packet size used internally by BIND */
#endif
typedef union
{
HEADER qb1;
u_char qb2[PACKETSZ];
u_char qb2[MAXPACKET];
} querybuf;
#ifndef MXHOSTBUFSIZE
@ -206,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
return (-1);
}
/* avoid problems after truncation in tcp packets */
if (n > sizeof(answer))
n = sizeof(answer);
/* find first satisfactory answer */
hp = (HEADER *)&answer;
cp = (u_char *)&answer + HFIXEDSZ;
@ -515,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp)
int qtype;
int loopcnt;
char *xp;
char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)];
char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)];
char *searchlist[MAXDNSRCH+2];
extern char *gethostalias();
@ -648,6 +665,10 @@ cnameloop:
else if (tTd(8, 7))
printf("\tYES\n");
/* avoid problems after truncation in tcp packets */
if (ret > sizeof(answer))
ret = sizeof(answer);
/*
** Appear to have a match. Confirm it by searching for A or
** CNAME records. If we don't have a local domain

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)envelope.c 8.93 (Berkeley) 9/26/96";
static char sccsid[] = "@(#)envelope.c 8.96 (Berkeley) 11/11/96";
#endif /* not lint */
#include "sendmail.h"
@ -153,9 +153,24 @@ dropenvelope(e, fulldrop)
e->e_flags &= ~EF_QUEUERUN;
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags) ||
bitset(QQUEUEUP, q->q_flags))
if (bitset(QQUEUEUP, q->q_flags) &&
bitset(QDONTSEND, q->q_flags))
{
/* I'm not sure how this happens..... */
if (tTd(50, 2))
{
printf("Bogus flags: ");
printaddr(q, FALSE);
}
q->q_flags &= ~QDONTSEND;
}
if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
queueit = TRUE;
#if XDEBUG
else if (bitset(QQUEUEUP, q->q_flags))
syslog(LOG_DEBUG, "%s: q_flags = %x",
e->e_id, q->q_flags);
#endif
/* see if a notification is needed */
if (bitset(QPINGONFAILURE, q->q_flags) &&
@ -203,8 +218,7 @@ dropenvelope(e, fulldrop)
fprintf(e->e_xfp, "Message will be deleted from queue\n");
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
if (bitset(QQUEUEUP, q->q_flags) ||
!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
{
q->q_flags |= QBADADDR;
q->q_status = "4.4.7";

View File

@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96";
static char sccsid[] = "@(#)main.c 8.215 (Berkeley) 11/16/96";
#endif /* not lint */
#define _DEFINE
@ -387,12 +387,18 @@ main(argc, argv, envp)
OpMode = MD_DELIVER;
FullName = getextenv("NAME");
/*
** Initialize name server if it is going to be used.
*/
#if NAMED_BIND
if (tTd(8, 8))
{
if (!bitset(RES_INIT, _res.options))
res_init();
if (tTd(8, 8))
_res.options |= RES_DEBUG;
}
# ifdef RES_NOALIASES
_res.options |= RES_NOALIASES;
# endif
#endif
errno = 0;
@ -513,15 +519,7 @@ main(argc, argv, envp)
{
case MD_DAEMON:
case MD_FGDAEMON:
# ifdef DAEMON
if (RealUid != 0)
{
usrerr("Permission denied");
exit(EX_USAGE);
}
vendor_daemon_setup(CurEnv);
/* fall through ... */
# else
# ifndef DAEMON
usrerr("Daemon mode not implemented");
ExitStat = EX_USAGE;
break;
@ -534,8 +532,6 @@ main(argc, argv, envp)
# endif /* SMTP */
case MD_INITALIAS:
/* fall through ... */
case MD_DELIVER:
case MD_VERIFY:
case MD_TEST:
@ -844,18 +840,6 @@ main(argc, argv, envp)
printf("\n========================================================\n\n");
}
/*
** Initialize name server if it is going to be used.
*/
#if NAMED_BIND
if (UseNameServer && !bitset(RES_INIT, _res.options))
res_init();
# ifdef RES_NOALIASES
_res.options |= RES_NOALIASES;
# endif
#endif
/*
** Do more command line checking -- these are things that
** have to modify the results of reading the config file.
@ -897,8 +881,8 @@ main(argc, argv, envp)
/* check for sane configuration level */
if (ConfigLevel > MAXCONFIGLEVEL)
{
syserr("Warning: .cf version level (%d) exceeds program functionality (%d)",
ConfigLevel, MAXCONFIGLEVEL);
syserr("Warning: .cf version level (%d) exceeds sendmail version %s functionality (%d)",
ConfigLevel, Version, MAXCONFIGLEVEL);
}
/* need MCI cache to have persistence */
@ -931,6 +915,19 @@ main(argc, argv, envp)
/* fall through ... */
case MD_DAEMON:
/* check for permissions */
if (RealUid != 0)
{
#ifdef LOG
if (LogLevel > 1)
syslog(LOG_ALERT, "user %d attempted to run daemon",
RealUid);
#endif
usrerr("Permission denied");
exit(EX_USAGE);
}
vendor_daemon_setup(CurEnv);
/* remove things that don't make sense in daemon mode */
FullName = NULL;
GrabTo = FALSE;
@ -1964,6 +1961,15 @@ sighup()
syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]);
#endif
releasesignal(SIGHUP);
if (setgid(RealGid) < 0 || setuid(RealUid) < 0)
{
#ifdef LOG
if (LogLevel > 0)
syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m",
RealUid, RealGid);
#endif
exit(EX_OSERR);
}
execv(SaveArgv[0], (ARGV_T) SaveArgv);
#ifdef LOG
if (LogLevel > 0)

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96";
static char sccsid[] = "@(#)map.c 8.144 (Berkeley) 11/16/96";
#endif /* not lint */
#include "sendmail.h"
@ -107,7 +107,7 @@ static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96";
extern bool aliaswait __P((MAP *, char *, int));
extern bool extract_canonname __P((char *, char *, char[], int));
#if defined(O_EXLOCK) && HASFLOCK
#if O_EXLOCK && HASFLOCK
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
#else
# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
@ -690,6 +690,8 @@ extract_canonname(name, line, cbuf, cbuflen)
p = get_column(line, i, '\0', nbuf, sizeof nbuf);
if (p == NULL)
break;
if (*p == '\0')
continue;
if (cbuf[0] == '\0' ||
(strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL))
{
@ -1034,17 +1036,30 @@ ndbm_map_close(map)
** be pokey about it. That's hard to do.
*/
extern bool db_map_open __P((MAP *, int, DBTYPE));
extern bool db_map_open __P((MAP *, int, DBTYPE, const void *));
/* these should be K line arguments */
#ifndef DB_CACHE_SIZE
# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
#endif
#ifndef DB_HASH_NELEM
# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
#endif
bool
bt_map_open(map, mode)
MAP *map;
int mode;
{
BTREEINFO btinfo;
if (tTd(38, 2))
printf("bt_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
return db_map_open(map, mode, DB_BTREE);
bzero(&btinfo, sizeof btinfo);
btinfo.cachesize = DB_CACHE_SIZE;
return db_map_open(map, mode, DB_BTREE, &btinfo);
}
bool
@ -1052,17 +1067,24 @@ hash_map_open(map, mode)
MAP *map;
int mode;
{
HASHINFO hinfo;
if (tTd(38, 2))
printf("hash_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
return db_map_open(map, mode, DB_HASH);
bzero(&hinfo, sizeof hinfo);
hinfo.nelem = DB_HASH_NELEM;
hinfo.cachesize = DB_CACHE_SIZE;
return db_map_open(map, mode, DB_HASH, &hinfo);
}
bool
db_map_open(map, mode, dbtype)
db_map_open(map, mode, dbtype, openinfo)
MAP *map;
int mode;
DBTYPE dbtype;
const void *openinfo;
{
DB *db;
int i;
@ -1113,7 +1135,7 @@ db_map_open(map, mode, dbtype)
omode |= O_TRUNC;
#endif
db = dbopen(buf, omode, DBMMODE, dbtype, NULL);
db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
saveerrno = errno;
#if !LOCK_ON_OPEN

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mci.c 8.44 (Berkeley) 10/9/96";
static char sccsid[] = "@(#)mci.c 8.46 (Berkeley) 11/3/96";
#endif /* not lint */
#include "sendmail.h"
@ -362,6 +362,7 @@ mci_get(host, m)
**
** Parameters:
** mci -- the MCI structure to set.
** xstat -- the exit status code.
** dstat -- the DSN status code.
** rstat -- the SMTP status code.
**
@ -370,18 +371,19 @@ mci_get(host, m)
*/
void
mci_setstat(mci, dstat, rstat)
mci_setstat(mci, xstat, dstat, rstat)
MCI *mci;
int xstat;
char *dstat;
char *rstat;
{
mci->mci_exitstat = xstat;
mci->mci_status = dstat;
if (mci->mci_rstatus != NULL)
free(mci->mci_rstatus);
if (rstat != NULL)
{
if (mci->mci_rstatus != NULL)
free(mci->mci_rstatus);
mci->mci_rstatus = newstr(rstat);
}
rstat = newstr(rstat);
mci->mci_rstatus = rstat;
}
/*
** MCI_DUMP -- dump the contents of an MCI structure.
@ -1032,6 +1034,7 @@ mci_print_persistent(pathname, hostname)
int status;
int width = Verbose ? 78 : 25;
bool locked;
char *p;
MCI mcib;
if (!initflag)
@ -1061,16 +1064,34 @@ mci_print_persistent(pathname, hostname)
locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB);
fclose(fp);
if (mcib.mci_rstatus == NULL)
printf("%c%-39s %12s %.*s\n",
locked ? '*' : ' ', hostname,
pintvl(curtime() - mcib.mci_lastuse, TRUE),
width, errstring(mcib.mci_errno));
printf("%c%-39s %12s ",
locked ? '*' : ' ', hostname,
pintvl(curtime() - mcib.mci_lastuse, TRUE));
if (mcib.mci_rstatus != NULL)
printf("%.*s\n", width, mcib.mci_rstatus);
else if (mcib.mci_exitstat == EX_TEMPFAIL && mcib.mci_errno != 0)
printf("Deferred: %.*s\n", width - 10, errstring(mcib.mci_errno));
else if (mcib.mci_exitstat != 0)
{
int i = mcib.mci_exitstat - EX__BASE;
extern int N_SysEx;
extern char *SysExMsg[];
if (i < 0 || i > N_SysEx)
{
char buf[80];
snprintf(buf, sizeof buf, "Unknown mailer error %d",
mcib.mci_exitstat);
printf("%.*s\n", width, buf);
}
else
printf("%.*s\n", width, &(SysExMsg[i])[5]);
}
else if (mcib.mci_errno == 0)
printf("OK\n");
else
printf("%c%-39s %12s %.*s\n",
locked ? '*' : ' ', hostname,
pintvl(curtime() - mcib.mci_lastuse, TRUE),
width, mcib.mci_rstatus);
printf("OK: %.*s\n", width - 4, errstring(mcib.mci_errno));
return 0;
}

View File

@ -36,7 +36,7 @@
# include <string.h>
#ifndef lint
static char sccsid[] = "@(#)mime.c 8.48 (Berkeley) 10/18/96";
static char sccsid[] = "@(#)mime.c 8.49 (Berkeley) 10/30/96";
#endif /* not lint */
/*
@ -932,9 +932,23 @@ isboundary(line, boundaries)
** none.
*/
extern void mime_from64 __P((u_char *, u_char *, int));
extern int mime_fromqp __P((u_char *, u_char **, int, int));
static char index_64[128] =
{
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
};
#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
void
mime7to8(mci, header, e)
register MCI *mci;
@ -996,28 +1010,81 @@ mime7to8(mci, header, e)
if (strcasecmp(cte, "base64") == 0)
{
fbufp = fbuf;
while (fgets(buf, sizeof buf, e->e_dfp) != NULL)
{
obufp = obuf;
mime_from64((u_char *) buf, obuf, MAXLINE);
while ((ch = *obufp++) != '\0')
{
*fbufp++ = ch;
if (ch == '\n' || fbufp >= &fbuf[MAXLINE])
{
*fbufp = '\0';
putline((char *) fbuf, mci);
fbufp = fbuf;
}
}
int nchar = 0;
int c1, c2, c3, c4;
/* force out partial last line */
if (fbufp > fbuf)
fbufp = fbuf;
while ((c1 = fgetc(e->e_dfp)) != EOF)
{
if (isascii(c1) && isspace(c1))
continue;
do
{
c2 = fgetc(e->e_dfp);
} while (isascii(c2) && isspace(c2));
if (c2 == EOF)
break;
do
{
c3 = fgetc(e->e_dfp);
} while (isascii(c3) && isspace(c3));
if (c3 == EOF)
break;
do
{
c4 = fgetc(e->e_dfp);
} while (isascii(c4) && isspace(c4));
if (c4 == EOF)
break;
if (c1 == '=' || c2 == '=')
continue;
c1 = CHAR64(c1);
c2 = CHAR64(c2);
*fbufp = (c1 << 2) | ((c2 & 0x30) >> 4);
if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
{
if (*--fbufp != '\n' || *--fbufp != '\r')
fbufp++;
*fbufp = '\0';
putline((char *) fbuf, mci);
fbufp = fbuf;
}
if (c3 == '=')
continue;
c3 = CHAR64(c3);
*fbufp = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
{
if (*--fbufp != '\n' || *--fbufp != '\r')
fbufp++;
*fbufp = '\0';
putline((char *) fbuf, mci);
fbufp = fbuf;
}
if (c4 == '=')
continue;
c4 = CHAR64(c4);
*fbufp = ((c3 & 0x03) << 6) | c4;
if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
{
if (*--fbufp != '\n' || *--fbufp != '\r')
fbufp++;
*fbufp = '\0';
putline((char *) fbuf, mci);
fbufp = fbuf;
}
}
/* force out partial last line */
if (fbufp > fbuf)
{
*fbufp = '\0';
putline((char *) fbuf, mci);
}
}
else
@ -1113,89 +1180,5 @@ mime_fromqp(infile, outfile, state, maxlen)
return 1;
}
static char index_64[128] =
{
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
};
#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
void
mime_from64(infile, outfile, maxlen)
u_char *infile;
u_char *outfile;
int maxlen;
{
int nchar = 0;
int c1, c2, c3, c4;
while ((c1 = *infile++) != '\0')
{
if (isascii(c1) && isspace(c1))
continue;
do
{
c2 = *infile++;
} while (isascii(c2) && isspace(c2));
if (c2 == '\0')
break;
do
{
c3 = *infile++;
} while (isascii(c3) && isspace(c3));
if (c3 == '\0')
break;
do
{
c4 = *infile++;
} while (isascii(c4) && isspace(c4));
if (c4 == '\0')
break;
if (c1 == '=' || c2 == '=')
{
continue;
}
c1 = CHAR64(c1);
c2 = CHAR64(c2);
if (++nchar > maxlen)
break;
*outfile++ = (c1 << 2) | ((c2 & 0x30) >> 4);
if (c3 != '=')
{
c3 = CHAR64(c3);
if (++nchar > maxlen)
break;
*outfile++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
if (c4 != '=')
{
c4 = CHAR64(c4);
if (++nchar > maxlen)
break;
*outfile++ = ((c3 & 0x03) << 6) | c4;
}
}
}
*outfile = '\0';
return;
}
#endif /* MIME7TO8 */

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef QUEUE
static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (with queueing)";
static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (with queueing)";
#else
static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (without queueing)";
static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (without queueing)";
#endif
#endif /* not lint */
@ -296,40 +296,45 @@ queueup(e, announce)
printctladdr(NULL, NULL);
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
if (bitset(QQUEUEUP, q->q_flags) ||
!bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))
if (bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))
{
printctladdr(q, tfp);
if (q->q_orcpt != NULL)
fprintf(tfp, "Q%s\n",
denlstring(q->q_orcpt, TRUE, FALSE));
putc('R', tfp);
if (bitset(QPRIMARY, q->q_flags))
putc('P', tfp);
if (bitset(QHASNOTIFY, q->q_flags))
putc('N', tfp);
if (bitset(QPINGONSUCCESS, q->q_flags))
putc('S', tfp);
if (bitset(QPINGONFAILURE, q->q_flags))
putc('F', tfp);
if (bitset(QPINGONDELAY, q->q_flags))
putc('D', tfp);
putc(':', tfp);
fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE));
if (announce)
{
e->e_to = q->q_paddr;
message("queued");
if (LogLevel > 8)
logdelivery(q->q_mailer, NULL, "queued",
NULL, (time_t) 0, e);
e->e_to = NULL;
}
if (tTd(40, 1))
{
printf("queueing ");
printaddr(q, FALSE);
}
#if XDEBUG
if (bitset(QQUEUEUP, q->q_flags))
syslog(LOG_DEBUG, "%s: q_flags = %x",
e->e_id, q->q_flags);
#endif
continue;
}
printctladdr(q, tfp);
if (q->q_orcpt != NULL)
fprintf(tfp, "Q%s\n",
denlstring(q->q_orcpt, TRUE, FALSE));
putc('R', tfp);
if (bitset(QPRIMARY, q->q_flags))
putc('P', tfp);
if (bitset(QHASNOTIFY, q->q_flags))
putc('N', tfp);
if (bitset(QPINGONSUCCESS, q->q_flags))
putc('S', tfp);
if (bitset(QPINGONFAILURE, q->q_flags))
putc('F', tfp);
if (bitset(QPINGONDELAY, q->q_flags))
putc('D', tfp);
putc(':', tfp);
fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE));
if (announce)
{
e->e_to = q->q_paddr;
message("queued");
if (LogLevel > 8)
logdelivery(q->q_mailer, NULL, "queued",
NULL, (time_t) 0, e);
e->e_to = NULL;
}
if (tTd(40, 1))
{
printf("queueing ");
printaddr(q, FALSE);
}
}
@ -574,7 +579,7 @@ runqueue(forkflag)
if (forkflag)
{
int pid;
pid_t pid;
extern void intsig();
#ifdef SIGCHLD
extern void reapchild();
@ -625,6 +630,15 @@ runqueue(forkflag)
/* force it to run expensive jobs */
NoConnect = FALSE;
/* drop privileges */
if (geteuid() == (uid_t) 0)
{
if (RunAsGid != (gid_t) 0)
(void) setgid(RunAsGid);
if (RunAsUid != (uid_t) 0)
(void) setuid(RunAsUid);
}
/*
** Create ourselves an envelope
*/
@ -1387,6 +1401,7 @@ readqf(e)
struct stat st;
char *bp;
int qfver = 0;
long hdrsize = 0;
register char *p;
char *orcpt = NULL;
bool nomore = FALSE;
@ -1579,6 +1594,7 @@ readqf(e)
case 'H': /* header */
(void) chompheader(&bp[1], FALSE, NULL, e);
hdrsize += strlen(&bp[1]);
break;
case 'M': /* message */
@ -1611,6 +1627,26 @@ readqf(e)
case 'N': /* number of delivery attempts */
e->e_ntries = atoi(&buf[1]);
/* if this has been tried recently, let it be */
if (e->e_ntries > 0 &&
(curtime() - e->e_dtime) < MinQueueAge)
{
char *howlong = pintvl(curtime() - e->e_dtime, TRUE);
extern void unlockqueue();
if (Verbose || tTd(40, 8))
printf("%s: too young (%s)\n",
e->e_id, howlong);
#ifdef LOG
if (LogLevel > 19)
syslog(LOG_DEBUG, "%s: too young (%s)",
e->e_id, howlong);
#endif
e->e_id = NULL;
unlockqueue(e);
return FALSE;
}
break;
case 'P': /* message priority */
@ -1694,25 +1730,6 @@ readqf(e)
return TRUE;
}
/* if this has been tried recently, let it be */
if (e->e_ntries > 0 && (curtime() - e->e_dtime) < MinQueueAge)
{
char *howlong = pintvl(curtime() - e->e_dtime, TRUE);
extern void unlockqueue();
if (Verbose || tTd(40, 8))
printf("%s: too young (%s)\n",
e->e_id, howlong);
#ifdef LOG
if (LogLevel > 19)
syslog(LOG_DEBUG, "%s: too young (%s)",
e->e_id, howlong);
#endif
e->e_id = NULL;
unlockqueue(e);
return FALSE;
}
/*
** Arrange to read the data file.
*/
@ -1728,7 +1745,7 @@ readqf(e)
e->e_flags |= EF_HAS_DF;
if (fstat(fileno(e->e_dfp), &st) >= 0)
{
e->e_msgsize = st.st_size;
e->e_msgsize = st.st_size + hdrsize;
e->e_dfdev = st.st_dev;
e->e_dfino = st.st_ino;
}
@ -1971,7 +1988,7 @@ queuename(e, type)
register ENVELOPE *e;
int type;
{
static int pid = -1;
static pid_t pid = -1;
static char c0;
static char c1;
static char c2;

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96";
static char sccsid[] = "@(#)readcf.c 8.176 (Berkeley) 11/10/96";
#endif /* not lint */
# include "sendmail.h"
@ -715,7 +715,7 @@ fileclass(class, filename, fmt, safe, optional)
{
FILE *f;
int sff;
int pid;
pid_t pid;
register char *p;
char buf[MAXLINE];
@ -1024,6 +1024,10 @@ makemailer(line)
m->m_uid = strtol(p, &q, 0);
p = q;
while (isascii(*p) && isspace(*p))
p++;
if (*p != '\0')
p++;
}
while (isascii(*p) && isspace(*p))
p++;

View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)sendmail.h 8.206 (Berkeley) 10/17/96
* @(#)sendmail.h 8.209 (Berkeley) 11/8/96
*/
/*
@ -41,7 +41,7 @@
# ifdef _DEFINE
# define EXTERN
# ifndef lint
static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96";
static char SmailSccsId[] = "@(#)sendmail.h 8.209 11/8/96";
# endif
# else /* _DEFINE */
# define EXTERN extern
@ -275,6 +275,7 @@ struct mailer
# define M_HASPWENT 'w' /* check for /etc/passwd entry */
/* 'x' CF: include Full-Name: */
# define M_XDOT 'X' /* use hidden-dot algorithm */
# define M_LMTP 'z' /* run Local Mail Transport Protocol */
# define M_NOMX '0' /* turn off MX lookups */
# define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
# define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
@ -310,7 +311,7 @@ MCI
long mci_maxsize; /* max size this server will accept */
FILE *mci_in; /* input side of connection */
FILE *mci_out; /* output side of connection */
int mci_pid; /* process id of subordinate proc */
pid_t mci_pid; /* process id of subordinate proc */
char *mci_phase; /* SMTP phase string */
struct mailer *mci_mailer; /* ptr to the mailer for this conn */
char *mci_host; /* host name */
@ -1095,7 +1096,7 @@ EXTERN gid_t RealGid; /* real gid of caller */
EXTERN uid_t DefUid; /* default uid to run as */
EXTERN gid_t DefGid; /* default gid to run as */
EXTERN char *DefUser; /* default user to run as (from DefUid) */
EXTERN int OldUmask; /* umask when sendmail starts up */
EXTERN MODE_T OldUmask; /* umask when sendmail starts up */
EXTERN int Errors; /* set if errors (local to single pass) */
EXTERN int ExitStat; /* exit status code */
EXTERN int LineNumber; /* line number in current input */
@ -1303,7 +1304,7 @@ extern void inittimeouts __P((char *));
extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *));
extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *));
extern void buildfname __P((char *, char *, char *, int));
extern void mci_setstat __P((MCI *, char *, char *));
extern void mci_setstat __P((MCI *, int, char *, char *));
extern char *smtptodsn __P((int));
extern int rscheck __P((char *, char *, char *, ENVELOPE *e));
extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *));

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)";
static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (with SMTP)";
#else
static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)";
static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (without SMTP)";
#endif
#endif /* not lint */
@ -1270,10 +1270,20 @@ runinchild(label, e)
char *label;
register ENVELOPE *e;
{
int childpid;
pid_t childpid;
sigfunc_t chldsig;
if (!OneXact)
{
/*
** Disable child process reaping, in case ETRN has preceeded
** MAIL command.
*/
#ifdef SIGCHLD
chldsig = setsignal(SIGCHLD, SIG_IGN);
#endif
childpid = dofork();
if (childpid < 0)
{
@ -1300,6 +1310,11 @@ runinchild(label, e)
finis();
}
#ifdef SIGCHLD
/* restore the child signal */
(void) setsignal(SIGCHLD, chldsig);
#endif
return (1);
}
else

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)";
static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (with SMTP)";
#else
static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)";
static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (without SMTP)";
#endif
#endif /* not lint */
@ -143,8 +143,10 @@ smtpinit(m, mci, e)
SmtpPhase = mci->mci_phase = "client greeting";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check);
if (r < 0 || REPLYTYPE(r) == 4)
if (r < 0)
goto tempfail1;
if (REPLYTYPE(r) == 4)
goto tempfail2;
if (REPLYTYPE(r) != 2)
goto unavailable;
@ -153,11 +155,24 @@ smtpinit(m, mci, e)
** My mother taught me to always introduce myself.
*/
#if FFR_LMTP
if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags))
#else
if (bitnset(M_ESMTP, m->m_flags))
#endif
mci->mci_flags |= MCIF_ESMTP;
tryhelo:
#if FFR_LMTP
if (bitnset(M_LMTP, m->m_flags))
{
smtpmessage("LHLO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client LHLO";
}
else if (bitset(MCIF_ESMTP, mci->mci_flags))
#else
if (bitset(MCIF_ESMTP, mci->mci_flags))
#endif
{
smtpmessage("EHLO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client EHLO";
@ -173,7 +188,12 @@ tryhelo:
goto tempfail1;
else if (REPLYTYPE(r) == 5)
{
#if FFR_LMTP
if (bitset(MCIF_ESMTP, mci->mci_flags) &&
!bitnset(M_LMTP, m->m_flags))
#else
if (bitset(MCIF_ESMTP, mci->mci_flags))
#endif
{
/* try old SMTP instead */
mci->mci_flags &= ~MCIF_ESMTP;
@ -182,7 +202,7 @@ tryhelo:
goto unavailable;
}
else if (REPLYTYPE(r) != 2)
goto tempfail1;
goto tempfail2;
/*
** Check to see if we actually ended up talking to ourself.
@ -194,11 +214,14 @@ tryhelo:
if (p != NULL)
*p = '\0';
if (!bitnset(M_NOLOOPCHECK, m->m_flags) &&
#if FFR_LMTP
!bitnset(M_LMTP, m->m_flags) &&
#endif
strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
{
syserr("553 %s config error: mail loops back to me (MX problem?)",
mci->mci_host);
mci->mci_exitstat = EX_CONFIG;
mci_setstat(mci, EX_CONFIG, NULL, NULL);
mci->mci_errno = 0;
smtpquit(m, mci, e);
return;
@ -215,7 +238,7 @@ tryhelo:
smtpmessage("VERB", m, mci);
r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
if (r < 0)
goto tempfail2;
goto tempfail1;
}
if (mci->mci_state != MCIS_CLOSED)
@ -227,17 +250,25 @@ tryhelo:
/* got a 421 error code during startup */
tempfail1:
tempfail2:
mci->mci_exitstat = EX_TEMPFAIL;
if (mci->mci_errno == 0)
mci->mci_errno = errno;
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
if (mci->mci_state != MCIS_CLOSED)
smtpquit(m, mci, e);
return;
tempfail2:
if (mci->mci_errno == 0)
mci->mci_errno = errno;
/* XXX should use code from other end iff ENHANCEDSTATUSCODES */
mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer);
if (mci->mci_state != MCIS_CLOSED)
smtpquit(m, mci, e);
return;
unavailable:
mci->mci_exitstat = EX_UNAVAILABLE;
mci->mci_errno = errno;
mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer);
smtpquit(m, mci, e);
return;
}
@ -387,7 +418,7 @@ smtpmailfrom(m, mci, e)
extern char MsgBuf[];
usrerr("%s does not support 8BITMIME", mci->mci_host);
mci_setstat(mci, "5.6.3", MsgBuf);
mci_setstat(mci, EX_DATAERR, "5.6.3", MsgBuf);
return EX_DATAERR;
}
@ -447,17 +478,24 @@ smtpmailfrom(m, mci, e)
SmtpPhase = mci->mci_phase = "client MAIL";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_mail, NULL);
if (r < 0 || r == 421)
if (r < 0)
{
/* communications failure/service shutting down */
mci->mci_exitstat = EX_TEMPFAIL;
/* communications failure */
mci->mci_errno = errno;
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
else if (r == 421)
{
/* service shutting down */
mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 4)
{
mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
mci_setstat(mci, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer);
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 2)
@ -467,25 +505,25 @@ smtpmailfrom(m, mci, e)
else if (r == 501)
{
/* syntax error in arguments */
mci_setstat(mci, "5.5.2", SmtpReplyBuffer);
mci_setstat(mci, EX_DATAERR, "5.5.2", SmtpReplyBuffer);
return EX_DATAERR;
}
else if (r == 553)
{
/* mailbox name not allowed */
mci_setstat(mci, "5.1.3", SmtpReplyBuffer);
mci_setstat(mci, EX_DATAERR, "5.1.3", SmtpReplyBuffer);
return EX_DATAERR;
}
else if (r == 552)
{
/* exceeded storage allocation */
mci_setstat(mci, "5.2.2", SmtpReplyBuffer);
mci_setstat(mci, EX_UNAVAILABLE, "5.2.2", SmtpReplyBuffer);
return EX_UNAVAILABLE;
}
else if (REPLYTYPE(r) == 5)
{
/* unknown error */
mci_setstat(mci, "5.0.0", SmtpReplyBuffer);
mci_setstat(mci, EX_UNAVAILABLE, "5.0.0", SmtpReplyBuffer);
return EX_UNAVAILABLE;
}
@ -499,7 +537,7 @@ smtpmailfrom(m, mci, e)
#endif
/* protocol error -- close up */
mci_setstat(mci, "5.5.1", SmtpReplyBuffer);
mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer);
smtpquit(m, mci, e);
return EX_PROTOCOL;
}
@ -536,7 +574,8 @@ smtprcpt(to, m, mci, e)
{
/* NOTIFY= parameter */
if (bitset(QHASNOTIFY, to->q_flags) &&
bitset(QPRIMARY, to->q_flags))
bitset(QPRIMARY, to->q_flags) &&
!bitnset(M_LOCALMAILER, m->m_flags))
{
bool firstone = TRUE;
@ -622,6 +661,7 @@ smtprcpt(to, m, mci, e)
**
** Parameters:
** m -- mailer being sent to.
** mci -- the mailer connection information.
** e -- the envelope for this message.
**
** Returns:
@ -642,6 +682,7 @@ smtpdata(m, mci, e)
{
register int r;
register EVENT *ev;
int rstat;
time_t timeout;
/*
@ -690,8 +731,8 @@ smtpdata(m, mci, e)
if (setjmp(CtxDataTimeout) != 0)
{
mci->mci_errno = errno;
mci->mci_exitstat = EX_TEMPFAIL;
mci->mci_state = MCIS_ERROR;
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
syserr("451 timeout writing message to %s", mci->mci_host);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
@ -720,8 +761,8 @@ smtpdata(m, mci, e)
{
/* error during processing -- don't send the dot */
mci->mci_errno = EIO;
mci->mci_exitstat = EX_IOERR;
mci->mci_state = MCIS_ERROR;
mci_setstat(mci, EX_IOERR, "4.4.2", NULL);
smtpquit(m, mci, e);
return EX_IOERR;
}
@ -734,8 +775,12 @@ smtpdata(m, mci, e)
nmessage(">>> .");
/* check for the results of the transaction */
SmtpPhase = mci->mci_phase = "client DATA 250";
SmtpPhase = mci->mci_phase = "client DATA status";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
#if FFR_LMTP
if (bitnset(M_LMTP, m->m_flags))
return EX_OK;
#endif
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
if (r < 0)
{
@ -743,16 +788,22 @@ smtpdata(m, mci, e)
return EX_TEMPFAIL;
}
mci->mci_state = MCIS_OPEN;
mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
if (REPLYTYPE(r) == 4)
return EX_TEMPFAIL;
rstat = EX_TEMPFAIL;
else if (REPLYCLASS(r) != 5)
/* fall through */ ;
rstat = EX_PROTOCOL;
else if (REPLYTYPE(r) == 2)
return EX_OK;
rstat = EX_OK;
else if (REPLYTYPE(r) == 5)
return EX_UNAVAILABLE;
rstat = EX_UNAVAILABLE;
else
rstat = EX_PROTOCOL;
mci_setstat(mci, rstat, smtptodsn(r), SmtpReplyBuffer);
if (e->e_statmsg != NULL)
free(e->e_statmsg);
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
if (rstat != EX_PROTOCOL)
return rstat;
#ifdef LOG
if (LogLevel > 1)
{
@ -761,7 +812,7 @@ smtpdata(m, mci, e)
shortenstring(SmtpReplyBuffer, 403));
}
#endif
return EX_PROTOCOL;
return rstat;
}
@ -771,10 +822,66 @@ datatimeout()
longjmp(CtxDataTimeout, 1);
}
/*
** SMTPGETSTAT -- get status code from DATA in LMTP
**
** Parameters:
** m -- the mailer to which we are sending the message.
** mci -- the mailer connection structure.
** e -- the current envelope.
**
** Returns:
** The exit status corresponding to the reply code.
*/
#if FFR_LMTP
int
smtpgetstat(m, mci, e)
MAILER *m;
MCI *mci;
ENVELOPE *e;
{
int r;
int stat;
/* check for the results of the transaction */
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
if (r < 0)
{
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
if (e->e_statmsg != NULL)
free(e->e_statmsg);
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
if (REPLYTYPE(r) == 4)
stat = EX_TEMPFAIL;
else if (REPLYCLASS(r) != 5)
stat = EX_PROTOCOL;
else if (REPLYTYPE(r) == 2)
stat = EX_OK;
else if (REPLYTYPE(r) == 5)
stat = EX_UNAVAILABLE;
mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer);
#ifdef LOG
if (LogLevel > 1 && stat == EX_PROTOCOL)
{
syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-3 protocol error: %s",
e->e_id, mci->mci_host,
shortenstring(SmtpReplyBuffer, 403));
}
#endif
return stat;
}
#endif
/*
** SMTPQUIT -- close the SMTP connection.
**
** Parameters:
** m -- a pointer to the mailer.
** mci -- the mailer connection information.
** e -- the current envelope.
**
** Returns:
** none.
@ -927,6 +1034,7 @@ reply(m, mci, e, timeout, pfunc)
if (p == NULL)
{
bool oldholderrs;
extern char MsgBuf[];
/* if the remote end closed early, fake an error */
if (errno == 0)
@ -937,10 +1045,10 @@ reply(m, mci, e, timeout, pfunc)
# endif /* ECONNRESET */
mci->mci_errno = errno;
mci->mci_exitstat = EX_TEMPFAIL;
oldholderrs = HoldErrs;
HoldErrs = TRUE;
usrerr("451 reply: read error from %s", mci->mci_host);
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
/* if debugging, pause so we can see state */
if (tTd(18, 100))

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96";
static char sccsid[] = "@(#)util.c 8.109 (Berkeley) 11/16/96";
#endif /* not lint */
# include "sendmail.h"
@ -1012,6 +1012,15 @@ putxline(l, mci, pxflags)
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
else if (l[0] == 'F' && slop == 0 &&
bitset(PXLF_MAPFROM, pxflags) &&
strncmp(l, "From ", 5) == 0 &&
bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
{
(void) putc('>', mci->mci_out);
if (TrafficLogFile != NULL)
(void) putc('>', TrafficLogFile);
}
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%.*s\n", p - l, l);
for ( ; l < p; ++l)
@ -2197,6 +2206,7 @@ proc_list_add(pid)
pid_t pid;
{
int i;
extern void proc_list_probe __P((void));
for (i = 0; i < ProcListSize; i++)
{
@ -2204,6 +2214,18 @@ proc_list_add(pid)
break;
}
if (i >= ProcListSize)
{
/* probe the existing vector to avoid growing infinitely */
proc_list_probe();
/* now scan again */
for (i = 0; i < ProcListSize; i++)
{
if (ProcListVec[i] == NO_PID)
break;
}
}
if (i >= ProcListSize)
{
/* grow process list */
pid_t *npv;
@ -2244,8 +2266,42 @@ proc_list_drop(pid)
if (ProcListVec[i] == pid)
{
ProcListVec[i] = NO_PID;
CurChildren--;
break;
}
}
if (CurChildren > 0)
CurChildren--;
}
/*
** PROC_LIST_PROBE -- probe processes in the list to see if they still exist
**
** Parameters:
** none
**
** Returns:
** none
*/
void
proc_list_probe()
{
int i;
for (i = 0; i < ProcListSize; i++)
{
if (ProcListVec[i] == NO_PID)
continue;
if (kill(ProcListVec[i], 0) < 0)
{
#ifdef LOG
if (LogLevel > 3)
syslog(LOG_DEBUG, "proc_list_probe: lost pid %d",
ProcListVec[i]);
#endif
ProcListVec[i] = NO_PID;
CurChildren--;
}
}
if (CurChildren < 0)
CurChildren = 0;
}

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)version.c 8.8.2.1 (Berkeley) 10/18/96";
static char sccsid[] = "@(#)version.c 8.8.3.2 (Berkeley) 11/16/96";
#endif /* not lint */
char Version[] = "8.8.2";
char Version[] = "8.8.3";

View File

@ -39,6 +39,7 @@ AIX 3.1.5 FAIL 93.08.07 David J. N. Begley
AIX 3.2.3e FAIL 93.07.26 Steve Bauer <sbauer@silver.sdsmt.edu>
AIX 3.2.4 FAIL 93.10.07 David J. N. Begley
AIX 3.2.5 FAIL 94.05.17 Steve Bauer <sbauer@hpcmmib.hpc.sdsmt.edu>
AIX 4.1 FAIL 96.10.21 Hakan Lindholm <hakan@af.lu.se>
AIX 4.2 OK 96.10.16 Steve Bauer <sbauer@krypton.hpc.sdsmt.edu>
IRIX 4.0.4 OK 93.09.25 Robert Elz
@ -78,6 +79,8 @@ Solaris 2.5 OK 96.02.29 Carson Gaspar <carson@lehman.com>
Linux 1.2.13 FAIL 95.11.02 Sven Neuhaus <sven@ping.de>
Linux 2.0.17 FAIL 96.09.03 Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
AIX 4.1 OK 96.10.21 Hakan Lindholm <hakan@af.lu.se>
IRIX 5.2 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com>
IRIX 5.3 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com>
IRIX 6.2 OK 96.09.16 Kari E. Hurtta <Kari.Hurtta@ozone.FMI.FI>