-----BEGIN PGP SIGNED MESSAGE----- diff -c -r sendmail-8.8.2/RELEASE_NOTES sendmail-8.8.3/RELEASE_NOTES *** sendmail-8.8.2/RELEASE_NOTES Fri Oct 18 08:32:05 1996 - --- sendmail-8.8.3/RELEASE_NOTES Sat Nov 16 18:35:59 1996 *************** *** 1,12 **** SENDMAIL RELEASE NOTES ! @(#)RELEASE_NOTES 8.8.2.1 (Berkeley) 10/18/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 SECURITY: fix a botch in the 7-bit MIME patch; the previous patch changed the code but didn't fix the problem. PORTABILITY FIXES: - --- 1,125 ---- SENDMAIL RELEASE NOTES ! @(#)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.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 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, (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 . ! 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 . ! 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,1095 **** 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 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. - --- 1202,1208 ---- 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 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,1829 **** 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. 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. - --- 1936,1942 ---- 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 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,2426 **** 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 values to the -d flag. Thanks to Alain Durand of INRIA for forwarding me the notice from the bugtraq list. - --- 2533,2539 ---- 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 weird values to the -d flag. Thanks to Alain Durand of INRIA for forwarding me the notice from the bugtraq list. *************** *** 2558,2564 **** 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 CNAME loops). Problem noted by James M.R.Matheson of Cambridge University. Avoid giving ``warning: foo owned process doing -bs'' messages - --- 2671,2677 ---- 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 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,2829 **** Make sure that route-addrs always have around them in non-SMTP envelopes (SMTP envelopes already do this properly). ! Avoid wierd headers on unbalanced punctuation of the form: ``Joe User around them in non-SMTP envelopes (SMTP envelopes already do this properly). ! Avoid weird headers on unbalanced punctuation of the form: ``Joe User ! @(#)README 8.106 (Berkeley) 10/12/96 This document describes the sendmail configuration files being used - --- 4,10 ---- Eric Allman ! @(#)README 8.108 (Berkeley) 11/16/96 This document describes the sendmail configuration files being used *************** *** 128,134 **** 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; 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. - --- 128,134 ---- divert(0) The divert(-1) will delete the crud in the resulting output file. ! 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,594 **** always_add_domain Include the local host domain even on locally delivered ! mail. Normally it is not added unless it is already ! present. allmasquerade If masquerading is enabled (using MASQUERADE_AS), this feature will cause recipient addresses to also masquerade - --- 587,596 ---- always_add_domain Include the local host domain even on locally delivered ! 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,947 **** 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 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. - --- 942,949 ---- MASQUERADE_AS(host.domain) This causes mail being sent to be labeled as coming from the ! 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. *************** *** 1216,1221 **** - --- 1218,1228 ---- On the server, this will match an alias for "root+client1". 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 + +----------------+ diff -c -r sendmail-8.8.2/cf/feature/bestmx_is_local.m4 sendmail-8.8.3/cf/feature/bestmx_is_local.m4 *** sendmail-8.8.2/cf/feature/bestmx_is_local.m4 Sat May 11 11:59:07 1996 - --- sendmail-8.8.3/cf/feature/bestmx_is_local.m4 Wed Oct 23 08:43:46 1996 *************** *** 34,40 **** # divert(0) ! VERSIONID(`@(#)bestmx_is_local.m4 8.3 (Berkeley) 5/11/96') divert(-1) LOCAL_CONFIG - --- 34,40 ---- # divert(0) ! VERSIONID(`@(#)bestmx_is_local.m4 8.4 (Berkeley) 10/23/96') divert(-1) LOCAL_CONFIG *************** *** 60,66 **** 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$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3 R$* < @ $* @@ $=w . > $* $#local $: $1 R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4 - --- 60,66 ---- ifelse(_ARG_, `', `', `#')dnl unlimited bestmx R$* < @ $* > $* $: $1 < @ $2 @@ $(bestmx $2 $) > $3 ifelse(_ARG_, `', `#', `')dnl limit bestmx to $=B ! R$* < @ $* $=B > $* $: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4 R$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3 R$* < @ $* @@ $=w . > $* $#local $: $1 R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4 diff -c -r sendmail-8.8.2/cf/feature/local_procmail.m4 sendmail-8.8.3/cf/feature/local_procmail.m4 *** sendmail-8.8.2/cf/feature/local_procmail.m4 Mon Feb 12 10:38:23 1996 - --- sendmail-8.8.3/cf/feature/local_procmail.m4 Sun Oct 20 07:46:49 1996 *************** *** 34,40 **** # divert(0) ! VERSIONID(`@(#)local_procmail.m4 8.5 (Berkeley) 2/12/96') divert(-1) define(`LOCAL_MAILER_PATH', - --- 34,40 ---- # divert(0) ! VERSIONID(`@(#)local_procmail.m4 8.6 (Berkeley) 10/20/96') divert(-1) define(`LOCAL_MAILER_PATH', *************** *** 43,47 **** PROCMAIL_MAILER_PATH, `/usr/local/bin/procmail'), _ARG_)) ! define(`LOCAL_MAILER_FLAGS', `SPfhn') define(`LOCAL_MAILER_ARGS', `procmail -Y -a $h -d $u') - --- 43,47 ---- PROCMAIL_MAILER_PATH, `/usr/local/bin/procmail'), _ARG_)) ! define(`LOCAL_MAILER_FLAGS', `SPfhn9') define(`LOCAL_MAILER_ARGS', `procmail -Y -a $h -d $u') diff -c -r sendmail-8.8.2/cf/m4/proto.m4 sendmail-8.8.3/cf/m4/proto.m4 *** sendmail-8.8.2/cf/m4/proto.m4 Sun Oct 13 13:45:36 1996 - --- sendmail-8.8.3/cf/m4/proto.m4 Sat Oct 26 09:12:17 1996 *************** *** 34,40 **** # divert(0) ! VERSIONID(`@(#)proto.m4 8.134 (Berkeley) 10/13/96') MAILER(local)dnl - --- 34,40 ---- # divert(0) ! VERSIONID(`@(#)proto.m4 8.135 (Berkeley) 10/26/96') MAILER(local)dnl *************** *** 662,668 **** 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" ifdef(`_MAILER_smtp_', `# handle numeric address spec - --- 662,668 ---- 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" ifdef(`_MAILER_smtp_', `# handle numeric address spec diff -c -r sendmail-8.8.2/cf/m4/version.m4 sendmail-8.8.3/cf/m4/version.m4 *** sendmail-8.8.2/cf/m4/version.m4 Fri Oct 18 08:28:28 1996 - --- sendmail-8.8.3/cf/m4/version.m4 Sat Nov 16 15:01:50 1996 *************** *** 32,39 **** # 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') # divert(0) # Configuration version number ! DZ8.8.2`'ifdef(`confCF_VERSION', `/confCF_VERSION') - --- 32,39 ---- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ! VERSIONID(`@(#)version.m4 8.8.3.1 (Berkeley) 11/16/96') # divert(0) # Configuration version number ! DZ8.8.3`'ifdef(`confCF_VERSION', `/confCF_VERSION') Only in sendmail-8.8.3/cf/ostype: aix4.m4 Only in sendmail-8.8.3/cf/ostype: mklinux.m4 diff -c -r sendmail-8.8.2/contrib/mailprio sendmail-8.8.3/contrib/mailprio *** sendmail-8.8.2/contrib/mailprio Sat Dec 10 08:20:25 1994 - --- sendmail-8.8.3/contrib/mailprio Thu Oct 31 09:38:16 1996 *************** *** 1,280 **** ! Message-Id: <199412081919.NAA23234@austin.BSDI.COM> ! To: Eric Allman ! 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 Organization: Berkeley Software Design, Inc. ! Date: Thu, 08 Dec 1994 13:19:39 -0600 ! 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. ! 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. ! There are two programs, mailprio_mkdb and mailprio (source below). ! 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 '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"; 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} 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 ! X ! X# Setup %list and @list ! Xlocal($addr, $canon); ! Xwhile ($addr = ) { ! 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; X } ! X if (defined $list{$canon}) { ! X warn "duplicate: ``$addr -> $canon''\n"; ! X push(@list, $addr); # save it anyway ! X next; 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 } ! 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"; ! 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 ! 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 ! Xexit(0); X ! X# REPL-LIB --------------------------------------------------------------- X ! Xsub 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 { X local($_) = shift; ! 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 } 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] =~ /^-/) { 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); X ! Xsub getlog_stats { X local($maillog, *stats) = @_; X local($to, $delay); X local($h, $m, $s); X open(MAILLOG, "< $maillog") || die "$maillog: $!\n"; X while () { ! X ($delay) = (m/, delay=([^,]*), /); ! X $delay || next; ! 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 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 $stats{$addr} = int(($stats{$addr} + $delay) / 2); X } X } X close(MAILLOG); ! X} X ! X# REPL-LIB --------------------------------------------------------------- X ! Xsub 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 { X local($_) = shift; X 1 while s/\([^\(\)]*\)//g; # strip comments X 1 while s/"[^"]*"//g; # strip comments - --- 1,540 ---- ! 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 ; 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 ! cc: marc@xfree86.org ! Subject: Updated mailprio_0_93.shar ! From: Tony Sanders Organization: Berkeley Software Design, Inc. ! Date: Thu, 31 Oct 1996 10:28:14 -0700 ! Sender: sanders@austin.bsdi.com ! Eric, please update contrib/mailprio in the sendmail distribution ! to this version at your convenience. Thanks. ! I've also made this available in: ! ftp://ftp.earth.com/pub/postmaster/ ! mailprio_0_93.shar follows... ! #!/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 . ! # ! # 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 ! 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 ! # 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 ! # 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 ! $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 ! 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 ! 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 ! 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 ! sub output { ! X local($sink, *list) = @_; X ! 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 # 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 ! 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 # 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 ! 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 ! # @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 foreach (@_) { ! X 1 while s/.*<(.*)>.*/\1/; ! X s/^\s+//; ! X s/\s+$//; X } X @_; ! } ! X ! ### ---- ### ! # ! # 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 ! 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:). ! 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 ! # 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 ! $SIG{'PIPE'} = 'handle_pipe'; X ! # 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 () { ! 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 ($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 $stats{$addr} = $delay unless defined $stats{$addr}; # init ! 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 ! # 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 ! # @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,297 **** 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! ! fi ! chmod +x 'mailprio_mkdb' ! # end of 'mailprio_mkdb' fi - - echo shar: End of shell archive. exit 0 - --- 545,557 ---- X s/\s+$//; X } X @_; ! } ! 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 exit 0 diff -c -r sendmail-8.8.2/doc/op/op.me sendmail-8.8.3/doc/op/op.me *** sendmail-8.8.2/doc/op/op.me Thu Oct 17 18:08:21 1996 - --- sendmail-8.8.3/doc/op/op.me Sat Nov 16 08:08:23 1996 *************** *** 30,36 **** .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" ! .\" @(#)op.me 8.97 (Berkeley) 10/17/96 .\" .\" eqn op.me | pic | troff -me .eh 'SMM:08-%''Sendmail Installation and Operation Guide' - --- 30,36 ---- .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" ! .\" @(#)op.me 8.98 (Berkeley) 11/16/96 .\" .\" eqn op.me | pic | troff -me .eh 'SMM:08-%''Sendmail Installation and Operation Guide' *************** *** 68,74 **** InReference, Inc. eric@Sendmail.ORG .sp ! Version 8.97 .sp For Sendmail Version 8.8 .)l - --- 68,74 ---- InReference, Inc. eric@Sendmail.ORG .sp ! Version 8.98 .sp For Sendmail Version 8.8 .)l *************** *** 3561,3566 **** - --- 3561,3585 ---- 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,3767 **** it will include the user name on that host. .pp The ! .b ${client_name} and ! .b ${client_addr} ! are set to the name and address of the SMTP client who is invoking .i sendmail as a server. - --- 3777,3788 ---- it will include the user name on that host. .pp The ! .b ${client_name} , ! .b ${client_addr} , and ! .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,8135 **** .\"Eric Allman .\"InReference, Inc. .\".sp ! .\"Version 8.97 .\".ce 0 .bp 2 .rs - --- 8150,8156 ---- .\"Eric Allman .\"InReference, Inc. .\".sp ! .\"Version 8.98 .\".ce 0 .bp 2 .rs diff -c -r sendmail-8.8.2/mail.local/mail.local.c sendmail-8.8.3/mail.local/mail.local.c *** sendmail-8.8.2/mail.local/mail.local.c Wed Oct 9 13:15:32 1996 - --- sendmail-8.8.3/mail.local/mail.local.c Wed Nov 13 16:17:43 1996 *************** *** 38,44 **** #endif /* not lint */ #ifndef lint ! static char sccsid[] = "@(#)mail.local.c 8.30 (Berkeley) 10/9/96"; #endif /* not lint */ /* - --- 38,44 ---- #endif /* not lint */ #ifndef lint ! static char sccsid[] = "@(#)mail.local.c 8.33 (Berkeley) 11/13/96"; #endif /* not lint */ /* diff -c -r sendmail-8.8.2/makemap/makemap.c sendmail-8.8.3/makemap/makemap.c *** sendmail-8.8.2/makemap/makemap.c Wed Sep 25 08:38:02 1996 - --- sendmail-8.8.3/makemap/makemap.c Wed Nov 13 10:04:03 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)makemap.c 8.17 (Berkeley) 9/25/96"; #endif /* not lint */ #include - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)makemap.c 8.18 (Berkeley) 11/13/96"; #endif /* not lint */ #include *************** *** 97,102 **** - --- 97,103 ---- int st; int mode; int putflags; + long dbcachesize = 1024 * 1024; enum type type; int fd; union *************** *** 112,117 **** - --- 113,119 ---- union dbent key, val; #ifdef NEWDB BTREEINFO bti; + HASHINFO hinfo; #endif char ibuf[BUFSIZE]; char fbuf[MAXNAME]; *************** *** 122,128 **** progname = argv[0]; ! while ((opt = getopt(argc, argv, "Ndforv")) != EOF) { switch (opt) { - --- 124,135 ---- progname = argv[0]; ! #ifdef FFR_CFLAG ! #define OPTIONS "Nc:dforv" ! #else ! #define OPTIONS "Ndforv" ! #endif ! while ((opt = getopt(argc, argv, OPTIONS)) != EOF) { switch (opt) { *************** *** 130,135 **** - --- 137,148 ---- inclnull = TRUE; break; + #ifdef FFR_CFLAG + case 'c': + dbcachesize = atol(optarg); + break; + #endif + case 'd': allowdups = TRUE; break; *************** *** 189,195 **** - --- 202,212 ---- 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,300 **** #ifdef NEWDB case T_HASH: ! dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL); if (dbp.db != NULL) { # if OLD_NEWDB - --- 311,321 ---- #ifdef NEWDB case T_HASH: ! /* 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,311 **** - --- 327,335 ---- 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) { diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.IRIX sendmail-8.8.3/src/Makefiles/Makefile.IRIX *** sendmail-8.8.2/src/Makefiles/Makefile.IRIX Fri Sep 20 07:35:43 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.IRIX Sat Nov 16 09:29:07 1996 *************** *** 7,19 **** # # This has been tested on IRIX 4.0.4. # ! # @(#)Makefile.IRIX 8.11 (Berkeley) 9/20/96 # SHELL= /bin/sh # use O=-O (usual) or O=-g (debugging) O= -O - - CC=gcc # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM - --- 7,18 ---- # # This has been tested on IRIX 4.0.4. # ! # @(#)Makefile.IRIX 8.12 (Berkeley) 11/16/96 # SHELL= /bin/sh # use O=-O (usual) or O=-g (debugging) O= -O # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.IRIX64 sendmail-8.8.3/src/Makefiles/Makefile.IRIX64 *** sendmail-8.8.2/src/Makefiles/Makefile.IRIX64 Fri Sep 20 07:35:44 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.IRIX64 Sat Nov 16 09:29:07 1996 *************** *** 8,20 **** # This has been tested on IRIX64 6.0. # Changes from Mark R. Levinson . # ! # @(#)Makefile.IRIX64 8.5 (Berkeley) 9/20/96 # SHELL= /bin/sh # use O=-O (usual) or O=-g (debugging) O= -O - - CC=gcc # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM - --- 8,19 ---- # This has been tested on IRIX64 6.0. # Changes from Mark R. Levinson . # ! # @(#)Makefile.IRIX64 8.6 (Berkeley) 11/16/96 # SHELL= /bin/sh # use O=-O (usual) or O=-g (debugging) O= -O # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM Only in sendmail-8.8.3/src/Makefiles: Makefile.Linux.ppc diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.NEWS-OS.4.x sendmail-8.8.3/src/Makefiles/Makefile.NEWS-OS.4.x *** sendmail-8.8.2/src/Makefiles/Makefile.NEWS-OS.4.x Thu Sep 26 07:16:19 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.NEWS-OS.4.x Sat Nov 16 18:16:48 1996 *************** *** 5,18 **** # old make program (I recommend that you get and port the new make if you # are going to be doing any signficant work on sendmail). # ! # @(#)Makefile.NEWS-OS.4.x 8.6 (Berkeley) 9/26/96 # # use O=-O (usual) or O=-g (debugging) O= -O ! # native compiler requires -Olimit to optimize properly ! CC= cc -Olimit 1100 # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM - --- 5,18 ---- # old make program (I recommend that you get and port the new make if you # are going to be doing any signficant work on sendmail). # ! # @(#)Makefile.NEWS-OS.4.x 8.7 (Berkeley) 11/16/96 # # use O=-O (usual) or O=-g (debugging) O= -O ! # native compiler on RISC OS requires -Olimit to optimize properly ! #CC= cc -Olimit 1100 # define the database mechanisms available for map & alias lookups: # -DNDBM -- use new DBM diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.SCO sendmail-8.8.3/src/Makefiles/Makefile.SCO *** sendmail-8.8.2/src/Makefiles/Makefile.SCO Fri Sep 20 07:35:44 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.SCO Sun Nov 10 11:15:56 1996 *************** *** 7,13 **** # # This has been tested on SCO. # ! # @(#)Makefile.SCO 8.9 (Berkeley) 9/20/96 # # use O=-O (usual) or O=-g (debugging) - --- 7,13 ---- # # This has been tested on SCO. # ! # @(#)Makefile.SCO 8.10 (Berkeley) 11/10/96 # # use O=-O (usual) or O=-g (debugging) *************** *** 34,40 **** LIBDIRS= # libraries required on your system ! LIBS= -lsocket # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib - --- 34,40 ---- LIBDIRS= # libraries required on your system ! LIBS= -lsocket -lprot_s -lx -lc_s # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.SCO.4.2 sendmail-8.8.3/src/Makefiles/Makefile.SCO.4.2 *** sendmail-8.8.2/src/Makefiles/Makefile.SCO.4.2 Fri Sep 20 07:35:45 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.SCO.4.2 Sun Nov 10 11:15:56 1996 *************** *** 7,13 **** # # Tested on SCO rel 4.2 by Marian Durkovic . # ! # @(#)Makefile.SCO.4.2 8.3 (Berkeley) 9/20/96 # # use O=-O (usual) or O=-g (debugging) - --- 7,13 ---- # # Tested on SCO rel 4.2 by Marian Durkovic . # ! # @(#)Makefile.SCO.4.2 8.4 (Berkeley) 11/10/96 # # use O=-O (usual) or O=-g (debugging) *************** *** 34,40 **** LIBDIRS= # libraries required on your system ! LIBS= -lsocket -lndbm # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib - --- 34,40 ---- LIBDIRS= # libraries required on your system ! LIBS= -lsocket -lndbm -lprot_s -lx -lc_s # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.SCO.5.x sendmail-8.8.3/src/Makefiles/Makefile.SCO.5.x *** sendmail-8.8.2/src/Makefiles/Makefile.SCO.5.x Fri Sep 20 07:35:45 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.SCO.5.x Sun Nov 10 11:15:56 1996 *************** *** 7,13 **** # # Tested on SCO OpenServer 5 by Keith Reynolds . # ! # @(#)Makefile.SCO.5.x 8.2 (Berkeley) 9/20/96 # # use O=-O (usual) or O=-g (debugging) - --- 7,13 ---- # # Tested on SCO OpenServer 5 by Keith Reynolds . # ! # @(#)Makefile.SCO.5.x 8.3 (Berkeley) 11/10/96 # # use O=-O (usual) or O=-g (debugging) *************** *** 34,40 **** LIBDIRS= # libraries required on your system ! LIBS= -lsocket -lndbm # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib - --- 34,40 ---- LIBDIRS= # libraries required on your system ! LIBS= -lsocket -lndbm -lcurses -lm -lx # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/lib diff -c -r sendmail-8.8.2/src/Makefiles/Makefile.UXPDS.V10 sendmail-8.8.3/src/Makefiles/Makefile.UXPDS.V10 *** sendmail-8.8.2/src/Makefiles/Makefile.UXPDS.V10 Fri Sep 20 07:35:46 1996 - --- sendmail-8.8.3/src/Makefiles/Makefile.UXPDS.V10 Sat Nov 16 09:28:17 1996 *************** *** 12,18 **** # and Toshiaki Nomura of the Fujitsu FreeSoftware Group # . # ! # @(#)Makefile.UXPDS.V10 8.6 (Berkeley) 9/20/96 # # make sure the shell constructs below use the right shell - --- 12,18 ---- # and Toshiaki Nomura of the Fujitsu FreeSoftware Group # . # ! # @(#)Makefile.UXPDS.V10 8.7 (Berkeley) 11/16/96 # # make sure the shell constructs below use the right shell *************** *** 119,125 **** ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} # doesn't actually install them -- you may want to install pre-nroff versions ! install-docs: aliases.0 mailq.0 newaliases.0 sendmail.0 cp aliases.0 ${MAN4}/aliases.4 chmod ${MANMODE} ${MAN4}/aliases.4 cp mailq.0 ${MAN1}/mailq.1m - --- 119,125 ---- ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} # doesn't actually install them -- you may want to install pre-nroff versions ! install-docs: ${MAN1} ${MAN4} aliases.0 mailq.0 newaliases.0 sendmail.0 cp aliases.0 ${MAN4}/aliases.4 chmod ${MANMODE} ${MAN4}/aliases.4 cp mailq.0 ${MAN1}/mailq.1m *************** *** 129,137 **** - --- 129,142 ---- cp sendmail.0 ${MAN1}/sendmail.1m chmod ${MANMODE} ${MAN1}/sendmail.1m + ${MAN1} ${MAN4}: + mkdir -p $@ + clean: rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0 # dependencies # gross overkill, and yet still not quite enough.... ${OBJS}: sendmail.h conf.h + + depend: diff -c -r sendmail-8.8.2/src/READ_ME sendmail-8.8.3/src/READ_ME *** sendmail-8.8.2/src/READ_ME Fri Oct 18 08:32:41 1996 - --- sendmail-8.8.3/src/READ_ME Sun Nov 10 11:15:33 1996 *************** *** 30,36 **** # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ! # @(#)READ_ME 8.125 (Berkeley) 10/18/96 # This directory contains the source files for sendmail. - --- 30,36 ---- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ! # @(#)READ_ME 8.130 (Berkeley) 11/10/96 # This directory contains the source files for sendmail. *************** *** 168,174 **** 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 >>> 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 - --- 168,174 ---- this flag. >>> NOTE WELL for NEWDB support: it is CRITICAL that you remove ndbm.o ! >>> 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,365 **** the dg_sys_info system call. LA_HPUX (10) is an HP-UX specific version that uses the pstat_getdynamic system call. 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. 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 - --- 355,374 ---- 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. 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,814 **** - --- 818,843 ---- 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 , 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,1351 **** Eric Allman ! (Version 8.125, last update 10/18/96 07:32:40) - --- 1377,1380 ---- Eric Allman ! (Version 8.130, last update 11/10/96 11:15:30) diff -c -r sendmail-8.8.2/src/collect.c sendmail-8.8.3/src/collect.c *** sendmail-8.8.2/src/collect.c Wed Sep 18 14:49:26 1996 - --- sendmail-8.8.3/src/collect.c Fri Nov 15 07:23:02 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96"; #endif /* not lint */ # include - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)collect.c 8.60 (Berkeley) 11/15/96"; #endif /* not lint */ # include *************** *** 488,494 **** ** Examples are who is the from person & the date. */ ! eatheader(e, !requeueflag); if (GrabTo && e->e_sendqueue == NULL) usrerr("No recipient addresses found in header"); - --- 488,494 ---- ** Examples are who is the from person & the date. */ ! eatheader(e, TRUE); if (GrabTo && e->e_sendqueue == NULL) usrerr("No recipient addresses found in header"); *************** *** 557,562 **** - --- 557,563 ---- /* 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); diff -c -r sendmail-8.8.2/src/conf.c sendmail-8.8.3/src/conf.c *** sendmail-8.8.2/src/conf.c Thu Oct 17 07:52:56 1996 - --- sendmail-8.8.3/src/conf.c Sun Nov 10 11:15:35 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)conf.c 8.312 (Berkeley) 10/17/96"; #endif /* not lint */ # include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)conf.c 8.315 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" *************** *** 1188,1195 **** /* keep gethostby*() from stripping the local domain name */ set_domain_trim_off(); #endif ! #if SECUREWARE set_auth_parameters(argc, argv); #endif #ifdef VENDOR_DEFAULT - --- 1188,1206 ---- /* keep gethostby*() from stripping the local domain name */ set_domain_trim_off(); #endif ! #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,1250 **** - --- 1256,1263 ---- #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,1787 **** - --- 1793,1892 ---- } #endif + #if LA_TYPE == LA_KSTAT + + #include + + 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,1948 **** syslog(LOG_INFO, "rejecting connections on port %d: load average: %d", port, CurrentLA); #endif } ! else if (!enoughdiskspace(MinBlocksFree + 1)) { setproctitle("rejecting connections on port %d: min free: %d", port, MinBlocksFree); - --- 2046,2055 ---- syslog(LOG_INFO, "rejecting connections on port %d: load average: %d", port, CurrentLA); #endif + return TRUE; } ! ! if (!enoughdiskspace(MinBlocksFree + 1)) { setproctitle("rejecting connections on port %d: min free: %d", port, MinBlocksFree); *************** *** 1951,1970 **** syslog(LOG_INFO, "rejecting connections on port %d: min free: %d", port, MinBlocksFree); #endif } ! else 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", port, CurChildren, MaxChildren); #endif } ! else ! return FALSE; ! return TRUE; } /* ** SETPROCTITLE -- set process title for ps - --- 2058,2083 ---- syslog(LOG_INFO, "rejecting connections on port %d: min free: %d", port, MinBlocksFree); #endif + return TRUE; } ! ! if (MaxChildren > 0 && CurChildren >= MaxChildren) { ! 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; + } } ! ! return FALSE; } /* ** SETPROCTITLE -- set process title for ps diff -c -r sendmail-8.8.2/src/conf.h sendmail-8.8.3/src/conf.h *** sendmail-8.8.2/src/conf.h Thu Oct 17 18:09:04 1996 - --- sendmail-8.8.3/src/conf.h Sat Nov 16 18:32:10 1996 *************** *** 31,37 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)conf.h 8.267 (Berkeley) 10/17/96 */ /* - --- 31,37 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)conf.h 8.272 (Berkeley) 11/16/96 */ /* *************** *** 41,47 **** - --- 41,49 ---- ** included in the next release. */ + #ifdef __GNUC__ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ + #endif # include # include *************** *** 216,222 **** #ifdef _AIX4 # define _AIX3 1 /* pull in AIX3 stuff */ ! # define HASSETREUID 1 /* setreuid(2) works */ #endif - --- 218,228 ---- #ifdef _AIX4 # define _AIX3 1 /* pull in AIX3 stuff */ ! # 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,414 **** - --- 415,423 ---- # 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,593 **** - --- 597,603 ---- # 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,821 **** ** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier. */ #if _SCO_DS >= 1 # include # define _SCO_unix_4_2 ! # define HASSNPRINTF 1 /* has snprintf() call */ ! # define HASFCHMOD 1 /* has fchmod() call */ ! # define HASSETRLIMIT 1 /* has setrlimit() call */ # define RLIMIT_NEEDS_SYS_TIME_H 1 #endif ! #ifdef _SCO_unix_4_2 # define _SCO_unix_ # define HASSETREUID 1 /* has setreuid(2) call */ #endif #ifdef _SCO_unix_ # include /* needed for IP_SRCROUTE */ # define SYSTEM5 1 /* include all the System V defines */ # define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ # define MAXPATHLEN PATHSIZE - - # define LA_TYPE LA_SHORT # define SFS_TYPE SFS_4ARGS /* use 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 _PATH_UNIX "/unix" # define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" # ifndef _PATH_SENDMAILPID - --- 801,843 ---- ** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier. */ + /* SCO OpenServer 5 */ #if _SCO_DS >= 1 # include # define _SCO_unix_4_2 ! # 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 /* 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 SFS_TYPE SFS_4ARGS /* use 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,836 **** # endif # ifndef _SCO_DS ! # define NOFTRUNCATE 0 /* does not have ftruncate(3) call */ # define NEEDFSYNC 1 /* needs the fsync(2) call stub */ # define NETUNIX 0 /* no unix domain socket support */ # endif #endif - --- 850,859 ---- # endif # ifndef _SCO_DS ! # 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 *************** *** 1848,1853 **** - --- 1871,1880 ---- #ifndef SIZE_T # define SIZE_T size_t + #endif + + #ifndef MODE_T + # define MODE_T mode_t #endif #ifndef ARGV_T diff -c -r sendmail-8.8.2/src/daemon.c sendmail-8.8.3/src/daemon.c *** sendmail-8.8.2/src/daemon.c Sat Oct 12 13:35:11 1996 - --- sendmail-8.8.3/src/daemon.c Fri Nov 8 09:09:27 1996 *************** *** 37,45 **** #ifndef lint #ifdef DAEMON ! static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)"; #else ! static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)"; #endif #endif /* not lint */ - --- 37,45 ---- #ifndef lint #ifdef DAEMON ! static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (with daemon mode)"; #else ! static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (without daemon mode)"; #endif #endif /* not lint */ *************** *** 193,199 **** for (;;) { ! register int pid; auto int lotherend; extern bool refuseconnections(); extern int getla(); - --- 193,199 ---- for (;;) { ! register pid_t pid; auto int lotherend; extern bool refuseconnections(); extern int getla(); *************** *** 244,249 **** - --- 244,259 ---- /* wait for a connection */ setproctitle("accepting connections on port %d", ntohs(DaemonAddr.sin.sin_port)); + #if 0 + /* + ** Andrew Sun 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,742 **** 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); } #if NETINET addr.sin.sin_family = AF_INET; /*XXX*/ - --- 744,751 ---- extern char MsgBuf[]; usrerr("553 Invalid numeric domain spec \"%s\"", host); ! mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf); ! return EX_NOHOST; } #if NETINET addr.sin.sin_family = AF_INET; /*XXX*/ *************** *** 773,783 **** if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || (errno == ECONNREFUSED && UseNameServer)) { ! mci->mci_status = "4.4.3"; ! mci->mci_rstatus = NULL; ! return (EX_TEMPFAIL); } #endif return (EX_NOHOST); } addr.sa.sa_family = hp->h_addrtype; - --- 782,792 ---- if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || (errno == ECONNREFUSED && UseNameServer)) { ! 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,844 **** - --- 848,854 ---- 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,882 **** { sav_errno = errno; syserr("makeconnection: cannot create socket"); ! goto failure; } #ifdef SO_SNDBUF - --- 886,896 ---- { sav_errno = errno; syserr("makeconnection: cannot create socket"); ! #ifdef XLA ! xla_host_end(host); ! #endif ! mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); ! return EX_TEMPFAIL; } #ifdef SO_SNDBUF *************** *** 964,981 **** continue; } ! /* failure, decide if temporary or not */ ! failure: #ifdef XLA xla_host_end(host); #endif ! if (transienterror(sav_errno)) ! return EX_TEMPFAIL; ! else ! { ! message("%s", errstring(sav_errno)); ! return (EX_UNAVAILABLE); ! } } /* connection ok, put it into canonical form */ - --- 978,989 ---- continue; } ! /* couldn't open connection */ #ifdef XLA xla_host_end(host); #endif ! mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); ! return EX_TEMPFAIL; } /* connection ok, put it into canonical form */ *************** *** 984,992 **** - --- 992,1002 ---- (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); } /* diff -c -r sendmail-8.8.2/src/deliver.c sendmail-8.8.3/src/deliver.c *** sendmail-8.8.2/src/deliver.c Thu Oct 17 07:54:08 1996 - --- sendmail-8.8.3/src/deliver.c Sat Nov 16 07:40:26 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96"; #endif /* not lint */ #include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)deliver.c 8.251 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" *************** *** 78,84 **** ENVELOPE *splitenv = NULL; bool oldverbose = Verbose; bool somedeliveries = FALSE; ! int pid; extern void sendenvelope(); /* - --- 78,84 ---- ENVELOPE *splitenv = NULL; bool oldverbose = Verbose; bool somedeliveries = FALSE; ! pid_t pid; extern void sendenvelope(); /* *************** *** 760,766 **** int dofork() { ! register int pid = -1; DOFORK(fork); return (pid); - --- 760,766 ---- int dofork() { ! register pid_t pid = -1; DOFORK(fork); return (pid); *************** *** 813,823 **** ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */ int rcode; /* response code */ char *firstsig; /* signature of firstto */ ! int pid = -1; char *volatile curhost; register volatile u_short port = 0; time_t xstart; bool suidwarn; int mpvect[2]; int rpvect[2]; char *pv[MAXPV+1]; - --- 813,824 ---- ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */ int rcode; /* response code */ char *firstsig; /* signature of firstto */ ! 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,1320 **** if (mci_lock_host(mci) != EX_OK) { ! mci->mci_exitstat = EX_TEMPFAIL; continue; } - --- 1315,1321 ---- if (mci_lock_host(mci) != EX_OK) { ! mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); continue; } *************** *** 1840,1845 **** - --- 1841,1847 ---- 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,1892 **** 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') { - --- 1885,1890 ---- *************** *** 1917,1927 **** */ give_up: ! if (tobuf[0] != '\0') ! giveresponse(rcode, m, mci, ctladdr, xstart, e); ! if (rcode == EX_OK) ! markstats(e, tochain); ! mci_store_persistent(mci); for (to = tochain; to != NULL; to = to->q_tchain) { - --- 1915,1931 ---- */ give_up: ! #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,1939 **** if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) continue; ! /* mark bad addresses */ ! if (rcode != EX_OK) { ! markfailure(e, to, mci, rcode); ! continue; } /* successful delivery */ - --- 1933,1969 ---- if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) continue; ! #ifdef SMTP ! # if FFR_LMTP ! /* if running LMTP, get the status for each address */ ! if (bitnset(M_LMTP, m->m_flags)) { ! 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,1963 **** - --- 1988,2025 ---- } } + #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,2148 **** st = waitfor(mci->mci_pid); if (st == -1) { ! syserr("endmailer %s: wait", pv[0]); return (EX_SOFTWARE); } - --- 2204,2210 ---- st = waitfor(mci->mci_pid); if (st == -1) { ! syserr("endmailer %s: wait", mci->mci_mailer->m_name); return (EX_SOFTWARE); } *************** *** 2951,2957 **** register ENVELOPE *e; { register FILE *f; ! register int pid = -1; int mode; bool suidwarn = geteuid() == 0; - --- 3013,3019 ---- register ENVELOPE *e; { register FILE *f; ! register pid_t pid = -1; int mode; bool suidwarn = geteuid() == 0; *************** *** 3146,3154 **** /* reset ISUID & ISGID bits for paranoid systems */ #if HASFCHMOD ! (void) fchmod(fileno(f), (int) stb.st_mode); #else ! (void) chmod(filename, (int) stb.st_mode); #endif (void) xfclose(f, "mailfile", filename); (void) fflush(stdout); - --- 3208,3216 ---- /* reset ISUID & ISGID bits for paranoid systems */ #if HASFCHMOD ! (void) fchmod(fileno(f), (MODE_T) stb.st_mode); #else ! (void) chmod(filename, (MODE_T) stb.st_mode); #endif (void) xfclose(f, "mailfile", filename); (void) fflush(stdout); *************** *** 3259,3268 **** /* 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; /* use the original host name as signature */ nmx = 1; - --- 3321,3330 ---- /* update the connection info for this host */ mci = mci_get(hp, m); 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; diff -c -r sendmail-8.8.2/src/domain.c sendmail-8.8.3/src/domain.c *** sendmail-8.8.2/src/domain.c Sat Oct 12 17:14:28 1996 - --- sendmail-8.8.3/src/domain.c Wed Oct 30 09:42:41 1996 *************** *** 36,44 **** #ifndef lint #if NAMED_BIND ! static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)"; #else ! static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)"; #endif #endif /* not lint */ - --- 36,44 ---- #ifndef lint #if NAMED_BIND ! static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)"; #else ! static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)"; #endif #endif /* not lint */ *************** *** 48,57 **** #include #include typedef union { HEADER qb1; ! u_char qb2[PACKETSZ]; } querybuf; #ifndef MXHOSTBUFSIZE - --- 48,70 ---- #include #include + /* + ** 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[MAXPACKET]; } querybuf; #ifndef MXHOSTBUFSIZE *************** *** 206,211 **** - --- 219,228 ---- 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,521 **** int qtype; int loopcnt; char *xp; ! char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; extern char *gethostalias(); - --- 532,538 ---- int qtype; int loopcnt; char *xp; ! char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; extern char *gethostalias(); *************** *** 647,652 **** - --- 664,673 ---- } 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 diff -c -r sendmail-8.8.2/src/envelope.c sendmail-8.8.3/src/envelope.c *** sendmail-8.8.2/src/envelope.c Sat Oct 12 17:14:28 1996 - --- sendmail-8.8.3/src/envelope.c Mon Nov 11 09:34:08 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)envelope.c 8.93 (Berkeley) 9/26/96"; #endif /* not lint */ #include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)envelope.c 8.96 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" *************** *** 153,161 **** 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)) queueit = TRUE; /* see if a notification is needed */ if (bitset(QPINGONFAILURE, q->q_flags) && - --- 153,176 ---- e->e_flags &= ~EF_QUEUERUN; for (q = e->e_sendqueue; q != NULL; q = q->q_next) { ! 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,210 **** 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)) { q->q_flags |= QBADADDR; q->q_status = "4.4.7"; - --- 218,224 ---- fprintf(e->e_xfp, "Message will be deleted from queue\n"); for (q = e->e_sendqueue; q != NULL; q = q->q_next) { ! if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) { q->q_flags |= QBADADDR; q->q_status = "4.4.7"; diff -c -r sendmail-8.8.2/src/main.c sendmail-8.8.3/src/main.c *** sendmail-8.8.2/src/main.c Sat Oct 12 17:19:41 1996 - --- sendmail-8.8.3/src/main.c Sat Nov 16 10:34:25 1996 *************** *** 39,45 **** #endif /* not lint */ #ifndef lint ! static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96"; #endif /* not lint */ #define _DEFINE - --- 39,45 ---- #endif /* not lint */ #ifndef lint ! static char sccsid[] = "@(#)main.c 8.215 (Berkeley) 11/16/96"; #endif /* not lint */ #define _DEFINE *************** *** 387,398 **** OpMode = MD_DELIVER; FullName = getextenv("NAME"); #if NAMED_BIND ! if (tTd(8, 8)) ! { res_init(); _res.options |= RES_DEBUG; ! } #endif errno = 0; - --- 387,404 ---- OpMode = MD_DELIVER; FullName = getextenv("NAME"); + /* + ** Initialize name server if it is going to be used. + */ + #if NAMED_BIND ! 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,527 **** { case MD_DAEMON: case MD_FGDAEMON: ! # ifdef DAEMON ! if (RealUid != 0) ! { ! usrerr("Permission denied"); ! exit(EX_USAGE); ! } ! vendor_daemon_setup(CurEnv); ! /* fall through ... */ ! # else usrerr("Daemon mode not implemented"); ExitStat = EX_USAGE; break; - --- 519,525 ---- { case MD_DAEMON: case MD_FGDAEMON: ! # ifndef DAEMON usrerr("Daemon mode not implemented"); ExitStat = EX_USAGE; break; *************** *** 534,541 **** # endif /* SMTP */ case MD_INITALIAS: - - /* fall through ... */ - - case MD_DELIVER: case MD_VERIFY: case MD_TEST: - --- 532,537 ---- *************** *** 845,862 **** } /* - - ** 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. */ - --- 841,846 ---- *************** *** 897,904 **** /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { ! syserr("Warning: .cf version level (%d) exceeds program functionality (%d)", ! ConfigLevel, MAXCONFIGLEVEL); } /* need MCI cache to have persistence */ - --- 881,888 ---- /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { ! syserr("Warning: .cf version level (%d) exceeds sendmail version %s functionality (%d)", ! ConfigLevel, Version, MAXCONFIGLEVEL); } /* need MCI cache to have persistence */ *************** *** 931,936 **** - --- 915,933 ---- /* 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,1969 **** - --- 1961,1975 ---- 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) diff -c -r sendmail-8.8.2/src/makesendmail sendmail-8.8.3/src/makesendmail *** sendmail-8.8.2/src/makesendmail Mon Sep 23 07:00:30 1996 - --- sendmail-8.8.3/src/makesendmail Sun Nov 10 11:15:33 1996 *************** *** 32,38 **** # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ! # @(#)makesendmail 8.41 (Berkeley) 9/23/96 # # - --- 32,38 ---- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ! # @(#)makesendmail 8.42 (Berkeley) 11/10/96 # # *************** *** 109,114 **** - --- 109,121 ---- esac # tweak operating system type and release + node=`uname -n | sed -e 's/\//-/g' -e 's/ //g'` + if [ "$os" = "$node" -a "$arch" = "i386" -a "$rel" = 3.2 -a "`uname -v`" = 2 ] + then + # old versions of SCO UNIX set uname -s the same as uname -n + os=SCO_SV + fi + case $os in DYNIX-ptx) os=PTX;; diff -c -r sendmail-8.8.2/src/map.c sendmail-8.8.3/src/map.c *** sendmail-8.8.2/src/map.c Sat Oct 12 10:12:11 1996 - --- sendmail-8.8.3/src/map.c Sat Nov 16 18:32:45 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96"; #endif /* not lint */ #include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)map.c 8.144 (Berkeley) 11/16/96"; #endif /* not lint */ #include "sendmail.h" *************** *** 107,113 **** extern bool aliaswait __P((MAP *, char *, int)); extern bool extract_canonname __P((char *, char *, char[], int)); ! #if defined(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 */ - --- 107,113 ---- extern bool aliaswait __P((MAP *, char *, int)); extern bool extract_canonname __P((char *, char *, char[], int)); ! #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,695 **** - --- 690,697 ---- 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,1050 **** ** be pokey about it. That's hard to do. */ ! extern bool db_map_open __P((MAP *, int, DBTYPE)); bool bt_map_open(map, mode) MAP *map; int mode; { 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); } bool - --- 1036,1065 ---- ** be pokey about it. That's hard to do. */ ! 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); ! ! bzero(&btinfo, sizeof btinfo); ! btinfo.cachesize = DB_CACHE_SIZE; ! return db_map_open(map, mode, DB_BTREE, &btinfo); } bool *************** *** 1052,1068 **** MAP *map; int mode; { 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); } bool ! db_map_open(map, mode, dbtype) MAP *map; int mode; DBTYPE dbtype; { DB *db; int i; - --- 1067,1090 ---- 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); ! ! 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, openinfo) MAP *map; int mode; DBTYPE dbtype; + const void *openinfo; { DB *db; int i; *************** *** 1113,1119 **** omode |= O_TRUNC; #endif ! db = dbopen(buf, omode, DBMMODE, dbtype, NULL); saveerrno = errno; #if !LOCK_ON_OPEN - --- 1135,1141 ---- omode |= O_TRUNC; #endif ! db = dbopen(buf, omode, DBMMODE, dbtype, openinfo); saveerrno = errno; #if !LOCK_ON_OPEN diff -c -r sendmail-8.8.2/src/mci.c sendmail-8.8.3/src/mci.c *** sendmail-8.8.2/src/mci.c Wed Oct 9 11:48:43 1996 - --- sendmail-8.8.3/src/mci.c Sun Nov 3 15:23:30 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)mci.c 8.44 (Berkeley) 10/9/96"; #endif /* not lint */ #include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)mci.c 8.46 (Berkeley) 11/3/96"; #endif /* not lint */ #include "sendmail.h" *************** *** 362,367 **** - --- 362,368 ---- ** ** Parameters: ** mci -- the MCI structure to set. + ** xstat -- the exit status code. ** dstat -- the DSN status code. ** rstat -- the SMTP status code. ** *************** *** 370,387 **** */ void ! mci_setstat(mci, dstat, rstat) MCI *mci; char *dstat; char *rstat; { mci->mci_status = dstat; if (rstat != NULL) ! { ! if (mci->mci_rstatus != NULL) ! free(mci->mci_rstatus); ! mci->mci_rstatus = newstr(rstat); ! } } /* ** MCI_DUMP -- dump the contents of an MCI structure. - --- 371,389 ---- */ void ! 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) ! rstat = newstr(rstat); ! mci->mci_rstatus = rstat; } /* ** MCI_DUMP -- dump the contents of an MCI structure. *************** *** 1032,1037 **** - --- 1034,1040 ---- int status; int width = Verbose ? 78 : 25; bool locked; + char *p; MCI mcib; if (!initflag) *************** *** 1061,1076 **** 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)); else ! printf("%c%-39s %12s %.*s\n", ! locked ? '*' : ' ', hostname, ! pintvl(curtime() - mcib.mci_lastuse, TRUE), ! width, mcib.mci_rstatus); return 0; } - --- 1064,1097 ---- locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB); fclose(fp); ! 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("OK: %.*s\n", width - 4, errstring(mcib.mci_errno)); return 0; } diff -c -r sendmail-8.8.2/src/mime.c sendmail-8.8.3/src/mime.c *** sendmail-8.8.2/src/mime.c Fri Oct 18 08:33:00 1996 - --- sendmail-8.8.3/src/mime.c Wed Oct 30 09:20:43 1996 *************** *** 36,42 **** # include #ifndef lint ! static char sccsid[] = "@(#)mime.c 8.48 (Berkeley) 10/18/96"; #endif /* not lint */ /* - --- 36,42 ---- # include #ifndef lint ! static char sccsid[] = "@(#)mime.c 8.49 (Berkeley) 10/30/96"; #endif /* not lint */ /* *************** *** 932,940 **** ** none. */ - - extern void mime_from64 __P((u_char *, u_char *, int)); extern int mime_fromqp __P((u_char *, u_char **, int, int)); void mime7to8(mci, header, e) register MCI *mci; - --- 932,954 ---- ** none. */ 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,1024 **** 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; ! } ! } ! /* force out partial last line */ ! if (fbufp > fbuf) { *fbufp = '\0'; putline((char *) fbuf, mci); } } } else { - --- 1010,1091 ---- if (strcasecmp(cte, "base64") == 0) { + int nchar = 0; + int c1, c2, c3, c4; + 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,1201 **** 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 */ - --- 1180,1184 ---- diff -c -r sendmail-8.8.2/src/queue.c sendmail-8.8.3/src/queue.c *** sendmail-8.8.2/src/queue.c Sat Oct 12 13:35:12 1996 - --- sendmail-8.8.3/src/queue.c Sun Nov 10 14:04:48 1996 *************** *** 36,44 **** #ifndef lint #ifdef QUEUE ! static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (with queueing)"; #else ! static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (without queueing)"; #endif #endif /* not lint */ - --- 36,44 ---- #ifndef lint #ifdef QUEUE ! static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (with queueing)"; #else ! static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (without queueing)"; #endif #endif /* not lint */ *************** *** 296,335 **** 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)) { ! 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); ! } } } - --- 296,340 ---- printctladdr(NULL, NULL); for (q = e->e_sendqueue; q != NULL; q = q->q_next) { ! if (bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) { ! #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,580 **** if (forkflag) { ! int pid; extern void intsig(); #ifdef SIGCHLD extern void reapchild(); - --- 579,585 ---- if (forkflag) { ! pid_t pid; extern void intsig(); #ifdef SIGCHLD extern void reapchild(); *************** *** 625,630 **** - --- 630,644 ---- /* 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,1392 **** - --- 1401,1407 ---- struct stat st; char *bp; int qfver = 0; + long hdrsize = 0; register char *p; char *orcpt = NULL; bool nomore = FALSE; *************** *** 1579,1584 **** - --- 1594,1600 ---- case 'H': /* header */ (void) chompheader(&bp[1], FALSE, NULL, e); + hdrsize += strlen(&bp[1]); break; case 'M': /* message */ *************** *** 1611,1616 **** - --- 1627,1652 ---- 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,1718 **** 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. */ - --- 1730,1735 ---- *************** *** 1728,1734 **** e->e_flags |= EF_HAS_DF; if (fstat(fileno(e->e_dfp), &st) >= 0) { ! e->e_msgsize = st.st_size; e->e_dfdev = st.st_dev; e->e_dfino = st.st_ino; } - --- 1745,1751 ---- e->e_flags |= EF_HAS_DF; if (fstat(fileno(e->e_dfp), &st) >= 0) { ! e->e_msgsize = st.st_size + hdrsize; e->e_dfdev = st.st_dev; e->e_dfino = st.st_ino; } *************** *** 1971,1977 **** register ENVELOPE *e; int type; { ! static int pid = -1; static char c0; static char c1; static char c2; - --- 1988,1994 ---- register ENVELOPE *e; int type; { ! static pid_t pid = -1; static char c0; static char c1; static char c2; diff -c -r sendmail-8.8.2/src/readcf.c sendmail-8.8.3/src/readcf.c *** sendmail-8.8.2/src/readcf.c Wed Oct 9 11:46:22 1996 - --- sendmail-8.8.3/src/readcf.c Sun Nov 10 10:25:26 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96"; #endif /* not lint */ # include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)readcf.c 8.176 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" *************** *** 715,721 **** { FILE *f; int sff; ! int pid; register char *p; char buf[MAXLINE]; - --- 715,721 ---- { FILE *f; int sff; ! pid_t pid; register char *p; char buf[MAXLINE]; *************** *** 1024,1029 **** - --- 1024,1033 ---- 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++; diff -c -r sendmail-8.8.2/src/sendmail.h sendmail-8.8.3/src/sendmail.h *** sendmail-8.8.2/src/sendmail.h Thu Oct 17 18:09:15 1996 - --- sendmail-8.8.3/src/sendmail.h Fri Nov 8 09:09:26 1996 *************** *** 31,37 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)sendmail.h 8.206 (Berkeley) 10/17/96 */ /* - --- 31,37 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)sendmail.h 8.209 (Berkeley) 11/8/96 */ /* *************** *** 41,47 **** # ifdef _DEFINE # define EXTERN # ifndef lint ! static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96"; # endif # else /* _DEFINE */ # define EXTERN extern - --- 41,47 ---- # ifdef _DEFINE # define EXTERN # ifndef lint ! static char SmailSccsId[] = "@(#)sendmail.h 8.209 11/8/96"; # endif # else /* _DEFINE */ # define EXTERN extern *************** *** 275,280 **** - --- 275,281 ---- # 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,316 **** 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 */ char *mci_phase; /* SMTP phase string */ struct mailer *mci_mailer; /* ptr to the mailer for this conn */ char *mci_host; /* host name */ - --- 311,317 ---- long mci_maxsize; /* max size this server will accept */ FILE *mci_in; /* input side of connection */ FILE *mci_out; /* output side of connection */ ! 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,1101 **** 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 int Errors; /* set if errors (local to single pass) */ EXTERN int ExitStat; /* exit status code */ EXTERN int LineNumber; /* line number in current input */ - --- 1096,1102 ---- 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 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,1309 **** 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 char *smtptodsn __P((int)); extern int rscheck __P((char *, char *, char *, ENVELOPE *e)); extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *)); - --- 1304,1310 ---- 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 *, int, char *, char *)); extern char *smtptodsn __P((int)); extern int rscheck __P((char *, char *, char *, ENVELOPE *e)); extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *)); diff -c -r sendmail-8.8.2/src/srvrsmtp.c sendmail-8.8.3/src/srvrsmtp.c *** sendmail-8.8.2/src/srvrsmtp.c Fri Oct 18 08:27:47 1996 - --- sendmail-8.8.3/src/srvrsmtp.c Sun Nov 10 13:55:16 1996 *************** *** 36,44 **** #ifndef lint #ifdef SMTP ! static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)"; #else ! static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)"; #endif #endif /* not lint */ - --- 36,44 ---- #ifndef lint #ifdef SMTP ! static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (with SMTP)"; #else ! static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (without SMTP)"; #endif #endif /* not lint */ *************** *** 1270,1279 **** char *label; register ENVELOPE *e; { ! int childpid; if (!OneXact) { childpid = dofork(); if (childpid < 0) { - --- 1270,1289 ---- char *label; register ENVELOPE *e; { ! 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) { *************** *** 1299,1304 **** - --- 1309,1319 ---- disconnect(1, e); finis(); } + + #ifdef SIGCHLD + /* restore the child signal */ + (void) setsignal(SIGCHLD, chldsig); + #endif return (1); } diff -c -r sendmail-8.8.2/src/usersmtp.c sendmail-8.8.3/src/usersmtp.c *** sendmail-8.8.2/src/usersmtp.c Sun Sep 15 11:46:25 1996 - --- sendmail-8.8.3/src/usersmtp.c Sat Nov 16 07:40:07 1996 *************** *** 36,44 **** #ifndef lint #ifdef SMTP ! static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)"; #else ! static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)"; #endif #endif /* not lint */ - --- 36,44 ---- #ifndef lint #ifdef SMTP ! static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (with SMTP)"; #else ! static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (without SMTP)"; #endif #endif /* not lint */ *************** *** 143,150 **** 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) goto tempfail1; if (REPLYTYPE(r) != 2) goto unavailable; - --- 143,152 ---- 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) goto tempfail1; + if (REPLYTYPE(r) == 4) + goto tempfail2; if (REPLYTYPE(r) != 2) goto unavailable; *************** *** 153,163 **** - --- 155,178 ---- ** 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,179 **** - --- 188,199 ---- 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,188 **** goto unavailable; } else if (REPLYTYPE(r) != 2) ! goto tempfail1; /* ** Check to see if we actually ended up talking to ourself. - --- 202,208 ---- goto unavailable; } else if (REPLYTYPE(r) != 2) ! goto tempfail2; /* ** Check to see if we actually ended up talking to ourself. *************** *** 194,204 **** if (p != NULL) *p = '\0'; if (!bitnset(M_NOLOOPCHECK, m->m_flags) && 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->mci_errno = 0; smtpquit(m, mci, e); return; - --- 214,227 ---- 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_setstat(mci, EX_CONFIG, NULL, NULL); mci->mci_errno = 0; smtpquit(m, mci, e); return; *************** *** 215,221 **** smtpmessage("VERB", m, mci); r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); if (r < 0) ! goto tempfail2; } if (mci->mci_state != MCIS_CLOSED) - --- 238,244 ---- smtpmessage("VERB", m, mci); r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); if (r < 0) ! goto tempfail1; } if (mci->mci_state != MCIS_CLOSED) *************** *** 227,243 **** /* got a 421 error code during startup */ tempfail1: tempfail2: - - mci->mci_exitstat = EX_TEMPFAIL; if (mci->mci_errno == 0) mci->mci_errno = errno; if (mci->mci_state != MCIS_CLOSED) smtpquit(m, mci, e); return; unavailable: - - mci->mci_exitstat = EX_UNAVAILABLE; mci->mci_errno = errno; smtpquit(m, mci, e); return; } - --- 250,274 ---- /* got a 421 error code during startup */ tempfail1: + 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_errno = errno; + mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return; } *************** *** 387,393 **** extern char MsgBuf[]; usrerr("%s does not support 8BITMIME", mci->mci_host); ! mci_setstat(mci, "5.6.3", MsgBuf); return EX_DATAERR; } - --- 418,424 ---- extern char MsgBuf[]; usrerr("%s does not support 8BITMIME", mci->mci_host); ! mci_setstat(mci, EX_DATAERR, "5.6.3", MsgBuf); return EX_DATAERR; } *************** *** 447,463 **** 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) { ! /* communications failure/service shutting down */ ! mci->mci_exitstat = EX_TEMPFAIL; mci->mci_errno = errno; smtpquit(m, mci, e); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 4) { ! mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 2) - --- 478,501 ---- 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) { ! /* 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, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 2) *************** *** 467,491 **** else if (r == 501) { /* syntax error in arguments */ ! mci_setstat(mci, "5.5.2", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 553) { /* mailbox name not allowed */ ! mci_setstat(mci, "5.1.3", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 552) { /* exceeded storage allocation */ ! mci_setstat(mci, "5.2.2", SmtpReplyBuffer); return EX_UNAVAILABLE; } else if (REPLYTYPE(r) == 5) { /* unknown error */ ! mci_setstat(mci, "5.0.0", SmtpReplyBuffer); return EX_UNAVAILABLE; } - --- 505,529 ---- else if (r == 501) { /* syntax error in arguments */ ! mci_setstat(mci, EX_DATAERR, "5.5.2", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 553) { /* mailbox name not allowed */ ! mci_setstat(mci, EX_DATAERR, "5.1.3", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 552) { /* exceeded storage allocation */ ! mci_setstat(mci, EX_UNAVAILABLE, "5.2.2", SmtpReplyBuffer); return EX_UNAVAILABLE; } else if (REPLYTYPE(r) == 5) { /* unknown error */ ! mci_setstat(mci, EX_UNAVAILABLE, "5.0.0", SmtpReplyBuffer); return EX_UNAVAILABLE; } *************** *** 499,505 **** #endif /* protocol error -- close up */ ! mci_setstat(mci, "5.5.1", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_PROTOCOL; } - --- 537,543 ---- #endif /* protocol error -- close up */ ! mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_PROTOCOL; } *************** *** 536,542 **** { /* NOTIFY= parameter */ if (bitset(QHASNOTIFY, to->q_flags) && ! bitset(QPRIMARY, to->q_flags)) { bool firstone = TRUE; - --- 574,581 ---- { /* NOTIFY= parameter */ if (bitset(QHASNOTIFY, to->q_flags) && ! bitset(QPRIMARY, to->q_flags) && ! !bitnset(M_LOCALMAILER, m->m_flags)) { bool firstone = TRUE; *************** *** 622,627 **** - --- 661,667 ---- ** ** Parameters: ** m -- mailer being sent to. + ** mci -- the mailer connection information. ** e -- the envelope for this message. ** ** Returns: *************** *** 642,647 **** - --- 682,688 ---- { register int r; register EVENT *ev; + int rstat; time_t timeout; /* *************** *** 690,697 **** if (setjmp(CtxDataTimeout) != 0) { mci->mci_errno = errno; - - mci->mci_exitstat = EX_TEMPFAIL; mci->mci_state = MCIS_ERROR; syserr("451 timeout writing message to %s", mci->mci_host); smtpquit(m, mci, e); return EX_TEMPFAIL; - --- 731,738 ---- if (setjmp(CtxDataTimeout) != 0) { mci->mci_errno = errno; 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,727 **** { /* error during processing -- don't send the dot */ mci->mci_errno = EIO; - - mci->mci_exitstat = EX_IOERR; mci->mci_state = MCIS_ERROR; smtpquit(m, mci, e); return EX_IOERR; } - --- 761,768 ---- { /* error during processing -- don't send the dot */ mci->mci_errno = EIO; mci->mci_state = MCIS_ERROR; + mci_setstat(mci, EX_IOERR, "4.4.2", NULL); smtpquit(m, mci, e); return EX_IOERR; } *************** *** 734,741 **** nmessage(">>> ."); /* check for the results of the transaction */ ! SmtpPhase = mci->mci_phase = "client DATA 250"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); if (r < 0) { - --- 775,786 ---- nmessage(">>> ."); /* check for the results of the transaction */ ! 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,758 **** 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; else if (REPLYCLASS(r) != 5) ! /* fall through */ ; else if (REPLYTYPE(r) == 2) ! return EX_OK; else if (REPLYTYPE(r) == 5) ! return EX_UNAVAILABLE; #ifdef LOG if (LogLevel > 1) { - --- 788,809 ---- return EX_TEMPFAIL; } mci->mci_state = MCIS_OPEN; if (REPLYTYPE(r) == 4) ! rstat = EX_TEMPFAIL; else if (REPLYCLASS(r) != 5) ! rstat = EX_PROTOCOL; else if (REPLYTYPE(r) == 2) ! rstat = EX_OK; else if (REPLYTYPE(r) == 5) ! 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,767 **** shortenstring(SmtpReplyBuffer, 403)); } #endif ! return EX_PROTOCOL; } - --- 812,818 ---- shortenstring(SmtpReplyBuffer, 403)); } #endif ! return rstat; } *************** *** 771,780 **** - --- 822,887 ---- 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,932 **** - --- 1034,1040 ---- if (p == NULL) { bool oldholderrs; + extern char MsgBuf[]; /* if the remote end closed early, fake an error */ if (errno == 0) *************** *** 937,946 **** # 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); /* if debugging, pause so we can see state */ if (tTd(18, 100)) - --- 1045,1054 ---- # endif /* ECONNRESET */ mci->mci_errno = errno; 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)) diff -c -r sendmail-8.8.2/src/util.c sendmail-8.8.3/src/util.c *** sendmail-8.8.2/src/util.c Sat Oct 12 13:35:11 1996 - --- sendmail-8.8.3/src/util.c Sat Nov 16 18:32:28 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96"; #endif /* not lint */ # include "sendmail.h" - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)util.c 8.109 (Berkeley) 11/16/96"; #endif /* not lint */ # include "sendmail.h" *************** *** 1012,1017 **** - --- 1012,1026 ---- 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,2202 **** - --- 2206,2212 ---- pid_t pid; { int i; + extern void proc_list_probe __P((void)); for (i = 0; i < ProcListSize; i++) { *************** *** 2205,2210 **** - --- 2215,2232 ---- } 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,2251 **** if (ProcListVec[i] == pid) { ProcListVec[i] = NO_PID; - - CurChildren--; break; } } } - --- 2266,2307 ---- if (ProcListVec[i] == pid) { ProcListVec[i] = NO_PID; 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; } diff -c -r sendmail-8.8.2/src/version.c sendmail-8.8.3/src/version.c *** sendmail-8.8.2/src/version.c Fri Oct 18 08:28:13 1996 - --- sendmail-8.8.3/src/version.c Sat Nov 16 18:33:07 1996 *************** *** 33,39 **** */ #ifndef lint ! static char sccsid[] = "@(#)version.c 8.8.2.1 (Berkeley) 10/18/96"; #endif /* not lint */ ! char Version[] = "8.8.2"; - --- 33,39 ---- */ #ifndef lint ! static char sccsid[] = "@(#)version.c 8.8.3.2 (Berkeley) 11/16/96"; #endif /* not lint */ ! char Version[] = "8.8.3"; diff -c -r sendmail-8.8.2/test/Results sendmail-8.8.3/test/Results *** sendmail-8.8.2/test/Results Wed Oct 16 10:01:48 1996 - --- sendmail-8.8.3/test/Results Mon Oct 21 07:12:10 1996 *************** *** 39,44 **** - --- 39,45 ---- AIX 3.2.3e FAIL 93.07.26 Steve Bauer AIX 3.2.4 FAIL 93.10.07 David J. N. Begley AIX 3.2.5 FAIL 94.05.17 Steve Bauer + AIX 4.1 FAIL 96.10.21 Hakan Lindholm AIX 4.2 OK 96.10.16 Steve Bauer IRIX 4.0.4 OK 93.09.25 Robert Elz *************** *** 77,82 **** - --- 78,85 ---- Linux 1.2.13 FAIL 95.11.02 Sven Neuhaus Linux 2.0.17 FAIL 96.09.03 Horst von Brand + + AIX 4.1 OK 96.10.21 Hakan Lindholm IRIX 5.2 OK 95.12.01 Mark Andrews IRIX 5.3 OK 95.12.01 Mark Andrews -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBMo9USCPkYtS/e6QhAQHqdgP/WYbk0ue9iNsevGaTc1oF6vwB3GUqCDFd V9JfnRoMqzmRkHU+AKt/r+Vk5pow3VeOXHGxMp7fghgdm3QylsV7UC0cXeTgZoVq /VnH4+nwajoX9KfF4kPBYdtHMeg4IEZTaMWY0APlWXse0LDUyr1n3JIUADRv+ZLn Yki60zhoPbs= =hBv3 -----END PGP SIGNATURE-----